summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-12-14 23:30:12 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-12-14 23:30:12 (GMT)
commitdb1a6171007a6641a4659392c9bcc05670396643 (patch)
treed011651b8b73b2a28d01e416d613d63bf5b0b4e6
parentba6ca32c37c5db2582a015ed15d6ba128c36968e (diff)
Provided an iterator for instructions.
-rw-r--r--ChangeLog26
-rw-r--r--plugins/pychrysa/arch/Makefile.am1
-rw-r--r--plugins/pychrysa/arch/instriter.c265
-rw-r--r--plugins/pychrysa/arch/instriter.h42
-rw-r--r--plugins/pychrysa/arch/module.c2
-rw-r--r--plugins/pychrysa/arch/processor.c44
-rw-r--r--src/arch/Makefile.am1
-rw-r--r--src/arch/instriter.c135
-rw-r--r--src/arch/instriter.h50
-rw-r--r--src/arch/instruction.h2
-rw-r--r--src/arch/processor-int.h5
-rw-r--r--src/arch/processor.c196
-rw-r--r--src/arch/processor.h18
13 files changed, 710 insertions, 77 deletions
diff --git a/ChangeLog b/ChangeLog
index 856c430..00d2f12 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+16-12-15 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/pychrysa/arch/Makefile.am:
+ Add the 'instriter.[ch]' files to libpychrysaarch_la_SOURCES.
+
+ * plugins/pychrysa/arch/instriter.c:
+ * plugins/pychrysa/arch/instriter.h:
+ New entries: provide an iterator for instructions.
+
+ * plugins/pychrysa/arch/module.c:
+ * plugins/pychrysa/arch/processor.c:
+ Update code.
+
+ * src/arch/Makefile.am:
+ Add the 'instriter.[ch]' files to libarch_la_SOURCES.
+
+ * src/arch/instriter.c:
+ * src/arch/instriter.h:
+ New entries: provide an iterator for instructions.
+
+ * src/arch/instruction.h:
+ * src/arch/processor-int.h:
+ * src/arch/processor.c:
+ * src/arch/processor.h:
+ Update code.
+
16-12-13 Cyrille Bagard <nocbos@gmail.com>
* src/gui/editem.c:
diff --git a/plugins/pychrysa/arch/Makefile.am b/plugins/pychrysa/arch/Makefile.am
index 7607ed8..5d631bb 100644
--- a/plugins/pychrysa/arch/Makefile.am
+++ b/plugins/pychrysa/arch/Makefile.am
@@ -2,6 +2,7 @@
noinst_LTLIBRARIES = libpychrysaarch.la
libpychrysaarch_la_SOURCES = \
+ instriter.h instriter.c \
instruction.h instruction.c \
module.h module.c \
processor.h processor.c \
diff --git a/plugins/pychrysa/arch/instriter.c b/plugins/pychrysa/arch/instriter.c
new file mode 100644
index 0000000..1e5346e
--- /dev/null
+++ b/plugins/pychrysa/arch/instriter.c
@@ -0,0 +1,265 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instriter.c - équivalent Python du fichier "arch/instriter.c"
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "instriter.h"
+
+
+#include <pygobject.h>
+
+
+#include <arch/instriter.h>
+#include <arch/processor.h>
+
+
+#include "processor.h"
+
+
+
+/* Transcription d'un itérateur en Python */
+typedef struct _PyInstrIterator
+{
+ PyObject_HEAD; /* A laisser en premier */
+
+ instr_iter_t *native; /* Version native de l'objet */
+
+} PyInstrIterator;
+
+
+/* Libère de la mémoire un itérateur sur des instructions. */
+static void py_instr_iterator_dealloc(PyInstrIterator *);
+
+/* Fournit l'instruction qui en suit une autre. */
+static PyObject *py_instr_iterator_next(PyInstrIterator *);
+
+/* Initialise un nouvel itérateur. */
+static int py_instr_iterator_init(PyInstrIterator *, PyObject *, PyObject *);
+
+/* Construit un nouvel itérateur. */
+static PyObject *py_instr_iterator_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = itérateur à supprimer. *
+* *
+* Description : Libère de la mémoire un itérateur sur des instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_instr_iterator_dealloc(PyInstrIterator *self)
+{
+ delete_instruction_iterator(self->native);
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = itérateur à manipuler. *
+* *
+* Description : Fournit l'instruction qui en suit une autre. *
+* *
+* Retour : Instruction suivante trouvée, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_instr_iterator_next(PyInstrIterator *self)
+{
+ PyObject *result; /* Résultat à retourner */
+ GArchInstruction *next; /* Instruction suivante */
+
+ next = get_instruction_iterator_next(self->native);
+
+ if (next != NULL)
+ result = pygobject_new(G_OBJECT(next));
+
+ else
+ {
+ PyErr_SetNone(PyExc_StopIteration);
+ result = NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance d'objet à initialiser. *
+* args = arguments passés pour l'appel. *
+* kwds = mots clefs éventuellement fournis en complément. *
+* *
+* Description : Initialise un nouvel itérateur. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_instr_iterator_init(PyInstrIterator *self, PyObject *args, PyObject *kwds)
+{
+ int result; /* Bilan à retourner */
+ PyObject *proc_obj; /* Processeur version Python */
+ unsigned long index; /* Indice de première instruc. */
+ int ret; /* Bilan de lecture des args. */
+ GArchProcessor *proc; /* Version native du processeur*/
+
+ result = -1;
+
+ ret = PyArg_ParseTuple(args, "Ok", &proc_obj, &index);
+ if (ret == 0) goto piii_exit;
+
+ ret = PyObject_IsInstance(proc_obj, (PyObject *)get_python_arch_processor_type());
+ if (!ret) goto piii_exit;
+
+ proc = G_ARCH_PROCESSOR(pygobject_get(proc_obj));
+
+ self->native = create_instruction_iterator(proc, index);
+
+ result = 0;
+
+ piii_exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'objet à mettre en place. *
+* args = arguments passés pour l'appel. *
+* kwds = mots clefs éventuellement fournis en complément. *
+* *
+* Description : Construit un nouvel itérateur. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_instr_iterator_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyInstrIterator *result; /* Nouvelle instance à renvoyer*/
+ int ret; /* Bilan de l'initialisation */
+
+ result = (PyInstrIterator *)type->tp_alloc(type, 0);
+
+ if (result != NULL)
+ {
+ ret = py_instr_iterator_init(result, args, kwds);
+
+ if (ret != 0)
+ {
+ Py_DECREF(result);
+ result = NULL;
+ }
+
+ }
+
+ return (PyObject *)result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_instr_iterator_type(void)
+{
+ static PyTypeObject py_instr_iterator_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.arch.InstrIterator",
+ .tp_basicsize = sizeof(PyInstrIterator),
+
+ .tp_dealloc = (destructor)py_instr_iterator_dealloc,
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "Iterator for Chrysalide instructions loaded in a given processor.",
+
+ .tp_iter = PyObject_SelfIter,
+ .tp_iternext = (iternextfunc)py_instr_iterator_next,
+
+ .tp_init = (initproc)py_instr_iterator_init,
+ .tp_new = py_instr_iterator_new,
+
+ };
+
+ return &py_instr_iterator_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.arch.InstrIterator'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_instr_iterator(PyObject *module)
+{
+ PyTypeObject *py_instr_iterator_type; /* Type Python 'BinContent' */
+ int ret; /* Bilan d'un appel */
+
+ py_instr_iterator_type = get_python_instr_iterator_type();
+
+ if (PyType_Ready(py_instr_iterator_type) < 0)
+ return false;
+
+ Py_INCREF(py_instr_iterator_type);
+ ret = PyModule_AddObject(module, "InstrIterator", (PyObject *)py_instr_iterator_type);
+
+ return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/arch/instriter.h b/plugins/pychrysa/arch/instriter.h
new file mode 100644
index 0000000..be84dbc
--- /dev/null
+++ b/plugins/pychrysa/arch/instriter.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instriter.h - prototypes pour l'équivalent Python du fichier "arch/instriter.h"
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_INSTRITER_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_INSTRITER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_instr_iterator_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.arch.InstrIterator'. */
+bool register_python_instr_iterator(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_INSTRITER_H */
diff --git a/plugins/pychrysa/arch/module.c b/plugins/pychrysa/arch/module.c
index 73f8770..ce5db70 100644
--- a/plugins/pychrysa/arch/module.c
+++ b/plugins/pychrysa/arch/module.c
@@ -28,6 +28,7 @@
#include <assert.h>
+#include "instriter.h"
#include "instruction.h"
#include "processor.h"
#include "vmpa.h"
@@ -83,6 +84,7 @@ bool add_arch_module_to_python_module(PyObject *super)
result &= register_python_arch_instruction(module);
result &= register_python_arch_processor(module);
+ result &= register_python_instr_iterator(module);
result &= register_python_vmpa(module);
result &= register_python_mrange(module);
diff --git a/plugins/pychrysa/arch/processor.c b/plugins/pychrysa/arch/processor.c
index 291d788..3ef56e4 100644
--- a/plugins/pychrysa/arch/processor.c
+++ b/plugins/pychrysa/arch/processor.c
@@ -34,6 +34,7 @@
#include <arch/processor.h>
+#include "instriter.h"
#include "instruction.h"
#include "vmpa.h"
#include "../helpers.h"
@@ -62,7 +63,7 @@
/* Fournit les instructions désassemblées pour une architecture. */
-static PyObject *py_arch_processor_get_disass_instrs(PyObject *, void *);
+static PyObject *py_arch_processor_get_instrs(PyObject *, void *);
/* Recherche une instruction d'après son adresse. */
static PyObject *py_arch_processor_find_instr_by_addr(PyObject *, PyObject *);
@@ -75,8 +76,6 @@ static PyObject *py_arch_processor_get_next_instr(PyObject *, PyObject *);
-
-
/* ---------------------------------------------------------------------------------- */
/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */
/* ---------------------------------------------------------------------------------- */
@@ -95,22 +94,19 @@ static PyObject *py_arch_processor_get_next_instr(PyObject *, PyObject *);
* *
******************************************************************************/
-static PyObject *py_arch_processor_get_disass_instrs(PyObject *self, void *closure)
+static PyObject *py_arch_processor_get_instrs(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
- GArchProcessor *proc; /* Architecture visée */
- GArchInstruction *instrs; /* Série d'instructions liées */
+ PyTypeObject *iterator_type; /* Type Python de l'itérateur */
+ PyObject *args; /* Liste des arguments d'appel */
- proc = G_ARCH_PROCESSOR(pygobject_get(self));
- instrs = g_arch_processor_get_disassembled_instructions(proc);
+ iterator_type = get_python_instr_iterator_type();
- if (instrs != NULL)
- result = pygobject_new(G_OBJECT(instrs));
- else
- {
- result = Py_None;
- Py_INCREF(result);
- }
+ args = Py_BuildValue("On", self, 0);
+
+ result = PyObject_CallObject((PyObject *)iterator_type, args);
+
+ Py_DECREF(args);
return result;
@@ -293,22 +289,6 @@ static PyObject *py_arch_processor_get_next_instr(PyObject *self, PyObject *args
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : - *
@@ -344,7 +324,7 @@ PyTypeObject *get_python_arch_processor_type(void)
static PyGetSetDef py_arch_processor_getseters[] = {
{
- "disass_instrs", py_arch_processor_get_disass_instrs, py_arch_processor_set_disass_instrs,
+ "instrs", py_arch_processor_get_instrs, py_arch_processor_set_disass_instrs,
"Give access to the disassembled instructions run by the current processor.", NULL
},
{ NULL }
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 030ee87..a7ff3a2 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -6,6 +6,7 @@ libarch_la_SOURCES = \
context-int.h \
context.h context.c \
immediate.h immediate.c \
+ instriter.h instriter.c \
instruction-int.h \
instruction.h instruction.c \
link.h link.c \
diff --git a/src/arch/instriter.c b/src/arch/instriter.c
new file mode 100644
index 0000000..0f33998
--- /dev/null
+++ b/src/arch/instriter.c
@@ -0,0 +1,135 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instriter.h - prototypes pour le parcours simplifié d'un ensemble d'instructions
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "instriter.h"
+
+
+#include <malloc.h>
+
+
+#include "processor.h"
+
+
+
+/* Suivi d'un parcours d'instructions */
+typedef struct _instr_iter_t
+{
+ GArchProcessor *proc; /* Conteneur associé */
+ unsigned int stamp; /* Suivi d'évolutions externes */
+
+ size_t index; /* Instruction courante */
+
+} instr_iter_t;
+
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur recensant diverses instructions. *
+* index = indice de la première instruction à fournir. *
+* *
+* Description : Construit un itérateur pour parcourir des instructions. *
+* *
+* Retour : Itérateur prêt à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+instr_iter_t *create_instruction_iterator(GArchProcessor *proc, size_t index)
+{
+ instr_iter_t *result; /* Structure à retourner */
+
+ result = (instr_iter_t *)malloc(sizeof(instr_iter_t));
+
+ g_object_ref(G_OBJECT(proc));
+
+ result->proc = proc;
+ result->stamp = g_arch_processor_get_stamp(proc);
+
+ result->index = index;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iter = itérateur à traiter. *
+* *
+* Description : Détruit un itérateur mis en place. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_instruction_iterator(instr_iter_t *iter)
+{
+ g_object_unref(G_OBJECT(iter->proc));
+
+ free(iter);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iter = itérateur à manipuler. *
+* *
+* Description : Fournit l'instruction qui en suit une autre. *
+* *
+* Retour : Instruction suivante trouvée, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *get_instruction_iterator_next(instr_iter_t *iter)
+{
+ GArchInstruction *result; /* Résultat à retourner */
+
+ g_arch_processor_lock(iter->proc);
+
+ if (iter->stamp != g_arch_processor_get_stamp(iter->proc))
+ result = NULL;
+
+ else
+ {
+ if (iter->index < g_arch_processor_count_disassembled_instructions(iter->proc))
+ result = g_arch_processor_get_disassembled_instruction(iter->proc, iter->index);
+ else
+ result = NULL;
+
+ if (result != NULL)
+ iter->index++;
+
+ }
+
+ g_arch_processor_unlock(iter->proc);
+
+ return result;
+
+}
diff --git a/src/arch/instriter.h b/src/arch/instriter.h
new file mode 100644
index 0000000..b9c7621
--- /dev/null
+++ b/src/arch/instriter.h
@@ -0,0 +1,50 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instriter.h - prototypes pour le parcours simplifié d'un ensemble d'instructions
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_INSTRITER_H
+#define _ARCH_INSTRITER_H
+
+
+#include "instruction.h"
+
+
+
+/* Depuis "processeur.h" : définition générique d'un processeur d'architecture (instance) */
+typedef struct _GArchProcessor GArchProcessor;
+
+/* Suivi d'un parcours d'instructions */
+typedef struct _instr_iter_t instr_iter_t;
+
+
+/* Construit un itérateur pour parcourir des instructions. */
+instr_iter_t *create_instruction_iterator(GArchProcessor *, size_t);
+
+/* Détruit un itérateur mis en place. */
+void delete_instruction_iterator(instr_iter_t *);
+
+/* Fournit l'instruction qui en suit une autre. */
+GArchInstruction *get_instruction_iterator_next(instr_iter_t *);
+
+
+
+#endif /* _ARCH_INSTRITER_H */
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index d625e77..bddc2bf 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -84,7 +84,7 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *);
* On procède donc à une seconde déclaration, en attendant éventuellement mieux.
*/
-/* Ligne de représentation générique (instance) */
+/* Depuis "processeur.h" : définition générique d'un processeur d'architecture (instance) */
typedef struct _GArchProcessor GArchProcessor;
diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h
index 8631731..b170cad 100644
--- a/src/arch/processor-int.h
+++ b/src/arch/processor-int.h
@@ -87,6 +87,11 @@ struct _GArchProcessor
GArchInstruction **instructions; /* Instructions désassemblées */
size_t instr_allocated; /* Taille de la liste allouée */
size_t instr_count; /* Taille de la liste aplatie */
+ unsigned int stamp; /* Marque de suivi des modifs */
+ GMutex mutex; /* Verrou pour l'accès */
+#ifndef NDEBUG
+ gint locked; /* Statut d'accès à la liste */
+#endif
instr_coverage *coverages; /* Liste de couvertures */
size_t cov_allocated; /* Taille de la liste allouée */
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 615aa86..26c7170 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -59,6 +59,12 @@ static void g_arch_processor_class_init(GArchProcessorClass *);
/* Initialise une instance de processeur d'architecture. */
static void g_arch_processor_init(GArchProcessor *);
+/* Supprime toutes les références externes. */
+static void g_arch_processor_dispose(GArchProcessor *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_arch_processor_finalize(GArchProcessor *);
+
@@ -76,6 +82,9 @@ static void g_arch_processor_finish_last_coverage(GArchProcessor *, GArchInstruc
+
+
+
/* Indique le type défini pour un processeur d'architecture. */
G_DEFINE_TYPE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT);
@@ -94,6 +103,12 @@ G_DEFINE_TYPE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT);
static void g_arch_processor_class_init(GArchProcessorClass *klass)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_processor_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_arch_processor_finalize;
}
@@ -112,6 +127,11 @@ static void g_arch_processor_class_init(GArchProcessorClass *klass)
static void g_arch_processor_init(GArchProcessor *proc)
{
+#ifndef DEBUG
+ g_atomic_int_set(&proc->loacked, 0);
+#endif
+ g_mutex_init(&proc->mutex);
+
proc->coverages = NULL;
proc->cov_allocated = 0;
proc->cov_count = 0;
@@ -121,6 +141,46 @@ static void g_arch_processor_init(GArchProcessor *proc)
/******************************************************************************
* *
+* Paramètres : proc = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_processor_dispose(GArchProcessor *proc)
+{
+ g_mutex_clear(&proc->mutex);
+
+ G_OBJECT_CLASS(g_arch_processor_parent_class)->dispose(G_OBJECT(proc));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_processor_finalize(GArchProcessor *proc)
+{
+ G_OBJECT_CLASS(g_arch_processor_parent_class)->finalize(G_OBJECT(proc));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture visée par la procédure. *
* *
* Description : Fournit un contexte propre au processeur d'une architecture. *
@@ -268,6 +328,62 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc
/* ---------------------------------------------------------------------------------- */
+/* RASSEMBLEMENT DES INSTRUCTIONS DESASSEMBLEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture à manipuler. *
+* state = nouvel état de l'accès aux instructions. *
+* *
+* Description : Protège ou lève la protection de l'accès aux instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_processor_lock_unlock(GArchProcessor *proc, bool state)
+{
+ if (state)
+ {
+ g_mutex_lock(&proc->mutex);
+ g_atomic_int_set(&proc->locked, 1);
+ }
+ else
+ {
+ g_atomic_int_set(&proc->locked, 0);
+ g_mutex_unlock(&proc->mutex);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture à consulter via la procédure. *
+* *
+* Description : Fournit la marque de dernière modification des instructions. *
+* *
+* Retour : Marque de la dernière modification de la liste d'instruct°. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+unsigned int g_arch_processor_get_stamp(const GArchProcessor *proc)
+{
+ //assert(g_atomic_int_get(&proc->locked) == 1);
+
+ return proc->stamp;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */
/* ---------------------------------------------------------------------------------- */
@@ -348,48 +464,6 @@ static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchIns
/******************************************************************************
* *
-* Paramètres : proc = processeur recensant diverses instructions. *
-* addr = position en mémoire ou physique à chercher. *
-* *
-* Description : Recherche un groupe d'instruction d'après son adresse. *
-* *
-* Retour : Couverture trouvée ou NULL si aucune. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *proc, const vmpa2t *addr)
-{
- instr_coverage *result; /* Trouvaille à retourner */
- void *ptr; /* Résultat des recherches */
-
- int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c)
- {
- int status; /* Bilan d'une comparaison */
-
- status = cmp_mrange_with_vmpa(&c->range, a);
-
- return status;
-
- }
-
- ptr = bsearch(addr, proc->coverages, proc->cov_count,
- sizeof(instr_coverage), (__compar_fn_t)search_for_coverage_by_addr);
-
- result = ((instr_coverage *)ptr);
-
- return result;
-
-}
-
-
-
-
-
-
-/******************************************************************************
-* *
* Paramètres : proc = architecture visée par la procédure. *
* list = liste des instructions désassemblées. *
* *
@@ -519,6 +593,44 @@ size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *pr
/******************************************************************************
* *
+* Paramètres : proc = processeur recensant diverses instructions. *
+* addr = position en mémoire ou physique à chercher. *
+* *
+* Description : Recherche un groupe d'instruction d'après son adresse. *
+* *
+* Retour : Couverture trouvée ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *proc, const vmpa2t *addr)
+{
+ instr_coverage *result; /* Trouvaille à retourner */
+ void *ptr; /* Résultat des recherches */
+
+ int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c)
+ {
+ int status; /* Bilan d'une comparaison */
+
+ status = cmp_mrange_with_vmpa(&c->range, a);
+
+ return status;
+
+ }
+
+ ptr = bsearch(addr, proc->coverages, proc->cov_count,
+ sizeof(instr_coverage), (__compar_fn_t)search_for_coverage_by_addr);
+
+ result = ((instr_coverage *)ptr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = processeur recensant diverses instructions. *
* addr = position en mémoire ou physique à chercher. *
* nearby = la recherche s'effectue-t-elle de façon stricte ? *
diff --git a/src/arch/processor.h b/src/arch/processor.h
index f0f9b55..02b3533 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -44,10 +44,10 @@
-/* Ligne de représentation générique (instance) */
+/* Définition générique d'un processeur d'architecture (instance) */
typedef struct _GArchProcessor GArchProcessor;
-/* Ligne de représentation générique (classe) */
+/* Définition générique d'un processeur d'architecture (classe) */
typedef struct _GArchProcessorClass GArchProcessorClass;
@@ -74,6 +74,20 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcCont
+/* ------------------ RASSEMBLEMENT DES INSTRUCTIONS DESASSEMBLEES ------------------ */
+
+
+/* Protège ou lève la protection de l'accès aux instructions. */
+void g_arch_processor_lock_unlock(GArchProcessor *, bool);
+
+#define g_arch_processor_lock(p) g_arch_processor_lock_unlock(p, true)
+#define g_arch_processor_unlock(p) g_arch_processor_lock_unlock(p, false)
+
+/* Fournit la marque de dernière modification des instructions. */
+unsigned int g_arch_processor_get_stamp(const GArchProcessor *);
+
+
+
/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */