diff options
Diffstat (limited to 'plugins/pychrysalide/analysis/routine.c')
-rw-r--r-- | plugins/pychrysalide/analysis/routine.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/plugins/pychrysalide/analysis/routine.c b/plugins/pychrysalide/analysis/routine.c index a95131d..fddc026 100644 --- a/plugins/pychrysalide/analysis/routine.c +++ b/plugins/pychrysalide/analysis/routine.c @@ -37,6 +37,7 @@ #include "block.h" +#include "type.h" #include "../helpers.h" #include "../format/symbol.h" @@ -48,15 +49,39 @@ static PyObject *py_binary_routine_to_str(PyObject *); /* Crée un nouvel objet Python de type 'BinRoutine'. */ static PyObject *py_binary_routine_new(PyTypeObject *, PyObject *, PyObject *); +/* Fournit le groupe d'appartenance d'une routine donnée. */ +static PyObject *py_binary_routine_get_namespace(PyObject *, void *); + +/* Définit le groupe d'appartenance d'une routine donnée. */ +static int py_binary_routine_set_namespace(PyObject *, PyObject *, void *); + /* Fournit le nom humain d'une routine. */ static PyObject *py_binary_routine_get_name(PyObject *, void *); /* Définit le nom humain d'une routine. */ static int py_binary_routine_set_name(PyObject *, PyObject *, void *); +/* Fournit le type construisant le nom humain d'une routine. */ +static PyObject *py_binary_routine_get_typed_name(PyObject *, void *); + +/* Définit de façon indirecte le nom humain d'une routine. */ +static int py_binary_routine_set_typed_name(PyObject *, PyObject *, void *); + +/* Fournit le type de retour d'une routine. */ +static PyObject *py_binary_routine_get_return_type(PyObject *, void *); + +/* Définit le type de retour d'une routine. */ +static int py_binary_routine_set_return_type(PyObject *, PyObject *, void *); + +/* Fournit la liste des arguments associés à la routine. */ +static PyObject *py_binary_routine_get_args(PyObject *, void *); + /* Fournit les blocs basiques de la routine. */ static PyObject *py_binary_routine_get_basic_blocks(PyObject *, void *); +/* Définit les blocs basiques de la routine. */ +static int py_binary_routine_set_basic_blocks(PyObject *, PyObject *, void *); + /****************************************************************************** @@ -120,6 +145,104 @@ static PyObject *py_binary_routine_new(PyTypeObject *type, PyObject *args, PyObj * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * +* Description : Fournit le groupe d'appartenance d'une routine donnée. * +* * +* Retour : Eventuelle instance d'appartenance ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_routine_get_namespace(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBinRoutine *routine; /* Elément à consulter */ + GDataType *ns; /* Espace de noms */ + + routine = G_BIN_ROUTINE(pygobject_get(self)); + ns = g_binary_routine_get_namespace(routine); + + if (ns != NULL) + { + result = pygobject_new(G_OBJECT(ns)); + g_object_unref(G_OBJECT(ns)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit le groupe d'appartenance d'une routine donnée. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_binary_routine_set_namespace(PyObject *self, PyObject *value, void *closure) +{ + GBinRoutine *routine; /* Elément à traiter */ + GDataType *ns; /* Espace de noms */ + char *sep; /* Séparateur des espaces */ + + if ((!PyTuple_Check(value) || (PyTuple_Check(value) && PyTuple_Size(value) != 2)) && value != Py_None) + { + PyErr_SetString(PyExc_TypeError, + _("The attribute value must be a tuple with GDataType and a separator or None.")); + return -1; + } + + routine = G_BIN_ROUTINE(pygobject_get(self)); + + if (value == Py_None) + g_binary_routine_set_namespace(routine, NULL, NULL); + + else + { + if (!PyObject_IsInstance(PyTuple_GetItem(value, 0), (PyObject *)get_python_data_type_type())) + { + PyErr_SetString(PyExc_TypeError, _("The first tuple item must be a GDataType.")); + return -1; + } + + if (!PyUnicode_Check(PyTuple_GetItem(value, 1))) + { + PyErr_SetString(PyExc_TypeError, _("The second tuple item must be a string.")); + return -1; + } + + ns = G_DATA_TYPE(pygobject_get(PyTuple_GetItem(value, 0))); + sep = strdup(PyUnicode_DATA(pygobject_get(PyTuple_GetItem(value, 1)))); + + g_object_ref(G_OBJECT(ns)); + g_binary_routine_set_namespace(routine, ns, sep); + + } + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * * Description : Fournit le nom humain d'une routine. * * * * Retour : Désignation humainement lisible ou None si non définie. * @@ -189,6 +312,214 @@ static int py_binary_routine_set_name(PyObject *self, PyObject *value, void *clo /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type construisant le nom humain d'une routine. * +* * +* Retour : Eventuel type à l'origine du nom ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_routine_get_typed_name(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBinRoutine *routine; /* Elément à consulter */ + GDataType *name; /* Type de nom */ + + routine = G_BIN_ROUTINE(pygobject_get(self)); + name = g_binary_routine_get_typed_name(routine); + + if (name != NULL) + { + result = pygobject_new(G_OBJECT(name)); + g_object_unref(G_OBJECT(name)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit de façon indirecte le nom humain d'une routine. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_binary_routine_set_typed_name(PyObject *self, PyObject *value, void *closure) +{ + GBinRoutine *routine; /* Elément à traiter */ + GDataType *name; /* Type de nom */ + + if (!PyObject_IsInstance(value, (PyObject *)get_python_data_type_type()) && value != Py_None) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a GDataType or None.")); + return -1; + } + + routine = G_BIN_ROUTINE(pygobject_get(self)); + + if (value == Py_None) + g_binary_routine_set_return_type(routine, NULL); + + else + { + name = G_DATA_TYPE(pygobject_get(value)); + + g_object_ref(G_OBJECT(name)); + g_binary_routine_set_typed_name(routine, name); + + } + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type de retour d'une routine. * +* * +* Retour : Indication sur le type de retour en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_routine_get_return_type(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBinRoutine *routine; /* Elément à consulter */ + GDataType *ret; /* Type de retour */ + + routine = G_BIN_ROUTINE(pygobject_get(self)); + ret = g_binary_routine_get_return_type(routine); + + if (ret != NULL) + { + result = pygobject_new(G_OBJECT(ret)); + g_object_unref(G_OBJECT(ret)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit le type de retour d'une routine. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_binary_routine_set_return_type(PyObject *self, PyObject *value, void *closure) +{ + GBinRoutine *routine; /* Elément à traiter */ + GDataType *ret; /* Type de retour */ + + if (!PyObject_IsInstance(value, (PyObject *)get_python_data_type_type()) && value != Py_None) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a GDataType or None.")); + return -1; + } + + routine = G_BIN_ROUTINE(pygobject_get(self)); + + if (value == Py_None) + g_binary_routine_set_return_type(routine, NULL); + + else + { + ret = G_DATA_TYPE(pygobject_get(value)); + + g_object_ref(G_OBJECT(ret)); + g_binary_routine_set_return_type(routine, ret); + + } + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une routine binaire. * +* closure = adresse non utilisée ici. * +* * +* Description : Fournit la liste des arguments associés à la routine. * +* * +* Retour : Ensemble de blocs déterminés via les instructions. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_routine_get_args(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GBinRoutine *routine; /* Version native */ + size_t count; /* Nombre de paramètres */ + size_t i; /* Boucle de parcours */ + GBinVariable *arg; /* Argument à transcrire */ + + routine = G_BIN_ROUTINE(pygobject_get(self)); + + count = g_binary_routine_get_args_count(routine); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + arg = g_binary_routine_get_arg(routine, i); + + PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(arg))); + + g_object_unref(arg); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = classe représentant une routine binaire. * * closure = adresse non utilisée ici. * * * @@ -269,10 +600,26 @@ PyTypeObject *get_python_binary_routine_type(void) static PyGetSetDef py_binary_routine_getseters[] = { { + "namespace", py_binary_routine_get_namespace, py_binary_routine_set_namespace, + "Namespace for the routine, None if any.", NULL + }, + { "name", py_binary_routine_get_name, py_binary_routine_set_name, "Name of the current routine.", NULL }, { + "typed_name", py_binary_routine_get_typed_name, py_binary_routine_set_typed_name, + "Name of the current routine provided by a type.", NULL + }, + { + "ret", py_binary_routine_get_return_type, py_binary_routine_set_return_type, + "Return type of the routine, None if any.", NULL + }, + { + "args", py_binary_routine_get_args, NULL, + "Arguments for the routine.", NULL + }, + { "basic_blocks", py_binary_routine_get_basic_blocks, py_binary_routine_set_basic_blocks, "Basic blocks of the binary routine.", NULL }, |