summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/pychrysalide/arch/Makefile.am14
-rw-r--r--plugins/pychrysalide/arch/constants.c5
-rw-r--r--plugins/pychrysalide/arch/constants.h5
-rw-r--r--plugins/pychrysalide/arch/instruction.c866
-rw-r--r--plugins/pychrysalide/arch/instructions/Makefile.am3
-rw-r--r--plugins/pychrysalide/arch/instructions/constants.c58
-rw-r--r--plugins/pychrysalide/arch/instructions/constants.h5
-rw-r--r--plugins/pychrysalide/arch/instructions/raw.c142
-rw-r--r--plugins/pychrysalide/arch/instructions/undefined.c145
-rw-r--r--plugins/pychrysalide/arch/instructions/undefined.h4
-rw-r--r--plugins/pychrysalide/arch/module-ui.c7
-rw-r--r--plugins/pychrysalide/arch/module.c10
-rw-r--r--plugins/pychrysalide/arch/operand.c4
13 files changed, 806 insertions, 462 deletions
diff --git a/plugins/pychrysalide/arch/Makefile.am b/plugins/pychrysalide/arch/Makefile.am
index a134947..a0dcfdb 100644
--- a/plugins/pychrysalide/arch/Makefile.am
+++ b/plugins/pychrysalide/arch/Makefile.am
@@ -2,17 +2,12 @@
noinst_LTLIBRARIES = libpychrysaarch4.la libpychrysaarchui.la # libpychrysaarch.la
# libpychrysaarch_la_SOURCES = \
-# constants.h constants.c \
# context.h context.c \
# instriter.h instriter.c \
-# instruction.h instruction.c \
-# module.h module.c \
-# operand.h operand.c \
-# processor.h processor.c \
-# vmpa.h vmpa.c
+# processor.h processor.c
# libpychrysaarch_la_LIBADD = \
-# instructions/libpychrysaarchinstructions.la \
+# \
# operands/libpychrysaarchoperands.la
# libpychrysaarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
@@ -21,12 +16,14 @@ noinst_LTLIBRARIES = libpychrysaarch4.la libpychrysaarchui.la # libpychrysaarch.
libpychrysaarch4_la_SOURCES = \
constants.h constants.c \
+ instruction.h instruction.c \
module.h module.c \
operand.h operand.c \
register.h register.c \
vmpa.h vmpa.c
libpychrysaarch4_la_LIBADD = \
+ instructions/libpychrysaarchinstructions.la \
operands/libpychrysaarchoperands.la
libpychrysaarch4_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
@@ -48,5 +45,4 @@ devdir = $(includedir)/chrysalide/$(subdir)
dev_HEADERS = $(libpychrysaarch_la_SOURCES:%c=)
-# SUBDIRS = instructions operands
-SUBDIRS = operands
+SUBDIRS = instructions operands
diff --git a/plugins/pychrysalide/arch/constants.c b/plugins/pychrysalide/arch/constants.c
index 3604795..5db59ff 100644
--- a/plugins/pychrysalide/arch/constants.c
+++ b/plugins/pychrysalide/arch/constants.c
@@ -25,7 +25,7 @@
#include "constants.h"
-//#include <arch/instruction.h>
+#include <arch/instruction.h>
//#include <arch/processor.h>
#include <arch/vmpa.h>
@@ -33,7 +33,6 @@
#include "../helpers.h"
-#if 0 // FIXME
/******************************************************************************
* *
@@ -116,6 +115,8 @@ bool define_arch_instruction_constants(PyTypeObject *type)
}
+#if 0 // FIXME
+
/******************************************************************************
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h
index b12579e..2f16c4f 100644
--- a/plugins/pychrysalide/arch/constants.h
+++ b/plugins/pychrysalide/arch/constants.h
@@ -30,10 +30,13 @@
#include <stdbool.h>
-#if 0 // FIXME
+
/* Définit les constantes relatives aux instructions. */
bool define_arch_instruction_constants(PyTypeObject *);
+
+#if 0 // FIXME
+
/* Définit les constantes relatives aux processeurs. */
bool define_arch_processor_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index 0a9ba16..49daa9c 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -27,13 +27,12 @@
#include <assert.h>
#include <malloc.h>
-#include <string.h>
#include <pygobject.h>
#include <i18n.h>
+#include <plugins/self.h>
#include <arch/instruction-int.h>
-#include <plugins/dt.h>
#include "constants.h"
@@ -41,30 +40,38 @@
#include "vmpa.h"
#include "../access.h"
#include "../helpers.h"
-#include "../glibext/linegen.h"
-
-
-
-static G_DEFINE_QUARK(cached_keyword, get_cached_keyword);
+#include "../glibext/objhole.h"
+#include "../glibext/serialize.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_arch_instruction_new(PyTypeObject *, PyObject *, PyObject *);
-
/* Initialise la classe générique des instructions. */
-static void py_arch_instruction_init_gclass(GArchInstructionClass *, gpointer);
+static int py_arch_instruction_init_gclass(GArchInstructionClass *, PyTypeObject *);
-CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_instruction, G_TYPE_ARCH_INSTRUCTION, py_arch_instruction_init_gclass);
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_instruction, G_TYPE_ARCH_INSTRUCTION);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_arch_instruction_init(PyObject *, PyObject *, PyObject *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static char *py_arch_instruction_get_encoding_wrapper(const GArchInstruction *);
+
/* Fournit le nom humain de l'instruction manipulée. */
-static const char *py_arch_instruction_get_class_keyword(GArchInstruction *);
+static char *py_arch_instruction_get_keyword_wrapper(const GArchInstruction *);
+
+
+
+/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
+
+
+/* Fournit les origines d'une instruction donnée. */
+static PyObject *py_arch_instruction_get_sources(PyObject *, void *);
+
+/* Fournit les destinations d'une instruction donnée. */
+static PyObject *py_arch_instruction_get_destinations(PyObject *, void *);
@@ -72,10 +79,7 @@ static const char *py_arch_instruction_get_class_keyword(GArchInstruction *);
/* Attache un opérande supplémentaire à une instruction. */
-static PyObject *py_arch_instruction_attach_extra_operand(PyObject *, PyObject *);
-
-/* Fournit tous les opérandes d'une instruction. */
-static PyObject *py_arch_instruction_get_operands(PyObject *, void *);
+static PyObject *py_arch_instruction_attach_operand(PyObject *, PyObject *);
/* Remplace un opérande d'une instruction par un autre. */
static PyObject *py_arch_instruction_replace_operand(PyObject *, PyObject *);
@@ -89,34 +93,35 @@ static PyObject *py_arch_instruction_find_operand_path(PyObject *, PyObject *);
/* Obtient l'opérande correspondant à un chemin donné. */
static PyObject *py_arch_instruction_get_operand_from_path(PyObject *, PyObject *);
+/* Fournit tous les opérandes d'une instruction. */
+static PyObject *py_arch_instruction_get_operands(PyObject *, void *);
-/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
-/* Fournit les origines d'une instruction donnée. */
-static PyObject *py_arch_instruction_get_sources(PyObject *, void *);
-/* Fournit les destinations d'une instruction donnée. */
-static PyObject *py_arch_instruction_get_destinations(PyObject *, void *);
+/* Ajoute une information complémentaire à une instruction. */
+static PyObject *py_arch_instruction_set_flag(PyObject *, PyObject *);
+/* Retire une information complémentaire à une instruction. */
+static PyObject *py_arch_instruction_unset_flag(PyObject *, PyObject *);
+/* Détermine si une instruction possède un fanion particulier. */
+static PyObject *py_arch_instruction_has_flag(PyObject *, PyObject *);
-/* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */
+/* Fournit l'identifiant correspondant à un type d'instructions. */
+static PyObject *py_arch_instruction_get_type_id(PyObject *, void *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static PyObject *py_arch_instruction_get_encoding(PyObject *, void *);
-/* Fournit l'identifiant unique pour un ensemble d'instructions. */
-static PyObject *py_arch_instruction_get_unique_id(PyObject *, void *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
/* Fournit la place mémoire d'une instruction. */
static PyObject *py_arch_instruction_get_range(PyObject *, void *);
-/* Définit la localisation d'une instruction. */
-static int py_arch_instruction_set_range(PyObject *, PyObject *, void *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
-
/* ---------------------------------------------------------------------------------- */
@@ -126,24 +131,23 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : class = classe à initialiser. *
-* unused = données non utilisées ici. *
+* Paramètres : gclass = classe GLib à initialiser. *
+* pyclass = classe Python à initialiser. *
* *
* Description : Initialise la classe générique des instructions. *
* *
-* Retour : - *
+* Retour : 0 pour indiquer un succès de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_arch_instruction_init_gclass(GArchInstructionClass *class, gpointer unused)
+static int py_arch_instruction_init_gclass(GArchInstructionClass *gclass, PyTypeObject *pyclass)
{
- GArchInstructionClass *instr; /* Encore une autre vision... */
-
- instr = G_ARCH_INSTRUCTION_CLASS(class);
+ PY_CLASS_SET_WRAPPER(gclass->get_encoding, py_arch_instruction_get_encoding_wrapper);
+ PY_CLASS_SET_WRAPPER(gclass->get_keyword, py_arch_instruction_get_keyword_wrapper);
- instr->get_keyword = (get_instruction_keyword_fc)py_arch_instruction_get_class_keyword;
+ return 0;
}
@@ -164,17 +168,25 @@ static void py_arch_instruction_init_gclass(GArchInstructionClass *class, gpoint
static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- unsigned short int uid; /* Indentifiant unique de type */
- const char *keyword; /* Désignation d'instruction */
+ unsigned short int tid; /* Indentifiant unique de type */
int ret; /* Bilan de lecture des args. */
GArchInstruction *instr; /* Instruction à manipuler */
- GQuark cache_key; /* Emplacement local */
- static char *kwlist[] = { "uid", "keyword", NULL };
+#define ARCH_INSTRUCTION_DOC \
+ "The ArchInstruction object provides a base class for instructions" \
+ " of any architecture.\n" \
+ " operands of any kind for new architectures.\n" \
+ "\n" \
+ "Calls to the *__init__* constructor of this abstract object expect"\
+ " one argument: an unique identifier, as an integer value.\n" \
+ "\n" \
+ "The following methods have to be defined for new classes:\n" \
+ "* pychrysalide.arch.ArchRegister._get_encoding();\n" \
+ "* pychrysalide.arch.ArchRegister._get_keyword().\n"
/* Récupération des paramètres */
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "Hs", kwlist, &uid, &keyword);
+ ret = PyArg_ParseTuple(args, "H", &tid);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -186,13 +198,72 @@ static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kw
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- cache_key = get_cached_keyword_quark();
+ if (!g_arch_instruction_create(instr, tid))
+ return -1;
+
+ return 0;
- g_object_set_qdata_full(G_OBJECT(instr), cache_key, strdup(keyword), g_free);
+}
- g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(instr), uid);
- return 0;
+/******************************************************************************
+* *
+* Paramètres : instr = instruction quelconque à consulter. *
+* *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
+* *
+* Retour : Description humaine de l'encodage utilisé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_arch_instruction_get_encoding_wrapper(const GArchInstruction *instr)
+{
+ char *result; /* Encodage à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_GET_ENCODING_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_encoding, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method describing the encoding related to an" \
+ " instruction.\n" \
+ "\n" \
+ "The result should be the string value.\n" \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(instr));
+
+ if (has_python_method(pyobj, "_get_encoding"))
+ {
+ pyret = run_python_method(pyobj, "_get_encoding", NULL);
+
+ if (pyret != NULL)
+ {
+ if (!PyUnicode_Check(pyret))
+ log_variadic_message(LMT_ERROR, _("The returned raw name must be a string"));
+
+ else
+ result = strdup(PyUnicode_DATA(pyret));
+
+ }
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
}
@@ -209,15 +280,50 @@ static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kw
* *
******************************************************************************/
-static const char *py_arch_instruction_get_class_keyword(GArchInstruction *instr)
+static char *py_arch_instruction_get_keyword_wrapper(const GArchInstruction *instr)
{
- const char *result; /* Désignation à retourner */
- GQuark cache_key; /* Emplacement local */
+ char *result; /* Etiquette à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_GET_KEYWORD_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_keyword, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method giving the official name of the assembly" \
+ " instruction.\n" \
+ "\n" \
+ "The result should be the string value.\n" \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(instr));
+
+ if (has_python_method(pyobj, "_get_keyword"))
+ {
+ pyret = run_python_method(pyobj, "_get_keyword", NULL);
+
+ if (pyret != NULL)
+ {
+ if (!PyUnicode_Check(pyret))
+ log_variadic_message(LMT_ERROR, _("The returned raw name must be a string"));
- cache_key = get_cached_keyword_quark();
+ else
+ result = strdup(PyUnicode_DATA(pyret));
- result = g_object_get_qdata(G_OBJECT(instr), cache_key);
- assert(result != NULL);
+ }
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
return result;
@@ -226,94 +332,201 @@ static const char *py_arch_instruction_get_class_keyword(GArchInstruction *instr
/* ---------------------------------------------------------------------------------- */
-/* MANIPULATION DES OPERANDES */
+/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : self = architecture concernée par la procédure. *
-* args = instruction représentant le point de départ. *
+* Paramètres : self = instruction d'architecture à manipuler. *
+* unused = adresse non utilisée ici. *
* *
-* Description : Attache un opérande supplémentaire à une instruction. *
+* Description : Fournit les origines d'une instruction donnée. *
* *
-* Retour : None. *
+* Retour : Nombre de ces origines. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_attach_extra_operand(PyObject *self, PyObject *args)
+static PyObject *py_arch_instruction_get_sources(PyObject *self, void *unused)
{
- GArchOperand *op; /* Opérande concerné à ajouter */
- int ret; /* Bilan de lecture des args. */
- GArchInstruction *instr; /* Instruction manipulée */
+ PyObject *result; /* Instance à retourner */
+ GArchInstruction *instr; /* Version native */
+ size_t count; /* Nombre de liens présents */
+ size_t i; /* Boucle de parcours */
- ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &op);
- if (!ret) return NULL;
+
+ GArchInstruction *src; /* Instruction en source */
+ InstructionLinkType src_type; /* Type de lien */
+ PyObject *linked; /* Source de lien Python */
+ PyObject *lnk_type; /* Nature du lien en Python */
+#ifndef NDEBUG
+ int ret; /* Bilan d'une écriture d'arg. */
+#endif
+
+#define ARCH_INSTRUCTION_SOURCES_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ sources, py_arch_instruction, \
+ "Provide the instructions list driving to the current instruction.\n" \
+ "\n" \
+ "Each item of the resulting tuple is a pair of" \
+ " pychrysalide.arch.ArchInstruction instance and" \
+ " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_object_ref(G_OBJECT(op));
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+
+ count = g_arch_instruction_count_src_links(instr);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ src = g_arch_instruction_get_linked_source(instr, i, &src_type);
+
+ linked = pygobject_new(G_OBJECT(src));
+ lnk_type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
+ "InstructionLinkType", src_type);
+
+#ifndef NDEBUG
+ ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
+ assert(ret == 0);
+#else
+ PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
+#endif
+
+ unref_object(src);
+
+ }
- g_arch_instruction_attach_extra_operand(instr, op);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- Py_RETURN_NONE;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : self = objet représentant une instruction. *
+* Paramètres : self = instruction d'architecture à manipuler. *
* unused = adresse non utilisée ici. *
* *
-* Description : Fournit tous les opérandes d'une instruction. *
+* Description : Fournit les destinations d'une instruction donnée. *
* *
-* Retour : Valeur associée à la propriété consultée. *
+* Retour : Nombre de ces destinations. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_operands(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unused)
{
PyObject *result; /* Instance à retourner */
GArchInstruction *instr; /* Version native */
- size_t count; /* Nombre d'opérandes présents */
+ size_t count; /* Nombre de liens présents */
size_t i; /* Boucle de parcours */
- GArchOperand *operand; /* Opérande à manipuler */
- PyObject *opobj; /* Version Python */
+ GArchInstruction *dest; /* Instruction en source */
+ InstructionLinkType dest_type; /* Type de lien */
+ PyObject *linked; /* Destination de lien Python */
+ PyObject *lnk_type; /* Nature du lien en Python */
#ifndef NDEBUG
int ret; /* Bilan d'une écriture d'arg. */
#endif
+#define ARCH_INSTRUCTION_DESTINATIONS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ destinations, py_arch_instruction, \
+ "Provide the instructions list following the current instruction.\n" \
+ "\n" \
+ "Each item of the resulting tuple is a pair of" \
+ " pychrysalide.arch.ArchInstruction instance and" \
+ " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+)
+
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_lock_operands(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- count = _g_arch_instruction_count_operands(instr);
+ count = g_arch_instruction_count_dest_links(instr);
result = PyTuple_New(count);
for (i = 0; i < count; i++)
{
- operand = _g_arch_instruction_get_operand(instr, i);
+ dest = g_arch_instruction_get_linked_destination(instr, i, &dest_type);
- opobj = pygobject_new(G_OBJECT(operand));
+ linked = pygobject_new(G_OBJECT(dest));
+ lnk_type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
+ "InstructionLinkType", dest_type);
#ifndef NDEBUG
- ret = PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
+ ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
assert(ret == 0);
#else
- PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
+ PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, lnk_type));
#endif
- g_object_unref(G_OBJECT(operand));
+ unref_object(dest);
}
- g_arch_instruction_unlock_operands(instr);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATION DES OPERANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Attache un opérande supplémentaire à une instruction. *
+* *
+* Retour : None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_instruction_attach_operand(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ GArchOperand *op; /* Opérande concerné à ajouter */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+
+#define ARCH_INSTRUCTION_ATTACH_OPERAND_METHOD PYTHON_METHOD_DEF \
+( \
+ attach_operand, "$self, operand, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Add an extra operand to an instruction.\n" \
+ "\n" \
+ "The instruction has to be locked during the instruction.\n" \
+ "\n" \
+ "The *operand* argument has to be a pychrysalide.arch.ArchOperand" \
+ " instance." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &op);
+ if (!ret) return NULL;
+
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
+
+ g_arch_instruction_attach_operand(instr, op);
+
+ result = Py_None;
+ Py_INCREF(result);
return result;
@@ -342,6 +555,21 @@ static PyObject *py_arch_instruction_replace_operand(PyObject *self, PyObject *a
GArchInstruction *instr; /* Instruction manipulée */
bool status; /* Bilan de l'opération */
+#define ARCH_INSTRUCTION_REPLACE_OPERAND_METHOD PYTHON_METHOD_DEF \
+( \
+ replace_operand, "$self, old, new, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Replace an old instruction operand by a another one.\n" \
+ "\n" \
+ "The instruction has to be locked during the instruction.\n" \
+ "\n" \
+ "Both the *old* and *new* arguments have to be a" \
+ " pychrysalide.arch.ArchOperand instance.\n" \
+ "\n" \
+ "The status of the operation is returned as a boolean value: *True*"\
+ " if the operand has been replaced, *False* in case of failure." \
+)
+
ret = PyArg_ParseTuple(args, "O&O&", convert_to_arch_operand, &old, convert_to_arch_operand, &new);
if (!ret) return NULL;
@@ -349,9 +577,6 @@ static PyObject *py_arch_instruction_replace_operand(PyObject *self, PyObject *a
status = g_arch_instruction_replace_operand(instr, old, new);
- if (status)
- g_object_ref(G_OBJECT(new));
-
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -381,6 +606,21 @@ static PyObject *py_arch_instruction_detach_operand(PyObject *self, PyObject *ar
GArchInstruction *instr; /* Instruction manipulée */
bool status; /* Bilan de l'opération */
+#define ARCH_INSTRUCTION_DETACH_OPERAND_METHOD PYTHON_METHOD_DEF \
+( \
+ detach_operand, "$self, operand, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Remove an operand from the instruction.\n" \
+ "\n" \
+ "The instruction has to be locked during the instruction.\n" \
+ "\n" \
+ "The *operand* argument has to be a pychrysalide.arch.ArchOperand" \
+ " instance.\n" \
+ "\n" \
+ "The status of the operation is returned as a boolean value: *True*"\
+ " if the operand has been removed, *False* in case of failure." \
+)
+
ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &target);
if (!ret) return NULL;
@@ -500,7 +740,7 @@ static PyObject *py_arch_instruction_get_operand_from_path(PyObject *self, PyObj
if (op != NULL)
{
result = pygobject_new(G_OBJECT(op));
- g_object_unref(G_OBJECT(op));
+ unref_object(op);
}
else
{
@@ -513,182 +753,258 @@ static PyObject *py_arch_instruction_get_operand_from_path(PyObject *self, PyObj
}
-
-/* ---------------------------------------------------------------------------------- */
-/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : self = instruction d'architecture à manipuler. *
+* Paramètres : self = objet représentant une instruction. *
* unused = adresse non utilisée ici. *
* *
-* Description : Fournit les origines d'une instruction donnée. *
+* Description : Fournit tous les opérandes d'une instruction. *
* *
-* Retour : Nombre de ces origines. *
+* Retour : Valeur associée à la propriété consultée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_sources(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_get_operands(PyObject *self, void *unused)
{
PyObject *result; /* Instance à retourner */
GArchInstruction *instr; /* Version native */
- size_t count; /* Nombre de liens présents */
+ size_t count; /* Nombre d'opérandes présents */
size_t i; /* Boucle de parcours */
- const instr_link_t *source; /* Origine des liens */
- PyObject *linked; /* Source de lien Python */
- PyObject *type; /* Nature du lien en Python */
+ GArchOperand *operand; /* Opérande à manipuler */
+ PyObject *opobj; /* Version Python */
#ifndef NDEBUG
int ret; /* Bilan d'une écriture d'arg. */
#endif
-#define ARCH_INSTRUCTION_SOURCES_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- sources, py_arch_instruction, \
- "Provide the instructions list driving to the current instruction.\n" \
- "\n" \
- "Each item of the resulting tuple is a pair of" \
- " pychrysalide.arch.ArchInstruction instance and" \
- " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+#define ARCH_INSTRUCTION_OPERANDS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ operands, py_arch_instruction, \
+ "List of instruction attached operands.\n" \
+ "\n" \
+ "The result is a list of pychrysalide.arch.ArchOperand" \
+ " instances, which can be empty." \
)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_lock_src(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- count = g_arch_instruction_count_sources(instr);
+ count = g_arch_instruction_count_operands(instr);
result = PyTuple_New(count);
for (i = 0; i < count; i++)
{
- source = g_arch_instruction_get_source(instr, i);
+ operand = g_arch_instruction_get_operand(instr, i);
- linked = pygobject_new(G_OBJECT(source->linked));
- type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
- "InstructionLinkType", source->type);
+ opobj = pygobject_new(G_OBJECT(operand));
#ifndef NDEBUG
- ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
+ ret = PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
assert(ret == 0);
#else
- PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
+ PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
#endif
- unref_instr_link(source);
+ unref_object(operand);
}
- g_arch_instruction_unlock_src(instr);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* LIAISON DE FONCTIONNALITES AVEC L'API PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : self = instruction d'architecture à manipuler. *
-* unused = adresse non utilisée ici. *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
* *
-* Description : Fournit les destinations d'une instruction donnée. *
+* Description : Ajoute une information complémentaire à une instruction. *
* *
-* Retour : Nombre de ces destinations. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_set_flag(PyObject *self, PyObject *args)
{
- PyObject *result; /* Instance à retourner */
- GArchInstruction *instr; /* Version native */
- size_t count; /* Nombre de liens présents */
- size_t i; /* Boucle de parcours */
- const instr_link_t *dest; /* Destination des liens */
- PyObject *linked; /* Destination de lien Python */
- PyObject *type; /* Nature du lien en Python */
-#ifndef NDEBUG
- int ret; /* Bilan d'une écriture d'arg. */
-#endif
-
-#define ARCH_INSTRUCTION_DESTINATIONS_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- destinations, py_arch_instruction, \
- "Provide the instructions list following the current instruction.\n" \
- "\n" \
- "Each item of the resulting tuple is a pair of" \
- " pychrysalide.arch.ArchInstruction instance and" \
- " pychrysalide.arch.ArchInstruction.InstructionLinkType value." \
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_INSTRUCTION_SET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ set_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Add some flags to the instruction.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to apply to the instruction state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* for operation" \
+ " success, *False* otherwise." \
)
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_lock_dest(instr);
+ status = g_arch_instruction_set_flag(instr, flag);
- count = g_arch_instruction_count_destinations(instr);
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
- result = PyTuple_New(count);
+ return result;
- for (i = 0; i < count; i++)
- {
- dest = g_arch_instruction_get_destination(instr, i);
+}
- linked = pygobject_new(G_OBJECT(dest->linked));
- type = cast_with_constants_group_from_type(get_python_arch_instruction_type(),
- "InstructionLinkType", dest->type);
-#ifndef NDEBUG
- ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
- assert(ret == 0);
-#else
- PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
-#endif
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Retire une information complémentaire à une instruction. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_instruction_unset_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_INSTRUCTION_UNSET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ unset_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Remove some flags from the instruction.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to delete from the instruction state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* for operation" \
+ " success, *False* otherwise." \
+)
- unref_instr_link(dest);
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
- }
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_unlock_dest(instr);
+ status = g_arch_instruction_unset_flag(instr, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
return result;
}
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Détermine si une instruction possède un fanion particulier. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
-/* ---------------------------------------------------------------------------------- */
-/* INSTRUCTIONS D'ARCHITECTURES EN PYTHON */
-/* ---------------------------------------------------------------------------------- */
+static PyObject *py_arch_instruction_has_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_INSTRUCTION_HAS_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ has_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Tell if some flags are set for the instruction.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to test for the instruction state.\n" \
+ "\n" \
+ "The result is an boolean status: *True* if the bits" \
+ " are active, *False* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
+
+ status = g_arch_instruction_has_flag(instr, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : self = classe représentant une instruction. *
-* closure = adresse non utilisée ici. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit l'identifiant unique pour un ensemble d'instructions.*
+* Description : Fournit l'identifiant correspondant à un type d'instructions.*
* *
-* Retour : Identifiant unique par type d'instruction. *
+* Retour : Identifiant unique par type d'instruction et architecture. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_unique_id(PyObject *self, void *closure)
+static PyObject *py_arch_instruction_get_type_id(PyObject *self, void *closure)
{
- PyObject *result; /* Conversion à retourner */
- GArchInstruction *instr; /* Version native */
- itid_t uid; /* Identifiant unique associé */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ itid_t tid; /* Identifiant à transmettre */
+
+#define ARCH_INSTRUCTION_TYPE_ID_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ type_id, py_arch_instruction, \
+ "Provide the unique identifier given to this kind of" \
+ " instruction.\n" \
+ "\n" \
+ "The returned value is an integer." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- uid = g_arch_instruction_get_unique_id(instr);
+ tid = g_arch_instruction_get_type_id(instr);
- result = PyLong_FromUnsignedLong(uid);
+ result = PyLong_FromUnsignedLong(tid);
return result;
@@ -697,27 +1013,61 @@ static PyObject *py_arch_instruction_get_unique_id(PyObject *self, void *closure
/******************************************************************************
* *
-* Paramètres : self = classe représentant une instruction. *
-* closure = adresse non utilisée ici. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit la place mémoire d'une instruction. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : Valeur associée à la propriété consultée. *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_range(PyObject *self, void *closure)
+static PyObject *py_arch_instruction_get_encoding(PyObject *self, void *closure)
{
- PyObject *result; /* Conversion à retourner */
- GArchInstruction *instr; /* Version native */
- const mrange_t *range; /* Espace mémoire à exporter */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ char *encoding; /* Encodage d'une instruction */
+
+#define ARCH_INSTRUCTION_ENCODING_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ encoding, py_arch_instruction, \
+ "Describe the encoding related to an instruction.\n" \
+ "\n" \
+ "The returned value is an arbitrary string value." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- range = g_arch_instruction_get_range(instr);
- result = build_from_internal_mrange(range);
+ encoding = g_arch_instruction_get_encoding(instr);
+
+ if (encoding != NULL)
+ {
+ result = PyUnicode_FromString(encoding);
+
+ free(encoding);
+
+ }
+
+ else
+ {
+ /**
+ * La méthode de classe sollicitée a renvoyé une valeur nulle.
+ *
+ * Si cette méthode correspond à une implémentation Python
+ * (avec un appel à not_yet_implemented_method()), une exception
+ * est déjà en place.
+ *
+ * Si aucune exception n'a été prévue, un rattrapage est effectué ici.
+ */
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_NotImplementedError, _("unexpected NULL value as encoding"));
+
+ result = NULL;
+
+ }
return result;
@@ -727,59 +1077,108 @@ static PyObject *py_arch_instruction_get_range(PyObject *self, void *closure)
/******************************************************************************
* *
* Paramètres : self = objet Python concerné par l'appel. *
-* value = valeur fournie à intégrer ou prendre en compte. *
-* closure = adresse non utilisée ici. *
+* closure = non utilisé ici. *
* *
-* Description : Définit la localisation d'une instruction. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : Bilan de l'opération pour Python. *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-static int py_arch_instruction_set_range(PyObject *self, PyObject *value, void *closure)
+static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *closure)
{
- int ret; /* Bilan d'analyse */
- mrange_t *range; /* Espace mémoire à manipuler */
- GArchInstruction *instr; /* Version native */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ char *keyword; /* Désignation d'une instruct° */
+
+#define ARCH_INSTRUCTION_KEYWORD_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ keyword, py_arch_instruction, \
+ "Give the official name of the assembly instruction.\n" \
+ "\n" \
+ "The returned value is a string value." \
+)
- ret = PyObject_IsInstance(value, (PyObject *)get_python_mrange_type());
- if (!ret) return -1;
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- range = get_internal_mrange(value);
+ keyword = g_arch_instruction_get_keyword(instr);
- instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- g_arch_instruction_set_range(instr, range);
+ if (keyword != NULL)
+ {
+ result = PyUnicode_FromString(keyword);
- return 0;
+ free(keyword);
+
+ }
+
+ else
+ {
+ /**
+ * La méthode de classe sollicitée a renvoyé une valeur nulle.
+ *
+ * Si cette méthode correspond à une implémentation Python
+ * (avec un appel à not_yet_implemented_method()), une exception
+ * est déjà en place.
+ *
+ * Si aucune exception n'a été prévue, un rattrapage est effectué ici.
+ */
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_NotImplementedError, _("unexpected NULL value as keyword"));
+
+ result = NULL;
+
+ }
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : self = classe représentant une instruction. *
-* unused = adresse non utilisée ici. *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
+* Description : Fournit la place mémoire d'une instruction. *
* *
-* Retour : Valeur associée à la propriété consultée. *
+* Retour : Définition de localisation ou *None*. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused)
+static PyObject *py_arch_instruction_get_range(PyObject *self, void *closure)
{
- PyObject *result; /* Trouvailles à retourner */
- GArchInstruction *instr; /* Version native */
- const char *kw; /* Valeur récupérée */
+ PyObject *result; /* Valeur à retourner */
+ GArchInstruction *instr; /* Instruction manipulée */
+ mrange_t range; /* Localisation d'instruction */
+ bool valid; /* Validité de la localisation */
+
+#define ARCH_INSTRUCTION_RANGE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ range, py_arch_instruction, \
+ "Give access to the memory range covered by the" \
+ " current instruction.\n" \
+ "\n" \
+ "The returned value is a pychrysalide.arch.mrange" \
+ " instance or *None* if no location is currently" \
+ " defined." \
+)
instr = G_ARCH_INSTRUCTION(pygobject_get(self));
- kw = g_arch_instruction_get_keyword(instr);
- result = PyUnicode_FromString(kw);
+ valid = g_arch_instruction_get_range(instr, &range);
+
+ if (valid)
+ result = build_from_internal_mrange(&range);
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
@@ -801,45 +1200,25 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused)
PyTypeObject *get_python_arch_instruction_type(void)
{
static PyMethodDef py_arch_instruction_methods[] = {
- {
- "attach_operand", py_arch_instruction_attach_extra_operand,
- METH_VARARGS,
- "attach_operand($self, op, /)\n--\n\nAdd a new operand to the instruction."
- },
- {
- "replace_operand", py_arch_instruction_replace_operand,
- METH_VARARGS,
- "replace_operand($self, old, new, /)\n--\n\nReplace an old instruction operand by a another one."
- },
- {
- "detach_operand", py_arch_instruction_detach_operand,
- METH_VARARGS,
- "detach_operand($self, target, /)\n--\n\nRemove an operand from the instruction."
- },
+ ARCH_INSTRUCTION_ATTACH_OPERAND_METHOD,
+ ARCH_INSTRUCTION_REPLACE_OPERAND_METHOD,
+ ARCH_INSTRUCTION_DETACH_OPERAND_METHOD,
ARCH_INSTRUCTION_FIND_OPERAND_PATH_METHOD,
ARCH_INSTRUCTION_GET_OPERAND_FROM_PATH_METHOD,
+ ARCH_INSTRUCTION_SET_FLAG_METHOD,
+ ARCH_INSTRUCTION_UNSET_FLAG_METHOD,
+ ARCH_INSTRUCTION_HAS_FLAG_METHOD,
{ NULL }
};
static PyGetSetDef py_arch_instruction_getseters[] = {
- {
- "uid", py_arch_instruction_get_unique_id, NULL,
- "Provide the unique identification number given to this kind of instruction.", NULL
- },
- {
- "range", py_arch_instruction_get_range, py_arch_instruction_set_range,
- "Give access to the memory range covered by the current instruction.", NULL
- },
- {
- "keyword", (getter)py_arch_instruction_get_keyword, (setter)NULL,
- "Give le name of the assembly instruction.", NULL
- },
- {
- "operands", (getter)py_arch_instruction_get_operands, (setter)NULL,
- "Provide the list of instruction attached operands.", NULL
- },
ARCH_INSTRUCTION_SOURCES_ATTRIB,
ARCH_INSTRUCTION_DESTINATIONS_ATTRIB,
+ ARCH_INSTRUCTION_OPERANDS_ATTRIB,
+ ARCH_INSTRUCTION_TYPE_ID_ATTRIB,
+ ARCH_INSTRUCTION_ENCODING_ATTRIB,
+ ARCH_INSTRUCTION_KEYWORD_ATTRIB,
+ ARCH_INSTRUCTION_RANGE_ATTRIB,
{ NULL }
};
@@ -852,7 +1231,7 @@ PyTypeObject *get_python_arch_instruction_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide instruction for a given architecture.",
+ .tp_doc = ARCH_INSTRUCTION_DOC,
.tp_methods = py_arch_instruction_methods,
.tp_getset = py_arch_instruction_getseters,
@@ -893,9 +1272,14 @@ bool ensure_python_arch_instruction_is_registered(void)
dict = PyModule_GetDict(module);
- if (!ensure_python_line_generator_is_registered())
+ if (!ensure_python_thick_object_is_registered())
return false;
+ if (!ensure_python_serializable_object_is_registered())
+ return false;
+
+ pyg_register_class_init(G_TYPE_ARCH_INSTRUCTION, (PyGClassInitFunc)py_arch_instruction_init_gclass);
+
if (!register_class_for_pygobject(dict, G_TYPE_ARCH_INSTRUCTION, type))
return false;
diff --git a/plugins/pychrysalide/arch/instructions/Makefile.am b/plugins/pychrysalide/arch/instructions/Makefile.am
index 65efe42..29c2a45 100644
--- a/plugins/pychrysalide/arch/instructions/Makefile.am
+++ b/plugins/pychrysalide/arch/instructions/Makefile.am
@@ -7,7 +7,8 @@ libpychrysaarchinstructions_la_SOURCES = \
raw.h raw.c \
undefined.h undefined.c
-libpychrysaarchinstructions_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+libpychrysaarchinstructions_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ $(TOOLKIT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/pychrysalide/arch/instructions/constants.c b/plugins/pychrysalide/arch/instructions/constants.c
index af7baa9..257c501 100644
--- a/plugins/pychrysalide/arch/instructions/constants.c
+++ b/plugins/pychrysalide/arch/instructions/constants.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* constants.c - ajout des constantes de base pour les instructions
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -112,3 +112,59 @@ bool define_undefined_instruction_constants(PyTypeObject *type)
return result;
}
+
+
+/******************************************************************************
+* *
+* 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 constante ExpectedBehavior. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_undefined_expected_behavior(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur récupérée */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 ExpectedBehavior");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if (value > IEB_RESERVED)
+ {
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to ExpectedBehavior");
+ result = 0;
+ }
+
+ else
+ *((InstrExpectedBehavior *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/instructions/constants.h b/plugins/pychrysalide/arch/instructions/constants.h
index 2f0c587..b6ef9a4 100644
--- a/plugins/pychrysalide/arch/instructions/constants.h
+++ b/plugins/pychrysalide/arch/instructions/constants.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* constants.h - prototypes pour l'ajout des constantes de base pour les instructions
*
- * Copyright (C) 2020 Cyrille Bagard
+ * Copyright (C) 2020-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -37,6 +37,9 @@ bool define_raw_instruction_constants(PyTypeObject *);
/* Définit les constantes liées aux comportements erratiques. */
bool define_undefined_instruction_constants(PyTypeObject *);
+/* Tente de convertir en constante ExpectedBehavior. */
+int convert_to_undefined_expected_behavior(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/instructions/raw.c b/plugins/pychrysalide/arch/instructions/raw.c
index 7e58b96..ae730e8 100644
--- a/plugins/pychrysalide/arch/instructions/raw.c
+++ b/plugins/pychrysalide/arch/instructions/raw.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* raw.c - équivalent Python du fichier "arch/instructions/raw.h"
*
- * Copyright (C) 2018-2020 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -28,26 +28,33 @@
#include <pygobject.h>
-#include <i18n.h>
-#include <arch/instructions/raw.h>
-#include <plugins/dt.h>
+#include <arch/instructions/raw-int.h>
#include "constants.h"
#include "../instruction.h"
#include "../vmpa.h"
#include "../../access.h"
+#include "../../constants.h"
#include "../../helpers.h"
#include "../../analysis/content.h"
+#include "../../glibext/portion.h"
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_raw_instruction_new(PyTypeObject *, PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(raw_instruction, G_TYPE_RAW_INSTRUCTION);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_raw_instruction_init(PyObject *, PyObject *, PyObject *);
+
+
+/* ------------------------ FONCTIONNALITES DE L'INSTRUCTION ------------------------ */
+
+
/* Indique si le contenu de l'instruction est du bourrage. */
static PyObject *py_raw_instruction_get_padding(PyObject *, void *);
@@ -62,64 +69,9 @@ static int py_raw_instruction_set_string(PyObject *, PyObject *, void *);
-/******************************************************************************
-* *
-* Paramètres : type = type du nouvel objet à mettre en place. *
-* args = éventuelle liste d'arguments. *
-* kwds = éventuel dictionnaire de valeurs mises à disposition. *
-* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
-* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_raw_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyObject *result; /* Objet à retourner */
- PyTypeObject *base; /* Type de base à dériver */
- bool first_time; /* Evite les multiples passages*/
- GType gtype; /* Nouveau type de processeur */
- bool status; /* Bilan d'un enregistrement */
-
- /* Validations diverses */
-
- base = get_python_raw_instruction_type();
-
- if (type == base)
- goto simple_way;
-
- /* Mise en place d'un type dédié */
-
- first_time = (g_type_from_name(type->tp_name) == 0);
-
- gtype = build_dynamic_type(G_TYPE_RAW_INSTRUCTION, type->tp_name, NULL, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
-
- if (!status)
- {
- result = NULL;
- goto exit;
- }
-
- }
-
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
-
- simple_way:
-
- result = PyType_GenericNew(type, args, kwds);
-
- exit:
-
- return result;
-
-}
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -139,20 +91,17 @@ static PyObject *py_raw_instruction_new(PyTypeObject *type, PyObject *args, PyOb
static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
{
int result; /* Bilan à retourner */
+ GBinaryPortion *area; /* Zone de contenance */
vmpa2t *addr; /* Texte de lecture */
- unsigned long mem_size; /* Taille de portion brute */
+ MemoryDataSize size; /* Taille de portion brute */
unsigned long long value; /* Valeur brute à considérer */
GBinContent *content; /* Contenu à lire au besoin */
unsigned long count; /* Nombre d'éléments à lister */
- unsigned int endian; /* Type de boutisme impliqué */
+ SourceEndian endian; /* Type de boutisme impliqué */
int ret; /* Bilan de lecture des args. */
- GArchInstruction *fake; /* Instruction à copier */
- GArchInstruction *instr; /* Instruction à manipuler */
- size_t op_count; /* Nombre d'opérande à copier */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à transférer */
+ GRawInstruction *instr; /* Instruction à manipuler */
- static char *kwlist[] = { "addr", "mem_size", "value", "content", "count", "endian", NULL };
+ static char *kwlist[] = { "area", "addr", "size", "value", "content", "count", "endian", NULL };
#define RAW_INSTRUCTION_DOC \
"The RawInstruction object handles data which is not (yet?) disassembled" \
@@ -187,9 +136,14 @@ static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwd
count = 0;
endian = 0;
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&k|KO&kI", kwlist,
- convert_any_to_vmpa, &addr, &mem_size,
- &value, convert_to_binary_content, &content, &count, &endian);
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&O&O&|KO&kO&", kwlist,
+ convert_to_binary_portion, &area,
+ convert_any_to_vmpa, &addr,
+ convert_to_memory_data_size, &size,
+ &value,
+ convert_to_binary_content, &content,
+ &count,
+ convert_to_source_endian, &endian);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -199,35 +153,19 @@ static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwd
/* Eléments de base */
- if (content != NULL)
- fake = g_raw_instruction_new_array(content, mem_size, count, addr, endian);
- else
- fake = g_raw_instruction_new_from_value(addr, mem_size, value);
+ instr = G_RAW_INSTRUCTION(pygobject_get(self));
- if (fake == NULL)
+ if (content != NULL)
{
- PyErr_SetString(PyExc_ValueError, _("Unable to build the object with the given parameters."));
- goto clean_exit;
+ if (!g_raw_instruction_create_array(instr, area, addr, size, content, count, endian))
+ goto clean_exit;
}
-
- instr = G_ARCH_INSTRUCTION(pygobject_get(self));
-
- g_arch_instruction_lock_operands(fake);
-
- op_count = _g_arch_instruction_count_operands(fake);
-
- for (i = 0; i < op_count; i++)
+ else
{
- op = _g_arch_instruction_get_operand(fake, i);
- g_arch_instruction_attach_extra_operand(instr, op);
+ if (!g_raw_instruction_create_value(instr, area, addr, size, value))
+ goto clean_exit;
}
- g_arch_instruction_unlock_operands(fake);
-
- g_arch_instruction_set_range(instr, g_arch_instruction_get_range(fake));
-
- g_object_unref(G_OBJECT(fake));
-
result = 0;
clean_exit:
@@ -239,6 +177,12 @@ static int py_raw_instruction_init(PyObject *self, PyObject *args, PyObject *kwd
}
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES DE L'INSTRUCTION */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = classe représentant une instruction. *
@@ -271,7 +215,6 @@ static PyObject *py_raw_instruction_get_padding(PyObject *self, void *closure)
result = state ? Py_True : Py_False;
Py_INCREF(result);
-
return result;
}
@@ -342,7 +285,6 @@ static PyObject *py_raw_instruction_get_string(PyObject *self, void *closure)
result = state ? Py_True : Py_False;
Py_INCREF(result);
-
return result;
}
diff --git a/plugins/pychrysalide/arch/instructions/undefined.c b/plugins/pychrysalide/arch/instructions/undefined.c
index 1246daa..1c2bccc 100644
--- a/plugins/pychrysalide/arch/instructions/undefined.c
+++ b/plugins/pychrysalide/arch/instructions/undefined.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* undefined.c - équivalent Python du fichier "arch/instructions/undefined.h"
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -28,9 +28,7 @@
#include <pygobject.h>
-#include <i18n.h>
#include <arch/instructions/undefined-int.h>
-#include <plugins/dt.h>
#include "constants.h"
@@ -40,75 +38,27 @@
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_undef_instruction_new(PyTypeObject *, PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Initialise une instance sur la base du dérivé de GObject. */
-static int py_undef_instruction_init(PyObject *, PyObject *, PyObject *);
-
-/* Indique le type de conséquences réél de l'instruction. */
-static PyObject *py_undef_instruction_get_behavior(PyObject *, void *);
-
-
-
-/******************************************************************************
-* *
-* Paramètres : type = type du nouvel objet à mettre en place. *
-* args = éventuelle liste d'arguments. *
-* kwds = éventuel dictionnaire de valeurs mises à disposition. *
-* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
-* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_undef_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyObject *result; /* Objet à retourner */
- PyTypeObject *base; /* Type de base à dériver */
- bool first_time; /* Evite les multiples passages*/
- GType gtype; /* Nouveau type de processeur */
- bool status; /* Bilan d'un enregistrement */
-
- /* Validations diverses */
- base = get_python_undefined_instruction_type();
+CREATE_DYN_CONSTRUCTOR(undefined_instruction, G_TYPE_UNDEFINED_INSTRUCTION);
- if (type == base)
- goto simple_way;
-
- /* Mise en place d'un type dédié */
-
- first_time = (g_type_from_name(type->tp_name) == 0);
-
- gtype = build_dynamic_type(G_TYPE_UNDEF_INSTRUCTION, type->tp_name, NULL, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_undefined_instruction_init(PyObject *, PyObject *, PyObject *);
- if (!status)
- {
- result = NULL;
- goto exit;
- }
- }
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+/* ------------------------ FONCTIONNALITES DE L'INSTRUCTION ------------------------ */
- simple_way:
- result = PyType_GenericNew(type, args, kwds);
+/* Indique le type de conséquences réél de l'instruction. */
+static PyObject *py_undefined_instruction_get_behavior(PyObject *, void *);
- exit:
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -125,30 +75,27 @@ static PyObject *py_undef_instruction_new(PyTypeObject *type, PyObject *args, Py
* *
******************************************************************************/
-static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
+static int py_undefined_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- unsigned long behavior; /* Conséquence pour l'instruct°*/
+ InstrExpectedBehavior behavior; /* Conséquence pour l'instruct°*/
int ret; /* Bilan de lecture des args. */
- GUndefInstruction *instr; /* Instruction à manipuler */
- undef_extra_data_t *extra; /* Données insérées à modifier */
+ GUndefinedInstruction *instr; /* Instruction à manipuler */
- static char *kwlist[] = { "behavior", NULL };
-
-#define UNDEF_INSTRUCTION_DOC \
- "UndefInstruction represents all kinds of instructions which are" \
+#define UNDEFINED_INSTRUCTION_DOC \
+ "UndefinedInstruction represents all kinds of instructions which are" \
" officially not part of a runnable instruction set.\n" \
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " UndefInstruction(behavior)" \
+ " UndefinedInstruction(behavior)" \
"\n" \
"Where behavior is a" \
- " pychrysalide.arch.instructions.UndefInstruction.ExpectedBehavior" \
+ " pychrysalide.arch.instructions.UndefinedInstruction.ExpectedBehavior" \
" constant describing the state of the CPU once the instruction is run."
/* Récupération des paramètres */
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "k", kwlist, &behavior);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_undefined_expected_behavior, &behavior);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -158,17 +105,22 @@ static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *k
/* Eléments de base */
- instr = G_UNDEF_INSTRUCTION(pygobject_get(self));
-
- extra = GET_UNDEF_INSTR_EXTRA(instr);
+ instr = G_UNDEFINED_INSTRUCTION(pygobject_get(self));
- extra->behavior = behavior;
+ if (!g_undefined_instruction_create(instr, behavior))
+ return -1;
return 0;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* FONCTIONNALITES DE L'INSTRUCTION */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = classe représentant une instruction. *
@@ -182,24 +134,25 @@ static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *k
* *
******************************************************************************/
-static PyObject *py_undef_instruction_get_behavior(PyObject *self, void *closure)
+static PyObject *py_undefined_instruction_get_behavior(PyObject *self, void *closure)
{
PyObject *result; /* Conversion à retourner */
- GUndefInstruction *instr; /* Version native */
+ GUndefinedInstruction *instr; /* Version native */
InstrExpectedBehavior behavior; /* Comportement attendu */
-#define UNDEF_INSTRUCTION_BEHAVIOR_ATTRIB PYTHON_GET_DEF_FULL \
-( \
- behavior, py_undef_instruction, \
- "Consequence carried by the undefined instruction.\n" \
- "\n" \
- "The result is provided as a" \
- " pychrysalide.arch.instructions.UndefInstruction.ExpectedBehavior" \
- " constant." \
+#define UNDEFINED_INSTRUCTION_BEHAVIOR_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ behavior, py_undefined_instruction, \
+ "Consequence carried by the undefined instruction.\n" \
+ "\n" \
+ "The result is provided as a" \
+ " pychrysalide.arch.instructions.UndefinedInstruction.ExpectedBehavior" \
+ " constant." \
)
- instr = G_UNDEF_INSTRUCTION(pygobject_get(self));
- behavior = g_undef_instruction_get_behavior(instr);
+ instr = G_UNDEFINED_INSTRUCTION(pygobject_get(self));
+
+ behavior = g_undefined_instruction_get_behavior(instr);
result = cast_with_constants_group_from_type(get_python_undefined_instruction_type(),
"ExpectedBehavior", behavior);
@@ -228,7 +181,7 @@ PyTypeObject *get_python_undefined_instruction_type(void)
};
static PyGetSetDef py_undefined_instruction_getseters[] = {
- UNDEF_INSTRUCTION_BEHAVIOR_ATTRIB,
+ UNDEFINED_INSTRUCTION_BEHAVIOR_ATTRIB,
{ NULL }
};
@@ -236,18 +189,18 @@ PyTypeObject *get_python_undefined_instruction_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.instructions.UndefInstruction",
+ .tp_name = "pychrysalide.arch.instructions.UndefinedInstruction",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = UNDEF_INSTRUCTION_DOC,
+ .tp_doc = UNDEFINED_INSTRUCTION_DOC,
.tp_methods = py_undefined_instruction_methods,
.tp_getset = py_undefined_instruction_getseters,
- .tp_init = py_undef_instruction_init,
- .tp_new = py_undef_instruction_new,
+ .tp_init = py_undefined_instruction_init,
+ .tp_new = py_undefined_instruction_new,
};
@@ -260,7 +213,7 @@ PyTypeObject *get_python_undefined_instruction_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.....UndefInstruction'. *
+* Description : Prend en charge l'objet '....UndefinedInstruction'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -285,7 +238,7 @@ bool ensure_python_undefined_instruction_is_registered(void)
if (!ensure_python_arch_instruction_is_registered())
return false;
- if (!register_class_for_pygobject(dict, G_TYPE_UNDEF_INSTRUCTION, type))
+ if (!register_class_for_pygobject(dict, G_TYPE_UNDEFINED_INSTRUCTION, type))
return false;
if (!define_undefined_instruction_constants(type))
@@ -329,7 +282,7 @@ int convert_to_undefined_instruction(PyObject *arg, void *dst)
break;
case 1:
- *((GUndefInstruction **)dst) = G_UNDEF_INSTRUCTION(pygobject_get(arg));
+ *((GUndefinedInstruction **)dst) = G_UNDEFINED_INSTRUCTION(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/arch/instructions/undefined.h b/plugins/pychrysalide/arch/instructions/undefined.h
index 3fa0453..1453612 100644
--- a/plugins/pychrysalide/arch/instructions/undefined.h
+++ b/plugins/pychrysalide/arch/instructions/undefined.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* undefined.h - prototypes pour l'équivalent Python du fichier "arch/instructions/undefined.h"
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -34,7 +34,7 @@
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_undefined_instruction_type(void);
-/* Prend en charge l'objet 'pychrysalide.arch.instructions.UndefInstruction'. */
+/* Prend en charge l'objet 'pychrysalide.arch.instructions.UndefinedInstruction'. */
bool ensure_python_undefined_instruction_is_registered(void);
/* Tente de convertir en instruction non définie. */
diff --git a/plugins/pychrysalide/arch/module-ui.c b/plugins/pychrysalide/arch/module-ui.c
index 201f760..65d1290 100644
--- a/plugins/pychrysalide/arch/module-ui.c
+++ b/plugins/pychrysalide/arch/module-ui.c
@@ -29,6 +29,7 @@
#include "operand-ui.h"
+#include "../glibext/generator.h"
@@ -52,6 +53,12 @@ bool populate_arch_module_ui(void)
if (result) result = ensure_python_arch_operand_ui_is_registered();
+ /**
+ * Préparation du terrain pour les instructions, sans lien directe
+ * de la partie UI depuis la partie NOX.
+ */
+ if (result) result = ensure_python_token_generator_is_registered();
+
assert(result);
return result;
diff --git a/plugins/pychrysalide/arch/module.c b/plugins/pychrysalide/arch/module.c
index 3f52a58..94f5ad7 100644
--- a/plugins/pychrysalide/arch/module.c
+++ b/plugins/pychrysalide/arch/module.c
@@ -32,14 +32,12 @@
#include "context.h"
#include "instriter.h"
*/
-//#include "instruction.h"
+#include "instruction.h"
#include "operand.h"
//#include "processor.h"
#include "register.h"
#include "vmpa.h"
-/*
#include "instructions/module.h"
-*/
#include "operands/module.h"
#include "../helpers.h"
@@ -77,9 +75,7 @@ bool add_arch_module(PyObject *super)
result = (module != NULL);
- /*
if (result) result = add_arch_instructions_module(module);
- */
if (result) result = add_arch_operands_module(module);
return result;
@@ -109,16 +105,14 @@ bool populate_arch_module(void)
if (result) result = ensure_python_proc_context_is_registered();
if (result) result = ensure_python_instr_iterator_is_registered();
*/
- //if (result) result = ensure_python_arch_instruction_is_registered();
+ if (result) result = ensure_python_arch_instruction_is_registered();
if (result) result = ensure_python_arch_operand_is_registered();
//if (result) result = ensure_python_arch_processor_is_registered();
if (result) result = ensure_python_arch_register_is_registered();
if (result) result = ensure_python_vmpa_is_registered();
if (result) result = ensure_python_mrange_is_registered();
- /*
if (result) result = populate_arch_instructions_module();
- */
if (result) result = populate_arch_operands_module();
assert(result);
diff --git a/plugins/pychrysalide/arch/operand.c b/plugins/pychrysalide/arch/operand.c
index 42bd247..2281dae 100644
--- a/plugins/pychrysalide/arch/operand.c
+++ b/plugins/pychrysalide/arch/operand.c
@@ -94,6 +94,10 @@ static PyObject *py_arch_operand_set_flag(PyObject *, PyObject *);
/* Retire une information complémentaire à un opérande. */
static PyObject *py_arch_operand_unset_flag(PyObject *, PyObject *);
+/* Détermine si un opérande possède un fanion particulier. */
+static PyObject *py_arch_operand_has_flag(PyObject *, PyObject *);
+
+
/* ---------------------------------------------------------------------------------- */