summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/Makefile.am46
-rw-r--r--src/arch/instruction-int.h91
-rw-r--r--src/arch/instruction.c744
-rw-r--r--src/arch/instruction.h29
-rw-r--r--src/arch/instructions/Makefile.am18
-rw-r--r--src/arch/instructions/raw.c64
-rw-r--r--src/arch/instructions/undefined-int.h58
-rw-r--r--src/arch/instructions/undefined.c136
-rw-r--r--src/arch/meta.c428
-rw-r--r--src/arch/meta.h65
-rw-r--r--src/arch/operand-int.c308
-rw-r--r--src/arch/operand-int.h129
-rw-r--r--src/arch/operand.c639
-rw-r--r--src/arch/operand.h40
-rw-r--r--src/arch/operands/Makefile.am14
-rw-r--r--src/arch/operands/feeder-int.h14
-rw-r--r--src/arch/operands/feeder.c76
-rw-r--r--src/arch/operands/feeder.h9
-rw-r--r--src/arch/operands/immediate-int.h85
-rw-r--r--src/arch/operands/immediate.c1052
-rw-r--r--src/arch/operands/immediate.h46
-rw-r--r--src/arch/operands/known.c499
-rw-r--r--src/arch/operands/known.h59
-rw-r--r--src/arch/operands/proxy.c161
-rw-r--r--src/arch/operands/register-int.h45
-rw-r--r--src/arch/operands/register.c198
-rw-r--r--src/arch/operands/register.h14
-rw-r--r--src/arch/operands/target-int.h26
-rw-r--r--src/arch/operands/target.c223
-rw-r--r--src/arch/operands/target.h8
-rw-r--r--src/arch/processor.c419
-rw-r--r--src/arch/register-int.h16
-rw-r--r--src/arch/register.c115
-rw-r--r--src/arch/register.h15
-rw-r--r--src/arch/storage.c4
-rw-r--r--src/arch/vmpa.h56
36 files changed, 3588 insertions, 2361 deletions
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 5118296..bdfceb7 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -1,30 +1,29 @@
noinst_LTLIBRARIES = libarch.la
-libarch_la_SOURCES = \
- archbase.h archbase.c \
- context-int.h \
- context.h context.c \
- instriter.h instriter.c \
- instruction-int.h \
- instruction.h instruction.c \
- link.h link.c \
- meta.h meta.c \
- operand-int.h \
- operand.h operand.c \
- post.h post.c \
- processor-int.h \
- processor.h processor.c \
- register-int.h \
- register.h register.c \
- storage.h storage.c \
+libarch_la_SOURCES = \
+ archbase.h archbase.c \
+ context-int.h \
+ context.h context.c \
+ instriter.h instriter.c \
+ instruction-int.h \
+ instruction.h instruction.c \
+ link.h link.c \
+ operand-int.h operand-int.c \
+ operand.h operand.c \
+ post.h post.c \
+ processor-int.h \
+ processor.h processor.c \
+ register-int.h \
+ register.h register.c \
+ storage.h storage.c \
vmpa.h vmpa.c
-libarch_la_LIBADD = \
- instructions/libarchinstructions.la \
- operands/libarchoperands.la
+libarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
-libarch_la_LDFLAGS =
+libarch_la_LIBADD = \
+ instructions/libarchinstructions.la \
+ operands/libarchoperands.la
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
@@ -32,9 +31,4 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libarch_la_SOURCES:%c=)
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
-
SUBDIRS = instructions operands
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 6a3ccea..7dbbe27 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -26,6 +26,7 @@
#include "instruction.h"
+#include "../analysis/storage/storage.h"
#include "../common/array.h"
#include "../glibext/objhole.h"
@@ -58,27 +59,50 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe
/* Liste les registres lus et écrits par l'instruction. */
typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+typedef bool (* load_instruction_fc) (GArchInstruction *, GObjectStorage *, packed_buffer_t *);
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _instr_obj_extra
+/* Sauvegarde un contenu dans une mémoire tampon. */
+typedef bool (* store_instruction_fc) (GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _instr_extra_data_t
{
- struct
- {
- itid_t uid; /* Identifiant unique du type */
+ itid_t uid; /* Identifiant unique du type */
- ArchInstrFlag flags; /* Informations complémentaires*/
+ ArchInstrFlag flags; /* Informations complémentaires*/
- };
+} instr_extra_data_t;
+
+/* Informations glissées dans la structure GObject de GArchInstruction */
+typedef union _instr_obj_extra_t
+{
+ instr_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
- gint lock; /* Gestion d'accès aux fanions */
+} instr_obj_extra_t;
-} instr_obj_extra;
/* Définition générique d'une instruction d'architecture (instance) */
struct _GArchInstruction
{
GObject parent; /* A laisser en premier */
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+ /**
+ * L'inclusion des informations suivantes dépend de l'architecture.
+ *
+ * Si la structure GObject possède un trou, on remplit de préférence
+ * ce dernier.
+ */
+
+ instr_obj_extra_t extra; /* Externalisation embarquée */
+
+#endif
+
mrange_t range; /* Emplacement en mémoire */
flat_array_t *operands; /* Liste des opérandes */
@@ -108,39 +132,8 @@ struct _GArchInstruction
flat_array_t *from; /* Origines des références */
flat_array_t *to; /* Instructions visées */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- instr_obj_extra extra; /* Externalisation embarquée */
-
-#endif
-
};
-/**
- * Accès aux informations éventuellement déportées.
- */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
-# define INIT_ARCH_INSTR_EXTRA(ins) ins->extra.lock = 0
-
-# define GET_ARCH_INSTR_EXTRA(ins) &ins->extra
-
-#else
-
-# define INIT_ARCH_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins))
-
-# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_obj_extra)
-
-#endif
-
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
{
@@ -157,12 +150,30 @@ struct _GArchInstructionClass
print_instruction_fc print; /* Imprime l'ensemble */
+ load_instruction_fc load; /* Chargement depuis un tampon */
+ store_instruction_fc store; /* Conservation dans un tampon */
+
//get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */
};
/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARCH_INSTR_EXTRA(ins) (instr_extra_data_t *)&ins->extra
+
+#else
+
+# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_extra_data_t)
+
+#endif
+
+
+/**
* Fournit une marge pour toutes les instructions particulières communes
* à l'ensemble des architectures (GRawInstruction, GUndefInstruction).
*/
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 4079e82..cd1e9c7 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -34,10 +34,12 @@
#include "instruction-int.h"
#include "storage.h"
+#include "../analysis/storage/serialize-int.h"
+#include "../core/columns.h"
#include "../core/logs.h"
+#include "../core/processors.h"
#include "../glibext/gbinarycursor.h"
#include "../glibext/linegen-int.h"
-#include "../gtkext/gtkblockdisplay.h"
@@ -48,7 +50,10 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);
static void g_arch_instruction_init(GArchInstruction *);
/* Procède à l'initialisation de l'interface de génération. */
-static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *);
+static void g_arch_instruction_generator_init(GLineGeneratorInterface *);
+
+/* Procède à l'initialisation de l'interface de sérialisation. */
+static void g_arch_instruction_serializable_init(GSerializableObjectInterface *);
/* Supprime toutes les références externes. */
static void g_arch_instruction_dispose(GArchInstruction *);
@@ -58,14 +63,15 @@ static void g_arch_instruction_finalize(GArchInstruction *);
-/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */
-/* Charge une instruction depuis une mémoire tampon. */
-static bool g_arch_instruction_unserialize(GArchInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_instruction_load_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde toutes les destinations d'une instruction. */
+bool g_arch_instruction_store_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
-/* Sauvegarde une instruction dans une mémoire tampon. */
-static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, packed_buffer_t *);
@@ -75,12 +81,16 @@ static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, pack
/* Indique le nombre de ligne prêtes à être générées. */
static size_t g_arch_instruction_count_lines(const GArchInstruction *);
+#ifdef INCLUDE_GTK_SUPPORT
+
/* Retrouve l'emplacement correspondant à une position donnée. */
static void g_arch_instruction_compute_cursor(const GArchInstruction *, gint, size_t, size_t, GLineCursor **);
/* Détermine si le conteneur s'inscrit dans une plage donnée. */
static int g_arch_instruction_contain_cursor(const GArchInstruction *, size_t, size_t, const GLineCursor *);
+#endif
+
/* Renseigne sur les propriétés liées à un générateur. */
static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t);
@@ -91,10 +101,27 @@ static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t,
static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t, const GBinContent *);
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool _g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool _g_arch_instruction_store(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_arch_instruction_store(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+
/* Indique le type défini pour une instruction d'architecture. */
G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_interface_init));
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_instruction_serializable_init));
/******************************************************************************
@@ -121,11 +148,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
instr = G_ARCH_INSTRUCTION_CLASS(klass);
- instr->unserialize = (unserialize_instruction_fc)g_arch_instruction_unserialize;
- instr->serialize = (serialize_instruction_fc)g_arch_instruction_serialize;
-
instr->print = (print_instruction_fc)_g_arch_instruction_print;
+ instr->load = (load_instruction_fc)_g_arch_instruction_load;
+ instr->store = (store_instruction_fc)_g_arch_instruction_store;
+
}
@@ -143,7 +170,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
- INIT_ARCH_INSTR_EXTRA(instr);
+ instr_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ INIT_GOBJECT_EXTRA_LOCK(extra);
instr->operands = NULL;
@@ -165,11 +196,13 @@ static void g_arch_instruction_init(GArchInstruction *instr)
* *
******************************************************************************/
-static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *iface)
+static void g_arch_instruction_generator_init(GLineGeneratorInterface *iface)
{
iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines;
+#ifdef INCLUDE_GTK_SUPPORT
iface->compute = (linegen_compute_fc)g_arch_instruction_compute_cursor;
iface->contain = (linegen_contain_fc)g_arch_instruction_contain_cursor;
+#endif
iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2;
iface->print = (linegen_print_fc)g_arch_instruction_print;
@@ -178,6 +211,26 @@ static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface
/******************************************************************************
* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_serializable_init(GSerializableObjectInterface *iface)
+{
+ iface->load = (load_serializable_object_cb)g_arch_instruction_load;
+ iface->store = (store_serializable_object_cb)g_arch_instruction_store;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
@@ -285,19 +338,19 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- extra->flags |= flag;
+ result = !(extra->flags & flag);
- result = true;
+ extra->flags |= flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -320,19 +373,19 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- extra->flags &= ~flag;
+ result = (extra->flags & flag);
- result = true;
+ extra->flags &= ~flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -355,17 +408,17 @@ bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -387,27 +440,15 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
{
ArchInstrFlag result; /* Fanions à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->flags;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- /**
- * La pose du verrou a entraîné la mise à 1 du bit de poids fort de la zone
- * couverte par le champ "extra".
- *
- * Même si les fanions ne couvrent pas cet emplacement, leur stockage s'étend
- * sur 16 bits, et contient donc le fameux bit de verrouillage.
- *
- * On efface ce marqueur après-coup ici.
- */
-
- result &= ((AIF_HIGH_USER << 1) - 1);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -429,15 +470,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
{
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->uid = uid;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -457,15 +498,15 @@ void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)
{
itid_t result; /* Numéro à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->uid;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -666,9 +707,19 @@ void g_arch_instruction_unlock_operands(GArchInstruction *instr)
void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand)
{
+ GSingletonFactory *factory; /* Unise à instances uniques */
+ GArchOperand *singleton; /* Instance retenue */
+
+ factory = get_operands_factory();
+
+ singleton = G_ARCH_OPERAND(g_singleton_factory_get_instance(factory, G_SINGLETON_CANDIDATE(operand)));
+
+ g_object_unref(G_OBJECT(operand));
+ g_object_unref(G_OBJECT(factory));
+
g_arch_instruction_lock_operands(instr);
- add_item_to_flat_array(&instr->operands, &operand, sizeof(GArchOperand *));
+ add_item_to_flat_array(&instr->operands, &singleton, sizeof(GArchOperand *));
g_arch_instruction_unlock_operands(instr);
@@ -1557,59 +1608,54 @@ instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *instr, size_
}
-
-/* ---------------------------------------------------------------------------------- */
-/* CONVERSIONS DU FORMAT DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
-* Retour : Mot clef de bas niveau. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *g_arch_instruction_get_keyword(GArchInstruction *instr)
+static bool g_arch_instruction_load_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
{
- const char *result; /* Désignation à retourner */
-
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr);
-
- return result;
+ bool result; /* Bilan à retourner */
+ uleb128_t count; /* Nombre de liens à charger */
+ uleb128_t i; /* Boucle de parcours */
+ GArchInstruction *linked; /* Lien vers une instruction */
+ uleb128_t type; /* Valeur ULEB128 à charger */
-}
+ g_arch_instruction_lock_dest(instr);
+ result = unpack_uleb128(&count, pbuf);
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* *
-* Description : Construit un petit résumé concis de l'instruction. *
-* *
-* Retour : Chaîne de caractères à libérer après usage ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ for (i = 0; i < count && result; i++)
+ {
+ linked = G_ARCH_INSTRUCTION(g_object_storage_unpack_object(storage, "instructions", pbuf));
+ if (linked == NULL)
+ {
+ result = false;
+ break;
+ }
-char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
-{
- char *result; /* Description à retourner */
- GArchInstructionClass *class; /* Classe des instructions */
+ result = unpack_uleb128(&type, pbuf);
+ if (!result)
+ {
+ g_object_unref(G_OBJECT(linked));
+ break;
+ }
- class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+ g_arch_instruction_link_with(instr, linked, type);
+ g_object_unref(G_OBJECT(linked));
- if (class->build_tooltip != NULL)
- result = class->build_tooltip(instr);
+ }
- else
- result = NULL;
+ g_arch_instruction_unlock_dest(instr);
return result;
@@ -1618,41 +1664,11 @@ char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* *
-* Description : Fournit une description pour l'instruction manipulée. *
-* *
-* Retour : Chaîne de caractères avec balises éventuelles. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const char *g_arch_instruction_get_description(const GArchInstruction *instr)
-{
- const char *result; /* Description à retourner */
-
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_desc(instr);
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
+* Paramètres : instr = instruction dont les informations sont à consulter.*
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Charge une instruction depuis une mémoire tampon. *
+* Description : Sauvegarde toutes les destinations d'une instruction. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -1660,148 +1676,87 @@ const char *g_arch_instruction_get_description(const GArchInstruction *instr)
* *
******************************************************************************/
-static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+bool g_arch_instruction_store_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
- packed_buffer_t op_pbuf; /* Tampon des données à écrire */
size_t count; /* Nombre d'éléments à traiter */
+ size_t kept; /* Nombre de liens conservés */
size_t i; /* Boucle de parcours */
- off64_t pos; /* Position dans le flux */
- GArchOperand *op; /* Opérande à traiter */
- instr_link_t link; /* Lien vers une instruction */
- packed_buffer_t ins_pbuf; /* Tampon des données à écrire */
- instr_obj_extra *extra; /* Données insérées à consulter*/
-
- result = unpack_mrange(&instr->range, pbuf);
-
- if (result)
- {
- init_packed_buffer(&op_pbuf);
-
- result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
-
- for (i = 0; i < count && result; i++)
- {
- result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
-
- if (result)
- result = g_asm_storage_load_operand_data(storage, &op_pbuf, pos);
-
- if (result)
- {
- op = g_arch_operand_load(storage, format, &op_pbuf);
- result = (op != NULL);
- }
+ const instr_link_t *link; /* Lien vers une instruction */
- if (result)
- g_arch_instruction_attach_extra_operand(instr, op);
+ g_arch_instruction_lock_dest(instr);
- }
+ count = g_arch_instruction_count_destinations(instr);
- exit_packed_buffer(&op_pbuf);
+ /**
+ * Le type de lien ILT_REF n'est mis en place que lors de la création
+ * d'opérandes de type G_TYPE_TARGET_OPERAND, et sera donc remis en place
+ * dynamiquement lors de la restauration de ces derniers.
+ */
- }
+ kept = 0;
- bool unserialize_link(instr_link_t *lk)
+ for (i = 0; i < count; i++)
{
- bool status; /* Bilan d'une conservation */
- phys_t lk_phys; /* Position physique courante */
-
- status = extract_packed_buffer(pbuf, &lk_phys, sizeof(phys_t), true);
-
- if (status)
- {
- lk->linked = g_asm_storage_get_instruction_at(storage, format, lk_phys, &ins_pbuf);
- status = (lk->linked != NULL);
- }
-
- if (status)
- {
- status = extract_packed_buffer(pbuf, &lk->type, sizeof(InstructionLinkType), true);
+ link = g_arch_instruction_get_destination(instr, i);
- if (!status)
- g_object_unref(G_OBJECT(lk->linked));
+ if (link->type != ILT_REF)
+ kept++;
- }
-
- return status;
+ unref_instr_link(link);
}
- if (result)
- {
- init_packed_buffer(&ins_pbuf);
+ result = pack_uleb128((uleb128_t []){ kept }, pbuf);
- result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
+ for (i = 0; i < count && result; i++)
+ {
+ link = g_arch_instruction_get_destination(instr, i);
- for (i = 0; i < count && result; i++)
+ if (link->type != ILT_REF)
{
- result = unserialize_link(&link);
+ result = g_object_storage_pack_object(storage, "instructions",
+ G_SERIALIZABLE_OBJECT(link->linked), pbuf);
if (result)
- {
- g_arch_instruction_link_with(instr, link.linked, link.type);
- g_object_unref(G_OBJECT(link.linked));
- }
+ result = pack_uleb128((uleb128_t []){ link->type }, pbuf);
}
- exit_packed_buffer(&ins_pbuf);
+ unref_instr_link(link);
}
- if (result)
- {
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+ g_arch_instruction_unlock_dest(instr);
- if (result)
- result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+ return result;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+}
- }
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* CONVERSIONS DU FORMAT DES INSTRUCTIONS */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Charge une instruction depuis une mémoire tampon. *
+* Description : Fournit le nom humain de l'instruction manipulée. *
* *
-* Retour : Instruction d'assemblage constitué ou NULL en cas d'échec. *
+* Retour : Mot clef de bas niveau. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+const char *g_arch_instruction_get_keyword(GArchInstruction *instr)
{
- GArchInstruction *result; /* Instance à retourner */
- bool status; /* Bilan du chargement */
-
- result = G_ARCH_INSTRUCTION(g_asm_storage_create_object(storage, pbuf));
-
- if (result != NULL)
- {
- status = G_ARCH_INSTRUCTION_GET_CLASS(result)->unserialize(result, storage, format, pbuf);
-
- if (!status)
- {
- g_object_unref(G_OBJECT(result));
- result = NULL;
- }
+ const char *result; /* Désignation à retourner */
- }
+ result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr);
return result;
@@ -1810,142 +1765,28 @@ GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *form
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
+* Description : Construit un petit résumé concis de l'instruction. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Chaîne de caractères à libérer après usage ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
+char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
- packed_buffer_t op_pbuf; /* Tampon des données à écrire */
- size_t count; /* Nombre d'éléments à traiter */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à traiter */
- off64_t pos; /* Position dans le flux */
- size_t kept; /* Nombre de liens conservés */
- const instr_link_t *link; /* Lien vers une instruction */
- instr_obj_extra *extra; /* Données insérées à consulter*/
-
- result = pack_mrange(&instr->range, pbuf);
-
- if (result)
- {
- init_packed_buffer(&op_pbuf);
-
- g_arch_instruction_lock_operands(instr);
-
- count = _g_arch_instruction_count_operands(instr);
-
- result = extend_packed_buffer(pbuf, &count, sizeof(size_t), true);
-
- for (i = 0; i < count && result; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
-
- result = g_arch_operand_store(op, storage, &op_pbuf);
-
- if (result)
- result = g_asm_storage_store_operand_data(storage, &op_pbuf, &pos);
-
- if (result)
- result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
-
- g_object_unref(G_OBJECT(op));
-
- }
-
- g_arch_instruction_unlock_operands(instr);
-
- exit_packed_buffer(&op_pbuf);
-
- }
-
- bool serialize_link(const instr_link_t *lk)
- {
- bool status; /* Bilan d'une conservation */
- const mrange_t *range; /* Emplacement d'une instruct° */
- phys_t lk_phys; /* Position physique courante */
-
- if (lk->type == ILT_REF)
- status = true;
-
- else
- {
- range = g_arch_instruction_get_range(lk->linked);
-
- lk_phys = get_phy_addr(get_mrange_addr(range));
-
- status = extend_packed_buffer(pbuf, &lk_phys, sizeof(phys_t), true);
-
- if (status)
- status = extend_packed_buffer(pbuf, &lk->type, sizeof(InstructionLinkType), true);
-
- }
-
- return status;
-
- }
-
- if (result)
- {
- g_arch_instruction_lock_dest(instr);
-
- count = g_arch_instruction_count_destinations(instr);
-
- /**
- * Le type de lien ILT_REF n'est mis en place que lors de la création
- * d'opérandes de type G_TYPE_TARGET_OPERAND, et sera donc remis en place
- * dynamiquement lors de la restauration de ces derniers.
- */
-
- kept = 0;
-
- for (i = 0; i < count && result; i++)
- {
- link = g_arch_instruction_get_destination(instr, i);
-
- if (link->type != ILT_REF)
- kept++;
-
- unref_instr_link(link);
-
- }
-
- result = extend_packed_buffer(pbuf, &kept, sizeof(size_t), true);
-
- for (i = 0; i < count && result; i++)
- {
- link = g_arch_instruction_get_destination(instr, i);
- result = serialize_link(link);
- unref_instr_link(link);
- }
-
- g_arch_instruction_unlock_dest(instr);
-
- }
-
- if (result)
- {
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+ char *result; /* Description à retourner */
+ GArchInstructionClass *class; /* Classe des instructions */
- if (result)
- result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ if (class->build_tooltip != NULL)
+ result = class->build_tooltip(instr);
- }
+ else
+ result = NULL;
return result;
@@ -1954,29 +1795,24 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
+* Description : Fournit une description pour l'instruction manipulée. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Chaîne de caractères avec balises éventuelles. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_store(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
+const char *g_arch_instruction_get_description(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
-
- result = g_asm_storage_store_object_gtype(storage, G_OBJECT(instr), pbuf);
+ const char *result; /* Description à retourner */
- if (result)
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->serialize(instr, storage, pbuf);
+ result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_desc(instr);
return result;
-
+
}
@@ -2005,6 +1841,9 @@ static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
}
+#ifdef INCLUDE_GTK_SUPPORT
+
+
/******************************************************************************
* *
* Paramètres : instr = générateur à consulter. *
@@ -2061,6 +1900,9 @@ static int g_arch_instruction_contain_cursor(const GArchInstruction *instr, size
}
+#endif
+
+
/******************************************************************************
* *
* Paramètres : instr = générateur à consulter. *
@@ -2172,3 +2014,201 @@ static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line,
G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat, content);
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool _g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
+ uleb128_t value; /* Valeur ULEB128 à charger */
+ uleb128_t count; /* Nombre d'éléments à traiter */
+ uleb128_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à traiter */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->uid = value;
+
+ if (result)
+ {
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->flags = value;
+
+ }
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ if (result)
+ result = unpack_mrange(&instr->range, pbuf);
+
+ if (result)
+ {
+ result = unpack_uleb128(&count, pbuf);
+
+ for (i = 0; i < count && result; i++)
+ {
+ op = G_ARCH_OPERAND(g_object_storage_unpack_object(storage, "operands", pbuf));
+ result = (op != NULL);
+
+ if (result)
+ g_arch_instruction_attach_extra_operand(instr, op);
+
+ }
+
+ }
+
+ if (result)
+ result = g_arch_instruction_load_destinations(instr, storage, pbuf);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchInstructionClass *class; /* Classe à activer */
+
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+
+ result = class->load(instr, storage, pbuf);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool _g_arch_instruction_store(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
+ size_t count; /* Nombre d'éléments à traiter */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à traiter */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = pack_uleb128((uleb128_t []){ extra->uid }, pbuf);
+
+ if (result)
+ result = pack_uleb128((uleb128_t []){ extra->flags }, pbuf);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ if (result)
+ result = pack_mrange(&instr->range, pbuf);
+
+ if (result)
+ {
+ g_arch_instruction_lock_operands(instr);
+
+ count = _g_arch_instruction_count_operands(instr);
+
+ result = pack_uleb128((uleb128_t []){ count }, pbuf);
+
+ for (i = 0; i < count && result; i++)
+ {
+ op = _g_arch_instruction_get_operand(instr, i);
+
+ result = g_object_storage_pack_object(storage, "operands", G_SERIALIZABLE_OBJECT(op), pbuf);
+
+ g_object_unref(G_OBJECT(op));
+
+ }
+
+ g_arch_instruction_unlock_operands(instr);
+
+ }
+
+ if (result)
+ result = g_arch_instruction_store_destinations(instr, storage, pbuf);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_instruction_store(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchInstructionClass *class; /* Classe à activer */
+
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+
+ result = class->store(instr, storage, pbuf);
+
+ return result;
+
+}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 80c500b..3c9c149 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -38,12 +38,12 @@
-#define G_TYPE_ARCH_INSTRUCTION g_arch_instruction_get_type()
-#define G_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction))
-#define G_IS_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type()))
-#define G_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
-#define G_IS_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION))
-#define G_ARCH_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
+#define G_TYPE_ARCH_INSTRUCTION g_arch_instruction_get_type()
+#define G_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction))
+#define G_IS_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type()))
+#define G_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
+#define G_IS_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION))
+#define G_ARCH_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
/* Définition générique d'une instruction d'architecture (instance) */
@@ -66,7 +66,7 @@ typedef enum _ArchInstrFlag
AIF_CALL = (1 << 3), /* Instruction d'appel */
AIF_LOW_USER = (1 << AIF_USER_BIT), /* Premier bit disponible */
- AIF_HIGH_USER = (1 << 14), /* Dernier bit disponible */
+ AIF_HIGH_USER = (1 << 7), /* Dernier bit disponible */
} ArchInstrFlag;
@@ -310,19 +310,4 @@ const char *g_arch_instruction_get_description(const GArchInstruction *);
-/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */
-
-
-/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */
-typedef struct _GAsmStorage GAsmStorage;
-
-
-/* Charge une instruction depuis une mémoire tampon. */
-GArchInstruction *g_arch_instruction_load(GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde une instruction dans une mémoire tampon. */
-bool g_arch_instruction_store(GArchInstruction *, GAsmStorage *, packed_buffer_t *);
-
-
-
#endif /* _ARCH_INSTRUCTION_H */
diff --git a/src/arch/instructions/Makefile.am b/src/arch/instructions/Makefile.am
index 24d3eb5..28cf90f 100644
--- a/src/arch/instructions/Makefile.am
+++ b/src/arch/instructions/Makefile.am
@@ -1,24 +1,14 @@
noinst_LTLIBRARIES = libarchinstructions.la
-libarchinstructions_la_SOURCES = \
- raw.h raw.c \
- undefined-int.h \
+libarchinstructions_la_SOURCES = \
+ raw.h raw.c \
+ undefined-int.h \
undefined.h undefined.c
-libarchinstructions_la_LIBADD =
-
-libarchinstructions_la_LDFLAGS =
+libarchinstructions_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libarchinstructions_la_SOURCES:%c=)
-
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
-
-SUBDIRS =
diff --git a/src/arch/instructions/raw.c b/src/arch/instructions/raw.c
index 481dd1c..26282fa 100644
--- a/src/arch/instructions/raw.c
+++ b/src/arch/instructions/raw.c
@@ -35,7 +35,7 @@
#include "../instruction-int.h"
#include "../operands/immediate.h"
#include "../operands/target.h"
-#include "../../gtkext/gtkblockdisplay.h"
+#include "../../core/columns.h"
@@ -213,17 +213,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)
GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value)
{
GArchInstruction *result; /* Instruction à retourner */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
- operand = G_IMM_OPERAND(g_imm_operand_new_from_value(size, value));
- if (operand == NULL) goto grinfv_error;
+ operand = g_imm_operand_new_from_value(size, value);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
switch (size)
{
@@ -249,7 +249,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat
default:
assert(false);
- goto grinfv_error;
+ goto error;
break;
}
@@ -258,7 +258,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat
return result;
- grinfv_error:
+ error:
g_object_unref(G_OBJECT(result));
@@ -287,13 +287,15 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa
uleb128_t value; /* Valeur uleb128 à représenter*/
phys_t diff; /* Couverture de la lecture */
MemoryDataSize leb_size; /* Taille de la valeur */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
+ result = NULL;
+
copy_vmpa(&start, addr);
if (!g_binary_content_read_uleb128(content, addr, &value))
- goto grinu_error;
+ goto error;
diff = compute_vmpa_diff(&start, addr);
@@ -305,16 +307,18 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa
init_mrange(&range, &start, diff);
g_arch_instruction_set_range(result, &range);
- operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value));
- if (operand == NULL) goto grinu_error;
+ operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
return result;
- grinu_error:
+ error:
+
+ g_clear_object(&result);
return NULL;
@@ -341,13 +345,15 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa
uleb128_t value; /* Valeur uleb128 à représenter*/
phys_t diff; /* Couverture de la lecture */
MemoryDataSize leb_size; /* Taille de la valeur */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
+ result = NULL;
+
copy_vmpa(&start, addr);
if (!g_binary_content_read_uleb128(content, addr, &value))
- goto grins_error;
+ goto error;
diff = compute_vmpa_diff(&start, addr);
@@ -359,16 +365,18 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa
init_mrange(&range, &start, diff);
g_arch_instruction_set_range(result, &range);
- operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value));
- if (operand == NULL) goto grins_error;
+ operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
return result;
- grins_error:
+ error:
+
+ g_clear_object(&result);
return NULL;
@@ -396,7 +404,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
GArchInstruction *result; /* Instruction à retourner */
vmpa2t old; /* Sauvegarde de la position */
size_t i; /* Boucle de parcours */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
/* Par soucis de cohérence */
@@ -408,12 +416,12 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
for (i = 0; i < count; i++)
{
- operand = G_IMM_OPERAND(g_imm_operand_new_from_data(size, content, addr, endian));
- if (operand == NULL) goto grina_error;
+ operand = g_imm_operand_new_from_data(size, content, addr, endian);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
}
@@ -423,7 +431,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
return result;
- grina_error:
+ error:
g_object_unref(G_OBJECT(result));
diff --git a/src/arch/instructions/undefined-int.h b/src/arch/instructions/undefined-int.h
index 8a648cf..a9b7627 100644
--- a/src/arch/instructions/undefined-int.h
+++ b/src/arch/instructions/undefined-int.h
@@ -32,63 +32,57 @@
/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _undef_obj_extra
+typedef struct _undef_extra_data_t
{
- struct
- {
- InstrExpectedBehavior behavior; /* Conséquences réelles */
+ /**
+ * Le champ uid de la structure parente attendue conduit à une taille
+ * alignée sur 2 octets, donc à une taille totale de 4 octets ce qui
+ * représente la limite maximale de taille supportée.
+ *
+ * Pour 3 octets à la base, qui devraient laisser 8 - 1 octets disponbibles
+ * en incluant le bit de verrouillage.
+ *
+ * On reproduit donc la structure instr_extra_data_t ici, en basculant
+ * l'énumération InstrExpectedBehavior en champ de bits.
+ */
- };
+ itid_t uid; /* Identifiant unique du type */
+ ArchInstrFlag flags; /* Informations complémentaires*/
- gint lock; /* Gestion d'accès aux fanions */
+ unsigned int behavior : 2; /* Conséquences réelles */
+
+} undef_extra_data_t;
-} undef_obj_extra;
/* Définition générique d'une instruction au comportement non défini (instance) */
struct _GUndefInstruction
{
GArchInstruction parent; /* A laisser en premier */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- undef_obj_extra extra; /* Externalisation embarquée */
+};
-#endif
+/* Définition générique d'une instruction au comportement non défini (classe) */
+struct _GUndefInstructionClass
+{
+ GArchInstructionClass parent; /* A laisser en premier */
};
+
/**
* Accès aux informations éventuellement déportées.
*/
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
-# define INIT_UNDEF_INSTR_EXTRA(ins) ins->extra.lock = 0
-
-# define GET_UNDEF_INSTR_EXTRA(ins) &ins->extra
+# define GET_UNDEF_INSTR_EXTRA(ins) ((undef_extra_data_t *)&((GArchInstruction *)ins)->extra)
#else
-# define INIT_UNDEF_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins))
-
-# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_obj_extra)
+# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_extra_data_t)
#endif
-/* Définition générique d'une instruction au comportement non défini (classe) */
-struct _GUndefInstructionClass
-{
- GArchInstructionClass parent; /* A laisser en premier */
-
-};
-
#endif /* _ARCH_INSTRUCTIONS_UNDEFINED_INT_H */
diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c
index 880e338..15c63e7 100644
--- a/src/arch/instructions/undefined.c
+++ b/src/arch/instructions/undefined.c
@@ -31,7 +31,7 @@
#include "undefined-int.h"
-#include "../../gtkext/gtkblockdisplay.h"
+#include "../../core/columns.h"
@@ -74,6 +74,17 @@ static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_undef_instruction_load(GUndefInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_undef_instruction_store(GUndefInstruction *, GObjectStorage *, packed_buffer_t *);
+
+
+
/* ---------------------------------------------------------------------------------- */
/* INSTRUCTION INCONNUE / DONNEES */
/* ---------------------------------------------------------------------------------- */
@@ -115,6 +126,9 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)
instr->print = (print_instruction_fc)g_undef_instruction_print;
+ instr->load = (load_instruction_fc)g_undef_instruction_load;
+ instr->store = (store_instruction_fc)g_undef_instruction_store;
+
}
@@ -132,7 +146,7 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)
static void g_undef_instruction_init(GUndefInstruction *instr)
{
- INIT_ARCH_INSTR_EXTRA(instr);
+ GET_UNDEF_INSTR_EXTRA(instr)->behavior = IEB_UNDEFINED;
}
@@ -190,7 +204,7 @@ static void g_undef_instruction_finalize(GUndefInstruction *instr)
GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior)
{
GArchInstruction *result; /* Instruction à retourner */
- undef_obj_extra *extra; /* Données insérées à modifier */
+ undef_extra_data_t *extra; /* Données insérées à modifier */
result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL);
@@ -241,7 +255,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *ins
const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr)
{
const char *result; /* Désignation à retourner */
- undef_obj_extra *extra; /* Données insérées à consulter*/
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_UNDEF_INSTR_EXTRA(instr);
@@ -300,7 +314,8 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag
{
bool result; /* Bilan à retourner */
GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_obj_extra *extra; /* Données insérées à modifier */
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
+ uint8_t val; /* Champ de bits manipulé */
parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
@@ -310,7 +325,12 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag
{
extra = GET_UNDEF_INSTR_EXTRA(instr);
- result = extract_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true);
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
+ extra->behavior = val;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -337,7 +357,7 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage
{
bool result; /* Bilan à retourner */
GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_obj_extra *extra; /* Données insérées à consulter*/
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
@@ -347,7 +367,11 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage
{
extra = GET_UNDEF_INSTR_EXTRA(instr);
- result = extend_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true);
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -417,12 +441,106 @@ static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *lin
InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *instr)
{
InstrExpectedBehavior result; /* Comportement à retourner */
- undef_obj_extra *extra; /* Données insérées à consulter*/
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_UNDEF_INSTR_EXTRA(instr);
+ LOCK_GOBJECT_EXTRA(extra);
+
result = extra->behavior;
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_undef_instruction_load(GUndefInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchInstructionClass *parent; /* Classe parente à consulter */
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
+ uint8_t val; /* Champ de bits manipulé */
+
+ parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
+
+ result = parent->load(G_ARCH_INSTRUCTION(instr), storage, pbuf);
+
+ if (result)
+ {
+ extra = GET_UNDEF_INSTR_EXTRA(instr);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
+ extra->behavior = val;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_undef_instruction_store(GUndefInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchInstructionClass *parent; /* Classe parente à consulter */
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
+
+ parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
+
+ result = parent->store(G_ARCH_INSTRUCTION(instr), storage, pbuf);
+
+ if (result)
+ {
+ extra = GET_UNDEF_INSTR_EXTRA(instr);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ }
+
return result;
}
diff --git a/src/arch/meta.c b/src/arch/meta.c
deleted file mode 100644
index 137a043..0000000
--- a/src/arch/meta.c
+++ /dev/null
@@ -1,428 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * artificial.c - instructions pures vues de l'esprit
- *
- * Copyright (C) 2018 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "meta.h"
-
-
-#include <malloc.h>
-
-
-#include "instruction-int.h"
-
-
-
-/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
-
-
-/* Définition d'une instruction de rassemblement (instance) */
-struct _GMetaInstruction
-{
- GArchInstruction parent; /* A laisser en premier */
-
- GArchInstruction *fake; /* Instruction simulée */
-
- GArchInstruction **children; /* Instructions représentées */
- size_t count; /* Taille de cette liste */
-
-};
-
-/* Définition d'une instruction de rassemblement (classe) */
-struct _GMetaInstructionClass
-{
- GArchInstructionClass parent; /* A laisser en premier */
-
-};
-
-
-/* Initialise la classe des instructions de rassemblement. */
-static void g_meta_instruction_class_init(GMetaInstructionClass *);
-
-/* Initialise une instance d'instruction de rassemblement. */
-static void g_meta_instruction_init(GMetaInstruction *);
-
-/* Supprime toutes les références externes. */
-static void g_meta_instruction_dispose(GMetaInstruction *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_meta_instruction_finalize(GMetaInstruction *);
-
-/* Indique l'encodage d'une instruction de façon détaillée. */
-static const char *g_meta_instruction_get_encoding(const GMetaInstruction *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static const char *g_meta_instruction_get_keyword(const GMetaInstruction *);
-
-
-
-/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */
-
-
-/* Charge une instruction depuis une mémoire tampon. */
-static bool g_meta_instruction_unserialize(GMetaInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde une instruction dans une mémoire tampon. */
-static bool g_meta_instruction_serialize(GMetaInstruction *, GAsmStorage *, packed_buffer_t *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* INSTRUCTION INCONNUE / DONNEES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour une instruction inconnue d'architecture. */
-G_DEFINE_TYPE(GMetaInstruction, g_meta_instruction, G_TYPE_ARCH_INSTRUCTION);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des instructions de rassemblement. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_meta_instruction_class_init(GMetaInstructionClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GArchInstructionClass *instr; /* Encore une autre vision... */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_meta_instruction_dispose;
- object->finalize = (GObjectFinalizeFunc)g_meta_instruction_finalize;
-
- instr = G_ARCH_INSTRUCTION_CLASS(klass);
-
- instr->get_encoding = (get_instruction_encoding_fc)g_meta_instruction_get_encoding;
- instr->get_keyword = (get_instruction_keyword_fc)g_meta_instruction_get_keyword;
-
- instr->unserialize = (unserialize_instruction_fc)g_meta_instruction_unserialize;
- instr->serialize = (serialize_instruction_fc)g_meta_instruction_serialize;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instance à initialiser. *
-* *
-* Description : Initialise une instance d'instruction de rassemblement. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_meta_instruction_init(GMetaInstruction *instr)
-{
- GArchInstruction *parent; /* Version parente */
- vmpa2t invalid; /* Absence de position */
-
- parent = G_ARCH_INSTRUCTION(instr);
-
- init_vmpa(&invalid, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
- init_mrange(&parent->range, &invalid, 0);
-
- instr->fake = NULL;
-
- instr->children = NULL;
- instr->count = 0;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_meta_instruction_dispose(GMetaInstruction *instr)
-{
- size_t i; /* Boucle de parcours */
-
- if (instr->fake != NULL)
- g_object_unref(G_OBJECT(instr->fake));
-
- for (i = 0; i < instr->count; i++)
- g_object_unref(G_OBJECT(instr->children[i]));
-
- G_OBJECT_CLASS(g_meta_instruction_parent_class)->dispose(G_OBJECT(instr));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_meta_instruction_finalize(GMetaInstruction *instr)
-{
- if (instr->children != NULL)
- free(instr->children);
-
- G_OBJECT_CLASS(g_meta_instruction_parent_class)->finalize(G_OBJECT(instr));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : fake = instruction à simuler. *
-* *
-* Description : Crée une instruction rassemblant d'autres instructions. *
-* *
-* Retour : Instruction mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchInstruction *g_meta_instruction_new(GArchInstruction *fake)
-{
- GMetaInstruction *result; /* Instruction à retourner */
-
- result = g_object_new(G_TYPE_META_INSTRUCTION, NULL);
-
- result->fake = fake;
-
- return G_ARCH_INSTRUCTION(result);
-
-}
-
-
-/******************************************************************************
-* *
-* 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 const char *g_meta_instruction_get_encoding(const GMetaInstruction *instr)
-{
- const char *result; /* Description à retourner */
-
- result = g_arch_instruction_get_encoding(instr->fake);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
-* *
-* Retour : Mot clef de bas niveau. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static const char *g_meta_instruction_get_keyword(const GMetaInstruction *instr)
-{
- const char *result; /* Désignation à renvoyer */
-
- result = g_arch_instruction_get_keyword(instr->fake);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à compléter. *
-* child = instruction à intégrer au rassemblement. *
-* last = marque l'instruction comme étant la dernière du lot. *
-* *
-* Description : Intègre une nouvelle instruction dans un rassemblement. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_meta_instruction_add_child(GMetaInstruction *instr, GArchInstruction *child, bool last)
-{
- GArchInstruction *parent; /* Autre version de l'instruct°*/
- const mrange_t *base; /* Base d'une couverture */
- vmpa2t start; /* Position de départ */
- vmpa2t end; /* Position d'arrivée */
- mrange_t range; /* Couverture nouvelle */
- instr_link_t *links; /* Liens présents à copier */
- size_t count; /* Quantité de ces liens */
- size_t i; /* Boucle de parcours */
-
- instr->children = (GArchInstruction **)realloc(instr->children,
- ++instr->count * sizeof(GArchInstruction *));
-
- instr->children[instr->count - 1] = child;
-
- parent = G_ARCH_INSTRUCTION(instr);
-
- /* Mise à jour de la couverture totale */
-
- if (last)
- {
- if (instr->count == 1)
- g_arch_instruction_set_range(parent, g_arch_instruction_get_range(child));
-
- else
- {
- base = g_arch_instruction_get_range(instr->children[0]);
- copy_vmpa(&start, get_mrange_addr(base));
-
- base = g_arch_instruction_get_range(child);
- compute_mrange_end_addr(base, &end);
-
- init_mrange(&range, &start, compute_vmpa_diff(&start, &end));
-
- g_arch_instruction_set_range(parent, &range);
-
- }
-
- }
-
- /* Appropriation des liens contenus */
-
- links = g_arch_instruction_get_sources(child, &count);
-
- for (i = 0; i < count; i++)
- {
- if (instr->count == 1 || links[i].type == ILT_REF)
- g_arch_instruction_link_with(links[i].linked, parent, links[i].type);
-
- unref_instr_link((&links[i]));
-
- }
-
- if (links != NULL)
- free(links);
-
- links = g_arch_instruction_get_destinations(child, &count);
-
- for (i = 0; i < count; i++)
- {
- if (last || links[i].type == ILT_REF)
- g_arch_instruction_link_with(parent, links[i].linked, links[i].type);
-
- unref_instr_link((&links[i]));
-
- }
-
- if (links != NULL)
- free(links);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Charge une instruction depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_meta_instruction_unserialize(GMetaInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_meta_instruction_parent_class);
-
- result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_meta_instruction_serialize(GMetaInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_meta_instruction_parent_class);
-
- result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf);
-
- return result;
-
-}
diff --git a/src/arch/meta.h b/src/arch/meta.h
deleted file mode 100644
index 6c62654..0000000
--- a/src/arch/meta.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * meta.h - prototypes pour les instructions qui en rassemblent d'autres
- *
- * Copyright (C) 2018 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ARCH_META_H
-#define _ARCH_META_H
-
-
-#include <glib-object.h>
-#include <stdbool.h>
-
-
-#include "instruction.h"
-
-
-
-/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
-
-
-#define G_TYPE_META_INSTRUCTION g_meta_instruction_get_type()
-#define G_META_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_META_INSTRUCTION, GMetaInstruction))
-#define G_IS_META_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_META_INSTRUCTION))
-#define G_META_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_META_INSTRUCTION, GMetaInstructionClass))
-#define G_IS_META_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_META_INSTRUCTION))
-#define G_META_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_META_INSTRUCTION, GMetaInstructionClass))
-
-
-/* Définition d'une instruction de rassemblement (instance) */
-typedef struct _GMetaInstruction GMetaInstruction;
-
-/* Définition d'une instruction de rassemblement (classe) */
-typedef struct _GMetaInstructionClass GMetaInstructionClass;
-
-
-/* Indique le type défini pour une instruction inconnue d'architecture. */
-GType g_meta_instruction_get_type(void);
-
-/* Crée une instruction rassemblant d'autres instructions. */
-GArchInstruction *g_meta_instruction_new(GArchInstruction *);
-
-/* Intègre une nouvelle instruction dans un rassemblement. */
-void g_meta_instruction_add_child(GMetaInstruction *, GArchInstruction *, bool);
-
-
-
-#endif /* _ARCH_META_H */
diff --git a/src/arch/operand-int.c b/src/arch/operand-int.c
new file mode 100644
index 0000000..51e8d44
--- /dev/null
+++ b/src/arch/operand-int.c
@@ -0,0 +1,308 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand-int.c - définition générique interne des opérandes
+ *
+ * Copyright (C) 2021 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "operand-int.h"
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* count = quantité d'opérandes à extraire du tampon. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_arch_operand_load_inner_instances(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf, size_t count)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperand **instances; /* Liste d'opérandes à charger */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ instances = calloc(count, sizeof(GArchOperand *));
+
+ for (i = 0; i < count && result; i++)
+ result = g_object_storage_unpack_object_2(storage, "operands", pbuf, G_TYPE_ARCH_OPERAND, &instances[i]);
+
+ if (result)
+ g_arch_operand_update_inner_instances(operand, instances, count);
+
+ for (i = 0; i < count; i++)
+ g_clear_object(&instances[i]);
+
+ free(instances);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_load_generic_fixed_1(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, 1);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_load_generic_fixed_3(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, 3);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_load_generic_variadic(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, value);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* fixed = précise si le nombre d'opérande est fixe ou non. *
+* *
+* Description : Sauvegarde une série d'opérandes internes dans un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_arch_operand_store_inner_instances(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf, bool fixed)
+{
+ bool result; /* Bilan à retourner */
+ size_t count; /* Nombre d'opérandes listées */
+ GArchOperand **instances; /* Liste d'opérandes à traiter */
+ size_t i; /* Boucle de parcours */
+ GSerializableObject *obj; /* Objet à conserver */
+
+ result = true;
+
+ instances = g_arch_operand_list_inner_instances(operand, &count);
+
+ if (!fixed)
+ result = pack_uleb128((uleb128_t []){ count }, pbuf);
+
+ if (instances != NULL)
+ {
+ for (i = 0; i < count && result; i++)
+ {
+ if (instances[i] == NULL)
+ result = g_object_storage_pack_object(storage, "operands", NULL, pbuf);
+
+ else
+ {
+ obj = G_SERIALIZABLE_OBJECT(instances[i]);
+
+ result = g_object_storage_pack_object(storage, "operands", obj, pbuf);
+
+ g_object_unref(G_OBJECT(instances[i]));
+
+ }
+
+ }
+
+ for (; i < count && result; i++)
+ g_clear_object(&instances[i]);
+
+ free(instances);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* fixed = précise si le nombre d'opérande est fixe ou non. *
+* *
+* Description : Sauvegarde un opérande dans un tampon de façon générique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_store_generic_fixed(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_store_inner_instances(operand, storage, pbuf, true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* fixed = précise si le nombre d'opérande est fixe ou non. *
+* *
+* Description : Sauvegarde un opérande dans un tampon de façon générique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_store_generic_variadic(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_store_inner_instances(operand, storage, pbuf, false);
+
+ return result;
+
+}
diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h
index a50ec73..e6c1232 100644
--- a/src/arch/operand-int.h
+++ b/src/arch/operand-int.h
@@ -28,9 +28,16 @@
#include "operand.h"
+#include <stdbool.h>
+
+
+#include "../analysis/storage/storage.h"
+#include "../glibext/objhole.h"
+
+
/* Compare un opérande avec un autre. */
-typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *);
+typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *, bool);
/* Détermine le chemin conduisant à un opérande interne. */
typedef char * (* find_inner_operand_fc) (const GArchOperand *, const GArchOperand *);
@@ -41,14 +48,43 @@ typedef GArchOperand * (* get_inner_operand_fc) (const GArchOperand *, const cha
/* Traduit un opérande en version humainement lisible. */
typedef void (* operand_print_fc) (const GArchOperand *, GBufferLine *);
+#ifdef INCLUDE_GTK_SUPPORT
+
/* Construit un petit résumé concis de l'opérande. */
typedef char * (* operand_build_tooltip_fc) (const GArchOperand *, const GLoadedBinary *);
-/* Charge un opérande depuis une mémoire tampon. */
-typedef bool (* unserialize_operand_fc) (GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+#endif
+
+/* Fournit une liste de candidats embarqués par un candidat. */
+typedef GArchOperand ** (* operand_list_inners_fc) (const GArchOperand *, size_t *);
+
+/* Met à jour une liste de candidats embarqués par un candidat. */
+typedef void (* operand_update_inners_fc) (GArchOperand *, GArchOperand **, size_t);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-typedef bool (* serialize_operand_fc) (const GArchOperand *, GAsmStorage *, packed_buffer_t *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+typedef guint (* operand_hash_fc) (const GArchOperand *, bool);
+
+/* Charge un contenu depuis une mémoire tampon. */
+typedef bool (* load_operand_fc) (GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+typedef bool (* store_operand_fc) (GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _operand_extra_data_t
+{
+ ArchOperandFlag flags; /* Informations diverses */
+
+} operand_extra_data_t;
+
+/* Encapsulation avec un verrou d'accès */
+typedef union _operand_obj_extra_t
+{
+ operand_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
+
+} operand_obj_extra_t;
/* Définition générique d'un opérande d'architecture (instance) */
@@ -56,8 +92,20 @@ struct _GArchOperand
{
GObject parent; /* A laisser en premier */
-};
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+ /**
+ * L'inclusion des informations suivantes dépend de l'architecture.
+ *
+ * Si la structure GObject possède un trou, on remplit de préférence
+ * ce dernier.
+ */
+
+ operand_obj_extra_t extra; /* Externalisation embarquée */
+#endif
+
+};
/* Définition générique d'un opérande d'architecture (classe) */
struct _GArchOperandClass
@@ -69,13 +117,78 @@ struct _GArchOperandClass
get_inner_operand_fc get_inner; /* Récupération d'un opérande */
operand_print_fc print; /* Texte humain équivalent */
+#ifdef INCLUDE_GTK_SUPPORT
operand_build_tooltip_fc build_tooltip; /* Construction de description */
+#endif
+
+ operand_list_inners_fc list_inner; /* Récupération d'internes */
+ operand_update_inners_fc update_inner; /* Mise à jour des éléments */
+ operand_hash_fc hash; /* Prise d'empreinte */
- unserialize_operand_fc unserialize; /* Chargement depuis un tampon */
- serialize_operand_fc serialize; /* Conservation dans un tampon */
+ load_operand_fc load; /* Chargement depuis un tampon */
+ store_operand_fc store; /* Conservation dans un tampon */
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARCH_OP_EXTRA(op) (operand_extra_data_t *)&op->extra
+
+#else
+
+# define GET_ARCH_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), operand_extra_data_t)
+
+#endif
+
+
+/* Ajoute une information complémentaire à un opérande. */
+bool _g_arch_operand_set_flag(GArchOperand *, ArchOperandFlag, bool);
+
+/* Retire une information complémentaire à un opérande. */
+bool _g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag, bool);
+
+
+
+/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */
+
+
+/* Fournit une liste de candidats embarqués par un candidat. */
+GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *);
+
+/* Met à jour une liste de candidats embarqués par un candidat. */
+void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t);
+
+
+
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool _g_arch_operand_load_inner_instances(GArchOperand *, GObjectStorage *, packed_buffer_t *, size_t);
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool g_arch_operand_load_generic_fixed_1(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool g_arch_operand_load_generic_fixed_3(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool g_arch_operand_load_generic_variadic(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde une série d'opérandes internes dans un tampon. */
+bool _g_arch_operand_store_inner_instances(GArchOperand *, GObjectStorage *, packed_buffer_t *, bool);
+
+/* Sauvegarde un opérande dans un tampon de façon générique. */
+bool g_arch_operand_store_generic_fixed(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un opérande dans un tampon de façon générique. */
+bool g_arch_operand_store_generic_variadic(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+
#endif /* _ARCH_OPERAND_INT_H */
diff --git a/src/arch/operand.c b/src/arch/operand.c
index 3758d7f..0f5ffd5 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -31,14 +31,15 @@
#include "operand-int.h"
#include "storage.h"
+#include "../analysis/storage/serialize-int.h"
+#include "../common/fnv1a.h"
#include "../common/sort.h"
#include "../core/logs.h"
+#include "../glibext/singleton-int.h"
-/* ---------------------------------------------------------------------------------- */
-/* DEFINITION D'OPERANDE QUELCONQUE */
-/* ---------------------------------------------------------------------------------- */
+/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */
/* Initialise la classe générique des opérandes. */
@@ -47,29 +48,76 @@ static void g_arch_operand_class_init(GArchOperandClass *);
/* Initialise une instance d'opérande d'architecture. */
static void g_arch_operand_init(GArchOperand *);
+/* Procède à l'initialisation de l'interface de singleton. */
+static void g_arch_operand_singleton_init(GSingletonCandidateInterface *);
+
+/* Procède à l'initialisation de l'interface de sérialisation. */
+static void g_arch_operand_serializable_init(GSerializableObjectInterface *);
+
/* Supprime toutes les références externes. */
static void g_arch_operand_dispose(GArchOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_arch_operand_finalize(GArchOperand *);
+/* Compare un opérande avec un autre. */
+static int _g_arch_operand_compare(const GArchOperand *, const GArchOperand *, bool);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_arch_operand_unserialize(GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_arch_operand_serialize(const GArchOperand *, GAsmStorage *, packed_buffer_t *);
+/* Fournit une liste de candidats embarqués par un candidat. */
+GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *);
+/* Met à jour une liste de candidats embarqués par un candidat. */
+void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint _g_arch_operand_hash(const GArchOperand *, bool);
-/* Indique le type défini pour un opérande d'architecture. */
-G_DEFINE_TYPE(GArchOperand, g_arch_operand, G_TYPE_OBJECT);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_arch_operand_hash(const GArchOperand *);
+
+/* Détermine si deux candidats à l'unicité sont identiques. */
+static gboolean g_arch_operand_is_equal(const GArchOperand *, const GArchOperand *);
+
+/* Marque un candidat comme figé. */
+static void g_arch_operand_set_read_only(GArchOperand *);
+
+/* Indique si le candidat est figé. */
+static bool g_arch_operand_is_read_only(GArchOperand *);
+
+
+
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+/* Charge un contenu depuis une mémoire tampon. */
+static bool _g_arch_operand_load(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_operand_load(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool _g_arch_operand_store(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_arch_operand_store(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'OPERANDE QUELCONQUE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un opérande d'architecture. */
+G_DEFINE_TYPE_WITH_CODE(GArchOperand, g_arch_operand, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_SINGLETON_CANDIDATE, g_arch_operand_singleton_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_operand_serializable_init));
+
/******************************************************************************
* *
@@ -95,8 +143,12 @@ static void g_arch_operand_class_init(GArchOperandClass *klass)
operand = G_ARCH_OPERAND_CLASS(klass);
- operand->unserialize = (unserialize_operand_fc)g_arch_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_arch_operand_serialize;
+ operand->compare = (operand_compare_fc)_g_arch_operand_compare;
+
+ operand->hash = _g_arch_operand_hash;
+
+ operand->load = (load_operand_fc)_g_arch_operand_load;
+ operand->store = (store_operand_fc)_g_arch_operand_store;
}
@@ -115,6 +167,57 @@ static void g_arch_operand_class_init(GArchOperandClass *klass)
static void g_arch_operand_init(GArchOperand *operand)
{
+ operand_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ INIT_GOBJECT_EXTRA_LOCK(extra);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de singleton. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_operand_singleton_init(GSingletonCandidateInterface *iface)
+{
+ iface->list_inner = (list_inner_instances_fc)g_arch_operand_list_inner_instances;
+ iface->update_inner = (update_inner_instances_fc)g_arch_operand_update_inner_instances;
+
+ iface->hash = (hash_candidate_fc)g_arch_operand_hash;
+ iface->is_equal = (is_candidate_equal_fc)g_arch_operand_is_equal;
+
+ iface->set_ro = (set_candidate_ro_fc)g_arch_operand_set_read_only;
+ iface->is_ro = (is_candidate_ro_fc)g_arch_operand_is_read_only;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_operand_serializable_init(GSerializableObjectInterface *iface)
+{
+ iface->load = (load_serializable_object_cb)g_arch_operand_load;
+ iface->store = (store_serializable_object_cb)g_arch_operand_store;
}
@@ -159,6 +262,38 @@ static void g_arch_operand_finalize(GArchOperand *operand)
/******************************************************************************
* *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Compare un opérande avec un autre. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int _g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b, bool lock)
+{
+ int result; /* Bilan à faire remonter */
+ operand_extra_data_t *ea; /* Données insérées à consulter*/
+ operand_extra_data_t *eb; /* Données insérées à consulter*/
+
+ assert(!lock);
+
+ ea = GET_ARCH_OP_EXTRA(a);
+ eb = GET_ARCH_OP_EXTRA(b);
+
+ result = sort_unsigned_long(ea->flags, eb->flags);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : a = premier opérande à consulter. *
* b = second opérande à consulter. *
* *
@@ -184,7 +319,7 @@ int g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b)
result = sort_unsigned_long(type_a, type_b);
if (result == 0)
- result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b);
+ result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b, true);
return result;
@@ -273,6 +408,9 @@ void g_arch_operand_print(const GArchOperand *operand, GBufferLine *line)
}
+#ifdef INCLUDE_GTK_SUPPORT
+
+
/******************************************************************************
* *
* Paramètres : operand = opérande à consulter. *
@@ -303,20 +441,53 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin
}
+#endif
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à venir modifier. *
+* flag = drapeau d'information complémentaire à planter. *
+* lock = indique un besoin de verrouillage des données. *
+* *
+* Description : Ajoute une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_arch_operand_set_flag(GArchOperand *operand, ArchOperandFlag flag, bool lock)
+{
+ bool result; /* Bilan à retourner */
+ operand_extra_data_t *extra; /* Données insérées à modifier */
+
+ assert(flag <= AOF_HIGH_USER);
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = !(extra->flags & flag);
+
+ extra->flags |= flag;
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = opérande à venir modifier. *
+* flag = drapeau d'information complémentaire à planter. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Ajoute une information complémentaire à un opérande. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -324,11 +495,11 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin
* *
******************************************************************************/
-static bool g_arch_operand_unserialize(GArchOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+bool g_arch_operand_set_flag(GArchOperand *operand, ArchOperandFlag flag)
{
bool result; /* Bilan à retourner */
- result = true;
+ result = _g_arch_operand_set_flag(operand, flag, true);
return result;
@@ -337,37 +508,231 @@ static bool g_arch_operand_unserialize(GArchOperand *operand, GAsmStorage *stora
/******************************************************************************
* *
-* Paramètres : storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = opérande à venir modifier. *
+* flag = drapeau d'information complémentaire à planter. *
+* lock = indique un besoin de verrouillage des données. *
+* *
+* Description : Retire une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_arch_operand_unset_flag(GArchOperand *operand, ArchOperandFlag flag, bool lock)
+{
+ bool result; /* Bilan à retourner */
+ operand_extra_data_t *extra; /* Données insérées à modifier */
+
+ assert(flag <= AOF_HIGH_USER);
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = (extra->flags & flag);
+
+ extra->flags &= ~flag;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à venir modifier. *
+* flag = drapeau d'information complémentaire à planter. *
+* *
+* Description : Retire une information complémentaire à un opérande. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+******************************************************************************/
+
+bool g_arch_operand_unset_flag(GArchOperand *operand, ArchOperandFlag flag)
+{
+ bool result; /* Bilan à retourner */
+
+ result = _g_arch_operand_unset_flag(operand, flag, true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
* *
-* Retour : Opérande d'assemblage constitué ou NULL en cas d'échec. *
+* Paramètres : operand = opérande à venir consulter. *
+* flag = drapeau d'information à rechercher. *
+* *
+* Description : Détermine si un opérande possède un fanion particulier. *
+* *
+* Retour : Bilan de la détection. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+bool g_arch_operand_has_flag(const GArchOperand *operand, ArchOperandFlag flag)
{
- GArchOperand *result; /* Instance à retourner */
- bool status; /* Bilan du chargement */
+ bool result; /* Bilan à retourner */
+ operand_extra_data_t *extra; /* Données insérées à modifier */
+
+ assert(flag <= AOF_HIGH_USER);
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = (extra->flags & flag);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
- result = G_ARCH_OPERAND(g_asm_storage_create_object(storage, pbuf));
- if (result != NULL)
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à venir consulter. *
+* *
+* Description : Fournit les particularités de l'opérande. *
+* *
+* Retour : Somme de tous les fanions associés à l'opérande. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *operand)
+{
+ ArchOperandFlag result; /* Fanions à retourner */
+ operand_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extra->flags;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONTROLE DU VOLUME DES INSTANCES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
+* *
+* Retour : Liste de candidats internes ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *operand, size_t *count)
+{
+ GArchOperand **result; /* Instances à retourner */
+ GArchOperandClass *class; /* Classe associée à l'objet */
+
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
+
+ if (class->list_inner == NULL)
{
- status = G_ARCH_OPERAND_GET_CLASS(result)->unserialize(result, storage, format, pbuf);
+ *count = 0;
+ result = NULL;
+ }
+
+ else
+ result = class->list_inner(operand, count);
+
+ return result;
+
+}
- if (!status)
- {
- g_object_unref(G_OBJECT(result));
- result = NULL;
- }
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* instances = liste de candidats internes devenus singletons. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_operand_update_inner_instances(GArchOperand *operand, GArchOperand **instances, size_t count)
+{
+ GArchOperandClass *class; /* Classe associée à l'objet */
+
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
+
+ if (class->update_inner == NULL)
+ assert(class->list_inner == NULL);
+
+ else
+ {
+ assert(class->list_inner != NULL);
+ class->update_inner(operand, instances, count);
}
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint _g_arch_operand_hash(const GArchOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ const char *name; /* Désignation du type d'object*/
+ fnv64_t name_hash; /* Empreinte du nom */
+ operand_extra_data_t *extra; /* Données insérées à modifier */
+
+ assert(!lock);
+
+ name = G_OBJECT_TYPE_NAME(G_OBJECT(operand));
+ name_hash = fnv_64a_hash(name);
+
+ result = (name_hash & 0xffffffff);
+ result ^= (name_hash >> 32);
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ result ^= extra->flags;
+
return result;
}
@@ -375,11 +740,176 @@ GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, pack
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_arch_operand_hash(const GArchOperand *operand)
+{
+ guint result; /* Valeur à retourner */
+ GArchOperandClass *class; /* Classe associée à l'objet */
+
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
+
+ result = class->hash(operand, true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* other = second élément à analyser. *
+* *
+* Description : Détermine si deux candidats à l'unicité sont identiques. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean g_arch_operand_is_equal(const GArchOperand *operand, const GArchOperand *other)
+{
+ gboolean result; /* Bilan à renvoyer */
+ int ret; /* Bilan d'une comparaison */
+
+ ret = g_arch_operand_compare(operand, other);
+
+ result = (ret == 0);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* *
+* Description : Marque un candidat comme figé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_operand_set_read_only(GArchOperand *operand)
+{
+ g_arch_operand_set_flag(operand, AOF_READ_ONLY);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* *
+* Description : Indique si le candidat est figé. *
+* *
+* Retour : true si le contenu du candidat ne peut plus être modifié. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_operand_is_read_only(GArchOperand *operand)
+{
+ bool result; /* Etat à retourner */
+
+ result = g_arch_operand_has_flag(operand, AOF_READ_ONLY);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool _g_arch_operand_load(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ operand_extra_data_t *extra; /* Données insérées à consulter*/
+ uleb128_t value; /* Valeur ULEB128 à charger */
+
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->flags = value;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_operand_load(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *class; /* Classe à activer */
+
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
+
+ result = class->load(operand, storage, pbuf);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -387,11 +917,18 @@ GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, pack
* *
******************************************************************************/
-static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool _g_arch_operand_store(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
+ operand_extra_data_t *extra; /* Données insérées à consulter*/
- result = true;
+ extra = GET_ARCH_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = pack_uleb128((uleb128_t []){ extra->flags }, pbuf);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -400,11 +937,11 @@ static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *s
/******************************************************************************
* *
-* Paramètres : operand = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -412,14 +949,14 @@ static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *s
* *
******************************************************************************/
-bool g_arch_operand_store(const GArchOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_arch_operand_store(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
+ GArchOperandClass *class; /* Classe à activer */
- result = g_asm_storage_store_object_gtype(storage, G_OBJECT(operand), pbuf);
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
- if (result)
- result = G_ARCH_OPERAND_GET_CLASS(operand)->serialize(operand, storage, pbuf);
+ result = class->store(operand, storage, pbuf);
return result;
diff --git a/src/arch/operand.h b/src/arch/operand.h
index 9e1b5a8..234ee64 100644
--- a/src/arch/operand.h
+++ b/src/arch/operand.h
@@ -41,6 +41,23 @@
typedef struct _GLoadedBinary GLoadedBinary;
+/* Indications supplémentaires liées aux opérandes */
+
+#define AOF_USER_BIT 1
+
+typedef enum _ArchOperandFlag
+{
+ AOF_NONE = (0 << 0), /* Aucune propriété */
+ AOF_READ_ONLY = (1 << 0), /* Indication de nature */
+
+ AOF_LOW_USER = (1 << AOF_USER_BIT), /* Premier bit disponible */
+ AOF_HIGH_USER = (1 << 7), /* Dernier bit disponible */
+
+} ArchOperandFlag;
+
+#define AOF_USER_FLAG(n) (1 << (AOF_USER_BIT + n))
+
+
#define G_TYPE_ARCH_OPERAND g_arch_operand_get_type()
#define G_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARCH_OPERAND, GArchOperand))
#define G_IS_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARCH_OPERAND))
@@ -71,23 +88,32 @@ GArchOperand *g_arch_operand_get_inner_operand_from_path(const GArchOperand *, c
/* Traduit un opérande en version humainement lisible. */
void g_arch_operand_print(const GArchOperand *, GBufferLine *);
+#ifdef INCLUDE_GTK_SUPPORT
+
/* Construit un petit résumé concis de l'opérande. */
char *g_arch_operand_build_tooltip(const GArchOperand *, const GLoadedBinary *);
+#endif
+/* Ajoute une information complémentaire à un opérande. */
+bool g_arch_operand_set_flag(GArchOperand *, ArchOperandFlag);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Retire une information complémentaire à un opérande. */
+bool g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag);
+/* Détermine si un opérande possède un fanion particulier. */
+bool g_arch_operand_has_flag(const GArchOperand *, ArchOperandFlag);
+
+/* Fournit les particularités de l'opérande. */
+ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *);
-/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */
-typedef struct _GAsmStorage GAsmStorage;
-/* Charge un opérande depuis une mémoire tampon. */
-GArchOperand *g_arch_operand_load(GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+
-/* Sauvegarde un opérande dans une mémoire tampon. */
-bool g_arch_operand_store(const GArchOperand *, GAsmStorage *, packed_buffer_t *);
+/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */
+typedef struct _GAsmStorage GAsmStorage;
diff --git a/src/arch/operands/Makefile.am b/src/arch/operands/Makefile.am
index 0cb5b02..f2a8767 100644
--- a/src/arch/operands/Makefile.am
+++ b/src/arch/operands/Makefile.am
@@ -4,7 +4,9 @@ noinst_LTLIBRARIES = libarchoperands.la
libarchoperands_la_SOURCES = \
feeder-int.h \
feeder.h feeder.c \
+ immediate-int.h \
immediate.h immediate.c \
+ known.h known.c \
register-int.h \
register.h register.c \
proxy-int.h \
@@ -16,19 +18,9 @@ libarchoperands_la_SOURCES = \
targetable-int.h \
targetable.h targetable.c
-libarchoperands_la_LIBADD =
-
-libarchoperands_la_LDFLAGS =
+libarchoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libarchoperands_la_SOURCES:%c=)
-
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-
-
-SUBDIRS =
diff --git a/src/arch/operands/feeder-int.h b/src/arch/operands/feeder-int.h
index 86bc98f..f2f2566 100644
--- a/src/arch/operands/feeder-int.h
+++ b/src/arch/operands/feeder-int.h
@@ -28,6 +28,9 @@
#include "feeder.h"
+#include "../../analysis/storage/serialize-int.h"
+
+
/* Compare un fournisseur avec un autre. */
typedef int (* compare_proxy_operand_fc) (const GProxyFeeder *, const GProxyFeeder *);
@@ -35,26 +38,17 @@ typedef int (* compare_proxy_operand_fc) (const GProxyFeeder *, const GProxyFeed
/* Traduit un fournisseur en version humainement lisible. */
typedef void (* print_proxy_feeder_fc) (const GProxyFeeder *, GBufferLine *);
-/* Charge un fournisseur depuis une mémoire tampon. */
-typedef bool (* unserialize_proxy_feeder_fc) (GProxyFeeder *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un fournisseur dans une mémoire tampon. */
-typedef bool (* serialize_proxy_feeder_fc) (const GProxyFeeder *, packed_buffer_t *);
-
/* Fournisseur d'élément non architectural (interface) */
struct _GProxyFeederIface
{
- GTypeInterface base_iface; /* A laisser en premier */
+ GSerializableObjectInterface base_iface;/* A laisser en premier */
compare_proxy_operand_fc compare; /* Comparaison entre éléments */
print_proxy_feeder_fc print; /* Affichage sur une ligne */
- unserialize_proxy_feeder_fc unserialize;/* Restauration de l'élément */
- serialize_proxy_feeder_fc serialize; /* Sauvegarder de l'élément */
-
};
diff --git a/src/arch/operands/feeder.c b/src/arch/operands/feeder.c
index f34475c..af23fea 100644
--- a/src/arch/operands/feeder.c
+++ b/src/arch/operands/feeder.c
@@ -28,13 +28,32 @@
+/* -------------------- DEFINITION DE L'INTERFACE DE FOURNISSEUR -------------------- */
+
+
/* Procède à l'initialisation de l'interface de rassemblement. */
static void g_proxy_feeder_default_init(GProxyFeederInterface *);
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_proxy_feeder_load(GProxyFeeder *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_proxy_feeder_store(GProxyFeeder *, GObjectStorage *, packed_buffer_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION DE L'INTERFACE DE FOURNISSEUR */
+/* ---------------------------------------------------------------------------------- */
+
+
/* Détermine le type d'une interface pour la Fourniture d'éléments non architecturaux. */
-G_DEFINE_INTERFACE(GProxyFeeder, g_proxy_feeder, G_TYPE_OBJECT)
+G_DEFINE_INTERFACE(GProxyFeeder, g_proxy_feeder, G_TYPE_SERIALIZABLE_OBJECT)
/******************************************************************************
@@ -104,58 +123,3 @@ void g_proxy_feeder_print(const GProxyFeeder *feeder, GBufferLine *line)
iface->print(feeder, line);
}
-
-
-/******************************************************************************
-* *
-* Paramètres : feeder = fournisseur à constituer. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Charge un fournisseur depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_proxy_feeder_unserialize(GProxyFeeder *feeder, GBinFormat *format, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GProxyFeederIface *iface; /* Interface utilisée */
-
- iface = G_PROXY_FEEDER_GET_IFACE(feeder);
-
- result = iface->unserialize(feeder, format, pbuf);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : feeder = fournisseur à consulter. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde un fournisseur dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_proxy_feeder_serialize(const GProxyFeeder *feeder, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GProxyFeederIface *iface; /* Interface utilisée */
-
- iface = G_PROXY_FEEDER_GET_IFACE(feeder);
-
- result = iface->serialize(feeder, pbuf);
-
- return result;
-
-}
diff --git a/src/arch/operands/feeder.h b/src/arch/operands/feeder.h
index 2d8559e..685323b 100644
--- a/src/arch/operands/feeder.h
+++ b/src/arch/operands/feeder.h
@@ -26,11 +26,8 @@
#include <glib-object.h>
-#include <stdbool.h>
-#include "../../common/packed.h"
-#include "../../format/format.h"
#include "../../glibext/bufferline.h"
@@ -59,12 +56,6 @@ int g_proxy_feeder_compare(const GProxyFeeder *, const GProxyFeeder *);
/* Traduit un fournisseur en version humainement lisible. */
void g_proxy_feeder_print(const GProxyFeeder *, GBufferLine *);
-/* Charge un fournisseur depuis une mémoire tampon. */
-bool g_proxy_feeder_unserialize(GProxyFeeder *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un fournisseur dans une mémoire tampon. */
-bool g_proxy_feeder_serialize(const GProxyFeeder *, packed_buffer_t *);
-
#endif /* _ARCH_OPERANDS_FEEDER_H */
diff --git a/src/arch/operands/immediate-int.h b/src/arch/operands/immediate-int.h
new file mode 100644
index 0000000..d2313f5
--- /dev/null
+++ b/src/arch/operands/immediate-int.h
@@ -0,0 +1,85 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * immediate-int.h - définitions internes propres aux opérandes représentant des valeurs numériques
+ *
+ * Copyright (C) 2021 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_OPERANDS_IMMEDIATE_INT_H
+#define _ARCH_OPERANDS_IMMEDIATE_INT_H
+
+
+#include "immediate.h"
+#include "../operand-int.h"
+
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _immop_extra_data_t
+{
+ operand_extra_data_t parent; /* A laisser en premier */
+
+ MemoryDataSize size; /* Taille de l'opérande */
+
+ /**
+ * Les deux éléments suivants sont de type ImmOperandDisplay ;
+ * leur espace de conservation est réduit au maximum afin d'éviter
+ * un recouvrement .
+ */
+
+ unsigned int def_display : 3; /* Type par défaut d'affichage */
+ unsigned int display : 3; /* Format général d'affichage */
+
+} immop_extra_data_t;
+
+
+/* Définition d'un opérande de valeur numérique (instance) */
+struct _GImmOperand
+{
+ GArchOperand parent; /* Instance parente */
+
+ uint64_t raw; /* Valeur transtypée */
+
+};
+
+/* Définition d'un opérande de valeur numérique (classe) */
+struct _GImmOperandClass
+{
+ GArchOperandClass parent; /* Classe parente */
+
+};
+
+
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_IMM_OP_EXTRA(op) ((immop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_extra_data_t)
+
+#endif
+
+
+
+#endif /* _ARCH_OPERANDS_IMMEDIATE_INT_H */
diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c
index cb39fce..f40c645 100644
--- a/src/arch/operands/immediate.c
+++ b/src/arch/operands/immediate.c
@@ -31,100 +31,25 @@
#include <malloc.h>
#include <stdarg.h>
#include <stdio.h>
-#include <string.h>
#include <i18n.h>
+#include "immediate-int.h"
+#include "known.h"
#include "rename-int.h"
#include "targetable-int.h"
-#include "../operand-int.h"
#include "../../common/asm.h"
#include "../../common/extstr.h"
-#include "../../core/logs.h"
-#include "../../format/format.h"
-#include "../../glibext/objhole.h"
-#include "../../gtkext/gtkblockdisplay.h"
+#include "../../common/sort.h"
+#include "../../core/columns.h"
/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */
-/* Etats particuliers d'un opérande de valeur immédiate */
-typedef enum _ImmOpFlag
-{
- IOF_ZERO_PADDING_BY_DEFAULT, /* Bourrage avec 0 par défaut ?*/
- IOF_ZERO_PADDING, /* Bourrage avec 0 ? */
-
-} ImmOpFlag;
-
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _immop_obj_extra
-{
- struct
- {
- MemoryDataSize size; /* Taille de l'opérande */
-
- ImmOperandDisplay def_display; /* Type par défaut d'affichage */
- ImmOperandDisplay display; /* Format général d'affichage */
- ImmOpFlag flags; /* Informations diverses */
-
- };
-
- gint lock; /* Gestion d'accès aux fanions */
-
-} immop_obj_extra;
-
-/* Définition d'un opérande de valeur numérique (instance) */
-struct _GImmOperand
-{
- GArchOperand parent; /* Instance parente */
-
- uint64_t raw; /* Valeur transtypée */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- immop_obj_extra extra; /* Externalisation embarquée */
-
-#endif
-
-};
-
-/**
- * Accès aux informations éventuellement déportées.
- */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
-# define INIT_IMM_OP_EXTRA(op) op->extra.lock = 0
-
-# define GET_IMM_OP_EXTRA(op) &op->extra
-
-#else
-
-# define INIT_IMM_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op))
-
-# define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_obj_extra)
-
-#endif
-
-/* Définition d'un opérande de valeur numérique (classe) */
-struct _GImmOperandClass
-{
- GArchOperandClass parent; /* Classe parente */
-
-};
-
-
/* Initialise la classe des opérandes de valeur immédiate. */
static void g_imm_operand_class_init(GImmOperandClass *);
@@ -143,81 +68,51 @@ static void g_imm_operand_dispose(GImmOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_imm_operand_finalize(GImmOperand *);
-/* Compare un opérande avec un autre. */
-static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *);
-
/* Construit la chaîne de caractères correspondant à l'opérande. */
static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]);
/* Traduit un opérande en version humainement lisible. */
static void g_imm_operand_print(const GImmOperand *, GBufferLine *);
-/* Construit un petit résumé concis de l'opérande. */
-static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *);
-
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_imm_operand_serialize(const GImmOperand *, GAsmStorage *, packed_buffer_t *);
-/* Obtient l'adresse de la cible visée par un opérande. */
-static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *);
-
-/* Construit un opérande de représentation alternative. */
-static GRenamedOperand *g_imm_operand_build(const GImmOperand *, const char *);
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */
-
+/* Compare un opérande avec un autre. */
+static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *, bool);
-/* Définition d'un remplacement d'opérande de valeur numérique (instance) */
-struct _GKnownImmOperand
-{
- GImmOperand parent; /* Instance parente */
+#ifdef INCLUDE_GTK_SUPPORT
- char *alt_text; /* Alternative humaine */
+/* Construit un petit résumé concis de l'opérande. */
+static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *);
-};
+#endif
-/* Définition d'un remplacement d'opérande de valeur numérique (classe) */
-struct _GKnownImmOperandClass
-{
- GImmOperandClass parent; /* Classe parente */
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_imm_operand_hash(const GImmOperand *, bool);
-};
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_imm_operand_load(GImmOperand *, GObjectStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_imm_operand_store(GImmOperand *, GObjectStorage *, packed_buffer_t *);
-/* Initialise la classe des remplacements d'opérandes. */
-static void g_known_imm_operand_class_init(GKnownImmOperandClass *);
-/* Initialise un remplacement d'opérande de valeur immédiate. */
-static void g_known_imm_operand_init(GKnownImmOperand *);
-/* Procède à l'initialisation de l'interface de renommage. */
-static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *);
+/* ---------------------- COMMUNICATION D'UN CIBLAGE POTENTIEL ---------------------- */
-/* Supprime toutes les références externes. */
-static void g_known_imm_operand_dispose(GKnownImmOperand *);
-/* Procède à la libération totale de la mémoire. */
-static void g_known_imm_operand_finalize(GKnownImmOperand *);
+/* Obtient l'adresse de la cible visée par un opérande. */
+static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *);
-/* Compare un opérande avec un autre. */
-static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *);
-/* Traduit un opérande en version humainement lisible. */
-static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_known_imm_operand_unserialize(GKnownImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* ---------------------- CONSTRUCTION D'UN CONTENU ALTERNATIF ---------------------- */
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_known_imm_operand_serialize(const GKnownImmOperand *, GAsmStorage *, packed_buffer_t *);
-/* Fournit un texte comme représentation alternative d'opérande. */
-static const char *g_known_imm_operand_get_text(const GKnownImmOperand *);
+/* Construit un opérande de représentation alternative. */
+static GRenamedOperand *g_imm_operand_build(const GImmOperand *, const char *);
@@ -257,10 +152,14 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
operand->compare = (operand_compare_fc)g_imm_operand_compare;
operand->print = (operand_print_fc)g_imm_operand_print;
+#ifdef INCLUDE_GTK_SUPPORT
operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip;
+#endif
+
+ operand->hash = (operand_hash_fc)g_imm_operand_hash;
- operand->unserialize = (unserialize_operand_fc)g_imm_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_imm_operand_serialize;
+ operand->load = (load_operand_fc)g_imm_operand_load;
+ operand->store = (store_operand_fc)g_imm_operand_store;
}
@@ -279,13 +178,13 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
static void g_imm_operand_init(GImmOperand *operand)
{
- operand->raw = 0;
-
- INIT_IMM_OP_EXTRA(operand);
+ GET_IMM_OP_EXTRA(operand)->size = MDS_UNDEFINED;
GET_IMM_OP_EXTRA(operand)->def_display = IOD_HEX;
GET_IMM_OP_EXTRA(operand)->display = IOD_COUNT;
+ operand->raw = 0;
+
}
@@ -384,7 +283,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)
GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian)
{
GImmOperand *result; /* Opérande à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
uint8_t uval8; /* Valeur sur 8 bits */
uint16_t uval16; /* Valeur sur 16 bits */
uint32_t uval32; /* Valeur sur 32 bits */
@@ -495,7 +394,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten
GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
{
GImmOperand *result; /* Opérande à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
if (size == MDS_UNDEFINED)
result = NULL;
@@ -519,98 +418,6 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
-* *
-* Description : Compare un opérande avec un autre. *
-* *
-* Retour : Bilan de la comparaison. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)
-{
- int result; /* Bilan à retourner */
- immop_obj_extra *ea; /* Données insérées à modifier */
- immop_obj_extra *eb; /* Données insérées à modifier */
-
- ea = GET_IMM_OP_EXTRA(a);
- eb = GET_IMM_OP_EXTRA(b);
-
- g_bit_lock(&ea->lock, HOLE_LOCK_BIT);
- g_bit_lock(&eb->lock, HOLE_LOCK_BIT);
-
- if (ea->size < eb->size)
- {
- result = -1;
- goto done;
- }
- else if (ea->size > eb->size)
- {
- result = 1;
- goto done;
- }
-
- if (a->raw < b->raw)
- {
- result = -1;
- goto done;
- }
- else if (a->raw > b->raw)
- {
- result = 1;
- goto done;
- }
-
- if (ea->def_display < eb->def_display)
- {
- result = -1;
- goto done;
- }
- else if (ea->def_display > eb->def_display)
- {
- result = 1;
- goto done;
- }
-
- if (ea->display < eb->display)
- {
- result = -1;
- goto done;
- }
- else if (ea->display > eb->display)
- {
- result = 1;
- goto done;
- }
-
- if (ea->flags < eb->flags)
- {
- result = -1;
- goto done;
- }
- else if (ea->flags > eb->flags)
- {
- result = 1;
- goto done;
- }
-
- result = 0;
-
- done:
-
- g_bit_unlock(&eb->lock, HOLE_LOCK_BIT);
- g_bit_unlock(&ea->lock, HOLE_LOCK_BIT);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : operand = structure dont le contenu est à consulter. *
* *
* Description : Renseigne la taille de la valeur indiquée à la construction. *
@@ -624,15 +431,15 @@ static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)
MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
{
MemoryDataSize result; /* Taille à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->size;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -656,7 +463,7 @@ MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)
{
bool result; /* Bilan à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
va_list ap; /* Liste des compléments */
uint8_t *uval8; /* Valeur sur 8 bits */
uint16_t *uval16; /* Valeur sur 16 bits */
@@ -671,7 +478,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (extra->size != size)
goto exit;
@@ -726,7 +533,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..
exit:
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -768,141 +575,19 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand)
void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
assert(size != MDS_UNDEFINED);
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->size = size;
operand->raw = value;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à consulter. *
-* *
-* Description : Indique si une valeur est complétée par des zéros par défaut.*
-* *
-* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_imm_operand_get_default_padding(const GImmOperand *operand)
-{
- bool result; /* Statut à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = (extra->flags & IOF_ZERO_PADDING_BY_DEFAULT);
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] *
-* state = true si des zéro sont à ajouter, false sinon. *
-* *
-* Description : Précise si des zéro doivent compléter l'affichage ou non. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_imm_operand_set_default_padding(GImmOperand *operand, bool state)
-{
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- if (state)
- extra->flags |= IOF_ZERO_PADDING_BY_DEFAULT;
- else
- extra->flags &= ~IOF_ZERO_PADDING_BY_DEFAULT;
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] *
-* state = true si des zéro sont à ajouter, false sinon. *
-* *
-* Description : Précise si des zéro doivent compléter l'affichage ou non. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_imm_operand_pad(GImmOperand *operand, bool state)
-{
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- if (state)
- extra->flags |= (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- else
- extra->flags &= ~(IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à consulter. *
-* *
-* Description : Indique si une valeur est complétée par des zéros. *
-* *
-* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_imm_operand_does_padding(const GImmOperand *operand)
-{
- bool result; /* Statut à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING));
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- return result;
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -922,15 +607,15 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->def_display = display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -950,15 +635,15 @@ void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay d
ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
{
ImmOperandDisplay result; /* Affichage à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->def_display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -980,15 +665,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->display = display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1008,18 +693,18 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
{
ImmOperandDisplay result; /* Affichage à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (extra->display != IOD_COUNT)
result = extra->display;
else
result = extra->def_display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1041,11 +726,11 @@ ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
bool g_imm_operand_is_negative(const GImmOperand *operand)
{
bool result; /* Bilan à renvoyer */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
switch (extra->size)
{
@@ -1065,7 +750,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
break;
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1108,7 +793,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand)
static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE])
{
size_t result; /* Longueur à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
unsigned int range; /* Catégorie de la taille */
const char *prefix; /* Entrée en matière */
const char *suffix; /* Sortie de matière */
@@ -1132,7 +817,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ //LOCK_GOBJECT_EXTRA(extra);
range = MDS_RANGE(extra->size);
@@ -1173,7 +858,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
/* Drapeau de remplissage ? */
- do_padding = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING));
+ do_padding = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
if (do_padding)
{
@@ -1297,7 +982,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ //UNLOCK_GOBJECT_EXTRA(extra);
assert(result > 0);
@@ -1361,94 +1046,6 @@ static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line)
/******************************************************************************
* *
-* 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 *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary)
-{
- char *result; /* Description à retourner */
- char value[IMM_MAX_SIZE]; /* Conversion artificielle */
- char *conv; /* Affichage de la Conversion */
-
- if (operand->raw <= UCHAR_MAX && isprint(operand->raw))
- switch (operand->raw)
- {
- case '&':
- asprintf(&result, _("Character: '&amp;'"));
- break;
- case '<':
- asprintf(&result, _("Character: '&lt;'"));
- break;
- case '>':
- asprintf(&result, _("Character: '&gt;'"));
- break;
- default:
- asprintf(&result, _("Character: '%c'"), (char)operand->raw);
- break;
- }
-
- else
- asprintf(&result, _("Character: &lt;not printable&gt;"));
-
- /* Binaire */
-
- _g_imm_operand_to_string(operand, IOD_BIN, value);
-
- asprintf(&conv, _("Binary: %s"), value);
-
- result = stradd(result, "\n");
- result = stradd(result, conv);
-
- free(conv);
-
- /* Octal */
-
- _g_imm_operand_to_string(operand, IOD_OCT, value);
-
- asprintf(&conv, _("Octal: %s"), value);
-
- result = stradd(result, "\n");
- result = stradd(result, conv);
-
- free(conv);
-
- /* Décimal */
-
- _g_imm_operand_to_string(operand, IOD_DEC, value);
-
- asprintf(&conv, _("Decimal: %s"), value);
-
- result = stradd(result, "\n");
- result = stradd(result, conv);
-
- free(conv);
-
- /* Hexadécimal */
-
- _g_imm_operand_to_string(operand, IOD_HEX, value);
-
- asprintf(&conv, _("Hexadecimal: %s"), value);
-
- result = stradd(result, "\n");
- result = stradd(result, conv);
-
- free(conv);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : operand = opérande à traiter. *
* pos = valeur résultante. [OUT] *
* *
@@ -1463,18 +1060,18 @@ static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoad
bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)
{
bool result; /* Bilan à renvoyer */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = !MDS_IS_SIGNED(extra->size);
if (result)
*pos = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1497,18 +1094,18 @@ bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)
bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)
{
bool result; /* Bilan à renvoyer */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = !MDS_IS_SIGNED(extra->size);
if (result)
*addr = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1530,15 +1127,15 @@ bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)
void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
*val = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1558,119 +1155,76 @@ void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)
void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
*val = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
-/******************************************************************************
-* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Charge un opérande depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
-
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);
-
- if (result)
- {
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = extract_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);
-
- if (result)
- result = extract_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true);
- if (result)
- result = extract_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true);
-
- if (result)
- result = extract_packed_buffer(pbuf, &extra->flags, sizeof(uint8_t), false);
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- }
-
- return result;
-
-}
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Compare un opérande avec un autre. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Bilan de la comparaison. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b, bool lock)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
-
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ int result; /* Bilan à retourner */
+ immop_extra_data_t *ea; /* Données insérées à modifier */
+ immop_extra_data_t *eb; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
- if (result)
- result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);
+ ea = GET_IMM_OP_EXTRA(a);
+ eb = GET_IMM_OP_EXTRA(b);
- if (result)
+ if (lock)
{
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
- result = extend_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);
+ result = sort_unsigned_long(ea->size, eb->size);
- if (result)
- result = extend_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true);
+ if (result == 0)
+ sort_uint64_t(a->raw, b->raw);
- if (result)
- result = extend_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true);
+ if (result == 0)
+ result = sort_unsigned_long(ea->def_display, eb->def_display);
- if (result)
- result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ImmOpFlag), true);
+ if (result == 0)
+ result = sort_unsigned_long(ea->display, eb->display);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
}
return result;
@@ -1678,246 +1232,199 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto
}
-/******************************************************************************
-* *
-* Paramètres : operand = operande à consulter. *
-* src = localisation de l'instruction mère. *
-* format = format reconnu pour le binaire chargé. *
-* proc = architecture associée à ce même binaire. *
-* addr = localisation de la cible. [OUT] *
-* *
-* Description : Obtient l'adresse de la cible visée par un opérande. *
-* *
-* Retour : true si la cible est valide, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr)
-{
- bool result; /* Bilan à retourner */
- virt_t virt; /* Adresse virtuelle */
-
- result = g_imm_operand_to_virt_t(operand, &virt);
-
- if (result)
- result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr);
-
- return result;
-
-}
+#ifdef INCLUDE_GTK_SUPPORT
/******************************************************************************
* *
-* Paramètres : operand = operande à consulter. *
-* text = texte alternatif de représentation. *
+* Paramètres : operand = opérande à consulter. *
+* binary = informations relatives au binaire chargé. *
* *
-* Description : Construit un opérande de représentation alternative. *
+* Description : Construit un petit résumé concis de l'opérande. *
* *
-* Retour : Nouvel opérande, en version renommée. *
+* Retour : Chaîne de caractères à libérer après usage ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-static GRenamedOperand *g_imm_operand_build(const GImmOperand *operand, const char *text)
+static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary)
{
- GRenamedOperand *result; /* Instance à retourner */
+ char *result; /* Description à retourner */
+ char value[IMM_MAX_SIZE]; /* Conversion artificielle */
+ char *conv; /* Affichage de la Conversion */
- result = G_RENAMED_OPERAND(g_known_imm_operand_new(operand, text));
+ if (operand->raw <= UCHAR_MAX && isprint(operand->raw))
+ switch (operand->raw)
+ {
+ case '&':
+ asprintf(&result, _("Character: '&amp;'"));
+ break;
+ case '<':
+ asprintf(&result, _("Character: '&lt;'"));
+ break;
+ case '>':
+ asprintf(&result, _("Character: '&gt;'"));
+ break;
+ default:
+ asprintf(&result, _("Character: '%c'"), (char)operand->raw);
+ break;
+ }
- return result;
+ else
+ asprintf(&result, _("Character: &lt;not printable&gt;"));
-}
+ /* Binaire */
+ _g_imm_operand_to_string(operand, IOD_BIN, value);
+ asprintf(&conv, _("Binary: %s"), value);
-/* ---------------------------------------------------------------------------------- */
-/* REMPLACEMENT DE VALEURS IMMEDIATES */
-/* ---------------------------------------------------------------------------------- */
+ result = stradd(result, "\n");
+ result = stradd(result, conv);
+ free(conv);
-/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */
-G_DEFINE_TYPE_WITH_CODE(GKnownImmOperand, g_known_imm_operand, G_TYPE_IMM_OPERAND,
- G_IMPLEMENT_INTERFACE(G_TYPE_RENAMED_OPERAND, g_known_imm_operand_renamed_interface_init));
+ /* Octal */
+ _g_imm_operand_to_string(operand, IOD_OCT, value);
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des remplacements d'opérandes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ asprintf(&conv, _("Octal: %s"), value);
-static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GArchOperandClass *operand; /* Version de classe parente */
+ result = stradd(result, "\n");
+ result = stradd(result, conv);
- object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
+ free(conv);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_known_imm_operand_dispose;
- object->finalize = (GObjectFinalizeFunc)g_known_imm_operand_finalize;
+ /* Décimal */
- operand->compare = (operand_compare_fc)g_known_imm_operand_compare;
- operand->print = (operand_print_fc)g_known_imm_operand_print;
+ _g_imm_operand_to_string(operand, IOD_DEC, value);
- operand->unserialize = (unserialize_operand_fc)g_known_imm_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_known_imm_operand_serialize;
+ asprintf(&conv, _("Decimal: %s"), value);
-}
+ result = stradd(result, "\n");
+ result = stradd(result, conv);
+ free(conv);
-/******************************************************************************
-* *
-* Paramètres : operand = instance à initialiser. *
-* *
-* Description : Initialise un remplacement d'opérande de valeur immédiate. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ /* Hexadécimal */
-static void g_known_imm_operand_init(GKnownImmOperand *operand)
-{
- operand->alt_text = NULL;
+ _g_imm_operand_to_string(operand, IOD_HEX, value);
-}
+ asprintf(&conv, _("Hexadecimal: %s"), value);
+ result = stradd(result, "\n");
+ result = stradd(result, conv);
-/******************************************************************************
-* *
-* Paramètres : iface = interface GLib à initialiser. *
-* *
-* Description : Procède à l'initialisation de l'interface de renommage. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ free(conv);
-static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *iface)
-{
- iface->get_text = (get_renamed_text_fc)g_known_imm_operand_get_text;
+ return result;
}
+#endif
+
+
/******************************************************************************
* *
-* Paramètres : operand = instance d'objet GLib à traiter. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Supprime toutes les références externes. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : - *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_known_imm_operand_dispose(GKnownImmOperand *operand)
+static guint g_imm_operand_hash(const GImmOperand *operand, bool lock)
{
- if (operand->alt_text != NULL)
- free(operand->alt_text);
+ guint result; /* Valeur à retourner */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
- G_OBJECT_CLASS(g_known_imm_operand_parent_class)->dispose(G_OBJECT(operand));
+ extra = GET_IMM_OP_EXTRA(operand);
-}
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+ class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
-/******************************************************************************
-* *
-* Paramètres : operand = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ result ^= (operand->raw & 0xffffffff);
+ result ^= (operand->raw >> 32);
-static void g_known_imm_operand_finalize(GKnownImmOperand *operand)
-{
- G_OBJECT_CLASS(g_known_imm_operand_parent_class)->finalize(G_OBJECT(operand));
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : old = opérande à venir copier avant son remplacement. *
-* alt = texte alternatif à présenter pour l'impression. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Crée un opérande remplaçant visuellement une valeur. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
-* Retour : Instruction mise en place. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
+static bool g_imm_operand_load(GImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
- GKnownImmOperand *result; /* Remplacement à retourner */
- immop_obj_extra *src; /* Données insérées à consulter*/
- immop_obj_extra *dest; /* Données insérées à modifier */
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+ uint8_t val; /* Champ de bits manipulé */
- result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL);
+ parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
- result->parent.raw = old->raw;
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
- src = GET_IMM_OP_EXTRA(old);
- dest = GET_IMM_OP_EXTRA(&result->parent);
+ if (result)
+ {
+ extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&src->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- *dest = *src;
+ result = unpack_uleb128(&value, pbuf);
- g_bit_unlock(&src->lock, HOLE_LOCK_BIT);
+ if (result)
+ extra->size = value;
- result->alt_text = strdup(alt);
+ if (result)
+ {
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
- return G_ARCH_OPERAND(result);
+ if (result)
+ extra->def_display = val;
-}
+ }
+ if (result)
+ {
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
-/******************************************************************************
-* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
-* *
-* Description : Compare un opérande avec un autre. *
-* *
-* Retour : Bilan de la comparaison. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ if (result)
+ extra->display = val;
-static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b)
-{
- int result; /* Bilan à retourner */
- GArchOperandClass *class; /* Classe parente à consulter */
+ }
- class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ UNLOCK_GOBJECT_EXTRA(extra);
- result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b));
+ }
- if (result == 0)
- result = strcmp(a->alt_text, b->alt_text);
+ if (result)
+ result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);
return result;
@@ -1926,36 +1433,11 @@ static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownIm
/******************************************************************************
* *
-* Paramètres : operand = opérande à traiter. *
-* line = ligne tampon où imprimer l'opérande donné. *
-* *
-* Description : Traduit un opérande en version humainement lisible. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLine *line)
-{
- size_t len; /* Taille de l'élément inséré */
-
- len = strlen(operand->alt_text);
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY, operand->alt_text, len, RTT_IMMEDIATE, G_OBJECT(operand));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -1963,101 +1445,103 @@ static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLi
* *
******************************************************************************/
-static bool g_known_imm_operand_unserialize(GKnownImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_imm_operand_store(GImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
- unsigned short len; /* Taille du contenu alternatif*/
+ immop_extra_data_t *extra; /* Données insérées à modifier */
- parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extract_packed_buffer(pbuf, &len, sizeof(unsigned short), true);
+ {
+ extra = GET_IMM_OP_EXTRA(operand);
- if (result)
- result = (len > 0);
+ LOCK_GOBJECT_EXTRA(extra);
- if (result)
- {
- operand->alt_text = malloc(len);
+ result = pack_uleb128((uleb128_t []){ extra->size }, pbuf);
- result = extract_packed_buffer(pbuf, operand->alt_text, len, false);
+ if (result)
+ result = extend_packed_buffer(pbuf, (uint8_t []) { extra->def_display }, sizeof(uint8_t), false);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, (uint8_t []) { extra->display }, sizeof(uint8_t), false);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
}
+ if (result)
+ result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);
+
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* COMMUNICATION D'UN CIBLAGE POTENTIEL */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = operande à consulter. *
+* src = localisation de l'instruction mère. *
+* format = format reconnu pour le binaire chargé. *
+* proc = architecture associée à ce même binaire. *
+* addr = localisation de la cible. [OUT] *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Obtient l'adresse de la cible visée par un opérande. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : true si la cible est valide, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_known_imm_operand_serialize(const GKnownImmOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr)
{
bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- size_t len; /* Taille du contenu alternatif*/
-
- parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ virt_t virt; /* Adresse virtuelle */
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = g_imm_operand_to_virt_t(operand, &virt);
if (result)
- {
- len = strlen(operand->alt_text) + 1;
- assert(len > 1);
-
- if (len > (2 << (sizeof(unsigned short) * 8 - 1)))
- {
- log_variadic_message(LMT_ERROR, "Alternative text too long: '%s' (%zu bytes)",
- operand->alt_text, len);
- result = false;
- }
+ result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr);
- else
- result = extend_packed_buffer(pbuf, (unsigned short []) { len }, sizeof(unsigned short), true);
+ return result;
- if (result)
- result = extend_packed_buffer(pbuf, operand->alt_text, len, false);
+}
- }
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* CONSTRUCTION D'UN CONTENU ALTERNATIF */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
* Paramètres : operand = operande à consulter. *
+* text = texte alternatif de représentation. *
* *
-* Description : Fournit un texte comme représentation alternative d'opérande.*
+* Description : Construit un opérande de représentation alternative. *
* *
-* Retour : Chaîne de caractère de représentation alternative. *
+* Retour : Nouvel opérande, en version renommée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static const char *g_known_imm_operand_get_text(const GKnownImmOperand *operand)
+static GRenamedOperand *g_imm_operand_build(const GImmOperand *operand, const char *text)
{
- const char *result; /* Texte à retourner */
+ GRenamedOperand *result; /* Instance à retourner */
- result = operand->alt_text;
+ result = G_RENAMED_OPERAND(g_known_imm_operand_new(operand, text));
return result;
diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h
index e6fab96..7c1ff03 100644
--- a/src/arch/operands/immediate.h
+++ b/src/arch/operands/immediate.h
@@ -36,8 +36,13 @@
-/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _ImmOpFlag
+{
+ IOF_ZERO_PADDING_BY_DEFAULT = AOF_USER_FLAG(0), /* Bourrage avec 0 par défaut ?*/
+ IOF_ZERO_PADDING = AOF_USER_FLAG(1), /* Bourrage avec 0 ? */
+} ImmOpFlag;
/* Grande ligne d'un format d'affichage */
typedef enum _ImmOperandDisplay
@@ -52,7 +57,6 @@ typedef enum _ImmOperandDisplay
} ImmOperandDisplay;
-
#define IOD_LAST_VALID IOD_CHAR
@@ -95,18 +99,6 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *);
/* Définit la nouvelle valeur de l'opérande à une valeur. */
void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t);
-/* Indique si une valeur est complétée par des zéros par défaut. */
-bool g_imm_operand_get_default_padding(const GImmOperand *);
-
-/* Précise si des zéro doivent compléter l'affichage ou non. */
-void g_imm_operand_set_default_padding(GImmOperand *, bool);
-
-/* Précise si des zéro doivent compléter l'affichage ou non. */
-void g_imm_operand_pad(GImmOperand *, bool);
-
-/* Indique si une valeur est complétée par des zéros. */
-bool g_imm_operand_does_padding(const GImmOperand *);
-
/* Définit le format textuel par défaut de la valeur. */
void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay);
@@ -148,30 +140,4 @@ void g_imm_operand_as_uleb128(const GImmOperand *, uleb128_t *);
-/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */
-
-
-#define G_TYPE_KNOWN_IMM_OPERAND g_known_imm_operand_get_type()
-#define G_KNOWN_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperand))
-#define G_IS_KNOWN_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KNOWN_IMM_OPERAND))
-#define G_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass))
-#define G_IS_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KNOWN_IMM_OPERAND))
-#define G_KNOWN_IMM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass))
-
-
-/* Définition d'un remplacement d'opérande de valeur numérique (instance) */
-typedef struct _GKnownImmOperand GKnownImmOperand;
-
-/* Définition d'un remplacement d'opérande de valeur numérique (classe) */
-typedef struct _GKnownImmOperandClass GKnownImmOperandClass;
-
-
-/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */
-GType g_known_imm_operand_get_type(void);
-
-/* Crée un opérande remplaçant visuellement une valeur. */
-GArchOperand *g_known_imm_operand_new(const GImmOperand *, const char *);
-
-
-
#endif /* _ARCH_OPERANDS_IMMEDIATE_H */
diff --git a/src/arch/operands/known.c b/src/arch/operands/known.c
new file mode 100644
index 0000000..5402879
--- /dev/null
+++ b/src/arch/operands/known.c
@@ -0,0 +1,499 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * known.c - opérandes représentant des valeurs numériques avec sémantique
+ *
+ * Copyright (C) 2020 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "known.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "immediate-int.h"
+#include "rename-int.h"
+#include "../../analysis/db/misc/rlestr.h"
+#include "../../core/columns.h"
+#include "../../core/logs.h"
+
+
+
+/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */
+
+
+/* Définition d'un remplacement d'opérande de valeur numérique (instance) */
+struct _GKnownImmOperand
+{
+ GImmOperand parent; /* Instance parente */
+
+ char *alt_text; /* Alternative humaine */
+
+};
+
+/* Définition d'un remplacement d'opérande de valeur numérique (classe) */
+struct _GKnownImmOperandClass
+{
+ GImmOperandClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des remplacements d'opérandes. */
+static void g_known_imm_operand_class_init(GKnownImmOperandClass *);
+
+/* Initialise un remplacement d'opérande de valeur immédiate. */
+static void g_known_imm_operand_init(GKnownImmOperand *);
+
+/* Procède à l'initialisation de l'interface de renommage. */
+static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_known_imm_operand_dispose(GKnownImmOperand *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_known_imm_operand_finalize(GKnownImmOperand *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Compare un opérande avec un autre. */
+static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *, bool);
+
+/* Traduit un opérande en version humainement lisible. */
+static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *);
+
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_known_imm_operand_hash(const GKnownImmOperand *, bool);
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_known_imm_operand_load(GKnownImmOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_known_imm_operand_store(GKnownImmOperand *, GObjectStorage *, packed_buffer_t *);
+
+
+
+/* ------------------------- AFFICHAGE D'UN CONTENU RENOMME ------------------------- */
+
+
+/* Fournit un texte comme représentation alternative d'opérande. */
+static const char *g_known_imm_operand_get_text(const GKnownImmOperand *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* REMPLACEMENT DE VALEURS IMMEDIATES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */
+G_DEFINE_TYPE_WITH_CODE(GKnownImmOperand, g_known_imm_operand, G_TYPE_IMM_OPERAND,
+ G_IMPLEMENT_INTERFACE(G_TYPE_RENAMED_OPERAND, g_known_imm_operand_renamed_interface_init));
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des remplacements d'opérandes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GArchOperandClass *operand; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_known_imm_operand_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_known_imm_operand_finalize;
+
+ operand->compare = (operand_compare_fc)g_known_imm_operand_compare;
+ operand->print = (operand_print_fc)g_known_imm_operand_print;
+
+ operand->hash = (operand_hash_fc)g_known_imm_operand_hash;
+
+ operand->load = (load_operand_fc)g_known_imm_operand_load;
+ operand->store = (store_operand_fc)g_known_imm_operand_store;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise un remplacement d'opérande de valeur immédiate. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_known_imm_operand_init(GKnownImmOperand *operand)
+{
+ operand->alt_text = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de renommage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *iface)
+{
+ iface->get_text = (get_renamed_text_fc)g_known_imm_operand_get_text;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_known_imm_operand_dispose(GKnownImmOperand *operand)
+{
+ if (operand->alt_text != NULL)
+ free(operand->alt_text);
+
+ G_OBJECT_CLASS(g_known_imm_operand_parent_class)->dispose(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_known_imm_operand_finalize(GKnownImmOperand *operand)
+{
+ G_OBJECT_CLASS(g_known_imm_operand_parent_class)->finalize(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : old = opérande à venir copier avant son remplacement. *
+* alt = texte alternatif à présenter pour l'impression. *
+* *
+* Description : Crée un opérande remplaçant visuellement une valeur. *
+* *
+* Retour : Instruction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
+{
+ GKnownImmOperand *result; /* Remplacement à retourner */
+ immop_extra_data_t *src; /* Données insérées à consulter*/
+ immop_extra_data_t *dest; /* Données insérées à modifier */
+
+ result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL);
+
+ result->parent.raw = old->raw;
+
+ src = GET_IMM_OP_EXTRA(old);
+ dest = GET_IMM_OP_EXTRA(&result->parent);
+
+ LOCK_GOBJECT_EXTRA(src);
+
+ *(&dest->parent) = *(&src->parent);
+
+ dest->size = src->size;
+
+ dest->def_display = src->def_display;
+ dest->display = src->display;
+
+ UNLOCK_GOBJECT_EXTRA(src);
+
+ result->alt_text = strdup(alt);
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Compare un opérande avec un autre. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b, bool lock)
+{
+ int result; /* Bilan à retourner */
+ immop_extra_data_t *ea; /* Données insérées à consulter*/
+ immop_extra_data_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ ea = GET_IMM_OP_EXTRA(G_IMM_OPERAND(a));
+ eb = GET_IMM_OP_EXTRA(G_IMM_OPERAND(b));
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
+
+ result = strcmp(a->alt_text, b->alt_text);
+
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* line = ligne tampon où imprimer l'opérande donné. *
+* *
+* Description : Traduit un opérande en version humainement lisible. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLine *line)
+{
+ size_t len; /* Taille de l'élément inséré */
+
+ len = strlen(operand->alt_text);
+
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, operand->alt_text, len, RTT_IMMEDIATE, G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_known_imm_operand_hash(const GKnownImmOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_IMM_OP_EXTRA(G_IMM_OPERAND(operand));
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= g_str_hash(operand->alt_text);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_known_imm_operand_load(GKnownImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ rle_string str; /* Chaîne à charger */
+
+ parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ {
+ setup_empty_rle_string(&str);
+
+ result = unpack_rle_string(&str, pbuf);
+
+ if (result)
+ {
+ if (get_rle_string(&str) != NULL)
+ operand->alt_text = strdup(get_rle_string(&str));
+
+ exit_rle_string(&str);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_known_imm_operand_store(GKnownImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ rle_string str; /* Chaîne à conserver */
+
+ parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ {
+ init_static_rle_string(&str, operand->alt_text);
+
+ result = pack_rle_string(&str, pbuf);
+
+ exit_rle_string(&str);
+
+ }
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* AFFICHAGE D'UN CONTENU RENOMME */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = operande à consulter. *
+* *
+* Description : Fournit un texte comme représentation alternative d'opérande.*
+* *
+* Retour : Chaîne de caractère de représentation alternative. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_known_imm_operand_get_text(const GKnownImmOperand *operand)
+{
+ const char *result; /* Texte à retourner */
+
+ result = operand->alt_text;
+
+ return result;
+
+}
diff --git a/src/arch/operands/known.h b/src/arch/operands/known.h
new file mode 100644
index 0000000..eb84d3b
--- /dev/null
+++ b/src/arch/operands/known.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * known.h - prototypes pour les opérandes représentant des valeurs numériques avec sémantique
+ *
+ * Copyright (C) 2021 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_OPERANDS_KNOWN_H
+#define _ARCH_OPERANDS_KNOWN_H
+
+
+#include <glib-object.h>
+
+
+#include "immediate.h"
+#include "../operand.h"
+
+
+
+#define G_TYPE_KNOWN_IMM_OPERAND g_known_imm_operand_get_type()
+#define G_KNOWN_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperand))
+#define G_IS_KNOWN_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KNOWN_IMM_OPERAND))
+#define G_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass))
+#define G_IS_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KNOWN_IMM_OPERAND))
+#define G_KNOWN_IMM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass))
+
+
+/* Définition d'un remplacement d'opérande de valeur numérique (instance) */
+typedef struct _GKnownImmOperand GKnownImmOperand;
+
+/* Définition d'un remplacement d'opérande de valeur numérique (classe) */
+typedef struct _GKnownImmOperandClass GKnownImmOperandClass;
+
+
+/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */
+GType g_known_imm_operand_get_type(void);
+
+/* Crée un opérande remplaçant visuellement une valeur. */
+GArchOperand *g_known_imm_operand_new(const GImmOperand *, const char *);
+
+
+
+#endif /* _ARCH_OPERANDS_KNOWN_H */
diff --git a/src/arch/operands/proxy.c b/src/arch/operands/proxy.c
index bf26a4f..c71f96f 100644
--- a/src/arch/operands/proxy.c
+++ b/src/arch/operands/proxy.c
@@ -43,22 +43,25 @@ static void g_proxy_operand_dispose(GProxyOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_proxy_operand_finalize(GProxyOperand *);
-/* Compare un opérande avec un autre. */
-static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *);
-/* Traduit un opérande en version humainement lisible. */
-static void g_proxy_operand_print(const GProxyOperand *, GBufferLine *);
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Compare un opérande avec un autre. */
+static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *, bool);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Traduit un opérande en version humainement lisible. */
+static void g_proxy_operand_print(const GProxyOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_proxy_operand_hash(const GProxyOperand *, bool);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_proxy_operand_unserialize(GProxyOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_proxy_operand_load(GProxyOperand *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_proxy_operand_serialize(const GProxyOperand *, GAsmStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_proxy_operand_store(GProxyOperand *, GObjectStorage *, packed_buffer_t *);
@@ -98,8 +101,10 @@ static void g_proxy_operand_class_init(GProxyOperandClass *klass)
operand->compare = (operand_compare_fc)g_proxy_operand_compare;
operand->print = (operand_print_fc)g_proxy_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_proxy_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_proxy_operand_serialize;
+ operand->hash = (operand_hash_fc)g_proxy_operand_hash;
+
+ operand->load = (load_operand_fc)g_proxy_operand_load;
+ operand->store = (store_operand_fc)g_proxy_operand_store;
}
@@ -190,8 +195,40 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Fournit le fournisseur représenté par l'opérande. *
+* *
+* Retour : Fournisseur associé à l'opérande. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GProxyFeeder *g_proxy_operand_get_feeder(const GProxyOperand *operand)
+{
+ GProxyFeeder *result; /* Instance à retourner */
+
+ result = operand->feeder;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -201,12 +238,36 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)
* *
******************************************************************************/
-static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b)
+static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b, bool lock)
{
int result; /* Bilan à retourner */
+ operand_extra_data_t *ea; /* Données insérées à consulter*/
+ operand_extra_data_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ ea = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(a));
+ eb = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(b));
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
result = g_proxy_feeder_compare(a->feeder, b->feeder);
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
+
return result;
}
@@ -234,43 +295,48 @@ static void g_proxy_operand_print(const GProxyOperand *operand, GBufferLine *lin
/******************************************************************************
* *
-* Paramètres : operand = opérande à consulter. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Fournit le fournisseur représenté par l'opérande. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Fournisseur associé à l'opérande. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-GProxyFeeder *g_proxy_operand_get_feeder(const GProxyOperand *operand)
+static guint g_proxy_operand_hash(const GProxyOperand *operand, bool lock)
{
- GProxyFeeder *result; /* Instance à retourner */
+ guint result; /* Valeur à retourner */
+ operand_extra_data_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = operand->feeder;
+ extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand));
- g_object_ref(G_OBJECT(result));
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- return result;
+ class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
-}
+ result ^= g_direct_hash(operand->feeder);
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+ return result;
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
+}
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -278,17 +344,26 @@ GProxyFeeder *g_proxy_operand_get_feeder(const GProxyOperand *operand)
* *
******************************************************************************/
-static bool g_proxy_operand_unserialize(GProxyOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_proxy_operand_load(GProxyOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ GSerializableObject *feeder; /* Fournisseur manipulé */
parent = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class);
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = g_proxy_feeder_unserialize(operand->feeder, format, pbuf);
+ {
+ feeder = g_object_storage_unpack_object(storage, "operands", pbuf);
+
+ result = (feeder != NULL);
+
+ if (result)
+ operand->feeder = G_PROXY_FEEDER(feeder);
+
+ }
return result;
@@ -297,11 +372,11 @@ static bool g_proxy_operand_unserialize(GProxyOperand *operand, GAsmStorage *sto
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -309,17 +384,21 @@ static bool g_proxy_operand_unserialize(GProxyOperand *operand, GAsmStorage *sto
* *
******************************************************************************/
-static bool g_proxy_operand_serialize(const GProxyOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_proxy_operand_store(GProxyOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ GSerializableObject *feeder; /* Fournisseur manipulé */
parent = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = g_proxy_feeder_serialize(operand->feeder, pbuf);
+ {
+ feeder = G_SERIALIZABLE_OBJECT(operand->feeder);
+ result = g_object_storage_pack_object(storage, "operands", feeder, pbuf);
+ }
return result;
diff --git a/src/arch/operands/register-int.h b/src/arch/operands/register-int.h
index bf3e9d4..a887567 100644
--- a/src/arch/operands/register-int.h
+++ b/src/arch/operands/register-int.h
@@ -29,23 +29,9 @@
#include "../operand-int.h"
-#include "../../glibext/objhole.h"
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _regop_obj_extra
-{
- struct
- {
- bool is_written; /* Changement de contenu */
-
- };
-
- gint lock; /* Gestion d'accès aux fanions */
-
-} regop_obj_extra;
-
/* Définition d'un opérande visant un registre (instance) */
struct _GRegisterOperand
{
@@ -53,39 +39,8 @@ struct _GRegisterOperand
GArchRegister *reg; /* Registre représenté */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- regop_obj_extra extra; /* Externalisation embarquée */
-
-#endif
-
};
-/**
- * Accès aux informations éventuellement déportées.
- */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
-# define INIT_REG_OP_EXTRA(op) op->extra.lock = 0
-
-# define GET_REG_OP_EXTRA(op) &op->extra
-
-#else
-
-# define INIT_REG_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op))
-
-# define GET_REG_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), regop_obj_extra)
-
-#endif
-
/* Définition d'un opérande visant un registre (classe) */
struct _GRegisterOperandClass
{
diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c
index 9a6de17..4615a99 100644
--- a/src/arch/operands/register.c
+++ b/src/arch/operands/register.c
@@ -24,6 +24,9 @@
#include "register.h"
+#include <assert.h>
+
+
#include "register-int.h"
#include "../storage.h"
@@ -44,22 +47,25 @@ static void g_register_operand_dispose(GRegisterOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_register_operand_finalize(GRegisterOperand *);
-/* Compare un opérande avec un autre. */
-static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *);
-/* Traduit un opérande en version humainement lisible. */
-static void g_register_operand_print(const GRegisterOperand *, GBufferLine *);
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Compare un opérande avec un autre. */
+static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *, bool);
+/* Traduit un opérande en version humainement lisible. */
+static void g_register_operand_print(const GRegisterOperand *, GBufferLine *);
+
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_register_operand_hash(const GRegisterOperand *, bool);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_register_operand_unserialize(GRegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_register_operand_load(GRegisterOperand *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_register_operand_serialize(const GRegisterOperand *, GAsmStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_register_operand_store(GRegisterOperand *, GObjectStorage *, packed_buffer_t *);
@@ -100,8 +106,10 @@ static void g_register_operand_class_init(GRegisterOperandClass *klass)
operand->compare = (operand_compare_fc)g_register_operand_compare;
operand->print = (operand_print_fc)g_register_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_register_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_register_operand_serialize;
+ operand->hash = (operand_hash_fc)g_register_operand_hash;
+
+ operand->load = (load_operand_fc)g_register_operand_load;
+ operand->store = (store_operand_fc)g_register_operand_store;
}
@@ -122,8 +130,6 @@ static void g_register_operand_init(GRegisterOperand *operand)
{
operand->reg = NULL;
- INIT_REG_OP_EXTRA(operand);
-
}
@@ -169,68 +175,61 @@ static void g_register_operand_finalize(GRegisterOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : operand = opérande représentant un registre. *
* *
-* Description : Compare un opérande avec un autre. *
+* Description : Fournit le registre associé à l'opérande. *
* *
-* Retour : Bilan de la comparaison. *
+* Retour : Représentation interne du registre. *
* *
* Remarques : - *
* *
******************************************************************************/
-static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b)
+GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
{
- int result; /* Bilan à retourner */
+ GArchRegister *result; /* Instance à retourner */
- result = g_arch_register_compare(a->reg, b->reg);
+ result = operand->reg;
+
+ g_object_ref(G_OBJECT(result));
return result;
}
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à traiter. *
-* line = ligne tampon où imprimer l'opérande donné. *
-* *
-* Description : Traduit un opérande en version humainement lisible. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line)
-{
- g_arch_register_print(operand->reg, line);
-}
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : operand = opérande représentant un registre. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Fournit le registre associé à l'opérande. *
+* Description : Compare un opérande avec un autre. *
* *
-* Retour : Représentation interne du registre. *
+* Retour : Bilan de la comparaison. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
+static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock)
{
- GArchRegister *result; /* Instance à retourner */
+ int result; /* Bilan à retourner */
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = operand->reg;
+ result = g_arch_register_compare(a->reg, b->reg);
- if (result != NULL)
- g_object_ref(G_OBJECT(result));
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
return result;
@@ -239,9 +238,10 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
/******************************************************************************
* *
-* Paramètres : operand = opérande représentant un registre à mettre à jour. *
+* Paramètres : operand = opérande à traiter. *
+* line = ligne tampon où imprimer l'opérande donné. *
* *
-* Description : Marque l'opérande comme étant écrit plutôt que consulté. *
+* Description : Traduit un opérande en version humainement lisible. *
* *
* Retour : - *
* *
@@ -249,65 +249,53 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
* *
******************************************************************************/
-void g_register_operand_mark_as_written(GRegisterOperand *operand)
+static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line)
{
- regop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_REG_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- extra->is_written = true;
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ g_arch_register_print(operand->reg, line);
}
/******************************************************************************
* *
-* Paramètres : operand = opérande représentant un registre à consulter. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Indique le type d'accès réalisé sur l'opérande. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Type d'accès : true en cas d'écriture, false sinon. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_register_operand_is_written(const GRegisterOperand *operand)
+static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)
{
- bool result; /* Statut à retourner */
- regop_obj_extra *extra; /* Données insérées à modifier */
+ guint result; /* Valeur à retourner */
+ GArchOperandClass *class; /* Classe parente normalisée */
+ GArchRegister *reg; /* Registre visé par l'opérande*/
- extra = GET_REG_OP_EXTRA(operand);
+ class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ reg = g_register_operand_get_register(operand);
- result = extra->is_written;
+ result ^= g_arch_register_hash(reg);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ g_object_unref(G_OBJECT(reg));
return result;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -315,37 +303,24 @@ bool g_register_operand_is_written(const GRegisterOperand *operand)
* *
******************************************************************************/
-static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_register_operand_load(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
- off64_t pos; /* Position dans le flux */
- packed_buffer_t reg_pbuf; /* Tampon des données à écrire */
- GArchRegister *reg; /* Registre restauré */
+ GSerializableObject *reg; /* Registre manipulé */
parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
{
- init_packed_buffer(&reg_pbuf);
-
- result = g_asm_storage_load_register_data(storage, &reg_pbuf, pos);
+ reg = g_object_storage_unpack_object(storage, "registers", pbuf);
- if (result)
- {
- reg = g_arch_register_load(storage, &reg_pbuf);
- result = (reg != NULL);
- }
+ result = (reg != NULL);
if (result)
- operand->reg = reg;
-
- exit_packed_buffer(&reg_pbuf);
+ operand->reg = G_ARCH_REGISTER(reg);
}
@@ -356,11 +331,11 @@ static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorag
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -368,31 +343,20 @@ static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorag
* *
******************************************************************************/
-static bool g_register_operand_serialize(const GRegisterOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_register_operand_store(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- off64_t pos; /* Position dans le flux */
- packed_buffer_t reg_pbuf; /* Tampon des données à écrire */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ GSerializableObject *reg; /* Registre manipulé */
parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
{
- init_packed_buffer(&reg_pbuf);
-
- result = g_arch_register_store(operand->reg, storage, &reg_pbuf);
-
- if (result)
- result = g_asm_storage_store_register_data(storage, &reg_pbuf, &pos);
-
- if (result)
- result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
-
- exit_packed_buffer(&reg_pbuf);
-
+ reg = G_SERIALIZABLE_OBJECT(operand->reg);
+ result = g_object_storage_pack_object(storage, "registers", reg, pbuf);
}
return result;
diff --git a/src/arch/operands/register.h b/src/arch/operands/register.h
index 7f746b6..e2f2c46 100644
--- a/src/arch/operands/register.h
+++ b/src/arch/operands/register.h
@@ -37,6 +37,14 @@
/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */
+/* Etats particuliers d'un opérande de registre */
+typedef enum _RegOpFlag
+{
+ ROF_IS_WRITTEN = AOF_USER_FLAG(0), /* Opération d'écriture ? */
+
+} RegOpFlag;
+
+
#define G_TYPE_REGISTER_OPERAND g_register_operand_get_type()
#define G_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperand))
#define G_IS_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTER_OPERAND))
@@ -58,12 +66,6 @@ GType g_register_operand_get_type(void);
/* Fournit le registre associé à l'opérande. */
GArchRegister *g_register_operand_get_register(const GRegisterOperand *);
-/* Marque l'opérande comme étant écrit plutôt que consulté. */
-void g_register_operand_mark_as_written(GRegisterOperand *);
-
-/* Indique le type d'accès réalisé sur l'opérande. */
-bool g_register_operand_is_written(const GRegisterOperand *);
-
#endif /* _ARCH_OPERANDS_REGISTER_H */
diff --git a/src/arch/operands/target-int.h b/src/arch/operands/target-int.h
index f3ed447..aa48b2b 100644
--- a/src/arch/operands/target-int.h
+++ b/src/arch/operands/target-int.h
@@ -30,15 +30,22 @@
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _tarop_extra_data_t
+{
+ operand_extra_data_t parent; /* A laisser en premier */
+
+ MemoryDataSize size; /* Taille de l'opérande */
+
+} tarop_extra_data_t;
+
/* Définition d'un opérande ciblant idéalement un symbole connu (instance) */
struct _GTargetOperand
{
GArchOperand parent; /* Instance parente */
- MemoryDataSize size; /* Taille de l'opérande */
vmpa2t addr; /* Adresse de l'élément visé */
- bool strict; /* Résolution stricte */
/* Référence circulaire */
GBinSymbol *symbol; /* Eventuel symbole associé */
phys_t diff; /* Position dans le symbole */
@@ -54,5 +61,20 @@ struct _GTargetOperandClass
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_TARGET_OP_EXTRA(op) ((tarop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_TARGET_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), tarop_extra_data_t)
+
+#endif
+
+
#endif /* _ARCH_OPERANDS_TARGET_INT_H */
diff --git a/src/arch/operands/target.c b/src/arch/operands/target.c
index 5edc805..61f683a 100644
--- a/src/arch/operands/target.c
+++ b/src/arch/operands/target.c
@@ -37,13 +37,17 @@
#include "targetable-int.h"
#include "../../analysis/routine.h"
#include "../../common/extstr.h"
+#include "../../common/sort.h"
#include "../../format/format.h"
#include "../../format/strsym.h"
#include "../../glibext/gbinarycursor.h"
-#include "../../gtkext/gtkblockdisplay.h"
+#include "../../core/columns.h"
+/* ------------------------- POINTAGE D'UN SYMBOLE EXISTANT ------------------------- */
+
+
/* Initialise la classe des opérandes ciblant des symboles. */
static void g_target_operand_class_init(GTargetOperandClass *);
@@ -59,25 +63,32 @@ static void g_target_operand_dispose(GTargetOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_target_operand_finalize(GTargetOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *);
+static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_target_operand_print(const GTargetOperand *, GBufferLine *);
+#ifdef INCLUDE_GTK_SUPPORT
+
/* Construit un petit résumé concis de l'opérande. */
static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *);
+#endif
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_target_operand_hash(const GTargetOperand *, bool);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
-
-
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_target_operand_unserialize(GTargetOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_target_operand_load(GTargetOperand *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_target_operand_serialize(const GTargetOperand *, GAsmStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_target_operand_store(GTargetOperand *, GObjectStorage *, packed_buffer_t *);
@@ -89,6 +100,11 @@ static bool g_target_operand_get_addr(const GTargetOperand *, const vmpa2t *, GB
+/* ---------------------------------------------------------------------------------- */
+/* POINTAGE D'UN SYMBOLE EXISTANT */
+/* ---------------------------------------------------------------------------------- */
+
+
/* Indique le type défini pour un opérande de valeur numérique. */
G_DEFINE_TYPE_WITH_CODE(GTargetOperand, g_target_operand, G_TYPE_ARCH_OPERAND,
G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_target_operand_targetable_interface_init));
@@ -120,10 +136,14 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)
operand->compare = (operand_compare_fc)g_target_operand_compare;
operand->print = (operand_print_fc)g_target_operand_print;
+#ifdef INCLUDE_GTK_SUPPORT
operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip;
+#endif
+
+ operand->hash = (operand_hash_fc)g_target_operand_hash;
- operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_target_operand_serialize;
+ operand->load = (load_operand_fc)g_target_operand_load;
+ operand->store = (store_operand_fc)g_target_operand_store;
}
@@ -142,10 +162,10 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)
static void g_target_operand_init(GTargetOperand *operand)
{
- operand->size = MDS_UNDEFINED;
+ GET_TARGET_OP_EXTRA(operand)->size = MDS_UNDEFINED;
+
init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
- operand->strict = true;
operand->symbol = NULL;
operand->diff = 0;
@@ -211,8 +231,9 @@ static void g_target_operand_finalize(GTargetOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -222,56 +243,56 @@ static void g_target_operand_finalize(GTargetOperand *operand)
* *
******************************************************************************/
-static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b)
+static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b, bool lock)
{
int result; /* Bilan à retourner */
+ tarop_extra_data_t *ea; /* Données insérées à modifier */
+ tarop_extra_data_t *eb; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = cmp_vmpa(&a->addr, &b->addr);
- if (result != 0) goto gtoc_done;
+ ea = GET_TARGET_OP_EXTRA(a);
+ eb = GET_TARGET_OP_EXTRA(b);
- if (a->size < b->size)
+ if (lock)
{
- result = -1;
- goto gtoc_done;
- }
- else if (a->size > b->size)
- {
- result = 1;
- goto gtoc_done;
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
}
- if (a->symbol == NULL && b->symbol != NULL)
- {
- result = -1;
- goto gtoc_done;
- }
- else if (a->symbol != NULL && b->symbol == NULL)
- {
- result = 1;
- goto gtoc_done;
- }
- else if (a->symbol != NULL && b->symbol != NULL)
+ result = sort_unsigned_long(ea->size, eb->size);
+
+ if (result == 0)
+ result = cmp_vmpa(&a->addr, &b->addr);
+
+ if (result == 0)
{
- result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
- (const GBinSymbol *[]) { b->symbol });
- if (result != 0) goto gtoc_done;
+ if (a->symbol == NULL && b->symbol != NULL)
+ result = -1;
+
+ else if (a->symbol != NULL && b->symbol == NULL)
+ result = 1;
+
+ else if (a->symbol != NULL && b->symbol != NULL)
+ result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
+ (const GBinSymbol *[]) { b->symbol });
+
}
- if (a->diff < b->diff)
+ if (result == 0)
+ result = sort_uint64_t(a->diff, b->diff);
+
+ if (result == 0)
{
- result = -1;
- goto gtoc_done;
+ class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
}
- else if (a->diff > b->diff)
+
+ if (lock)
{
- result = 1;
- goto gtoc_done;
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
}
- result = 0;
-
- gtoc_done:
-
return result;
}
@@ -296,6 +317,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
vmpa2t tmp; /* Coquille vide pour argument */
VMPA_BUFFER(value); /* Adresse brute à imprimer */
size_t len; /* Taille de l'élément inséré */
+ MemoryDataSize size; /* Taille retenue */
label = g_binary_symbol_get_label(operand->symbol);
@@ -322,7 +344,9 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
}
else
{
- vmpa2_to_string(&operand->addr, operand->size, value, &len);
+ size = g_target_operand_get_size(operand);
+
+ vmpa2_to_string(&operand->addr, size, value, &len);
g_buffer_line_append_text(line, DLC_ASSEMBLY, value, len, RTT_LABEL, G_OBJECT(operand));
@@ -355,7 +379,8 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
assert(size != MDS_UNDEFINED);
- result->size = size;
+ GET_TARGET_OP_EXTRA(result)->size = size;
+
copy_vmpa(&result->addr, addr);
return G_ARCH_OPERAND(result);
@@ -363,6 +388,9 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
}
+#ifdef INCLUDE_GTK_SUPPORT
+
+
/******************************************************************************
* *
* Paramètres : operand = opérande à consulter. *
@@ -443,6 +471,9 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const
}
+#endif
+
+
/******************************************************************************
* *
* Paramètres : operand = structure dont le contenu est à consulter. *
@@ -457,7 +488,18 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const
MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)
{
- return operand->size;
+ MemoryDataSize result; /* Taille à retourner */
+ tarop_extra_data_t *extra; /* Données insérées à consulter*/
+
+ extra = GET_TARGET_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extra->size;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
}
@@ -485,7 +527,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
const mrange_t *range; /* Couverture du symbole */
#endif
- operand->strict = strict;
+ if (strict)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(operand), TOF_STRICT);
+ else
+ g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), TOF_STRICT);
result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
@@ -569,20 +614,55 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d
}
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
+static guint g_target_operand_hash(const GTargetOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ tarop_extra_data_t *extra; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_TARGET_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= extra->size;
+
+ result ^= g_direct_hash(operand->symbol);
+
+ result ^= (operand->diff & 0xffffffff);
+ result ^= (operand->diff >> 32);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -590,7 +670,7 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d
* *
******************************************************************************/
-static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_target_operand_load(GTargetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
@@ -617,11 +697,11 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -629,9 +709,10 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s
* *
******************************************************************************/
-static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_target_operand_store(GTargetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
+ MemoryDataSize size; /* Taille retenue */
GArchOperand *original; /* Opérande d'origine */
/**
@@ -639,12 +720,14 @@ static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorag
* par la position physique.
*/
+ size = g_target_operand_get_size(operand);
+
if (has_virt_addr(&operand->addr))
- original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr));
+ original = g_imm_operand_new_from_value(size, get_virt_addr(&operand->addr));
else
- original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr));
+ original = g_imm_operand_new_from_value(size, get_phy_addr(&operand->addr));
- result = g_arch_operand_store(original, storage, pbuf);
+ result = g_object_storage_pack_object(storage, "operands", G_SERIALIZABLE_OBJECT(original), pbuf);
g_object_unref(G_OBJECT(original));
diff --git a/src/arch/operands/target.h b/src/arch/operands/target.h
index 8810efa..40db610 100644
--- a/src/arch/operands/target.h
+++ b/src/arch/operands/target.h
@@ -35,6 +35,14 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _TargetOpFlag
+{
+ TOF_STRICT = AOF_USER_FLAG(0), /* Résolution stricte */
+
+} TargetOpFlag;
+
+
#define G_TYPE_TARGET_OPERAND g_target_operand_get_type()
#define G_TARGET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGET_OPERAND, GTargetOperand))
#define G_IS_TARGET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGET_OPERAND))
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 59af6cd..56a45a4 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -35,6 +35,8 @@
#include "instruction-int.h"
#include "processor-int.h"
+#include "../analysis/db/misc/rlestr.h"
+#include "../analysis/storage/serialize-int.h"
#include "../common/sort.h"
#include "../core/logs.h"
#include "../glibext/chrysamarshal.h"
@@ -62,6 +64,9 @@ static void g_arch_processor_class_init(GArchProcessorClass *);
/* Initialise une instance de processeur d'architecture. */
static void g_arch_processor_init(GArchProcessor *);
+/* Procède à l'initialisation de l'interface de sérialisation. */
+static void g_arch_processor_serializable_init(GSerializableObjectInterface *);
+
/* Supprime toutes les références externes. */
static void g_arch_processor_dispose(GArchProcessor *);
@@ -73,10 +78,26 @@ static GProcContext *_g_arch_processor_get_context(const GArchProcessor *);
+/* ------------------ CONSERVATION DES SOUCIS DURANT LE CHARGEMENT ------------------ */
+
+
+/* Procède à la libération totale de la mémoire. */
+static void g_arch_processor_finalize_errors(GArchProcessor *);
+
+/* Charge les erreurs de chargement depuis une mémoire tampon. */
+static bool g_arch_processor_load_errors(GArchProcessor *, packed_buffer_t *);
+
+/* Sauvegarde les erreurs de chargement dans une mémoire tampon. */
+static bool g_arch_processor_store_errors(GArchProcessor *, packed_buffer_t *);
+
+
/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
+/* Procède à la libération totale de la mémoire. */
+static void g_arch_processor_finalize_coverages(GArchProcessor *);
+
/* Démarre la définition d'un nouveau groupe d'instructions. */
static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction *, size_t);
@@ -92,17 +113,35 @@ static void g_arch_processor_merge_coverages(GArchProcessor *, instr_coverage *,
/* Met à jour une série de groupes d'instructions. */
static void g_arch_processor_update_coverages(GArchProcessor *, instr_coverage *, bool);
+/* Charge les plages de couvertures depuis une mémoire tampon. */
+static bool g_arch_processor_load_coverages(GArchProcessor *, packed_buffer_t *);
+
+/* Sauvegarde les plages de couvertures dans une mémoire tampon. */
+static bool g_arch_processor_store_coverages(GArchProcessor *, packed_buffer_t *);
+
/* Recherche rapidement un indice d'instruction via une adresse. */
static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool, size_t *);
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_processor_load(GArchProcessor *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_arch_processor_store(GArchProcessor *, GObjectStorage *, packed_buffer_t *);
+
+
/* Indique le type défini pour un processeur d'architecture. */
-G_DEFINE_TYPE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_processor_serializable_init));
+
/******************************************************************************
@@ -174,6 +213,26 @@ static void g_arch_processor_init(GArchProcessor *proc)
/******************************************************************************
* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_processor_serializable_init(GSerializableObjectInterface *iface)
+{
+ iface->load = (load_serializable_object_cb)g_arch_processor_load;
+ iface->store = (store_serializable_object_cb)g_arch_processor_store;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
@@ -224,23 +283,12 @@ static void g_arch_processor_dispose(GArchProcessor *proc)
static void g_arch_processor_finalize(GArchProcessor *proc)
{
- size_t i; /* Boucle de parcours */
-
if (proc->instructions != NULL)
free(proc->instructions);
- if (proc->errors != NULL)
- {
- for (i = 0; i < proc->error_count; i++)
- if (proc->errors[i].desc != NULL)
- free(proc->errors[i].desc);
-
- free(proc->errors);
+ g_arch_processor_finalize_errors(proc);
- }
-
- if (proc->coverages != NULL)
- free(proc->coverages);
+ g_arch_processor_finalize_coverages(proc);
G_OBJECT_CLASS(g_arch_processor_parent_class)->finalize(G_OBJECT(proc));
@@ -923,6 +971,41 @@ GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, s
/******************************************************************************
* *
+* Paramètres : proc = architecture à manipuler. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_processor_finalize_errors(GArchProcessor *proc)
+{
+ size_t i; /* Boucle de parcours */
+ proc_error *error; /* Raccourci de confort */
+
+ if (proc->errors != NULL)
+ {
+ for (i = 0; i < proc->error_count; i++)
+ {
+ error = &proc->errors[i];
+
+ if (error->desc != NULL)
+ free(error->desc);
+
+ }
+
+ free(proc->errors);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture à manipuler. *
* state = nouvel état de l'accès aux erreurs relevées. *
* *
@@ -1066,6 +1149,118 @@ bool g_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessi
}
+/******************************************************************************
+* *
+* Paramètres : proc = architecture concernée par la procédure. *
+* pbuf = zone tampon à vider. *
+* *
+* Description : Charge les erreurs de chargement depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_load_errors(GArchProcessor *proc, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+ size_t i; /* Boucle de parcours */
+ proc_error *error; /* Raccourci de confort */
+ rle_string str; /* Chaîne à charger */
+
+ g_arch_processor_lock_errors(proc);
+
+ result = unpack_uleb128(&value, pbuf);
+ if (!result) goto exit;
+
+ proc->error_count = value;
+
+ proc->errors = calloc(proc->error_count, sizeof(proc_error));
+
+ for (i = 0; i < proc->error_count && result; i++)
+ {
+ error = &proc->errors[i];
+
+ result = unpack_uleb128(&value, pbuf);
+ if (!result) break;
+
+ error->type = value;
+
+ result = unpack_vmpa(&error->addr, pbuf);
+ if (!result) break;
+
+ setup_empty_rle_string(&str);
+
+ result = unpack_rle_string(&str, pbuf);
+ if (!result) break;
+
+ if (get_rle_string(&str) != NULL)
+ error->desc = strdup(get_rle_string(&str));
+
+ exit_rle_string(&str);
+
+ }
+
+ exit:
+
+ g_arch_processor_unlock_errors(proc);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture concernée par la procédure. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde les erreurs de chargement dans une mémoire tampon.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_store_errors(GArchProcessor *proc, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+ proc_error *error; /* Raccourci de confort */
+ rle_string str; /* Chaîne à conserver */
+
+ g_arch_processor_lock_errors(proc);
+
+ result = pack_uleb128((uleb128_t []){ proc->error_count }, pbuf);
+
+ for (i = 0; i < proc->error_count && result; i++)
+ {
+ error = &proc->errors[i];
+
+ result = pack_uleb128((uleb128_t []){ error->type }, pbuf);
+ if (!result) break;
+
+ result = pack_vmpa(&error->addr, pbuf);
+ if (!result) break;
+
+ init_static_rle_string(&str, error->desc);
+
+ result = pack_rle_string(&str, pbuf);
+
+ exit_rle_string(&str);
+
+ }
+
+ g_arch_processor_unlock_errors(proc);
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */
@@ -1074,6 +1269,24 @@ bool g_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessi
/******************************************************************************
* *
+* Paramètres : proc = architecture à manipuler. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_processor_finalize_coverages(GArchProcessor *proc)
+{
+ if (proc->coverages != NULL)
+ free(proc->coverages);
+
+}
+/******************************************************************************
+* *
* Paramètres : proc = architecture à comléter par la procédure. *
* first = première instruction d'un nouveau groupe. *
* start = indice de cette instruction dans l'ensemble global. *
@@ -1342,6 +1555,101 @@ static void g_arch_processor_update_coverages(GArchProcessor *proc, instr_covera
/******************************************************************************
* *
+* Paramètres : proc = architecture concernée par la procédure. *
+* pbuf = zone tampon à vider. *
+* *
+* Description : Charge les plages de couvertures depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_load_coverages(GArchProcessor *proc, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+ size_t i; /* Boucle de parcours */
+ instr_coverage *coverage; /* Raccourci de confort */
+
+ result = unpack_uleb128(&value, pbuf);
+ if (!result) goto exit;
+
+ proc->cov_allocated = value;
+ proc->cov_count = value;
+
+ proc->coverages = calloc(proc->cov_count, sizeof(instr_coverage));
+
+ for (i = 0; i < proc->cov_count && result; i++)
+ {
+ coverage = &proc->coverages[i];
+
+ result = unpack_mrange(&coverage->range, pbuf);
+ if (!result) break;
+
+ result = unpack_uleb128(&value, pbuf);
+ if (!result) break;
+
+ coverage->start = value;
+
+ result = unpack_uleb128(&value, pbuf);
+ if (!result) break;
+
+ coverage->count = value;
+
+ }
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture concernée par la procédure. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde les plages de couvertures dans une mémoire tampon.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_store_coverages(GArchProcessor *proc, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+ instr_coverage *coverage; /* Raccourci de confort */
+
+ result = pack_uleb128((uleb128_t []){ proc->cov_count }, pbuf);
+
+ for (i = 0; i < proc->error_count && result; i++)
+ {
+ coverage = &proc->coverages[i];
+
+ result = pack_mrange(&coverage->range, pbuf);
+ if (!result) break;
+
+ result = pack_uleb128((uleb128_t []){ coverage->start }, pbuf);
+ if (!result) break;
+
+ result = pack_uleb128((uleb128_t []){ coverage->count }, pbuf);
+ if (!result) break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = processeur recensant diverses instructions. *
* addr = position en mémoire ou physique à chercher. *
* *
@@ -1580,3 +1888,86 @@ instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *pr
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_load(GArchProcessor *proc, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+
+ result = unpack_uleb128(&value, pbuf);
+ if (!result) goto exit;
+
+ proc->endianness = value;
+
+
+
+
+
+
+ if (result)
+ result = g_arch_processor_load_errors(proc, pbuf);
+
+ if (result)
+ result = g_arch_processor_load_coverages(proc, pbuf);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_store(GArchProcessor *proc, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+
+ result = pack_uleb128((uleb128_t []){ proc->endianness }, pbuf);
+
+
+
+
+
+ if (result)
+ result = g_arch_processor_store_coverages(proc, pbuf);
+
+ if (result)
+ result = g_arch_processor_store_errors(proc, pbuf);
+
+ return result;
+
+}
diff --git a/src/arch/register-int.h b/src/arch/register-int.h
index a162435..f0b9af9 100644
--- a/src/arch/register-int.h
+++ b/src/arch/register-int.h
@@ -26,9 +26,7 @@
#include "register.h"
-
-
-#include "operand-int.h"
+#include "../analysis/storage/serialize-int.h"
@@ -47,11 +45,11 @@ typedef bool (* reg_is_base_pointer_fc) (const GArchRegister *);
/* Indique si le registre correspond à esp ou similaire. */
typedef bool (* reg_is_stack_pointer_fc) (const GArchRegister *);
-/* Charge un registre depuis une mémoire tampon. */
-typedef GArchRegister * (* reg_unserialize_fc) (GArchRegister *, GAsmStorage *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+typedef bool (* load_register_fc) (GArchRegister *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un registre dans une mémoire tampon. */
-typedef bool (* reg_serialize_fc) (const GArchRegister *, GAsmStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+typedef bool (* store_register_fc) (GArchRegister *, GObjectStorage *, packed_buffer_t *);
/* Représentation d'un registre (instance) */
@@ -72,8 +70,8 @@ struct _GArchRegisterClass
reg_is_base_pointer_fc is_bp; /* Correspondance avec ebp */
reg_is_stack_pointer_fc is_sp; /* Correspondance avec esp */
- reg_unserialize_fc unserialize; /* Chargement depuis un tampon */
- reg_serialize_fc serialize; /* Conservation dans un tampon */
+ load_register_fc load; /* Chargement depuis un tampon */
+ store_register_fc store; /* Conservation dans un tampon */
};
diff --git a/src/arch/register.c b/src/arch/register.c
index 740a06b..f487419 100644
--- a/src/arch/register.c
+++ b/src/arch/register.c
@@ -25,7 +25,6 @@
#include "register-int.h"
-#include "storage.h"
@@ -38,6 +37,9 @@ static void g_arch_register_class_init(GArchRegisterClass *);
/* Initialise une instance de registre. */
static void g_arch_register_init(GArchRegister *);
+/* Procède à l'initialisation de l'interface de sérialisation. */
+static void g_arch_register_serializable_init(GSerializableObjectInterface *);
+
/* Supprime toutes les références externes. */
static void g_arch_register_dispose(GArchRegister *);
@@ -46,14 +48,20 @@ static void g_arch_register_finalize(GArchRegister *);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool _g_arch_register_load(GArchRegister *, GObjectStorage *, packed_buffer_t *);
-/* Charge un registre depuis une mémoire tampon. */
-static GArchRegister *g_arch_register_unserialize(GArchRegister *, GAsmStorage *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_register_load(GArchRegister *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un registre dans une mémoire tampon. */
-static bool g_arch_register_serialize(const GArchRegister *, GAsmStorage *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool _g_arch_register_store(GArchRegister *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_arch_register_store(GArchRegister *, GObjectStorage *, packed_buffer_t *);
@@ -63,7 +71,8 @@ static bool g_arch_register_serialize(const GArchRegister *, GAsmStorage *, pack
/* Indique le type défini pour une représentation d'un registre. */
-G_DEFINE_TYPE(GArchRegister, g_arch_register, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GArchRegister, g_arch_register, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_register_serializable_init));
/******************************************************************************
@@ -87,8 +96,8 @@ static void g_arch_register_class_init(GArchRegisterClass *klass)
object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_register_dispose;
object->finalize = (GObjectFinalizeFunc)g_arch_register_finalize;
- klass->unserialize = (reg_unserialize_fc)g_arch_register_unserialize;
- klass->serialize = (reg_serialize_fc)g_arch_register_serialize;
+ klass->load = (load_register_fc)_g_arch_register_load;
+ klass->store = (store_register_fc)_g_arch_register_store;
}
@@ -113,6 +122,26 @@ static void g_arch_register_init(GArchRegister *reg)
/******************************************************************************
* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_register_serializable_init(GSerializableObjectInterface *iface)
+{
+ iface->load = (load_serializable_object_cb)g_arch_register_load;
+ iface->store = (store_serializable_object_cb)g_arch_register_store;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : reg = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
@@ -262,17 +291,17 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *reg)
/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES REGISTRES */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : reg = registre d'architecture à constituer. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : reg = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Charge un registre depuis une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -280,11 +309,11 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *reg)
* *
******************************************************************************/
-static GArchRegister *g_arch_register_unserialize(GArchRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool _g_arch_register_load(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)
{
- GArchRegister *result; /* Instance à retourner */
+ bool result; /* Bilan à retourner */
- result = reg;
+ result = true;
return result;
@@ -293,36 +322,26 @@ static GArchRegister *g_arch_register_unserialize(GArchRegister *reg, GAsmStorag
/******************************************************************************
* *
-* Paramètres : storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : reg = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Charge un registre depuis une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
-* Retour : Registre d'architecture constitué ou NULL en cas d'échec. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_arch_register_load(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)
{
- GArchRegister *result; /* Instance à retourner */
- GArchRegister *dummy; /* Patron du type de registre */
-
- dummy = G_ARCH_REGISTER(g_asm_storage_create_object(storage, pbuf));
-
- if (dummy != NULL)
- {
- result = G_ARCH_REGISTER_GET_CLASS(dummy)->unserialize(dummy, storage, pbuf);
-
- /* Si personne ne l'a fait avant... */
- if (result != NULL)
- g_object_unref(G_OBJECT(dummy));
+ bool result; /* Bilan à retourner */
+ GArchRegisterClass *class; /* Classe à activer */
- }
+ class = G_ARCH_REGISTER_GET_CLASS(reg);
- else
- result = NULL;
+ result = class->load(reg, storage, pbuf);
return result;
@@ -331,11 +350,11 @@ GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer_t *pbuf)
/******************************************************************************
* *
-* Paramètres : reg = registre d'architecture à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : reg = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un registre dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -343,7 +362,7 @@ GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer_t *pbuf)
* *
******************************************************************************/
-static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool _g_arch_register_store(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
@@ -356,11 +375,11 @@ static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *sto
/******************************************************************************
* *
-* Paramètres : reg = registre d'architecture à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
+* Paramètres : reg = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Sauvegarde un registre dans une mémoire tampon. *
+* Description : Sauvegarde un contenu dans une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -368,14 +387,14 @@ static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *sto
* *
******************************************************************************/
-bool g_arch_register_store(const GArchRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_arch_register_store(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
+ GArchRegisterClass *class; /* Classe à activer */
- result = g_asm_storage_store_object_gtype(storage, G_OBJECT(reg), pbuf);
+ class = G_ARCH_REGISTER_GET_CLASS(reg);
- if (result)
- result = G_ARCH_REGISTER_GET_CLASS(reg)->serialize(reg, storage, pbuf);
+ result = class->store(reg, storage, pbuf);
return result;
diff --git a/src/arch/register.h b/src/arch/register.h
index 36bd9d9..0265a73 100644
--- a/src/arch/register.h
+++ b/src/arch/register.h
@@ -71,19 +71,4 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */
-
-
-/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */
-typedef struct _GAsmStorage GAsmStorage;
-
-
-/* Charge un registre depuis une mémoire tampon. */
-GArchRegister *g_arch_register_load(GAsmStorage *, packed_buffer_t *);
-
-/* Sauvegarde un registre dans une mémoire tampon. */
-bool g_arch_register_store(const GArchRegister *, GAsmStorage *, packed_buffer_t *);
-
-
-
#endif /* _ARCH_REGISTER_H */
diff --git a/src/arch/storage.c b/src/arch/storage.c
index 41fa602..73521df 100644
--- a/src/arch/storage.c
+++ b/src/arch/storage.c
@@ -486,7 +486,7 @@ static void g_ins_caching_process_store(GInsCaching *caching, GtkStatusStack *st
instr = g_arch_processor_get_instruction(proc, i);
- caching->status = g_arch_instruction_store(instr, storage, &pbuf);
+ caching->status = false;//g_arch_instruction_store__old(instr, storage, &pbuf);
if (caching->status)
caching->status = g_asm_storage_store_instruction_data(storage, &pbuf, &pos);
@@ -1544,7 +1544,7 @@ GArchInstruction *g_asm_storage_get_instruction_at(GAsmStorage *storage, GBinFor
status = g_asm_storage_load_instruction_data(storage, pbuf, target);
if (status)
- storage->collected[index] = g_arch_instruction_load(storage, format, pbuf);
+ storage->collected[index] = NULL;//g_arch_instruction_load__old(storage, format, pbuf);
if (storage->collected[index] != NULL)
{
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index f353ebd..4f35ebe 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -156,6 +156,62 @@ bool store_vmpa(const vmpa2t *, const char *, bound_value **, size_t *);
+/* ------------------------ DEFINITION DE POSITION AVEC BITS ------------------------ */
+
+
+/* Adresse mémoire ou position physique */
+typedef struct _ext_vmpa_t
+{
+ vmpa2t base; /* Vision macroscopique */
+
+ uint8_t consumed_extra_bits; /* Avancée supplémentaire */
+
+} ext_vmpa_t;
+
+
+#define init_evmpa_from_vmpa(d, s) \
+ do \
+ { \
+ copy_vmpa(&(d)->base, (s)); \
+ (d)->consumed_extra_bits = 0; \
+ } \
+ while (0)
+
+#define copy_evmpa(d, s) \
+ do \
+ { \
+ copy_vmpa(&(d)->base, &(s)->base); \
+ (d)->consumed_extra_bits = (s)->consumed_extra_bits; \
+ } \
+ while (0)
+
+#define advance_evmpa_bits(a, q) \
+ do \
+ { \
+ uint8_t __sum; \
+ __sum = (a)->consumed_extra_bits + q; \
+ if (__sum > 8) \
+ { \
+ advance_vmpa(&(a)->base, __sum / 8); \
+ (a)->consumed_extra_bits = __sum % 8; \
+ } \
+ else \
+ (a)->consumed_extra_bits = __sum; \
+ } \
+ while (0)
+
+#define align_evmpa_on_byte(a) \
+ do \
+ { \
+ if ((a)->consumed_extra_bits > 0) \
+ { \
+ advance_vmpa(&(a)->base, 1); \
+ (a)->consumed_extra_bits = 0; \
+ } \
+ } \
+ while (0);
+
+
/* ------------------------ AIDES FONCTIONNELLES AUXILIAIRES ------------------------ */