summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/analysis/routine.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/analysis/routine.c')
-rw-r--r--plugins/pychrysalide/analysis/routine.c347
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
},