summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/itanium/component.c77
-rw-r--r--plugins/pychrysalide/analysis/module.c2
-rw-r--r--plugins/pychrysalide/analysis/routine.c347
-rw-r--r--plugins/pychrysalide/analysis/type.c304
-rw-r--r--plugins/pychrysalide/analysis/variable.c2
-rw-r--r--src/analysis/routine.c24
-rw-r--r--src/analysis/routine.h4
-rw-r--r--src/analysis/type.c43
-rw-r--r--src/analysis/type.h10
9 files changed, 797 insertions, 16 deletions
diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c
index b8aa9c5..c2bf78a 100644
--- a/plugins/itanium/component.c
+++ b/plugins/itanium/component.c
@@ -60,6 +60,9 @@ static void visit_comp(itanium_component *, visit_comp_fc);
/* Traduit les composants de contexte Itanium en décalage. */
static bool itd_translate_component_to_offset(const itanium_component *, call_offset_t *);
+/* Ajoute un espace de noms à un type déjà préparé. */
+static void itd_prepend_namespace_to_type(GDataType *, GDataType *);
+
/******************************************************************************
@@ -1279,6 +1282,39 @@ static bool itd_translate_component_to_offset(const itanium_component *comp, cal
/******************************************************************************
* *
+* Paramètres : type = type à traiter. *
+* ns = espace à intégrer. *
+* *
+* Description : Ajoute un espace de noms à un type déjà préparé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void itd_prepend_namespace_to_type(GDataType *type, GDataType *ns)
+{
+ GDataType *existing; /* Espace en place ? */
+
+ existing = g_data_type_get_namespace(type);
+
+ if (existing == NULL)
+ g_data_type_set_namespace(type, ns, "::");
+
+ else
+ {
+ itd_prepend_namespace_to_type(existing, ns);
+
+ g_object_unref(G_OBJECT(existing));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : comp = composant Itanium à traduire en type. *
* *
* Description : Traduit les composants de contexte Itanium en type. *
@@ -1294,6 +1330,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
GDataType *result; /* Type à retourner */
char *name; /* Attribution finale */
GDataType *ns; /* Espace de noms d'un type */
+ GDataType *sub; /* Sous-titre à traiter */
call_offset_t off0; /* Décalage #0 */
call_offset_t off1; /* Décalage #1 */
itanium_component *iter; /* Boucle de parcours */
@@ -1316,7 +1353,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
if (result != NULL)
{
ns = g_class_enum_type_new(CET_NAMESPACE, strdup("std"));
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
break;
@@ -1348,7 +1385,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
result = itd_translate_component_to_type(comp->binary.right);
if (result != NULL && ns != NULL)
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
@@ -1360,8 +1397,30 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
if (result != NULL)
{
- name = itd_translate_component(comp->binary.left, NULL);
+ sub = itd_translate_component_to_type(comp->binary.left);
+
+ if (sub == NULL)
+ {
+ name = itd_translate_component(comp->binary.left, NULL);
+ ns = NULL;
+ }
+
+ else
+ {
+ ns = g_data_type_get_namespace(sub);
+ g_data_type_set_namespace(sub, NULL, NULL);
+
+ name = g_data_type_to_string(sub, true);
+
+ g_object_unref(G_OBJECT(sub));
+
+ }
+
g_template_type_set_name(G_TEMPLATE_TYPE(result), name);
+
+ if (ns != NULL)
+ itd_prepend_namespace_to_type(result, ns);
+
}
break;
@@ -1389,7 +1448,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
result = itd_translate_component_to_type(comp->binary.right);
if (result != NULL)
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
@@ -1426,7 +1485,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
if (result != NULL)
{
if (ns != NULL)
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
else
{
@@ -1452,7 +1511,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
else
{
result = g_class_enum_type_new(CET_VIRTUAL_TABLE, NULL);
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
break;
@@ -1467,7 +1526,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
else
{
result = g_class_enum_type_new(CET_VIRTUAL_STRUCT, NULL);
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
break;
@@ -1635,7 +1694,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp)
g_object_unref(G_OBJECT(ns));
else
- g_data_type_set_namespace(result, ns, "::");
+ itd_prepend_namespace_to_type(result, ns);
}
@@ -1773,7 +1832,7 @@ GBinRoutine *itd_translate_component_to_routine(const itanium_component *comp)
g_data_type_set_namespace(type, NULL, NULL);
if (G_IS_TEMPLATE_TYPE(type))
- g_binary_routine_set_name_from_type(result, type);
+ g_binary_routine_set_typed_name(result, type);
else
{
diff --git a/plugins/pychrysalide/analysis/module.c b/plugins/pychrysalide/analysis/module.c
index 614adf0..60f08ce 100644
--- a/plugins/pychrysalide/analysis/module.c
+++ b/plugins/pychrysalide/analysis/module.c
@@ -39,6 +39,7 @@
#include "variable.h"
#include "contents/module.h"
#include "db/module.h"
+#include "types/module.h"
#include "../access.h"
@@ -103,6 +104,7 @@ bool add_analysis_module_to_python_module(PyObject *super)
result &= add_analysis_contents_module_to_python_module(module);
result &= add_analysis_db_module_to_python_module(module);
+ result &= add_analysis_types_module_to_python_module(module);
if (result)
register_access_to_python_module("pychrysalide.analysis", module);
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
},
diff --git a/plugins/pychrysalide/analysis/type.c b/plugins/pychrysalide/analysis/type.c
index 146e490..3694877 100644
--- a/plugins/pychrysalide/analysis/type.c
+++ b/plugins/pychrysalide/analysis/type.c
@@ -29,6 +29,9 @@
#include <pygobject.h>
+#include <i18n.h>
+
+
#include <analysis/type.h>
@@ -39,6 +42,27 @@
/* Décrit le type fourni sous forme de caractères. */
static PyObject *py_data_type_to_str(PyObject *);
+/* Fournit le groupe d'appartenance d'un type donné. */
+static PyObject *py_data_type_get_namespace(PyObject *, void *);
+
+/* Définit le groupe d'appartenance d'un type donné. */
+static int py_data_type_set_namespace(PyObject *, PyObject *, void *);
+
+/* Fournit les qualificatifs associés à une instance de type. */
+static PyObject *py_data_type_get_qualifiers(PyObject *, void *);
+
+/* Définit l'ensemble des qualificatifs d'une instance de type. */
+static int py_data_type_set_qualifiers(PyObject *, PyObject *, void *);
+
+/* Indique si le type est un pointeur. */
+static PyObject *py_data_type_is_pointer(PyObject *, void *);
+
+/* Indique si le type est une référence. */
+static PyObject *py_data_type_is_reference(PyObject *, void *);
+
+/* Définit les constantes pour les types de données. */
+static bool py_data_type_define_constants(PyTypeObject *);
+
/******************************************************************************
@@ -74,6 +98,237 @@ static PyObject *py_data_type_to_str(PyObject *self)
/******************************************************************************
* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit le groupe d'appartenance d'un type donné. *
+* *
+* Retour : Eventuelle instance d'appartenance ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_get_namespace(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDataType *type; /* Elément à consulter */
+ GDataType *ns; /* Espace de noms */
+
+ type = G_DATA_TYPE(pygobject_get(self));
+ ns = g_data_type_get_namespace(type);
+
+ 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'un type donné. *
+* *
+* Retour : Bilan de l'opération pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_data_type_set_namespace(PyObject *self, PyObject *value, void *closure)
+{
+ GDataType *type; /* 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;
+ }
+
+ type = G_DATA_TYPE(pygobject_get(self));
+
+ if (value == Py_None)
+ g_data_type_set_namespace(type, 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_data_type_set_namespace(type, ns, sep);
+
+ }
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit les qualificatifs associés à une instance de type. *
+* *
+* Retour : Qualificatifs éventuels. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_get_qualifiers(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDataType *type; /* Elément à consulter */
+ TypeQualifier qualifiers; /* Qualificatifs en place */
+
+ type = G_DATA_TYPE(pygobject_get(self));
+ qualifiers = g_data_type_get_qualifiers(type);
+
+ result = PyLong_FromUnsignedLong(qualifiers);
+
+ 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 l'ensemble des qualificatifs d'une instance de type. *
+* *
+* Retour : Bilan de l'opération pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_data_type_set_qualifiers(PyObject *self, PyObject *value, void *closure)
+{
+ GDataType *type; /* Elément à traiter */
+ unsigned long qualifiers; /* Qualificatifs à intégrer */
+
+ if (!PyLong_Check(value))
+ {
+ PyErr_SetString(PyExc_TypeError, _("The attribute value must be a integer mask."));
+ return -1;
+ }
+
+ qualifiers = PyLong_AsUnsignedLong(value);
+
+ if (qualifiers > TQF_ALL)
+ {
+ PyErr_SetString(PyExc_TypeError, _("Invalid value for type qualifiers."));
+ return -1;
+ }
+
+ type = G_DATA_TYPE(pygobject_get(self));
+
+ g_data_type_set_qualifiers(type, qualifiers);
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique si le type est un pointeur. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_is_pointer(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDataType *type; /* Elément à consulter */
+ bool status; /* Etat à faire suivre */
+
+ type = G_DATA_TYPE(pygobject_get(self));
+
+ status = g_data_type_is_pointer(type);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique si le type est une référence. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_data_type_is_reference(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDataType *type; /* Elément à consulter */
+ bool status; /* Etat à faire suivre */
+
+ type = G_DATA_TYPE(pygobject_get(self));
+
+ status = g_data_type_is_reference(type);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -91,6 +346,22 @@ PyTypeObject *get_python_data_type_type(void)
};
static PyGetSetDef py_data_type_getseters[] = {
+ {
+ "namespace", py_data_type_get_namespace, py_data_type_set_namespace,
+ "Namespace for the type, None if any.", NULL
+ },
+ {
+ "qualifiers", py_data_type_get_qualifiers, py_data_type_set_qualifiers,
+ "Qualifiers linked to the type, TQF_NONE if any.", NULL
+ },
+ {
+ "is_pointer", py_data_type_is_pointer, NULL,
+ "True if the type is a pointer.", NULL
+ },
+ {
+ "is_reference", py_data_type_is_reference, NULL,
+ "True if the type is a reference.", NULL
+ },
{ NULL }
};
@@ -118,6 +389,36 @@ PyTypeObject *get_python_data_type_type(void)
/******************************************************************************
* *
+* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour les types de données. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_data_type_define_constants(PyTypeObject *obj_type)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ result &= PyDict_AddIntMacro(obj_type, TQF_NONE);
+ result &= PyDict_AddIntMacro(obj_type, TQF_RESTRICT);
+ result &= PyDict_AddIntMacro(obj_type, TQF_VOLATILE);
+ result &= PyDict_AddIntMacro(obj_type, TQF_CONST);
+
+ result &= PyDict_AddIntMacro(obj_type, TQF_ALL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : module = module dont la définition est à compléter. *
* *
* Description : Prend en charge l'objet 'pychrysalide.analysis.DataType'. *
@@ -140,6 +441,9 @@ bool register_python_data_type(PyObject *module)
if (!register_class_for_pygobject(dict, G_TYPE_DATA_TYPE, py_data_type_type, &PyGObject_Type))
return false;
+ if (!py_data_type_define_constants(py_data_type_type))
+ return false;
+
return true;
}
diff --git a/plugins/pychrysalide/analysis/variable.c b/plugins/pychrysalide/analysis/variable.c
index 7437e54..268e3c9 100644
--- a/plugins/pychrysalide/analysis/variable.c
+++ b/plugins/pychrysalide/analysis/variable.c
@@ -167,7 +167,7 @@ static PyObject *py_binary_variable_get_name(PyObject *self, void *closure)
static int py_binary_variable_set_name(PyObject *self, PyObject *value, void *closure)
{
- GBinVariable *variable; /* Elément à consulter */
+ GBinVariable *variable; /* Elément à traiter */
if (!PyUnicode_Check(value) && value != Py_None)
{
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index 43097cc..d223165 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -24,6 +24,7 @@
#include "routine.h"
+#include <assert.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
@@ -341,7 +342,7 @@ const char *g_binary_routine_get_name(const GBinRoutine *routine)
* *
******************************************************************************/
-void g_binary_routine_set_name_from_type(GBinRoutine *routine, GDataType *type)
+void g_binary_routine_set_typed_name(GBinRoutine *routine, GDataType *type)
{
if (routine->full_name != NULL)
g_object_unref(G_OBJECT(routine->full_name));
@@ -363,7 +364,7 @@ void g_binary_routine_set_name_from_type(GBinRoutine *routine, GDataType *type)
* *
******************************************************************************/
-GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *routine)
+GDataType *g_binary_routine_get_typed_name(const GBinRoutine *routine)
{
GDataType *result; /* Type à retourner */
@@ -486,7 +487,22 @@ size_t g_binary_routine_get_args_count(const GBinRoutine *routine)
GBinVariable *g_binary_routine_get_arg(GBinRoutine *routine, size_t index)
{
- return routine->args[index];
+ GBinVariable *result; /* Argument à retourner */
+
+ assert(index < routine->args_count);
+
+ if (index >= routine->args_count)
+ result = NULL;
+
+ else
+ {
+ result = routine->args[index];
+
+ g_object_ref(G_OBJECT(result));
+
+ }
+
+ return result;
}
@@ -537,7 +553,7 @@ static char *g_binary_routine_get_label(const GBinRoutine *routine)
char *result; /* Etiquette à renvoyer */
if (routine->full_name != NULL)
- result = g_data_type_to_string(routine->full_name, false);
+ result = g_data_type_to_string(routine->full_name, true);
else
result = strdup(routine->name != NULL ? routine->name : "");
diff --git a/src/analysis/routine.h b/src/analysis/routine.h
index 0a4917f..9671c92 100644
--- a/src/analysis/routine.h
+++ b/src/analysis/routine.h
@@ -87,10 +87,10 @@ void g_binary_routine_set_name(GBinRoutine *, char *);
const char *g_binary_routine_get_name(const GBinRoutine *);
/* Définit de façon indirecte le nom humain d'une routine. */
-void g_binary_routine_set_name_from_type(GBinRoutine *, GDataType *);
+void g_binary_routine_set_typed_name(GBinRoutine *, GDataType *);
/* Fournit le type construisant le nom humain d'une routine. */
-GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *);
+GDataType *g_binary_routine_get_typed_name(const GBinRoutine *);
/* Définit le type de retour d'une routine. */
void g_binary_routine_set_return_type(GBinRoutine *, GDataType *);
diff --git a/src/analysis/type.c b/src/analysis/type.c
index cc446cb..5c1878f 100644
--- a/src/analysis/type.c
+++ b/src/analysis/type.c
@@ -271,6 +271,26 @@ GDataType *g_data_type_get_namespace(const GDataType *type)
/******************************************************************************
* *
+* Paramètres : type = instance à mettre à jour. *
+* qualifiers = nouveaux qualificatifs pour la variable. *
+* *
+* Description : Définit l'ensemble des qualificatifs d'une instance de type. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers)
+{
+ type->qualifiers = qualifiers;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : type = instance à mettre à jour. *
* qualifier = nouveau qualificatif pour la variable. *
* *
@@ -291,6 +311,29 @@ void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier)
/******************************************************************************
* *
+* Paramètres : type = instance à consulter. *
+* *
+* Description : Fournit les qualificatifs associés à une instance de type. *
+* *
+* Retour : Qualificatifs éventuels. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+TypeQualifier g_data_type_get_qualifiers(const GDataType *type)
+{
+ TypeQualifier result; /* Qualificatifs à renvoyer */
+
+ result = type->qualifiers;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : type = type à consulter. *
* *
* Description : Indique si le type est un pointeur. *
diff --git a/src/analysis/type.h b/src/analysis/type.h
index bd80f18..a8a9d5f 100644
--- a/src/analysis/type.h
+++ b/src/analysis/type.h
@@ -56,6 +56,10 @@ typedef enum _TypeQualifier
} TypeQualifier;
+/* Masque de tous les qualificatifs */
+#define TQF_ALL ((1 << 3) - 1)
+
+
/* Indique le type défini pour un type quelconque. */
GType g_data_type_get_type(void);
@@ -71,9 +75,15 @@ void g_data_type_set_namespace(GDataType *, GDataType *, const char *);
/* Fournit le groupe d'appartenance d'un type donné. */
GDataType *g_data_type_get_namespace(const GDataType *);
+/* Définit l'ensemble des qualificatifs d'une instance de type. */
+void g_data_type_set_qualifiers(GDataType *, TypeQualifier);
+
/* Ajoute un qualificatif à une instance de type. */
void g_data_type_add_qualifier(GDataType *, TypeQualifier);
+/* Fournit les qualificatifs associés à une instance de type. */
+TypeQualifier g_data_type_get_qualifiers(const GDataType *);
+
/* Indique si le type est un pointeur. */
bool g_data_type_is_pointer(const GDataType *);