summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/arch/operand.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2025-03-17 07:36:58 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2025-03-17 07:36:58 (GMT)
commita28e1b94a83bee9a2424ab84818a5547eafaf0cf (patch)
treeecaf5556433afd4f19f4bfcbf378cdde3f619e51 /plugins/pychrysalide/arch/operand.c
parentb18c64b69c8c048c640b5d9f6c45b1cfda605ae8 (diff)
Restore the definition of main operands.gtk4
Diffstat (limited to 'plugins/pychrysalide/arch/operand.c')
-rw-r--r--plugins/pychrysalide/arch/operand.c476
1 files changed, 275 insertions, 201 deletions
diff --git a/plugins/pychrysalide/arch/operand.c b/plugins/pychrysalide/arch/operand.c
index 0aee4f7..42bd247 100644
--- a/plugins/pychrysalide/arch/operand.c
+++ b/plugins/pychrysalide/arch/operand.c
@@ -30,23 +30,32 @@
#include <i18n.h>
#include <arch/operand-int.h>
-#include <plugins/dt.h>
+#include <glibext/strbuilder-int.h>
#include "../access.h"
#include "../helpers.h"
+#include "../glibext/comparable.h"
+#include "../glibext/hashable.h"
+#include "../glibext/objhole.h"
+#include "../glibext/serialize.h"
#include "../glibext/singleton.h"
+#include "../glibext/strbuilder.h"
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_arch_operand_new(PyTypeObject *, PyObject *, PyObject *);
-
/* Initialise la classe générique des opérandes. */
-static void py_arch_operand_init_gclass(GArchOperandClass *, gpointer);
+static int py_arch_operand_init_gclass(GArchOperandClass *, PyTypeObject *);
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_operand, G_TYPE_ARCH_OPERAND);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_arch_operand_init(PyObject *, PyObject *, PyObject *);
+
+#if 0
/* Compare un opérande avec un autre. */
static int py_arch_operand___cmp___wrapper(const GArchOperand *, const GArchOperand *, bool);
@@ -57,14 +66,6 @@ static char *py_arch_operand_find_inner_operand_path_wrapper(const GArchOperand
/* Obtient l'opérande correspondant à un chemin donné. */
static GArchOperand *py_arch_operand_get_inner_operand_from_path_wrapper(const GArchOperand *, const char *);
-/* Traduit un opérande en version humainement lisible. */
-static void py_arch_operand_print_wrapper(const GArchOperand *, GBufferLine *);
-
-#ifdef INCLUDE_GTK_SUPPORT
-
-/* Construit un petit résumé concis de l'opérande. */
-static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *, const GLoadedBinary *);
-
#endif
@@ -72,6 +73,9 @@ static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *, const G
/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */
+#if 0
+
+
/* Effectue une comparaison avec un objet Python 'ArchOperand'. */
static PyObject *py_arch_operand_richcompare(PyObject *, PyObject *, int);
@@ -81,6 +85,15 @@ static PyObject *py_arch_operand_find_inner_operand_path(PyObject *, PyObject *)
/* Obtient l'opérande correspondant à un chemin donné. */
static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *, PyObject *);
+#endif
+
+
+/* Ajoute une information complémentaire à un opérande. */
+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 *);
+
/* ---------------------------------------------------------------------------------- */
@@ -90,113 +103,109 @@ static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *, PyObjec
/******************************************************************************
* *
-* Paramètres : type = type du nouvel objet à mettre en place. *
-* args = éventuelle liste d'arguments. *
-* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* Paramètres : gclass = classe GLib à initialiser. *
+* pyclass = classe Python à initialiser. *
* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
+* Description : Initialise la classe générique des opérandes. *
* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* Retour : 0 pour indiquer un succès de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_arch_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_arch_operand_init_gclass(GArchOperandClass *gclass, PyTypeObject *pyclass)
{
- 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 */
-#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" \
- "Some extra method definitions are optional for new classes:\n" \
- "* pychrysalide.arch.ArchRegister._find_inner_operand_path();\n" \
- "* pychrysalide.arch.ArchRegister._get_inner_operand_from_path().\n"\
- "\n" \
- "Chrysalide creates an internal glue to provide rich comparisons" \
- " for operands based on the old-style *__cmp__* function."
+#if 0
+ GStringBuilderInterface *iface; /* Interface utilisée */
- /* Validations diverses */
+ iface = g_type_interface_peek(gclass, G_TYPE_STRING_BUILDER);
- base = get_python_arch_operand_type();
- if (type == base)
- {
- result = NULL;
- PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
- goto exit;
- }
+ /*
+ printf("???????? init Python Operand ?????????????? -> class: %p '%s' - strbuilder iface: %p\n",
+ gclass, g_type_name(G_TYPE_FROM_CLASS(gclass)), iface);
+ */
- /* Mise en place d'un type dédié */
-
- first_time = (g_type_from_name(type->tp_name) == 0);
+#endif
- gtype = build_dynamic_type(G_TYPE_ARCH_OPERAND, type->tp_name,
- (GClassInitFunc)py_arch_operand_init_gclass, NULL, NULL);
+#if 0
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
+ class->compare = py_arch_operand___cmp___wrapper;
+ class->find_inner = py_arch_operand_find_inner_operand_path_wrapper;
+ class->get_inner = py_arch_operand_get_inner_operand_from_path_wrapper;
- if (!status)
- {
- result = NULL;
- goto exit;
- }
- }
+#endif
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
- result = PyType_GenericNew(type, args, kwds);
- exit:
+ //PY_CLASS_SET_WRAPPER(gclass->xxx, py_arch_operand_xxx_wrapper);
- return result;
+ return 0;
}
/******************************************************************************
* *
-* Paramètres : class = classe à initialiser. *
-* unused = données non utilisées ici. *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Initialise la classe générique des opérandes. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : - *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unused)
+static int py_arch_operand_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- class->compare = py_arch_operand___cmp___wrapper;
- class->find_inner = py_arch_operand_find_inner_operand_path_wrapper;
- class->get_inner = py_arch_operand_get_inner_operand_from_path_wrapper;
+ //unsigned int endianness; /* Boutisme du processeur */
+ int ret; /* Bilan de lecture des args. */
+ //GArchProcessor *proc; /* Processeur à manipuler */
- class->print = py_arch_operand_print_wrapper;
-#ifdef INCLUDE_GTK_SUPPORT
- class->build_tooltip = py_arch_operand_build_tooltip_wrapper;
-#endif
+#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" \
+ "Some extra method definitions are optional for new classes:\n" \
+ "* pychrysalide.arch.ArchRegister._find_inner_operand_path();\n" \
+ "* pychrysalide.arch.ArchRegister._get_inner_operand_from_path().\n"\
+ "\n" \
+ "Chrysalide creates an internal glue to provide rich comparisons" \
+ " for operands based on the old-style *__cmp__* function."
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ //proc = G_ARCH_PROCESSOR(pygobject_get(self));
+
+ //proc->endianness = endianness;
+
+ return 0;
}
+
+#if 0
+
/******************************************************************************
* *
* Paramètres : a = premier opérande à consulter. *
@@ -410,126 +419,6 @@ static GArchOperand *py_arch_operand_get_inner_operand_from_path_wrapper(const G
}
-/******************************************************************************
-* *
-* 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_XDECREF(pyret);
-
- Py_DECREF(args);
-
- }
-
- Py_DECREF(pyobj);
-
- PyGILState_Release(gstate);
-
-}
-
-
-#ifdef INCLUDE_GTK_SUPPORT
-
-
-/******************************************************************************
-* *
-* 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 */
-
-#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)
- {
- if (PyUnicode_Check(pyret))
- result = strdup(PyUnicode_AsUTF8(pyret));
- }
-
- Py_XDECREF(pyret);
-
- Py_DECREF(args);
-
- }
-
- Py_DECREF(pyobj);
-
- PyGILState_Release(gstate);
-
- return result;
-
-}
-
#endif
@@ -540,6 +429,9 @@ static char *py_arch_operand_build_tooltip_wrapper(const GArchOperand *operand,
/* ---------------------------------------------------------------------------------- */
+
+#if 0
+
/******************************************************************************
* *
* Paramètres : a = premier object Python à consulter. *
@@ -701,6 +593,164 @@ static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *self, PyO
}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = architecture concernée par la procédure. *
+* args = instruction représentant le point de départ. *
+* *
+* Description : Ajoute une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_set_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperand *operand; /* Opérande manipulé */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_OPERAND_SET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ set_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_operand, \
+ "Add some flags to the operand.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to apply to the operand 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;
+
+ operand = G_ARCH_OPERAND(pygobject_get(self));
+
+ status = g_arch_operand_set_flag(operand, 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 : Retire une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_unset_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperand *operand; /* Opérande manipulé */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_OPERAND_UNSET_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ unset_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_operand, \
+ "Remove some flags from the operand.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to delete from the operand 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;
+
+ operand = G_ARCH_OPERAND(pygobject_get(self));
+
+ status = g_arch_operand_unset_flag(operand, 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 un opérande possède un fanion particulier. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_operand_has_flag(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ unsigned int flag; /* Fanion(s) à appliquer */
+ int ret; /* Bilan de lecture des args. */
+ GArchOperand *operand; /* Opérande manipulé */
+ bool status; /* Bilan à transmettre */
+
+#define ARCH_OPERAND_HAS_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ has_flag, "$self, flag, /", \
+ METH_VARARGS, py_arch_operand, \
+ "Tell if some flags are set for the operand.\n" \
+ "\n" \
+ "This *flag* argument is an integer value containing" \
+ " bits to test for the operand 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;
+
+ operand = G_ARCH_OPERAND(pygobject_get(self));
+
+ status = g_arch_operand_has_flag(operand, flag);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
/******************************************************************************
* *
@@ -717,6 +767,11 @@ static PyObject *py_arch_operand_get_inner_operand_from_path(PyObject *self, PyO
PyTypeObject *get_python_arch_operand_type(void)
{
static PyMethodDef py_arch_operand_methods[] = {
+ ARCH_OPERAND_SET_FLAG_METHOD,
+ ARCH_OPERAND_UNSET_FLAG_METHOD,
+ ARCH_OPERAND_HAS_FLAG_METHOD,
+
+ /*
ARCH_OPERAND_CMP_WRAPPER,
ARCH_OPERAND_FIND_INNER_OPERAND_PATH_WRAPPER,
ARCH_OPERAND_GET_INNER_OPERAND_FROM_PATH_WRAPPER,
@@ -726,6 +781,7 @@ PyTypeObject *get_python_arch_operand_type(void)
#endif
ARCH_OPERAND_FIND_INNER_OPERAND_PATH_METHOD,
ARCH_OPERAND_GET_INNER_OPERAND_FROM_PATH_METHOD,
+ */
{ NULL }
};
@@ -744,11 +800,12 @@ PyTypeObject *get_python_arch_operand_type(void)
.tp_doc = ARCH_OPERAND_DOC,
- .tp_richcompare = py_arch_operand_richcompare,
+ //.tp_richcompare = py_arch_operand_richcompare,
.tp_methods = py_arch_operand_methods,
.tp_getset = py_arch_operand_getseters,
+ .tp_init = py_arch_operand_init,
.tp_new = py_arch_operand_new,
};
@@ -784,9 +841,26 @@ bool ensure_python_arch_operand_is_registered(void)
dict = PyModule_GetDict(module);
+ if (!ensure_python_thick_object_is_registered())
+ return false;
+
+ if (!ensure_python_comparable_object_is_registered())
+ return false;
+
+ if (!ensure_python_hashable_object_is_registered())
+ return false;
+
+ if (!ensure_python_serializable_object_is_registered())
+ return false;
+
if (!ensure_python_singleton_candidate_is_registered())
return false;
+ if (!ensure_python_string_builder_is_registered())
+ return false;
+
+ pyg_register_class_init(G_TYPE_ARCH_OPERAND, (PyGClassInitFunc)py_arch_operand_init_gclass);
+
if (!register_class_for_pygobject(dict, G_TYPE_ARCH_OPERAND, type))
return false;