diff options
Diffstat (limited to 'plugins/pychrysalide')
| -rw-r--r-- | plugins/pychrysalide/arch/instruction.c | 369 | ||||
| -rw-r--r-- | plugins/pychrysalide/arch/operand.c | 112 | ||||
| -rw-r--r-- | plugins/pychrysalide/arch/operands/register.c | 2 | 
3 files changed, 437 insertions, 46 deletions
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c index ce554ee..881c6ff 100644 --- a/plugins/pychrysalide/arch/instruction.c +++ b/plugins/pychrysalide/arch/instruction.c @@ -26,10 +26,13 @@  #include <assert.h> +#include <string.h>  #include <pygobject.h> -#include <arch/instruction.h> +#include <i18n.h> +#include <arch/instruction-int.h> +#include <plugins/dt.h>  #include "vmpa.h" @@ -39,17 +42,83 @@ +/* -------------------- INTERFACE INTERNE POUR EXTENSIONS PYTHON -------------------- */ + + +/* Définition générique d'une instruction d'architecture (instance) */ +typedef struct _GPyArchInstruction +{ +    GArchInstruction parent;                /* A laisser en premier        */ + +    char *cached_keyword;                   /* Conservation de constante   */ + +} GPyArchInstruction; + + +/* Définition générique d'une instruction d'architecture (classe) */ +typedef struct _GPyArchInstructionClass +{ +    GArchInstructionClass parent;           /* A laisser en premier        */ + +} GPyArchInstructionClass; + + +#define G_TYPE_PYARCH_INSTRUCTION            g_pyarch_instruction_get_type() +#define G_PYARCH_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PYARCH_INSTRUCTION, GPyArchInstruction)) +#define G_IS_PYTHON_INSTRUCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PYARCH_INSTRUCTION)) +#define G_PYARCH_INSTRUCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PYARCH_INSTRUCTION, GPyArchInstructionClass)) +#define G_IS_PYTHON_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PYARCH_INSTRUCTION)) +#define G_PYARCH_INSTRUCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PYARCH_INSTRUCTION, GPyArchInstructionClass)) + + +/* Indique le type défini pour une instruction d'architecture en Python. */ +GType g_pyarch_instruction_get_type(void); + +/* Initialise la classe générique des instructions en Python. */ +static void g_pyarch_instruction_class_init(GPyArchInstructionClass *); + +/* Initialise une instance d'opérande d'architecture. */ +static void g_pyarch_instruction_init(GPyArchInstruction *); + +/* Supprime toutes les références externes. */ +static void g_pyarch_instruction_dispose(GPyArchInstruction *); + +/* Procède à la libération totale de la mémoire. */ +static void g_pyarch_instruction_finalize(GPyArchInstruction *); + +/* Fournit le nom humain de l'instruction manipulée. */ +static const char *g_pyarch_instruction_get_keyword(GPyArchInstruction *); + + + +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Accompagne la création d'une instance dérivée en Python. */ +static PyObject *py_arch_instruction_new(PyTypeObject *, PyObject *, PyObject *); + +/* Initialise la classe générique des instructions. */ +static void py_arch_instruction_init_gclass(GPyArchInstructionClass *, gpointer); + +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_arch_instruction_init(PyObject *, PyObject *, PyObject *); + +  /* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */ +/* Fournit les origines d'une instruction donnée. */ +static PyObject *py_arch_instruction_get_sources(PyObject *, void *); + +/* Fournit les destinations d'une instruction donnée. */ +static PyObject *py_arch_instruction_get_destinations(PyObject *, void *);  /* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */ -  /* Fournit l'identifiant unique pour un ensemble d'instructions. */  static PyObject *py_arch_instruction_get_unique_id(PyObject *, void *); @@ -59,44 +128,281 @@ static PyObject *py_arch_instruction_get_range(PyObject *, void *);  /* Définit la localisation d'une instruction. */  static int py_arch_instruction_set_range(PyObject *, PyObject *, void *); - -  /* Fournit le nom humain de l'instruction manipulée. */  static PyObject *py_arch_instruction_get_keyword(PyObject *, void *); - -  /* Fournit tous les opérandes d'une instruction. */  static PyObject *py_arch_instruction_get_operands(PyObject *, void *); +/* Définit les constantes pour les instructions. */ +static bool py_arch_instruction_define_constants(PyTypeObject *); +/* ---------------------------------------------------------------------------------- */ +/*                      INTERFACE INTERNE POUR EXTENSIONS PYTHON                      */ +/* ---------------------------------------------------------------------------------- */ -/* Définit les constantes pour les instructions. */ -static bool py_arch_instruction_define_constants(PyTypeObject *); +/* Indique le type défini pour une instruction d'architecture en Python. */ +G_DEFINE_TYPE(GPyArchInstruction, g_pyarch_instruction, G_TYPE_ARCH_INSTRUCTION); +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe générique des instructions en Python.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_pyarch_instruction_class_init(GPyArchInstructionClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GArchInstructionClass *instr;           /* Encore une autre vision...  */ + +    object = G_OBJECT_CLASS(klass); +    object->dispose = (GObjectFinalizeFunc/* ! */)g_pyarch_instruction_dispose; +    object->finalize = (GObjectFinalizeFunc)g_pyarch_instruction_finalize; +    instr = G_ARCH_INSTRUCTION_CLASS(klass); + +    instr->get_keyword = (get_instruction_keyword_fc)g_pyarch_instruction_get_keyword; + +} +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instance à initialiser.                              * +*                                                                             * +*  Description : Initialise une instance d'instruction d'architecture.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_pyarch_instruction_init(GPyArchInstruction *instr) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_pyarch_instruction_dispose(GPyArchInstruction *instr) +{ +    G_OBJECT_CLASS(g_pyarch_instruction_parent_class)->dispose(G_OBJECT(instr)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_pyarch_instruction_finalize(GPyArchInstruction *instr) +{ +    if (instr->cached_keyword) +        free(instr->cached_keyword); + +    G_OBJECT_CLASS(g_pyarch_instruction_parent_class)->finalize(G_OBJECT(instr)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction d'assemblage à consulter.                * +*                                                                             * +*  Description : Fournit le nom humain de l'instruction manipulée.            * +*                                                                             * +*  Retour      : Mot clef de bas niveau.                                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static const char *g_pyarch_instruction_get_keyword(GPyArchInstruction *instr) +{ +    const char *result;                     /* Désignation à retourner     */ + +    result = instr->cached_keyword; + +    return result; + +} +  /* ---------------------------------------------------------------------------------- */ -/*                     DEFINITION DES LIAISONS ENTRE INSTRUCTIONS                     */ +/*                          GLUE POUR CREATION DEPUIS PYTHON                          */  /* ---------------------------------------------------------------------------------- */ +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type du nouvel objet à mettre en place.               * +*                args = éventuelle liste d'arguments.                         * +*                kwds = éventuel dictionnaire de valeurs mises à disposition. * +*                                                                             * +*  Description : Accompagne la création d'une instance dérivée en Python.     * +*                                                                             * +*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +static PyObject *py_arch_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    PyObject *result;                       /* Objet à retourner           */ +    PyTypeObject *base;                     /* Type de base à dériver      */ +    bool first_time;                        /* Evite les multiples passages*/ +    GType gtype;                            /* Nouveau type de processeur  */ +    bool status;                            /* Bilan d'un enregistrement   */ -/* Fournit les origines d'une instruction donnée. */ -static PyObject *py_arch_instruction_get_sources(PyObject *, void *); +    /* Validations diverses */ -/* Fournit les destinations d'une instruction donnée. */ -static PyObject *py_arch_instruction_get_destinations(PyObject *, void *); +    base = get_python_arch_instruction_type(); + +    if (type == base) +    { +        result = NULL; +        PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name); +        goto exit; +    } + +    /* Mise en place d'un type dédié */ + +    first_time = (g_type_from_name(type->tp_name) == 0); + +    gtype = build_dynamic_type(G_TYPE_PYARCH_INSTRUCTION, type->tp_name, +                               (GClassInitFunc)py_arch_instruction_init_gclass, NULL, NULL); + +    if (first_time) +    { +        status = register_class_for_dynamic_pygobject(gtype, type, base); + +        if (!status) +        { +            result = NULL; +            goto exit; +        } + +    } + +    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + +    result = PyType_GenericNew(type, args, kwds); + + exit: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class  = classe à initialiser.                               * +*                unused = données non utilisées ici.                          * +*                                                                             * +*  Description : Initialise la classe générique des instructions.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void py_arch_instruction_init_gclass(GPyArchInstructionClass *class, gpointer unused) +{ +    /// .... + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = objet à initialiser (théoriquement).                  * +*                args = arguments fournis à l'appel.                          * +*                kwds = arguments de type key=val fournis.                    * +*                                                                             * +*  Description : Initialise une instance sur la base du dérivé de GObject.    * +*                                                                             * +*  Retour      : 0.                                                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kwds) +{ +    unsigned short int uid;                 /* Indentifiant unique de type */ +    const char *keyword;                    /* Désignation d'instruction   */ +    int ret;                                /* Bilan de lecture des args.  */ +    PyObject *new_kwds;                     /* Nouveau dictionnaire épuré  */ +    GPyArchInstruction *instr;              /* Instruction à manipuler     */ + +    static char *kwlist[] = { "uid", "keyword", NULL }; + +    /* Récupération des paramètres */ + +    ret = PyArg_ParseTupleAndKeywords(args, kwds, "Hs", kwlist, &uid, &keyword); +    if (!ret) return -1; + +    /* Initialisation d'un objet GLib */ + +    new_kwds = PyDict_New(); + +    ret = PyGObject_Type.tp_init(self, args, new_kwds); + +    Py_DECREF(new_kwds); + +    if (ret == -1) return -1; + +    /* Eléments de base */ +    instr = G_PYARCH_INSTRUCTION(pygobject_get(self)); +    instr->cached_keyword = strdup(keyword); + +    G_ARCH_INSTRUCTION(instr)->uid = uid; + +    return 0; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                     DEFINITION DES LIAISONS ENTRE INSTRUCTIONS                     */ +/* ---------------------------------------------------------------------------------- */  /****************************************************************************** @@ -218,13 +524,9 @@ static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unus - - - - - - - +/* ---------------------------------------------------------------------------------- */ +/*                       INSTRUCTIONS D'ARCHITECTURES EN PYTHON                       */ +/* ---------------------------------------------------------------------------------- */  /****************************************************************************** @@ -319,11 +621,6 @@ static int py_arch_instruction_set_range(PyObject *self, PyObject *value, void *  } - - - - -  /******************************************************************************  *                                                                             *  *  Paramètres  : self   = classe représentant une instruction.                * @@ -353,9 +650,6 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused)  } - - -  /******************************************************************************  *                                                                             *  *  Paramètres  : self   = objet représentant une instruction.                 * @@ -413,18 +707,6 @@ static PyObject *py_arch_instruction_get_operands(PyObject *self, void *unused)  } - - - - - - - - - - - -  /******************************************************************************  *                                                                             *  *  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        * @@ -518,6 +800,9 @@ PyTypeObject *get_python_arch_instruction_type(void)          .tp_methods     = py_arch_instruction_methods,          .tp_getset      = py_arch_instruction_getseters, +        .tp_init        = py_arch_instruction_init, +        .tp_new         = py_arch_instruction_new, +      };      return &py_arch_instruction_type; @@ -547,8 +832,6 @@ bool ensure_python_arch_instruction_is_registered(void)      if (!PyType_HasFeature(type, Py_TPFLAGS_READY))      { -        APPLY_ABSTRACT_FLAG(type); -          module = get_access_to_python_module("pychrysalide.arch");          dict = PyModule_GetDict(module); @@ -556,7 +839,7 @@ bool ensure_python_arch_instruction_is_registered(void)          if (!ensure_python_line_generator_is_registered())              return false; -        if (!_register_class_for_pygobject(dict, G_TYPE_ARCH_INSTRUCTION, type, +        if (!_register_class_for_pygobject(dict, G_TYPE_PYARCH_INSTRUCTION, type,                                             &PyGObject_Type, get_python_line_generator_type(), NULL))              return false; diff --git a/plugins/pychrysalide/arch/operand.c b/plugins/pychrysalide/arch/operand.c index e464eac..4630b3a 100644 --- a/plugins/pychrysalide/arch/operand.c +++ b/plugins/pychrysalide/arch/operand.c @@ -29,6 +29,7 @@  #include <arch/operand.h> +#include <plugins/dt.h>  #include "../access.h" @@ -36,6 +37,113 @@ +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Accompagne la création d'une instance dérivée en Python. */ +static PyObject *py_arch_operand_new(PyTypeObject *, PyObject *, PyObject *); + +/* Initialise la classe des descriptions de fichier binaire. */ +static void py_arch_operand_init_gclass(GArchOperandClass *, gpointer); + + + +/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */ + + + + +/* ---------------------------------------------------------------------------------- */ +/*                          GLUE POUR CREATION DEPUIS PYTHON                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type du nouvel objet à mettre en place.               * +*                args = éventuelle liste d'arguments.                         * +*                kwds = éventuel dictionnaire de valeurs mises à disposition. * +*                                                                             * +*  Description : Accompagne la création d'une instance dérivée en Python.     * +*                                                                             * +*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    PyObject *result;                       /* Objet à retourner           */ +    PyTypeObject *base;                     /* Type de base à dériver      */ +    bool first_time;                        /* Evite les multiples passages*/ +    GType gtype;                            /* Nouveau type de processeur  */ +    bool status;                            /* Bilan d'un enregistrement   */ + +    /* Validations diverses */ + +    base = get_python_arch_operand_type(); + +    if (type == base) +        goto simple_way; + +    /* Mise en place d'un type dédié */ + +    first_time = (g_type_from_name(type->tp_name) == 0); + +    gtype = build_dynamic_type(G_TYPE_ARCH_OPERAND, type->tp_name, +                               (GClassInitFunc)py_arch_operand_init_gclass, NULL, NULL); + +    if (first_time) +    { +        status = register_class_for_dynamic_pygobject(gtype, type, base); + +        if (!status) +        { +            result = NULL; +            goto exit; +        } + +    } + +    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + + simple_way: + +    result = PyType_GenericNew(type, args, kwds); + + exit: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class  = classe à initialiser.                               * +*                unused = données non utilisées ici.                          * +*                                                                             * +*  Description : Initialise la classe des descriptions de fichier binaire.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unused) +{ + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                          DEFINITION D'OPERANDE QUELCONQUE                          */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             *  *  Paramètres  : -                                                            * @@ -72,6 +180,8 @@ PyTypeObject *get_python_arch_operand_type(void)          .tp_methods     = py_arch_operand_methods,          .tp_getset      = py_arch_operand_getseters, +        .tp_new         = py_arch_operand_new, +      };      return &py_arch_operand_type; @@ -101,8 +211,6 @@ bool ensure_python_arch_operand_is_registered(void)      if (!PyType_HasFeature(type, Py_TPFLAGS_READY))      { -        APPLY_ABSTRACT_FLAG(type); -          module = get_access_to_python_module("pychrysalide.arch");          dict = PyModule_GetDict(module); diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c index 8144af0..3e77c9b 100644 --- a/plugins/pychrysalide/arch/operands/register.c +++ b/plugins/pychrysalide/arch/operands/register.c @@ -50,7 +50,7 @@ static PyObject *py_register_operand_new(PyTypeObject *, PyObject *, PyObject *)  static void py_register_operand_init_gclass(GRegisterOperandClass *, gpointer);  /* Initialise une instance sur la base du dérivé de GObject. */ -static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kwds); +static int py_register_operand_init(PyObject *, PyObject *, PyObject *);  | 
