From a857e1e9db9d298b7aa91e8f618e6c0ea4db84ac Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 7 Jul 2018 12:49:20 +0200 Subject: Extended the types API. --- plugins/itanium/component.c | 77 ++++++- plugins/pychrysalide/analysis/module.c | 2 + plugins/pychrysalide/analysis/routine.c | 347 +++++++++++++++++++++++++++++++ plugins/pychrysalide/analysis/type.c | 304 +++++++++++++++++++++++++++ plugins/pychrysalide/analysis/variable.c | 2 +- src/analysis/routine.c | 24 ++- src/analysis/routine.h | 4 +- src/analysis/type.c | 43 ++++ src/analysis/type.h | 10 + 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 +#include + + #include @@ -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 #include #include #include @@ -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 *); -- cgit v0.11.2-87-g4458