summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-22 18:28:36 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-22 18:34:46 (GMT)
commitc1bcf3e7bd0a256005bd15832117b78cee5fdfab (patch)
tree54188ab3933526ca79ae3e8f86dd99adad49e681
parent3a8bc79d69acae3735cc0203b54d93b4137caa09 (diff)
Allowed to initialize instances of created dynamic types if needed.
-rw-r--r--plugins/pychrysalide/arch/operands/register.c4
-rw-r--r--plugins/pychrysalide/arch/processor.c105
-rw-r--r--plugins/pychrysalide/arch/register.c4
-rw-r--r--plugins/pychrysalide/gui/panels/panel.c4
-rw-r--r--plugins/pychrysalide/plugin.c4
-rw-r--r--src/plugins/dt.c98
-rw-r--r--src/plugins/dt.h8
-rw-r--r--src/plugins/plugin.c4
-rw-r--r--tests/arch/errors.py13
-rw-r--r--tests/arch/processor.py13
10 files changed, 229 insertions, 28 deletions
diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c
index 74b6a4f..8144af0 100644
--- a/plugins/pychrysalide/arch/operands/register.c
+++ b/plugins/pychrysalide/arch/operands/register.c
@@ -100,8 +100,8 @@ static PyObject *py_register_operand_new(PyTypeObject *type, PyObject *args, PyO
first_time = (g_type_from_name(type->tp_name) == 0);
- gtype = built_dynamic_type(G_TYPE_REGISTER_OPERAND, type->tp_name,
- (GClassInitFunc)py_register_operand_init_gclass, NULL);
+ gtype = build_dynamic_type(G_TYPE_REGISTER_OPERAND, type->tp_name,
+ (GClassInitFunc)py_register_operand_init_gclass, NULL, NULL);
if (first_time)
{
diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c
index 8fc2598..b59e59b 100644
--- a/plugins/pychrysalide/arch/processor.c
+++ b/plugins/pychrysalide/arch/processor.c
@@ -54,6 +54,12 @@ static PyObject *py_arch_processor_new(PyTypeObject *, PyObject *, PyObject *);
/* Initialise la classe des descriptions de fichier binaire. */
static void py_arch_processor_init_gclass(GArchProcessorClass *, gpointer);
+/* Initialise une instance de processeur d'architecture. */
+static void py_arch_processor_init_ginstance(GArchProcessor *, GArchProcessor *);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_arch_processor_init(PyObject *, PyObject *, PyObject *);
+
/* Fournit un contexte propre au processeur d'une architecture. */
static GProcContext *py_arch_processor_get_context_wrapper(const GArchProcessor *);
@@ -160,8 +166,9 @@ static PyObject *py_arch_processor_new(PyTypeObject *type, PyObject *args, PyObj
first_time = (g_type_from_name(type->tp_name) == 0);
- gtype = built_dynamic_type(G_TYPE_ARCH_PROCESSOR, type->tp_name,
- (GClassInitFunc)py_arch_processor_init_gclass, NULL);
+ gtype = build_dynamic_type(G_TYPE_ARCH_PROCESSOR, type->tp_name,
+ (GClassInitFunc)py_arch_processor_init_gclass, NULL,
+ (GInstanceInitFunc)py_arch_processor_init_ginstance);
if (first_time)
{
@@ -191,7 +198,7 @@ static PyObject *py_arch_processor_new(PyTypeObject *type, PyObject *args, PyObj
* Paramètres : class = classe à initialiser. *
* unused = données non utilisées ici. *
* *
-* Description : Initialise la classe des descriptions de fichier binaire. *
+* Description : Initialise la classe générique des processeurs. *
* *
* Retour : - *
* *
@@ -210,6 +217,97 @@ static void py_arch_processor_init_gclass(GArchProcessorClass *class, gpointer u
/******************************************************************************
* *
+* Paramètres : proc = instance à initialiser. *
+* class = classe du type correspondant. *
+* *
+* Description : Initialise une instance de processeur d'architecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_arch_processor_init_ginstance(GArchProcessor *proc, GArchProcessor *class)
+{
+ GType type; /* Type d'instances concerné */
+ GArchProcessor *pattern; /* Patron de données à copier */
+
+ type = G_TYPE_FROM_INSTANCE(proc);
+
+ pattern = get_dynamic_type_pattern(type);
+
+ if (pattern != NULL)
+ {
+ proc->endianness = pattern->endianness;
+ proc->memsize = pattern->memsize;
+ proc->inssize = pattern->inssize;
+ proc->virt_space = pattern->virt_space;
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_arch_processor_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ unsigned long endianness; /* Boutisme du processeur */
+ unsigned long mem_size; /* Taille d'adressage */
+ unsigned long ins_min_size; /* Taille minimale d'instruct° */
+ int vspace; /* Support d'un espace virtuel */
+ int ret; /* Bilan de lecture des args. */
+ PyObject *new_kwds; /* Nouveau dictionnaire épuré */
+ GArchProcessor *proc; /* Processeur à manipuler */
+
+ static char *kwlist[] = { "endianness", "mem_size", "ins_min_size", "vspace", NULL };
+
+ /* Récupération des paramètres */
+
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "kkkp", kwlist,
+ &endianness, &mem_size, &ins_min_size, &vspace);
+ if (!ret) return -1;
+
+ /* Initialisation d'un objet GLib */
+
+ new_kwds = PyDict_New();
+
+ ret = PyGObject_Type.tp_init(self, args, new_kwds);
+
+ Py_DECREF(new_kwds);
+
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ proc = G_ARCH_PROCESSOR(pygobject_get(self));
+
+ proc->endianness = endianness;
+ proc->memsize = mem_size;
+ proc->inssize = ins_min_size;
+ proc->virt_space = vspace;
+
+ register_dynamic_type_pattern(G_OBJECT(proc));
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture visée par la procédure. *
* *
* Description : Fournit un contexte propre au processeur d'une architecture. *
@@ -930,6 +1028,7 @@ PyTypeObject *get_python_arch_processor_type(void)
.tp_methods = py_arch_processor_methods,
.tp_getset = py_arch_processor_getseters,
+ .tp_init = py_arch_processor_init,
.tp_new = py_arch_processor_new,
};
diff --git a/plugins/pychrysalide/arch/register.c b/plugins/pychrysalide/arch/register.c
index 0299fa6..c55cd2b 100644
--- a/plugins/pychrysalide/arch/register.c
+++ b/plugins/pychrysalide/arch/register.c
@@ -103,8 +103,8 @@ static PyObject *py_arch_register_new(PyTypeObject *type, PyObject *args, PyObje
first_time = (g_type_from_name(type->tp_name) == 0);
- gtype = built_dynamic_type(G_TYPE_ARCH_REGISTER, type->tp_name,
- (GClassInitFunc)py_arch_register_init_gclass, NULL);
+ gtype = build_dynamic_type(G_TYPE_ARCH_REGISTER, type->tp_name,
+ (GClassInitFunc)py_arch_register_init_gclass, NULL, NULL);
if (first_time)
{
diff --git a/plugins/pychrysalide/gui/panels/panel.c b/plugins/pychrysalide/gui/panels/panel.c
index 0db1df8..2d0b562 100644
--- a/plugins/pychrysalide/gui/panels/panel.c
+++ b/plugins/pychrysalide/gui/panels/panel.c
@@ -109,8 +109,8 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
first_time = (g_type_from_name(type->tp_name) == 0);
- gtype = built_dynamic_type(G_TYPE_PANEL_ITEM, type->tp_name,
- (GClassInitFunc)py_panel_item_init_gclass, NULL);
+ gtype = build_dynamic_type(G_TYPE_PANEL_ITEM, type->tp_name,
+ (GClassInitFunc)py_panel_item_init_gclass, NULL, NULL);
if (first_time)
{
diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c
index 7667af7..51da910 100644
--- a/plugins/pychrysalide/plugin.c
+++ b/plugins/pychrysalide/plugin.c
@@ -175,8 +175,8 @@ static PyObject *py_plugin_module_new(PyTypeObject *type, PyObject *args, PyObje
first_time = (g_type_from_name(type->tp_name) == 0);
- gtype = built_dynamic_type(G_TYPE_PYTHON_PLUGIN, type->tp_name,
- (GClassInitFunc)py_plugin_module_init_gclass, NULL);
+ gtype = build_dynamic_type(G_TYPE_PYTHON_PLUGIN, type->tp_name,
+ (GClassInitFunc)py_plugin_module_init_gclass, NULL, NULL);
if (first_time)
{
diff --git a/src/plugins/dt.c b/src/plugins/dt.c
index afdba21..14b03f0 100644
--- a/src/plugins/dt.c
+++ b/src/plugins/dt.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include <malloc.h>
+#include <string.h>
@@ -44,9 +45,14 @@
typedef struct _type_dyn_info_t
{
GType type; /* Identifiant unique obtenu */
- GClassInitFunc init; /* Définition des méthodes */
+
+ GClassInitFunc cinit; /* Phase d'initialisation #1 */
gconstpointer data; /* Eventuelles données utiles */
+ GInstanceInitFunc init; /* Phase d'initialisation #2 */
+
+ void *pattern; /* Modèle de données d'instance*/
+
} type_dyn_info_t;
/* Description de fichier binaire (instance) */
@@ -98,10 +104,10 @@ static void g_dynamic_types_unuse(GDynamicTypes *);
static void g_dynamic_types_complete_type(GDynamicTypes *, GType, GTypeInfo *, GTypeValueTable *);
/* Retrouve les informations concernant un type dynamique. */
-static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *, GType);
+static type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *, GType);
/* Fournit un identifiant GLib pour un nouveau type. */
-static GType g_dynamic_types_register_type(GDynamicTypes *, GType, const char *, GClassInitFunc, gconstpointer);
+static GType g_dynamic_types_register_type(GDynamicTypes *, GType, const char *, GClassInitFunc, gconstpointer, GInstanceInitFunc);
@@ -297,7 +303,7 @@ static void g_dynamic_types_unuse(GDynamicTypes *types)
static void g_dynamic_types_complete_type(GDynamicTypes *types, GType type, GTypeInfo *info, GTypeValueTable *table)
{
- const type_dyn_info_t *nfo; /* Source d'inspiration */
+ type_dyn_info_t *nfo; /* Source d'inspiration */
GType parent; /* Type parent du type */
GTypeQuery query; /* Informations complémentaires*/
@@ -312,10 +318,11 @@ static void g_dynamic_types_complete_type(GDynamicTypes *types, GType type, GTyp
/* Définition */
info->class_size = query.class_size;
- info->class_init = nfo->init;
+ info->class_init = nfo->cinit;
info->class_data = nfo->data;
info->instance_size = query.instance_size;
+ info->instance_init = nfo->init;
}
@@ -333,7 +340,7 @@ static void g_dynamic_types_complete_type(GDynamicTypes *types, GType type, GTyp
* *
******************************************************************************/
-static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *types, GType target)
+static type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *types, GType target)
{
type_dyn_info_t *result; /* Informations à retourner */
size_t i; /* Boucle de parcours */
@@ -353,8 +360,9 @@ static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *types, G
* *
* Paramètres : parent = type GLib parent. *
* name = désignation du nouveau type. *
-* init = procédure d'initialisation de la classe associée. *
+* cinit = procédure d'initialisation de la classe associée. *
* data = éventuelles données à associer à la future classe. *
+* init = procédure d'initialisation pour chaque instance. *
* *
* Description : Fournit un identifiant GLib pour un nouveau type. *
* *
@@ -364,7 +372,7 @@ static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *types, G
* *
******************************************************************************/
-static GType g_dynamic_types_register_type(GDynamicTypes *types, GType parent, const char *name, GClassInitFunc init, gconstpointer data)
+static GType g_dynamic_types_register_type(GDynamicTypes *types, GType parent, const char *name, GClassInitFunc cinit, gconstpointer data, GInstanceInitFunc init)
{
GType result; /* Identifiant à retourner */
type_dyn_info_t *new; /* Mémorisation de paramètres */
@@ -379,9 +387,14 @@ static GType g_dynamic_types_register_type(GDynamicTypes *types, GType parent, c
new = malloc(sizeof(type_dyn_info_t));
new->type = result;
- new->init = init;
+
+ new->cinit = cinit;
new->data = data;
+ new->init = init;
+
+ new->pattern = NULL;
+
/* Inscription définitive */
types->info = realloc(types->info, ++types->count * sizeof(type_dyn_info_t *));
@@ -449,8 +462,9 @@ void exit_chrysalide_dynamic_types(void)
* *
* Paramètres : parent = type GLib parent. *
* name = désignation du nouveau type. *
-* init = procédure d'initialisation de la classe associée. *
+* cinit = procédure d'initialisation de la classe associée. *
* data = éventuelles données à associer à la future classe. *
+* init = procédure d'initialisation pour chaque instance. *
* *
* Description : Fournit un identifiant GLib pour un nouveau type. *
* *
@@ -460,14 +474,74 @@ void exit_chrysalide_dynamic_types(void)
* *
******************************************************************************/
-GType built_dynamic_type(GType parent, const char *name, GClassInitFunc init, gconstpointer data)
+GType build_dynamic_type(GType parent, const char *name, GClassInitFunc cinit, gconstpointer data, GInstanceInitFunc init)
{
GType result; /* Identifiant à retourner */
result = g_type_from_name(name);
if (result == 0)
- result = g_dynamic_types_register_type(_chrysalide_dtypes, parent, name, init, data);
+ result = g_dynamic_types_register_type(_chrysalide_dtypes, parent, name, cinit, data, init);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instance = instance portant les données à conserver. *
+* *
+* Description : Enregistre les données correspondant à une instance. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void register_dynamic_type_pattern(GObject *instance)
+{
+ GType type; /* Type d'instances concerné */
+ type_dyn_info_t *nfo; /* Source d'inspiration */
+ GTypeQuery query; /* Informations complémentaires*/
+
+ type = G_TYPE_FROM_INSTANCE(instance);
+
+ nfo = g_dynamic_types_find(_chrysalide_dtypes, type);
+ assert(nfo != NULL);
+
+ g_type_query(type, &query);
+
+ if (nfo->pattern == NULL)
+ nfo->pattern = malloc(query.instance_size);
+
+ memcpy(nfo->pattern, instance, query.instance_size);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'une instance créée sans initialisation. *
+* *
+* Description : Fournit les données correspondant à une instance initiale. *
+* *
+* Retour : Données issues de la première instance d'un type ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void *get_dynamic_type_pattern(GType type)
+{
+ void *result; /* Modèle éventuel à retourner */
+ type_dyn_info_t *nfo; /* Source d'inspiration */
+
+ nfo = g_dynamic_types_find(_chrysalide_dtypes, type);
+ assert(nfo != NULL);
+
+ result = nfo->pattern;
return result;
diff --git a/src/plugins/dt.h b/src/plugins/dt.h
index b9d4656..c25f4fd 100644
--- a/src/plugins/dt.h
+++ b/src/plugins/dt.h
@@ -40,7 +40,13 @@ bool init_chrysalide_dynamic_types(void);
void exit_chrysalide_dynamic_types(void);
/* Fournit un identifiant GLib pour un nouveau type. */
-GType built_dynamic_type(GType, const char *, GClassInitFunc, gconstpointer);
+GType build_dynamic_type(GType, const char *, GClassInitFunc, gconstpointer, GInstanceInitFunc);
+
+/* Enregistre les données correspondant à une instance. */
+void register_dynamic_type_pattern(GObject *);
+
+/* Fournit les données correspondant à une instance initiale. */
+void *get_dynamic_type_pattern(GType);
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index ff3db31..1bdcf04 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -450,8 +450,8 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
if (!valid)
goto bad_plugin;
- gtype = built_dynamic_type(G_TYPE_PLUGIN_MODULE, interface->gtp_name,
- (GClassInitFunc)g_plugin_module_init_gclass, module);
+ gtype = build_dynamic_type(G_TYPE_PLUGIN_MODULE, interface->gtp_name,
+ (GClassInitFunc)g_plugin_module_init_gclass, module, NULL);
if (gtype == G_TYPE_INVALID)
goto bad_plugin;
diff --git a/tests/arch/errors.py b/tests/arch/errors.py
index 8affb77..e57b94b 100644
--- a/tests/arch/errors.py
+++ b/tests/arch/errors.py
@@ -6,6 +6,7 @@
from chrysacase import ChrysalideTestCase
+from pychrysalide import arch
from pychrysalide.arch import vmpa
from pychrysalide.arch import ArchProcessor
@@ -28,7 +29,17 @@ class TestArchErrors(ChrysalideTestCase):
class NewProc(ArchProcessor):
- pass
+
+ def __init__(self):
+
+ props = {
+ 'endianness': arch.SRE_LITTLE,
+ 'mem_size': arch.MDS_32_BITS_UNSIGNED,
+ 'ins_min_size': arch.MDS_32_BITS_UNSIGNED,
+ 'vspace': False
+ }
+
+ super(NewProc, self).__init__(**props)
proc = NewProc()
diff --git a/tests/arch/processor.py b/tests/arch/processor.py
index 97a713d..bf17b98 100644
--- a/tests/arch/processor.py
+++ b/tests/arch/processor.py
@@ -5,13 +5,13 @@
import pychrysalide
from chrysacase import ChrysalideTestCase
from pychrysalide.analysis.contents import MemoryContent
+from pychrysalide import arch
from pychrysalide.arch import ArchProcessor
from pychrysalide.arch import ProcContext
from pychrysalide.arch import vmpa
from pychrysalide.format import FlatFormat
-
class TestProcessor(ChrysalideTestCase):
"""TestCase for arch.ArchProcessor."""
@@ -28,6 +28,17 @@ class TestProcessor(ChrysalideTestCase):
class NewProcWithCtx(ArchProcessor):
+ def __init__(self):
+
+ props = {
+ 'endianness': arch.SRE_LITTLE,
+ 'mem_size': arch.MDS_32_BITS_UNSIGNED,
+ 'ins_min_size': arch.MDS_32_BITS_UNSIGNED,
+ 'vspace': False
+ }
+
+ super(NewProcWithCtx, self).__init__(**props)
+
def _get_context(self):
return NewContext()