summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/arch/instruction.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/arch/instruction.c')
-rw-r--r--plugins/pychrysalide/arch/instruction.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index 058106d..fcd0c83 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -26,6 +26,7 @@
#include <assert.h>
+#include <malloc.h>
#include <string.h>
#include <pygobject.h>
@@ -122,6 +123,12 @@ static PyObject *py_arch_instruction_replace_operand(PyObject *, PyObject *);
/* Détache un opérande liée d'une instruction. */
static PyObject *py_arch_instruction_detach_operand(PyObject *, PyObject *);
+/* Détermine le chemin conduisant à un opérande. */
+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 *);
+
/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
@@ -578,6 +585,123 @@ static PyObject *py_arch_instruction_detach_operand(PyObject *self, PyObject *ar
}
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Détermine le chemin conduisant à un opérande. *
+* *
+* Retour : Chemin d'accès à l'opérande ou None en cas d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_instruction_find_operand_path(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Chemin à retourner */
+ GArchOperand *target; /* Opérande ciblé par l'action */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ char *path; /* Chemin déterminé */
+
+#define ARCH_INSTRUCTION_FIND_OPERAND_PATH_METHOD PYTHON_METHOD_DEF \
+( \
+ find_operand_path, "$self, target, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Compute the path leading to an instruction operand.\n" \
+ "\n" \
+ "The *target* has to be an instance of pychrysalide.arch.ArchOperand" \
+ " included in the instruction.\n" \
+ "\n" \
+ "The result is a string of the form 'n[:n:n:n]', where n is an" \
+ " internal index, or None if the *target* is not found. This kind of" \
+ " path is aimed to be built for the" \
+ " pychrysalide.arch.ArchInstruction.find_operand_path() function." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_arch_operand, &target);
+ if (!ret) return NULL;
+
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
+
+ path = g_arch_instruction_find_operand_path(instr, target);
+
+ if (path != NULL)
+ {
+ result = PyUnicode_FromString(path);
+ free(path);
+ }
+ else
+ {
+ result = Py_None;
+ 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 : Obtient l'opérande correspondant à un chemin donné. *
+* *
+* Retour : Opérande trouvé ou None en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_instruction_get_operand_from_path(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Trouvaille à retourner */
+ const char *path; /* Chemin à parcourir */
+ int ret; /* Bilan de lecture des args. */
+ GArchInstruction *instr; /* Instruction manipulée */
+ GArchOperand *op; /* Opérande retrouvé */
+
+#define ARCH_INSTRUCTION_GET_OPERAND_FROM_PATH_METHOD PYTHON_METHOD_DEF \
+( \
+ get_operand_from_path, "$self, path, /", \
+ METH_VARARGS, py_arch_instruction, \
+ "Retrieve an operand from an instruction by its path.\n" \
+ "\n" \
+ "This *path* is a string of the form 'n[:n:n:n]', where n is an" \
+ " internal index. Such a path is usually built by the" \
+ " pychrysalide.arch.ArchInstruction.find_operand_path() function.\n" \
+ "\n" \
+ "The result is an pychrysalide.arch.ArchOperand instance, or" \
+ " None if no operand was found." \
+)
+
+ ret = PyArg_ParseTuple(args, "s", &path);
+ if (!ret) return NULL;
+
+ instr = G_ARCH_INSTRUCTION(pygobject_get(self));
+
+ op = g_arch_instruction_get_operand_from_path(instr, path);
+
+ if (op != NULL)
+ {
+ result = pygobject_new(G_OBJECT(op));
+ g_object_unref(G_OBJECT(op));
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
@@ -859,6 +983,8 @@ PyTypeObject *get_python_arch_instruction_type(void)
METH_VARARGS,
"detach_operand($self, target, /)\n--\n\nRemove an operand from the instruction."
},
+ ARCH_INSTRUCTION_FIND_OPERAND_PATH_METHOD,
+ ARCH_INSTRUCTION_GET_OPERAND_FROM_PATH_METHOD,
{ NULL }
};