From 78da8b1ad594ca24292eb0f047698bc952b7b961 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 3 May 2020 20:15:46 +0200 Subject: Defined the missing features required to build operands from Python. --- plugins/pychrysalide/arch/operand.c | 281 ++++++++++++++++++++++++- plugins/pychrysalide/arch/operand.h | 3 + plugins/pychrysalide/arch/operands/immediate.c | 101 +++++++++ plugins/pychrysalide/arch/operands/register.c | 146 +++++++++++++ plugins/pychrysalide/arch/operands/register.h | 3 + plugins/pychrysalide/arch/register.c | 18 +- plugins/pychrysalide/arch/register.h | 3 - src/arch/operands/immediate.c | 5 + src/arch/register.c | 4 +- 9 files changed, 543 insertions(+), 21 deletions(-) diff --git a/plugins/pychrysalide/arch/operand.c b/plugins/pychrysalide/arch/operand.c index e3c6dcf..f14a6cc 100644 --- a/plugins/pychrysalide/arch/operand.c +++ b/plugins/pychrysalide/arch/operand.c @@ -28,7 +28,8 @@ #include -#include +#include +#include #include @@ -43,14 +44,26 @@ /* 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. */ +/* Initialise la classe générique des opérandes. */ static void py_arch_operand_init_gclass(GArchOperandClass *, gpointer); +/* Compare un opérande avec un autre. */ +static int py_arch_operand___cmp___wrapper(const GArchOperand *, const GArchOperand *); + +/* Traduit un opérande en version humainement lisible. */ +static void py_arch_operand_print_wrapper(const GArchOperand *, GBufferLine *); + +/* Construit un petit résumé concis de l'opérande. */ +static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *, const GLoadedBinary *); + /* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */ +/* Effectue une comparaison avec un objet Python 'ArchOperand'. */ +static PyObject *py_arch_operand_richcompare(PyObject *, PyObject *, int); + /* ---------------------------------------------------------------------------------- */ @@ -80,12 +93,31 @@ static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObjec GType gtype; /* Nouveau type de processeur */ bool status; /* Bilan d'un enregistrement */ +#define ARCH_OPERAND_DOC \ + "The ArchOperand object aims to get subclassed to create" \ + " operands of any kind for new architectures.\n" \ + "\n" \ + "Calls to the *__init__* constructor of this abstract object expect"\ + " no particular argument.\n" \ + "\n" \ + "The following methods have to be defined for new classes:\n" \ + "* pychrysalide.arch.ArchRegister.__cmp__();\n" \ + "* pychrysalide.arch.ArchRegister._print();\n" \ + "* pychrysalide.arch.ArchRegister._build_tooltip().\n" \ + "\n" \ + "Chrysalide creates an internal glue to provide rich comparisons" \ + " for operands based on the old-style *__cmp__* function." + /* Validations diverses */ base = get_python_arch_operand_type(); if (type == base) - goto simple_way; + { + result = NULL; + PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name); + goto exit; + } /* Mise en place d'un type dédié */ @@ -108,8 +140,6 @@ static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObjec /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ - simple_way: - result = PyType_GenericNew(type, args, kwds); exit: @@ -124,7 +154,7 @@ static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObjec * Paramètres : class = classe à initialiser. * * unused = données non utilisées ici. * * * -* Description : Initialise la classe des descriptions de fichier binaire. * +* Description : Initialise la classe générique des opérandes. * * * * Retour : - * * * @@ -134,6 +164,193 @@ static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObjec static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unused) { + class->compare = py_arch_operand___cmp___wrapper; + class->print = py_arch_operand_print_wrapper; + class->build_tooltip = py_arch_operand_build_tooltip_wrapper; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_arch_operand___cmp___wrapper(const GArchOperand *a, const GArchOperand *b) +{ + int result; /* Empreinte à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + +#define ARCH_OPERAND_CMP_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + __cmp__, "$self, other, /", \ + METH_VARARGS, \ + "Abstract method used to compare the operand with another" \ + " one. This second object is always an" \ + " pychrysalide.arch.ArchOperand instance.\n" \ + "\n" \ + " This is the Python old-style comparison method, but" \ + " Chrysalide provides a glue to automatically build a rich" \ + " version of this function." \ +) + + result = 0; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(a)); + + if (has_python_method(pyobj, "__cmp__")) + { + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(b))); + + pyret = run_python_method(pyobj, "__cmp__", args); + + if (pyret != NULL) + { + if (PyLong_Check(pyret)) + result = PyLong_AsLong(pyret); + } + + Py_DECREF(args); + + Py_XDECREF(pyret); + + } + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = registre visé par la procédure. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_arch_operand_print_wrapper(const GArchOperand *operand, GBufferLine *line) +{ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + +#define ARCH_OPERAND_PRINT_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _print, "$self, line, /", \ + METH_VARARGS, \ + "Abstract method used to print the operand into a rendering" \ + " line, which is a provided pychrysalide.glibext.BufferLine" \ + " instance." \ +) + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(operand)); + + if (has_python_method(pyobj, "_print")) + { + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(line))); + + pyret = run_python_method(pyobj, "_print", args); + + Py_DECREF(args); + + Py_XDECREF(pyret); + + } + + PyGILState_Release(gstate); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* binary = informations relatives au binaire chargé. * +* * +* Description : Construit un petit résumé concis de l'opérande. * +* * +* Retour : Chaîne de caractères à libérer après usage ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *operand, const GLoadedBinary *binary) +{ + char *result; /* Description à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + int ret; /* Bilan d'une conversion */ + +#define ARCH_OPERAND_BUILD_TOOLTIP_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _build_tooltip, "$self, line, /", \ + METH_VARARGS, \ + "Abstract method used to build a tooltip text shown when the" \ + " mouse is over the operand.\n" \ + "\n" \ + "A pychrysalide.analysis.LoadedBinary instance is provided in" \ + " case of need." \ +) + + result = NULL; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(operand)); + + if (has_python_method(pyobj, "_build_tooltip")) + { + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary))); + + pyret = run_python_method(pyobj, "_build_tooltip", args); + + if (pyret != NULL) + { + ret = PyUnicode_Check(pyret); + + if (ret) + result = strdup(PyUnicode_AsUTF8(pyret)); + + Py_DECREF(pyret); + + } + + Py_DECREF(args); + + } + + PyGILState_Release(gstate); + + return result; } @@ -146,6 +363,51 @@ static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unuse /****************************************************************************** * * +* Paramètres : a = premier object Python à consulter. * +* b = second object Python à consulter. * +* op = type de comparaison menée. * +* * +* Description : Effectue une comparaison avec un objet Python 'ArchOperand'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_operand_richcompare(PyObject *a, PyObject *b, int op) +{ + PyObject *result; /* Bilan à retourner */ + int ret; /* Bilan de lecture des args. */ + const GArchOperand *reg_a; /* Premier élément à traiter */ + const GArchOperand *reg_b; /* Second élément à traiter */ + int status; /* Résultat d'une comparaison */ + + ret = PyObject_IsInstance(b, (PyObject *)get_python_arch_operand_type()); + if (!ret) + { + result = Py_NotImplemented; + goto cmp_done; + } + + reg_a = G_ARCH_OPERAND(pygobject_get(a)); + reg_b = G_ARCH_OPERAND(pygobject_get(b)); + + status = py_arch_operand___cmp___wrapper(reg_a, reg_b); + + result = status_to_rich_cmp_state(status, op); + + cmp_done: + + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -159,6 +421,9 @@ static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unuse PyTypeObject *get_python_arch_operand_type(void) { static PyMethodDef py_arch_operand_methods[] = { + ARCH_OPERAND_CMP_WRAPPER, + ARCH_OPERAND_PRINT_WRAPPER, + ARCH_OPERAND_BUILD_TOOLTIP_WRAPPER, { NULL } }; @@ -175,7 +440,9 @@ PyTypeObject *get_python_arch_operand_type(void) .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE, - .tp_doc = "PyChrysalide instruction operand.", + .tp_doc = ARCH_OPERAND_DOC, + + .tp_richcompare = py_arch_operand_richcompare, .tp_methods = py_arch_operand_methods, .tp_getset = py_arch_operand_getseters, diff --git a/plugins/pychrysalide/arch/operand.h b/plugins/pychrysalide/arch/operand.h index fdbc4ba..9cb40a0 100644 --- a/plugins/pychrysalide/arch/operand.h +++ b/plugins/pychrysalide/arch/operand.h @@ -31,6 +31,9 @@ +/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */ + + /* Fournit un accès à une définition de type à diffuser. */ PyTypeObject *get_python_arch_operand_type(void); diff --git a/plugins/pychrysalide/arch/operands/immediate.c b/plugins/pychrysalide/arch/operands/immediate.c index 39ce2e2..2634352 100644 --- a/plugins/pychrysalide/arch/operands/immediate.c +++ b/plugins/pychrysalide/arch/operands/immediate.c @@ -42,6 +42,7 @@ #include "../../access.h" #include "../../helpers.h" #include "../../analysis/content.h" +#include "../../glibext/bufferline.h" @@ -51,6 +52,12 @@ /* Crée un nouvel objet Python de type 'ImmOperand'. */ static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *); +/* Compare un opérande avec un autre. */ +static PyObject *py_imm_operand___cmp__(PyObject *, PyObject *); + +/* Traduit un opérande en version humainement lisible. */ +static PyObject *py_imm_operand__print(PyObject *, PyObject *); + /* Renseigne la taille de la valeur indiquée à la construction. */ static PyObject *py_imm_operand_get_size(PyObject *, void *); @@ -158,6 +165,98 @@ static PyObject *py_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject /****************************************************************************** * * +* Paramètres : self = serveur à manipuler. * +* args = arguments associés à l'appel. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_imm_operand___cmp__(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + GImmOperand *other; /* Autre opérande à manipuler */ + int ret; /* Bilan de lecture des args. */ + GImmOperand *operand; /* Elément à manipuler */ + int status; /* Bilan de comparaison */ + +#define IMM_OPERAND_CMP_METHOD PYTHON_METHOD_DEF \ +( \ + __cmp__, "$self, other, /", \ + METH_VARARGS, py_imm_operand, \ + "Implementation of the required method used to compare the" \ + " operand with another one. This second object is always" \ + " an pychrysalide.arch.ImmOperand instance.\n" \ + "\n" \ + "See the parent class for more information about this method." \ +) + + ret = PyArg_ParseTuple(args, "O&", convert_to_imm_operand, &other); + if (!ret) return NULL; + + operand = G_IMM_OPERAND(pygobject_get(self)); + + status = g_arch_operand_compare(G_ARCH_OPERAND(operand), G_ARCH_OPERAND(other)); + + result = PyLong_FromLong(status); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = serveur à manipuler. * +* args = arguments associés à l'appel. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_imm_operand__print(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + GBufferLine *line; /* Ligne fournie à peupler */ + int ret; /* Bilan de lecture des args. */ + GImmOperand *operand; /* Elément à manipuler */ + +#define IMM_OPERAND_PRINT_METHOD PYTHON_METHOD_DEF \ +( \ + _print, "$self, line, /", \ + METH_VARARGS, py_imm_operand, \ + "Implementation of the required method used to print the operand" \ + " into a rendering line, which is a provided" \ + " pychrysalide.glibext.BufferLine instance.\n" \ + "\n" \ + "See the parent class for more information about this method." \ +) + + ret = PyArg_ParseTuple(args, "O&", convert_to_buffer_line, &line); + if (!ret) return NULL; + + operand = G_IMM_OPERAND(pygobject_get(self)); + + g_arch_operand_print(G_ARCH_OPERAND(operand), line); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -614,6 +713,8 @@ static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *clo PyTypeObject *get_python_imm_operand_type(void) { static PyMethodDef py_imm_operand_methods[] = { + IMM_OPERAND_CMP_METHOD, + IMM_OPERAND_PRINT_METHOD, { NULL } }; diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c index 300fd99..ac91945 100644 --- a/plugins/pychrysalide/arch/operands/register.c +++ b/plugins/pychrysalide/arch/operands/register.c @@ -37,6 +37,7 @@ #include "../register.h" #include "../../access.h" #include "../../helpers.h" +#include "../../glibext/bufferline.h" @@ -57,6 +58,12 @@ static int py_register_operand_init(PyObject *, PyObject *, PyObject *); /* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ +/* Compare un opérande avec un autre. */ +static PyObject *py_register_operand___cmp__(PyObject *, PyObject *); + +/* Traduit un opérande en version humainement lisible. */ +static PyObject *py_register_operand__print(PyObject *, PyObject *); + /* Fournit le registre associé à l'opérande. */ static PyObject *py_register_operand_get_register(PyObject *, void *); @@ -220,6 +227,98 @@ static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kw /****************************************************************************** * * +* Paramètres : self = serveur à manipuler. * +* args = arguments associés à l'appel. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_register_operand___cmp__(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + GRegisterOperand *other; /* Autre opérande à manipuler */ + int ret; /* Bilan de lecture des args. */ + GRegisterOperand *operand; /* Elément à manipuler */ + int status; /* Bilan de comparaison */ + +#define REGISTER_OPERAND_CMP_METHOD PYTHON_METHOD_DEF \ +( \ + __cmp__, "$self, other, /", \ + METH_VARARGS, py_register_operand, \ + "Implementation of the required method used to compare the" \ + " operand with another one. This second object is always" \ + " a pychrysalide.arch.RegisterOperand instance.\n" \ + "\n" \ + "See the parent class for more information about this method." \ +) + + ret = PyArg_ParseTuple(args, "O&", convert_to_register_operand, &other); + if (!ret) return NULL; + + operand = G_REGISTER_OPERAND(pygobject_get(self)); + + status = g_arch_operand_compare(G_ARCH_OPERAND(operand), G_ARCH_OPERAND(other)); + + result = PyLong_FromLong(status); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = serveur à manipuler. * +* args = arguments associés à l'appel. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_register_operand__print(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + GBufferLine *line; /* Ligne fournie à peupler */ + int ret; /* Bilan de lecture des args. */ + GRegisterOperand *operand; /* Elément à manipuler */ + +#define REGISTER_OPERAND_PRINT_METHOD PYTHON_METHOD_DEF \ +( \ + _print, "$self, line, /", \ + METH_VARARGS, py_register_operand, \ + "Implementation of the required method used to print the operand" \ + " into a rendering line, which is a provided" \ + " pychrysalide.glibext.BufferLine instance.\n" \ + "\n" \ + "See the parent class for more information about this method." \ +) + + ret = PyArg_ParseTuple(args, "O&", convert_to_buffer_line, &line); + if (!ret) return NULL; + + operand = G_REGISTER_OPERAND(pygobject_get(self)); + + g_arch_operand_print(G_ARCH_OPERAND(operand), line); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -317,6 +416,8 @@ static PyObject *py_register_operand_is_written(PyObject *self, void *closure) PyTypeObject *get_python_register_operand_type(void) { static PyMethodDef py_register_operand_methods[] = { + REGISTER_OPERAND_CMP_METHOD, + REGISTER_OPERAND_PRINT_METHOD, { NULL } }; @@ -384,3 +485,48 @@ bool ensure_python_register_operand_is_registered(void) return true; } + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en opérande de registre. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_register_operand(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_register_operand_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to register operand"); + break; + + case 1: + *((GRegisterOperand **)dst) = G_REGISTER_OPERAND(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/arch/operands/register.h b/plugins/pychrysalide/arch/operands/register.h index 5fac7c9..4d3fa4b 100644 --- a/plugins/pychrysalide/arch/operands/register.h +++ b/plugins/pychrysalide/arch/operands/register.h @@ -40,6 +40,9 @@ PyTypeObject *get_python_register_operand_type(void); /* Prend en charge l'objet 'pychrysalide.arch.operands.RegisterOperand'. */ bool ensure_python_register_operand_is_registered(void); +/* Tente de convertir en opérande de registre. */ +int convert_to_register_operand(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_REGISTER_H */ diff --git a/plugins/pychrysalide/arch/register.c b/plugins/pychrysalide/arch/register.c index 84d3180..2a407b5 100644 --- a/plugins/pychrysalide/arch/register.c +++ b/plugins/pychrysalide/arch/register.c @@ -45,7 +45,7 @@ /* Accompagne la création d'une instance dérivée en Python. */ static PyObject *py_arch_register_new(PyTypeObject *, PyObject *, PyObject *); -/* Initialise la classe des descriptions de fichier binaire. */ +/* Initialise la classe des registres. */ static void py_arch_register_init_gclass(GArchRegisterClass *, gpointer); /* Produit une empreinte à partir d'un registre. */ @@ -169,7 +169,7 @@ static PyObject *py_arch_register_new(PyTypeObject *type, PyObject *args, PyObje * Paramètres : class = classe à initialiser. * * unused = données non utilisées ici. * * * -* Description : Initialise la classe des descriptions de fichier binaire. * +* Description : Initialise la classe des registres. * * * * Retour : - * * * @@ -245,8 +245,8 @@ static guint py_arch_register___hash___wrapper(const GArchRegister *reg) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : a = premier registre à consulter. * +* b = second registre à consulter. * * * * Description : Compare un registre avec un autre. * * * @@ -268,13 +268,13 @@ static int py_arch_register___cmp___wrapper(const GArchRegister *a, const GArchR ( \ __cmp__, "$self, other, /", \ METH_VARARGS, \ - "Abstract method used to produce a compare the register" \ - " with another one. This second object is always an" \ + "Abstract method used to compare the register with another" \ + " one. This second object is always an" \ " pychrysalide.arch.ArchRegister instance.\n" \ "\n" \ - " This is the old-style comparison method, but Chrysalide" \ - " provides a glue to automatically build a rich version of" \ - " this function." \ + " This is the Python old-style comparison method, but" \ + " Chrysalide provides a glue to automatically build a rich" \ + " version of this function." \ ) result = 0; diff --git a/plugins/pychrysalide/arch/register.h b/plugins/pychrysalide/arch/register.h index 9ae8fee..63aeaa4 100644 --- a/plugins/pychrysalide/arch/register.h +++ b/plugins/pychrysalide/arch/register.h @@ -30,9 +30,6 @@ #include -#include - - /* ---------------------------- PUR REGISTRE DU MATERIEL ---------------------------- */ diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c index e2cf5e6..769826b 100644 --- a/src/arch/operands/immediate.c +++ b/src/arch/operands/immediate.c @@ -1825,6 +1825,9 @@ static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface static void g_known_imm_operand_dispose(GKnownImmOperand *operand) { + if (operand->alt_text != NULL) + free(operand->alt_text); + G_OBJECT_CLASS(g_known_imm_operand_parent_class)->dispose(G_OBJECT(operand)); } @@ -1881,6 +1884,8 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) g_bit_unlock(&src->lock, HOLE_LOCK_BIT); + result->alt_text = strdup(alt); + return G_ARCH_OPERAND(result); } diff --git a/src/arch/register.c b/src/arch/register.c index e08aa8b..0309c62 100644 --- a/src/arch/register.c +++ b/src/arch/register.c @@ -170,8 +170,8 @@ guint g_arch_register_hash(const GArchRegister *reg) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : a = premier registre à consulter. * +* b = second registre à consulter. * * * * Description : Compare un registre avec un autre. * * * -- cgit v0.11.2-87-g4458