summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/operands
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/arm/v7/operands')
-rw-r--r--plugins/arm/v7/operands/Makefile.am27
-rw-r--r--plugins/arm/v7/operands/estate.c178
-rw-r--r--plugins/arm/v7/operands/estate.h11
-rw-r--r--plugins/arm/v7/operands/iflags.c179
-rw-r--r--plugins/arm/v7/operands/iflags.h10
-rw-r--r--plugins/arm/v7/operands/it.c333
-rw-r--r--plugins/arm/v7/operands/limitation.c271
-rw-r--r--plugins/arm/v7/operands/maccess.c530
-rw-r--r--plugins/arm/v7/operands/maccess.h9
-rw-r--r--plugins/arm/v7/operands/offset.c280
-rw-r--r--plugins/arm/v7/operands/offset.h11
-rw-r--r--plugins/arm/v7/operands/register.c279
-rw-r--r--plugins/arm/v7/operands/register.h12
-rw-r--r--plugins/arm/v7/operands/reglist.c331
-rw-r--r--plugins/arm/v7/operands/rotation.c231
-rw-r--r--plugins/arm/v7/operands/shift.c335
16 files changed, 1673 insertions, 1354 deletions
diff --git a/plugins/arm/v7/operands/Makefile.am b/plugins/arm/v7/operands/Makefile.am
index 31f6a8a..fa7ab8b 100644
--- a/plugins/arm/v7/operands/Makefile.am
+++ b/plugins/arm/v7/operands/Makefile.am
@@ -1,26 +1,21 @@
noinst_LTLIBRARIES = libarmv7operands.la
-libarmv7operands_la_SOURCES = \
- estate.h estate.c \
- iflags.h iflags.c \
- it.h it.c \
- limitation.h limitation.c \
- maccess.h maccess.c \
- offset.h offset.c \
- register.h register.c \
- reglist.h reglist.c \
- rotation.h rotation.c \
+libarmv7operands_la_SOURCES = \
+ estate.h estate.c \
+ iflags.h iflags.c \
+ it.h it.c \
+ limitation.h limitation.c \
+ maccess.h maccess.c \
+ offset.h offset.c \
+ register.h register.c \
+ reglist.h reglist.c \
+ rotation.h rotation.c \
shift.h shift.c
-libarmv7operands_la_LIBADD =
+libarmv7operands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
devdir = $(includedir)/chrysalide/$(subdir)
dev_HEADERS = $(libarmv7operands_la_SOURCES:%c=)
-
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/arm/v7/operands/estate.c b/plugins/arm/v7/operands/estate.c
index a76b464..accde6d 100644
--- a/plugins/arm/v7/operands/estate.c
+++ b/plugins/arm/v7/operands/estate.c
@@ -24,18 +24,20 @@
#include "estate.h"
-#include <arch/operand-int.h>
-#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
/* Définition d'un opérande affichant le choix d'un boutisme (instance) */
struct _GArmV7EndianOperand
{
- GArchOperand parent; /* Instance parente */
-
- bool big; /* Grand boutisme à afficher ? */
+ GArmV7Operand parent; /* Instance parente */
};
@@ -43,7 +45,7 @@ struct _GArmV7EndianOperand
/* Définition d'un opérande affichant le choix d'un boutisme (classe) */
struct _GArmV7EndianOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -60,27 +62,23 @@ static void g_armv7_endian_operand_dispose(GArmV7EndianOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *);
-/* Compare un opérande avec un autre. */
-static int g_armv7_endian_operand_compare(const GArmV7EndianOperand *, const GArmV7EndianOperand *);
-/* Traduit un opérande en version humainement lisible. */
-static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *);
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
-
+/* Traduit un opérande en version humainement lisible. */
+static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_endian_operand_unserialize(GArmV7EndianOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour une endian de domaine et d'accès. */
-G_DEFINE_TYPE(GArmV7EndianOperand, g_armv7_endian_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7EndianOperand, g_armv7_endian_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -106,12 +104,8 @@ static void g_armv7_endian_operand_class_init(GArmV7EndianOperandClass *klass)
object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_endian_operand_dispose;
object->finalize = (GObjectFinalizeFunc)g_armv7_endian_operand_finalize;
- operand->compare = (operand_compare_fc)g_armv7_endian_operand_compare;
operand->print = (operand_print_fc)g_armv7_endian_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_endian_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_endian_operand_serialize;
-
}
@@ -173,53 +167,6 @@ static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *operand)
/******************************************************************************
* *
-* 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_armv7_endian_operand_compare(const GArmV7EndianOperand *a, const GArmV7EndianOperand *b)
-{
- int result; /* Bilan à faire remonter */
-
- result = sort_boolean(a->big, b->big);
-
- 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_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line)
-{
- if (operand->big)
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL);
- else
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL);
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : big = indication sur le boutisme à représenter. *
* *
* Description : Crée une représentation de boutisme ARMv7. *
@@ -236,107 +183,38 @@ GArchOperand *g_armv7_endian_operand_new(bool big)
result = g_object_new(G_TYPE_ARMV7_ENDIAN_OPERAND, NULL);
- result->big = big;
+ if (big)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7ESOF_BIG);
return G_ARCH_OPERAND(result);
}
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Indique le type de boutisme représenté. *
-* *
-* Retour : Type de boutisme. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *operand)
-{
- return operand->big;
-
-}
-
-
/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* 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_armv7_endian_operand_unserialize(GArmV7EndianOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t big; /* Grand boutisme à afficher ? */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class);
-
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &big, sizeof(uint8_t), false);
-
- if (result)
- operand->big = (big == 1 ? true : false);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = opérande à traiter. *
+* line = ligne tampon où imprimer l'opérande donné. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Traduit un opérande en version humainement lisible. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t big; /* Grand boutisme à afficher ? */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class);
-
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- big = (operand->big ? 1 : 0);
- result = extend_packed_buffer(pbuf, &big, sizeof(uint8_t), false);
- }
-
- return result;
+ if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ESOF_BIG))
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL);
+ else
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL);
}
diff --git a/plugins/arm/v7/operands/estate.h b/plugins/arm/v7/operands/estate.h
index d049357..9b75f9c 100644
--- a/plugins/arm/v7/operands/estate.h
+++ b/plugins/arm/v7/operands/estate.h
@@ -32,6 +32,14 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _A7EStateOpFlag
+{
+ A7ESOF_BIG = AOF_USER_FLAG(0), /* Grand boutisme à afficher ? */
+
+} A7EStateOpFlag;
+
+
#define G_TYPE_ARMV7_ENDIAN_OPERAND g_armv7_endian_operand_get_type()
#define G_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperand))
#define G_IS_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_ENDIAN_OPERAND))
@@ -53,9 +61,6 @@ GType g_armv7_endian_operand_get_type(void);
/* Crée une représentation de boutisme ARMv7. */
GArchOperand *g_armv7_endian_operand_new(bool);
-/* Indique le type de boutisme représenté. */
-bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *);
-
#endif /* _PLUGINS_ARM_V7_OPERANDS_ESTATE_H */
diff --git a/plugins/arm/v7/operands/iflags.c b/plugins/arm/v7/operands/iflags.c
index 019fd21..f0a5e07 100644
--- a/plugins/arm/v7/operands/iflags.c
+++ b/plugins/arm/v7/operands/iflags.c
@@ -24,19 +24,20 @@
#include "iflags.h"
-#include <arch/operand-int.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
/* Définition d'un opérande précisant un masque d'interruption ARMv7 (instance) */
struct _GArmV7IFlagsOperand
{
- GArchOperand parent; /* Instance parente */
-
- bool abort_bit; /* Interruption d'arrêt async. */
- bool irq_bit; /* Interruption IRQ */
- bool fiq_bit; /* Interruption FIQ */
+ GArmV7Operand parent; /* Instance parente */
};
@@ -44,7 +45,7 @@ struct _GArmV7IFlagsOperand
/* Définition d'un opérande précisant un masque d'interruption ARMv7 (classe) */
struct _GArmV7IFlagsOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -61,24 +62,22 @@ static void g_armv7_iflags_operand_dispose(GArmV7IFlagsOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_iflags_operand_finalize(GArmV7IFlagsOperand *);
-/* Traduit un opérande en version humainement lisible. */
-static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLine *);
-
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Traduit un opérande en version humainement lisible. */
+static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLine *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_iflags_operand_unserialize(GArmV7IFlagsOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_iflags_operand_serialize(const GArmV7IFlagsOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour un opérande de masque d'interruption ARMv7. */
-G_DEFINE_TYPE(GArmV7IFlagsOperand, g_armv7_iflags_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7IFlagsOperand, g_armv7_iflags_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -107,9 +106,6 @@ static void g_armv7_iflags_operand_class_init(GArmV7IFlagsOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_iflags_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_iflags_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_iflags_operand_serialize;
-
}
@@ -127,9 +123,6 @@ static void g_armv7_iflags_operand_class_init(GArmV7IFlagsOperandClass *klass)
static void g_armv7_iflags_operand_init(GArmV7IFlagsOperand *operand)
{
- operand->abort_bit = false;
- operand->irq_bit = false;
- operand->fiq_bit = false;
}
@@ -174,33 +167,6 @@ static void g_armv7_iflags_operand_finalize(GArmV7IFlagsOperand *operand)
/******************************************************************************
* *
-* 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_armv7_iflags_operand_print(const GArmV7IFlagsOperand *operand, GBufferLine *line)
-{
- if (operand->abort_bit)
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "A", 1, RTT_REGISTER, NULL);
-
- if (operand->irq_bit)
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "I", 1, RTT_REGISTER, NULL);
-
- if (operand->fiq_bit)
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "F", 1, RTT_REGISTER, NULL);
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : a = bit d'arrêt asynchrone. *
* i = bit d'interruption IRQ. *
* f = bit d'interruption FIQ. *
@@ -219,119 +185,48 @@ GArchOperand *g_armv7_iflags_operand_new(bool a, bool i, bool f)
result = g_object_new(G_TYPE_ARMV7_IFLAGS_OPERAND, NULL);
- result->abort_bit = a;
- result->irq_bit = i;
- result->fiq_bit = f;
+ if (a)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_ABORT);
+
+ if (i)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_IRQ);
+
+ if (f)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_FIQ);
return G_ARCH_OPERAND(result);
}
+
/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* 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_armv7_iflags_operand_unserialize(GArmV7IFlagsOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_iflags_operand_parent_class);
-
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- operand->abort_bit = (boolean == 1 ? true : false);
-
- }
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- operand->irq_bit = (boolean == 1 ? true : false);
-
- }
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- operand->fiq_bit = (boolean == 1 ? true : false);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = opérande à traiter. *
+* line = ligne tampon où imprimer l'opérande donné. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Traduit un opérande en version humainement lisible. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_iflags_operand_serialize(const GArmV7IFlagsOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *operand, GBufferLine *line)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_iflags_operand_parent_class);
-
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- boolean = (operand->abort_bit ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
-
- if (result)
- {
- boolean = (operand->irq_bit ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_ABORT))
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "A", 1, RTT_REGISTER, NULL);
- if (result)
- {
- boolean = (operand->fiq_bit ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_IRQ))
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "I", 1, RTT_REGISTER, NULL);
- return result;
+ if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_FIQ))
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "F", 1, RTT_REGISTER, NULL);
}
diff --git a/plugins/arm/v7/operands/iflags.h b/plugins/arm/v7/operands/iflags.h
index c0155a1..a198c85 100644
--- a/plugins/arm/v7/operands/iflags.h
+++ b/plugins/arm/v7/operands/iflags.h
@@ -33,6 +33,16 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _A7IFlagsOpFlag
+{
+ A7IFOF_ABORT = AOF_USER_FLAG(0), /* Interruption d'arrêt async. */
+ A7IFOF_IRQ = AOF_USER_FLAG(1), /* Interruption IRQ */
+ A7IFOF_FIQ = AOF_USER_FLAG(2), /* Interruption FIQ */
+
+} A7IFlagsOpFlag;
+
+
#define G_TYPE_ARMV7_IFLAGS_OPERAND g_armv7_iflags_operand_get_type()
#define G_ARMV7_IFLAGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_IFLAGS_OPERAND, GArmV7IFlagsOperand))
#define G_IS_ARMV7_IFLAGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_IFLAGS_OPERAND))
diff --git a/plugins/arm/v7/operands/it.c b/plugins/arm/v7/operands/it.c
index 6fab598..46e1b4c 100644
--- a/plugins/arm/v7/operands/it.c
+++ b/plugins/arm/v7/operands/it.c
@@ -27,27 +27,55 @@
#include <assert.h>
-#include <arch/operand-int.h>
#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
-/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */
-struct _GArmV7ITCondOperand
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _a7itcop_extra_data_t
{
- GArchOperand parent; /* Instance parente */
+ operand_extra_data_t parent; /* A laisser en premier */
ArmCondCode firstcond; /* Condition première */
uint8_t mask; /* Masque de l'interprétation */
+} a7itcop_extra_data_t;
+
+
+/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */
+struct _GArmV7ITCondOperand
+{
+ GArmV7Operand parent; /* Instance parente */
+
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_ITCOND_OP_EXTRA(op) ((a7itcop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_ARMV7_ITCOND_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7itcop_extra_data_t)
+
+#endif
+
+
/* Définition d'un opérande organisant l'application d'une instruction IT (classe) */
struct _GArmV7ITCondOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -64,27 +92,35 @@ static void g_armv7_itcond_operand_dispose(GArmV7ITCondOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GArmV7ITCondOperand *);
+static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GArmV7ITCondOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_itcond_operand_hash(const GArmV7ITCondOperand *, bool);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_itcond_operand_serialize(const GArmV7ITCondOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour l'application d'une instruction IT. */
-G_DEFINE_TYPE(GArmV7ITCondOperand, g_armv7_itcond_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7ITCondOperand, g_armv7_itcond_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -105,16 +141,20 @@ static void g_armv7_itcond_operand_class_init(GArmV7ITCondOperandClass *klass)
GArchOperandClass *operand; /* Version de classe parente */
object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_itcond_operand_dispose;
object->finalize = (GObjectFinalizeFunc)g_armv7_itcond_operand_finalize;
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
operand->compare = (operand_compare_fc)g_armv7_itcond_operand_compare;
+
operand->print = (operand_print_fc)g_armv7_itcond_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_itcond_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_itcond_operand_serialize;
+ operand->hash = (operand_hash_fc)g_armv7_itcond_operand_hash;
+
+ operand->load = (load_operand_fc)g_armv7_itcond_operand_load;
+ operand->store = (store_operand_fc)g_armv7_itcond_operand_store;
}
@@ -177,8 +217,100 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : firstcond = valeur brute de la condition d'exécution. *
+* mask = masque d'interprétation pour l'instruction. *
+* *
+* Description : Crée un opérande lié à une instruction IT. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask)
+{
+ GArmV7ITCondOperand *result; /* Structure à retourner */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
+
+ if (firstcond > ACC_NV)
+ return NULL;
+
+ result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL);
+
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(result);
+
+ extra->firstcond = firstcond;
+ extra->mask = mask;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Fournit la condition associée à l'opérande. *
+* *
+* Retour : Condition classique pour ARMv7. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand)
+{
+ ArmCondCode result; /* Condition à renvoyer */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ result = extra->firstcond;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Fournit le masque d'interprétation de la condition. *
+* *
+* Retour : Masque de bits. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand)
+{
+ uint8_t result; /* Valeur à retourner */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ result = extra->mask;
+
+ 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. *
* *
@@ -188,14 +320,38 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand)
* *
******************************************************************************/
-static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b)
+static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
+ a7itcop_extra_data_t *ea; /* Données insérées à consulter*/
+ a7itcop_extra_data_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ ea = GET_ARMV7_ITCOND_OP_EXTRA(a);
+ eb = GET_ARMV7_ITCOND_OP_EXTRA(b);
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
+
+ result = sort_boolean(ea->firstcond, eb->firstcond);
- result = sort_boolean(a->firstcond, b->firstcond);
+ if (result == 0)
+ result = sort_unsigned_long(ea->mask, eb->mask);
if (result == 0)
- result = sort_unsigned_long(a->mask, b->mask);
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_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;
@@ -217,9 +373,12 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GA
static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBufferLine *line)
{
+ a7itcop_extra_data_t *extra; /* Données insérées à consulter*/
const char *kw; /* Mot clef à imprimer */
- switch (operand->firstcond)
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ switch (extra->firstcond)
{
case ACC_EQ: kw = "EQ"; break;
case ACC_NE: kw = "NE"; break;
@@ -253,51 +412,37 @@ static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBu
/******************************************************************************
* *
-* Paramètres : firstcond = valeur brute de la condition d'exécution. *
-* mask = masque d'interprétation pour l'instruction. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Crée un opérande lié à une instruction IT. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Opérande mis en place. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask)
+static guint g_armv7_itcond_operand_hash(const GArmV7ITCondOperand *operand, bool lock)
{
- GArmV7ITCondOperand *result; /* Structure à retourner */
+ guint result; /* Valeur à retourner */
+ a7itcop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
- if (firstcond > ACC_NV)
- return NULL;
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
- result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL);
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- result->firstcond = firstcond;
- result->mask = mask;
+ class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
- return G_ARCH_OPERAND(result);
+ result ^= extra->firstcond;
-}
+ result ^= extra->mask;
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Fournit la condition associée à l'opérande. *
-* *
-* Retour : Condition classique pour ARMv7. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand)
-{
- ArmCondCode result; /* Condition à renvoyer */
-
- result = operand->firstcond;
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -306,41 +451,11 @@ ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *oper
/******************************************************************************
* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Fournit le masque d'interprétation de la condition. *
-* *
-* Retour : Masque de bits. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand)
-{
- uint8_t result; /* Valeur à retourner */
-
- result = operand->mask;
-
- 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. *
-* *
-* 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. *
* *
@@ -348,20 +463,30 @@ uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand)
* *
******************************************************************************/
-static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_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 = extract_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true);
+ {
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
- if (result)
- result = extract_packed_buffer(pbuf, &operand->mask, sizeof(uint8_t), false);
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->firstcond = value;
+
+ if (result)
+ result = extract_packed_buffer(pbuf, &extra->mask, sizeof(uint8_t), false);
+
+ }
return result;
@@ -370,11 +495,11 @@ static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAs
/******************************************************************************
* *
-* 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. *
* *
@@ -382,20 +507,26 @@ static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAs
* *
******************************************************************************/
-static bool g_armv7_itcond_operand_serialize(const GArmV7ITCondOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extend_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true);
+ {
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
- if (result)
- result = extend_packed_buffer(pbuf, &operand->mask, sizeof(uint8_t), false);
+ result = pack_uleb128((uleb128_t []){ extra->firstcond }, pbuf);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &extra->mask, sizeof(uint8_t), false);
+
+ }
return result;
diff --git a/plugins/arm/v7/operands/limitation.c b/plugins/arm/v7/operands/limitation.c
index 0d29545..d9e11cf 100644
--- a/plugins/arm/v7/operands/limitation.c
+++ b/plugins/arm/v7/operands/limitation.c
@@ -26,28 +26,57 @@
#include <arch/operand-int.h>
#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
-/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */
-struct _GArmV7LimitationOperand
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _a7limop_extra_data_t
{
- GArchOperand parent; /* Instance parente */
+ operand_extra_data_t parent; /* A laisser en premier */
BarrierLimitationType type; /* Type de limitation */
+} a7limop_extra_data_t;
+
+
+/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */
+struct _GArmV7LimitationOperand
+{
+ GArmV7Operand parent; /* Instance parente */
+
};
/* Définition d'un opérande déterminant une limitation de domaine et d'accès (classe) */
struct _GArmV7LimitationOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_LIMITATION_OP_EXTRA(op) ((a7limop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_ARMV7_LIMITATION_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7limop_extra_data_t)
+
+#endif
+
+
/* Initialise la classe des co-processeurs ARM. */
static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass *);
@@ -60,27 +89,35 @@ static void g_armv7_limitation_operand_dispose(GArmV7LimitationOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, const GArmV7LimitationOperand *);
+static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, const GArmV7LimitationOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_limitation_operand_hash(const GArmV7LimitationOperand *, bool);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *, GObjectStorage *, packed_buffer_t *);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
-
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *, GObjectStorage *, packed_buffer_t *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour une limitation de domaine et d'accès. */
-G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -107,10 +144,13 @@ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass *
object->finalize = (GObjectFinalizeFunc)g_armv7_limitation_operand_finalize;
operand->compare = (operand_compare_fc)g_armv7_limitation_operand_compare;
+
operand->print = (operand_print_fc)g_armv7_limitation_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_limitation_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_limitation_operand_serialize;
+ operand->hash = (operand_hash_fc)g_armv7_limitation_operand_hash;
+
+ operand->load = (load_operand_fc)g_armv7_limitation_operand_load;
+ operand->store = (store_operand_fc)g_armv7_limitation_operand_store;
}
@@ -173,8 +213,77 @@ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : raw = valeur brute de la limitation à considérer. *
+* *
+* Description : Crée une représentation d'une limitation pour barrière. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_limitation_operand_new(uint8_t raw)
+{
+ GArmV7LimitationOperand *result; /* Structure à retourner */
+ a7limop_extra_data_t *extra; /* Données insérées à modifier */
+
+ result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL);
+
+ extra = GET_ARMV7_LIMITATION_OP_EXTRA(result);
+
+ if (raw < 0b0010 || raw > 0b1111)
+ extra->type = BLT_RESERVED;
+
+ else
+ extra->type = raw;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Indique le type de limitation représentée. *
+* *
+* Retour : Type de limitation d'accès et de domaine. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand)
+{
+ BarrierLimitationType result; /* Type à retourner */
+ a7limop_extra_data_t *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extra->type;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ 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. *
* *
@@ -184,11 +293,35 @@ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand
* *
******************************************************************************/
-static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, const GArmV7LimitationOperand *b)
+static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, const GArmV7LimitationOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
+ a7limop_extra_data_t *ea; /* Données insérées à consulter*/
+ a7limop_extra_data_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = sort_unsigned_long(a->type, b->type);
+ ea = GET_ARMV7_LIMITATION_OP_EXTRA(a);
+ eb = GET_ARMV7_LIMITATION_OP_EXTRA(b);
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
+
+ result = sort_unsigned_long(ea->type, eb->type);
+
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_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;
@@ -210,7 +343,11 @@ static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a,
static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *operand, GBufferLine *line)
{
- switch (operand->type)
+ BarrierLimitationType type; /* Type porté par l'opérande */
+
+ type = g_armv7_limitation_operand_get_value(operand);
+
+ switch (type)
{
case BLT_SY:
g_buffer_line_append_text(line, DLC_ASSEMBLY, "SY", 2, RTT_KEY_WORD, NULL);
@@ -255,66 +392,48 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *oper
/******************************************************************************
* *
-* Paramètres : raw = valeur brute de la limitation à considérer. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Crée une représentation d'une limitation pour barrière. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Opérande mis en place. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_armv7_limitation_operand_new(uint8_t raw)
+static guint g_armv7_limitation_operand_hash(const GArmV7LimitationOperand *operand, bool lock)
{
- GArmV7LimitationOperand *result; /* Structure à retourner */
+ guint result; /* Valeur à retourner */
+ a7limop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL);
+ extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
- if (raw < 0b0010 || raw > 0b1111)
- result->type = BLT_RESERVED;
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- else
- result->type = raw;
+ class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
- return G_ARCH_OPERAND(result);
+ result ^= extra->type;
-}
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Indique le type de limitation représentée. *
-* *
-* Retour : Type de limitation d'accès et de domaine. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand)
-{
- return operand->type;
+ 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. *
* *
@@ -322,17 +441,27 @@ BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7Limitatio
* *
******************************************************************************/
-static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ a7limop_extra_data_t *extra; /* Données insérées à modifier */
+ uleb128_t value; /* Valeur ULEB128 à charger */
parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_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 = extract_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true);
+ {
+ extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
+
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->type = value;
+
+ }
return result;
@@ -341,11 +470,11 @@ static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *oper
/******************************************************************************
* *
-* 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. *
* *
@@ -353,17 +482,23 @@ static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *oper
* *
******************************************************************************/
-static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ a7limop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extend_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true);
+ {
+ extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
+
+ result = pack_uleb128((uleb128_t []){ extra->type }, pbuf);
+
+ }
return result;
diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c
index 07f38a6..77d031f 100644
--- a/plugins/arm/v7/operands/maccess.c
+++ b/plugins/arm/v7/operands/maccess.c
@@ -29,24 +29,26 @@
#include <stdlib.h>
-#include <arch/operand-int.h>
#include <common/cpp.h>
-#include <common/sort.h>
+#include <core/columns.h>
#include <core/logs.h>
-#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
/* Définition d'un opérande offrant un accès à la mémoire depuis une base (instance) */
struct _GArmV7MAccessOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
GArchOperand *base; /* Base de l'accès en mémoire */
GArchOperand *offset; /* Décalage pour l'adresse */
GArchOperand *shift; /* Décalage supplémentaire ? */
- bool post_indexed; /* Position du décalage */
- bool write_back; /* Mise à jour de la base */
};
@@ -54,7 +56,7 @@ struct _GArmV7MAccessOperand
/* Définition d'un opérande offrant un accès à la mémoire depuis une base (classe) */
struct _GArmV7MAccessOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -71,8 +73,13 @@ static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *);
+static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *, bool);
/* Détermine le chemin conduisant à un opérande interne. */
static char *g_armv7_maccess_operand_find_inner_operand_path(const GArmV7MAccessOperand *, const GArchOperand *);
@@ -83,21 +90,24 @@ static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const G
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *, GBufferLine *);
+/* Fournit une liste de candidats embarqués par un candidat. */
+static GArchOperand **g_armv7_maccess_operand_list_inner_instances(const GArmV7MAccessOperand *, size_t *);
+/* Met à jour une liste de candidats embarqués par un candidat. */
+static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand *, GArchOperand **, size_t);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *, bool);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour un accès à la mémoire depuis une base. */
-G_DEFINE_TYPE(GArmV7MAccessOperand, g_armv7_maccess_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7MAccessOperand, g_armv7_maccess_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -130,8 +140,12 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_maccess_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_maccess_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_maccess_operand_serialize;
+ operand->list_inner = (operand_list_inners_fc)g_armv7_maccess_operand_list_inner_instances;
+ operand->update_inner = (operand_update_inners_fc)g_armv7_maccess_operand_update_inner_instances;
+ operand->hash = (operand_hash_fc)g_armv7_maccess_operand_hash;
+
+ operand->load = g_arch_operand_load_generic_fixed_3;
+ operand->store = g_arch_operand_store_generic_fixed;
}
@@ -171,14 +185,9 @@ static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand)
static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *operand)
{
- if (operand->base != NULL)
- g_object_unref(G_OBJECT(operand->base));
-
- if (operand->offset != NULL)
- g_object_unref(G_OBJECT(operand->offset));
-
- if (operand->shift != NULL)
- g_object_unref(G_OBJECT(operand->shift));
+ g_clear_object(&operand->base);
+ g_clear_object(&operand->offset);
+ g_clear_object(&operand->shift);
G_OBJECT_CLASS(g_armv7_maccess_operand_parent_class)->dispose(G_OBJECT(operand));
@@ -206,8 +215,109 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : base = représente le registre de la base d'accès. *
+* offset = détermine le décalage entre l'adresse et la base. *
+* shift = opération de décalage pour jouer sur le décalage. *
+* post = précise la forme donnée au décalage à appliquer. *
+* wback = indique une mise à jour de la base après usage. *
+* *
+* Description : Crée un accès à la mémoire depuis une base et un décalage. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool post, bool wback)
+{
+ GArmV7MAccessOperand *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_ARMV7_MACCESS_OPERAND, NULL);
+
+ result->base = base;
+ result->offset = offset;
+ result->shift = shift;
+
+ if (post)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7MAOF_POST_INDEXED);
+
+ if (wback)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7MAOF_WRITE_BACK);
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Founit la base d'un accès à la mémoire. *
+* *
+* Retour : Opérande en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *operand)
+{
+ return operand->base;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Founit le décalage d'un accès à la mémoire depuis la base. *
+* *
+* Retour : Opérande en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *operand)
+{
+ return operand->offset;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Founit le décalage d'un décalage pour un accès mémoire. *
+* *
+* Retour : Opérande en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *operand)
+{
+ return operand->shift;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* 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. *
* *
@@ -217,25 +327,24 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand)
* *
******************************************************************************/
-static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const GArmV7MAccessOperand *b)
+static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const GArmV7MAccessOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
+ GArchOperandClass *class; /* Classe parente normalisée */
result = g_arch_operand_compare(a->base, b->base);
- if (result != 0) goto gamoc_done;
-
- result = sort_pointer(a->offset, b->offset, (__compar_fn_t)g_arch_operand_compare);
- if (result != 0) goto gamoc_done;
-
- result = sort_pointer(a->shift, b->shift, (__compar_fn_t)g_arch_operand_compare);
- if (result != 0) goto gamoc_done;
- result = sort_boolean(a->post_indexed, b->post_indexed);
- if (result != 0) goto gamoc_done;
+ if (result)
+ result = g_arch_operand_compare(a->offset, b->offset);
- result = sort_boolean(a->write_back, b->write_back);
+ if (result)
+ result = g_arch_operand_compare(a->shift, b->shift);
- gamoc_done:
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
return result;
@@ -392,11 +501,17 @@ static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const G
static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, GBufferLine *line)
{
+ bool post; /* Forme post-indexée ? */
+ bool wback; /* Ecriture après coup ? */
+
+ post = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7MAOF_POST_INDEXED);
+ wback = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7MAOF_WRITE_BACK);
+
g_buffer_line_append_text(line, DLC_ASSEMBLY, "[", 1, RTT_HOOK, NULL);
g_arch_operand_print(operand->base, line);
- if (operand->post_indexed)
+ if (post)
g_buffer_line_append_text(line, DLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL);
if (operand->offset != NULL)
@@ -417,10 +532,10 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G
}
- if (!operand->post_indexed)
+ if (!post)
g_buffer_line_append_text(line, DLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL);
- if (operand->post_indexed && operand->write_back)
+ if (post && wback)
g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL);
}
@@ -428,306 +543,169 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G
/******************************************************************************
* *
-* Paramètres : base = représente le registre de la base d'accès. *
-* offset = détermine le décalage entre l'adresse et la base. *
-* shift = opération de décalage pour jouer sur le décalage. *
-* post = précise la forme donnée au décalage à appliquer. *
-* wback = indique une mise à jour de la base après usage. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Crée un accès à la mémoire depuis une base et un décalage. *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
* *
-* Retour : Opérande mis en place. *
+* Retour : Liste de candidats internes ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool post, bool wback)
+static GArchOperand **g_armv7_maccess_operand_list_inner_instances(const GArmV7MAccessOperand *operand, size_t *count)
{
- GArmV7MAccessOperand *result; /* Structure à retourner */
-
- result = g_object_new(G_TYPE_ARMV7_MACCESS_OPERAND, NULL);
-
- result->base = base;
- result->offset = offset;
- result->shift = shift;
-
- result->post_indexed = post;
- result->write_back = wback;
-
- return G_ARCH_OPERAND(result);
-
-}
+ GArchOperand **result; /* Instances à retourner */
+ size_t idx; /* Indice de traitement */
+ *count = 1;
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Founit la base d'un accès à la mémoire. *
-* *
-* Retour : Opérande en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *operand)
-{
- return operand->base;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Founit le décalage d'un accès à la mémoire depuis la base. *
-* *
-* Retour : Opérande en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *operand)
-{
- return operand->offset;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Founit le décalage d'un décalage pour un accès mémoire. *
-* *
-* Retour : Opérande en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *operand)
-{
- return operand->shift;
+ if (operand->offset != NULL)
+ (*count)++;
-}
+ if (operand->shift != NULL)
+ (*count)++;
+ result = malloc(*count * sizeof(GArchOperand *));
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Indique si le décalage est post-indexé. *
-* *
-* Retour : Statut des opérations menées. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ result[0] = operand->base;
+ g_object_ref(G_OBJECT(result[0]));
-bool g_armv7_maccess_operand_is_post_indexed(const GArmV7MAccessOperand *operand)
-{
- return operand->post_indexed;
+ if (operand->offset != NULL)
+ {
+ result[1] = operand->offset;
+ g_object_ref(G_OBJECT(result[1]));
-}
+ idx = 2;
+ }
+ else
+ idx = 1;
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Indique si la base est mise à jour après usage. *
-* *
-* Retour : Statut des opérations menées. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ if (operand->shift != NULL)
+ {
+ result[idx] = operand->shift;
+ g_object_ref(G_OBJECT(result[idx]));
+ }
-bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *operand)
-{
- return operand->write_back;
+ 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 = objet dont l'instance se veut unique. *
+* instances = liste de candidats internes devenus singletons. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand *operand, GArchOperand **instances, size_t count)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GArchOperand *subop; /* Sous-opérande à intégrer */
- uint8_t boolean; /* Valeur booléenne */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
-
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- {
- subop = g_arch_operand_load(storage, format, pbuf);
-
- if (subop == NULL)
- result = false;
-
- else
- operand->base = subop;
-
- }
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result && boolean == 1)
- {
- subop = g_arch_operand_load(storage, format, pbuf);
+#ifndef NDEBUG
+ size_t idx_check; /* Décompte des éléments utiles*/
+#endif
+ size_t i; /* Boucle de parcours */
- if (subop == NULL)
- result = false;
+#ifndef NDEBUG
+ idx_check = 1;
- else
- operand->offset = subop;
+ if (operand->offset != NULL)
+ (idx_check)++;
- }
+ if (operand->shift != NULL)
+ (idx_check)++;
- }
+ assert(count == idx_check);
+#endif
- if (result)
+ for (i = 0; i < count; i++)
{
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result && boolean == 1)
+ switch (i)
{
- subop = g_arch_operand_load(storage, format, pbuf);
-
- if (subop == NULL)
- result = false;
-
- else
- operand->shift = subop;
+ case 0:
+ g_clear_object(&operand->base);
+ operand->base = instances[i];
+ break;
+
+ case 1:
+ if (operand->offset != NULL)
+ {
+ g_clear_object(&operand->offset);
+ operand->offset = instances[i];
+ }
+ else
+ {
+ assert(count == 2);
+
+ g_clear_object(&operand->shift);
+ operand->shift = instances[i];
+
+ }
+ break;
+
+ case 2:
+ g_clear_object(&operand->shift);
+ operand->shift = instances[i];
+ break;
}
- }
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- operand->post_indexed = (boolean == 1 ? true : false);
+ g_object_ref(G_OBJECT(instances[i]));
}
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- operand->write_back = (boolean == 1 ? true : false);
-
- }
-
- return result;
-
}
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *operand, bool lock)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
-
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- result = g_arch_operand_store(operand->base, storage, pbuf);
-
- if (result)
- {
- if (operand->offset == NULL)
- result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false);
-
- else
- {
- result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false);
+ guint result; /* Valeur à retourner */
+ operand_extra_data_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+ size_t count; /* Quantité d'éléments utiles */
- if (result)
- result = g_arch_operand_store(operand->offset, storage, pbuf);
+ extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand));
- }
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- }
+ class = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
- if (result)
- {
- if (operand->shift == NULL)
- result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false);
+ count = 1;
- else
- {
- result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false);
-
- if (result)
- result = g_arch_operand_store(operand->shift, storage, pbuf);
-
- }
+ if (operand->offset != NULL)
+ (count)++;
- }
+ if (operand->shift != NULL)
+ (count)++;
- if (result)
- {
- boolean = (operand->post_indexed ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ result ^= count;
- if (result)
- {
- boolean = (operand->write_back ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
diff --git a/plugins/arm/v7/operands/maccess.h b/plugins/arm/v7/operands/maccess.h
index bc80cfa..eb39c30 100644
--- a/plugins/arm/v7/operands/maccess.h
+++ b/plugins/arm/v7/operands/maccess.h
@@ -36,6 +36,15 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _A7MAccessOpFlag
+{
+ A7MAOF_POST_INDEXED = AOF_USER_FLAG(0), /* Position du décalage */
+ A7MAOF_WRITE_BACK = AOF_USER_FLAG(1), /* Mise à jour de la base */
+
+} A7MAccessOpFlag;
+
+
#define G_TYPE_ARMV7_MACCESS_OPERAND g_armv7_maccess_operand_get_type()
#define G_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperand))
#define G_IS_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_MACCESS_OPERAND))
diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c
index 615e296..724523d 100644
--- a/plugins/arm/v7/operands/offset.c
+++ b/plugins/arm/v7/operands/offset.c
@@ -24,22 +24,26 @@
#include "offset.h"
+#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include <arch/operand-int.h>
-#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
/* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (instance) */
struct _GArmV7OffsetOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
- bool positive; /* Sens du décalage */
GArchOperand *value; /* Valeur du décalage */
};
@@ -48,7 +52,7 @@ struct _GArmV7OffsetOperand
/* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (classe) */
struct _GArmV7OffsetOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -65,8 +69,13 @@ static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *);
+static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *, bool);
/* Détermine le chemin conduisant à un opérande interne. */
static char *g_armv7_offset_operand_find_inner_operand_path(const GArmV7OffsetOperand *, const GArchOperand *);
@@ -77,21 +86,21 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *, GBufferLine *);
+/* Fournit une liste de candidats embarqués par un candidat. */
+static GArchOperand **g_armv7_offset_operand_list_inner_instances(const GArmV7OffsetOperand *, size_t *);
-
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Met à jour une liste de candidats embarqués par un candidat. */
+static void g_armv7_offset_operand_update_inner_instances(GArmV7OffsetOperand *, GArchOperand **, size_t);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour un décalage relatif ARMv7. */
-G_DEFINE_TYPE(GArmV7OffsetOperand, g_armv7_offset_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7OffsetOperand, g_armv7_offset_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -124,8 +133,11 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_offset_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_offset_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_offset_operand_serialize;
+ operand->list_inner = (operand_list_inners_fc)g_armv7_offset_operand_list_inner_instances;
+ operand->update_inner = (operand_update_inners_fc)g_armv7_offset_operand_update_inner_instances;
+
+ operand->load = g_arch_operand_load_generic_fixed_1;
+ operand->store = g_arch_operand_store_generic_fixed;
}
@@ -163,8 +175,7 @@ static void g_armv7_offset_operand_init(GArmV7OffsetOperand *operand)
static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *operand)
{
- if (operand->value != NULL)
- g_object_unref(G_OBJECT(operand->value));
+ g_clear_object(&operand->value);
G_OBJECT_CLASS(g_armv7_offset_operand_parent_class)->dispose(G_OBJECT(operand));
@@ -192,8 +203,69 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : positive = indique si la quantité doit être ajoutée ou non. *
+* value = valeur du décalage à appliquer. *
+* *
+* Description : Crée un décalage selon un sens et une valeur donnés. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value)
+{
+ GArmV7OffsetOperand *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_ARMV7_OFFSET_OPERAND, NULL);
+
+ if (positive)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7OOF_POSITIVE);
+
+ result->value = value;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Founit la valeur utilisée pour un décalage. *
+* *
+* Retour : Opérande en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operand)
+{
+ GArchOperand *result; /* Instance à retourner */
+
+ result = operand->value;
+
+ 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. *
* *
@@ -203,16 +275,18 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *operand)
* *
******************************************************************************/
-static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GArmV7OffsetOperand *b)
+static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GArmV7OffsetOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
-
- result = sort_boolean(a->positive, b->positive);
- if (result != 0) goto gaooc_done;
+ GArchOperandClass *class; /* Classe parente normalisée */
result = g_arch_operand_compare(a->value, b->value);
- gaooc_done:
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
return result;
@@ -299,7 +373,7 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA
static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBufferLine *line)
{
- if (!operand->positive)
+ if (!g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7OOF_POSITIVE))
g_buffer_line_append_text(line, DLC_ASSEMBLY, "-", 1, RTT_KEY_WORD, NULL);
g_arch_operand_print(operand->value, line);
@@ -309,127 +383,27 @@ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBu
/******************************************************************************
* *
-* Paramètres : positive = indique si la quantité doit être ajoutée ou non. *
-* value = valeur du décalage à appliquer. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Crée un décalage selon un sens et une valeur donnés. *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
* *
-* Retour : Opérande mis en place. *
+* Retour : Liste de candidats internes ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value)
+static GArchOperand **g_armv7_offset_operand_list_inner_instances(const GArmV7OffsetOperand *operand, size_t *count)
{
- GArmV7OffsetOperand *result; /* Structure à retourner */
+ GArchOperand **result; /* Instances à retourner */
- result = g_object_new(G_TYPE_ARMV7_OFFSET_OPERAND, NULL);
+ *count = 1;
- result->positive = positive;
- result->value = value;
+ result = malloc(*count * sizeof(GArchOperand *));
- return G_ARCH_OPERAND(result);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Indique le sens du décalage représenté. *
-* *
-* Retour : Indication d'ajout ou de retrait. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_armv7_offset_operand_is_positive(const GArmV7OffsetOperand *operand)
-{
- return operand->positive;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Founit la valeur utilisée pour un décalage. *
-* *
-* Retour : Opérande en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operand)
-{
- GArchOperand *result; /* Instance à retourner */
-
- result = operand->value;
-
- g_object_ref(G_OBJECT(result));
-
- 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. *
-* *
-* Description : Charge un opérande depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GArchOperand *value; /* Valeur à intégrer */
- uint8_t positive; /* Sens du décalage */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class);
-
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- {
- value = g_arch_operand_load(storage, format, pbuf);
-
- if (value == NULL)
- result = false;
-
- else
- operand->value = value;
-
- }
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &positive, sizeof(uint8_t), false);
-
- if (result)
- operand->positive = (positive == 1 ? true : false);
-
- }
+ result[0] = operand->value;
+ g_object_ref(G_OBJECT(result[0]));
return result;
@@ -438,37 +412,25 @@ static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAs
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* 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 : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static void g_armv7_offset_operand_update_inner_instances(GArmV7OffsetOperand *operand, GArchOperand **instances, size_t count)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t positive; /* Sens du décalage */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class);
+ assert(count == 1);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ g_clear_object(&operand->value);
- if (result)
- {
- positive = (operand->positive ? 1 : 0);
- result = extend_packed_buffer(pbuf, &positive, sizeof(uint8_t), false);
- }
-
- if (result)
- result = g_arch_operand_store(operand->value, storage, pbuf);
-
- return result;
+ operand->value = instances[0];
+ g_object_ref(G_OBJECT(instances[0]));
}
diff --git a/plugins/arm/v7/operands/offset.h b/plugins/arm/v7/operands/offset.h
index aa4df5e..0b5f1bf 100644
--- a/plugins/arm/v7/operands/offset.h
+++ b/plugins/arm/v7/operands/offset.h
@@ -36,6 +36,14 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _A7OffOpFlag
+{
+ A7OOF_POSITIVE = AOF_USER_FLAG(0), /* Sens du décalage */
+
+} A7OffOpFlag;
+
+
#define G_TYPE_ARMV7_OFFSET_OPERAND g_armv7_offset_operand_get_type()
#define G_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperand))
#define G_IS_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_OFFSET_OPERAND))
@@ -57,9 +65,6 @@ GType g_armv7_offset_operand_get_type(void);
/* Crée un décalage selon un sens et une valeur donnés. */
GArchOperand *g_armv7_offset_operand_new(bool, GArchOperand *);
-/* Indique le sens du décalage représenté. */
-bool g_armv7_offset_operand_is_positive(const GArmV7OffsetOperand *);
-
/* Founit la valeur utilisée pour un décalage. */
GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *);
diff --git a/plugins/arm/v7/operands/register.c b/plugins/arm/v7/operands/register.c
index bfbaa70..fa5b887 100644
--- a/plugins/arm/v7/operands/register.c
+++ b/plugins/arm/v7/operands/register.c
@@ -25,20 +25,29 @@
#include <arch/operands/register-int.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <common/sort.h>
+#include <core/columns.h>
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _a7regop_extra_data_t
+{
+ operand_extra_data_t parent; /* A laisser en premier */
+
+ uint8_t alignment; /* Eventuel alignement */
+
+} a7regop_extra_data_t;
+
+
/* Définition d'un opérande visant un registre ARMv7 (instance) */
struct _GArmV7RegisterOperand
{
GRegisterOperand parent; /* Instance parente */
- unsigned int alignment; /* Eventuel alignement */
- bool has_alignment; /* Validité du champ */
-
- bool write_back; /* Mise à jour du registre ? */
-
};
@@ -50,6 +59,21 @@ struct _GArmV7RegisterOperandClass
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_REGISTER_OP_EXTRA(op) ((a7regop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_ARMV7_REGISTER_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7regop_extra_data_t)
+
+#endif
+
+
/* Initialise la classe des opérandes de registre ARMv7. */
static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *);
@@ -62,20 +86,31 @@ static void g_armv7_register_operand_dispose(GArmV7RegisterOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Compare un opérande avec un autre. */
+static int g_armv7_register_operand_compare(const GArmV7RegisterOperand *, const GArmV7RegisterOperand *, bool);
+
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_register_operand_print(const GArmV7RegisterOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_register_operand_hash(const GArmV7RegisterOperand *, bool);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_armv7_register_operand_load(GArmV7RegisterOperand *, GObjectStorage *, packed_buffer_t *);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_armv7_register_operand_store(GArmV7RegisterOperand *, GObjectStorage *, packed_buffer_t *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour un opérande de registre ARMv7. */
@@ -106,10 +141,14 @@ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klas
operand = G_ARCH_OPERAND_CLASS(klass);
+ operand->compare = (operand_compare_fc)g_armv7_register_operand_compare;
+
operand->print = (operand_print_fc)g_armv7_register_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_register_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_register_operand_serialize;
+ operand->hash = (operand_hash_fc)g_armv7_register_operand_hash;
+
+ operand->load = (load_operand_fc)g_armv7_register_operand_load;
+ operand->store = (store_operand_fc)g_armv7_register_operand_store;
}
@@ -128,7 +167,6 @@ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klas
static void g_armv7_register_operand_init(GArmV7RegisterOperand *operand)
{
- operand->write_back = false;
}
@@ -173,33 +211,6 @@ static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *operand)
/******************************************************************************
* *
-* 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_armv7_register_operand_print(const GArmV7RegisterOperand *operand, GBufferLine *line)
-{
- GArchOperandClass *parent; /* Classe parente */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
-
- parent->print(G_ARCH_OPERAND(operand), line);
-
- if (operand->write_back)
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL);
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : reg = registre déjà en place. *
* *
* Description : Crée un opérande visant un registre ARMv7. *
@@ -238,9 +249,20 @@ GArchOperand *g_armv7_register_operand_new(GArmV7Register *reg)
void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *operand, unsigned int align)
{
- operand->alignment = align;
+ a7regop_extra_data_t *extra; /* Données internes à manipuler*/
+
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ extra->alignment = align;
- operand->has_alignment = true;
+ if (align > 0)
+ _g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT, false);
+ else
+ _g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT, false);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -260,83 +282,159 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *operand,
void g_armv7_register_operand_write_back(GArmV7RegisterOperand *operand, bool wback)
{
- operand->write_back = wback;
+ g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_WRITE_BACK);
}
+
+/* ---------------------------------------------------------------------------------- */
+/* 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 : Indique si le registre est mis à jour après coup. *
+* Description : Compare un opérande avec un autre. *
* *
-* Retour : Evolution du registre. *
+* Retour : Bilan de la comparaison. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *operand)
+static int g_armv7_register_operand_compare(const GArmV7RegisterOperand *a, const GArmV7RegisterOperand *b, bool lock)
{
- bool result; /* Statut à retourner */
+ int result; /* Bilan à faire remonter */
+ a7regop_extra_data_t *ea; /* Données insérées à consulter*/
+ a7regop_extra_data_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ ea = GET_ARMV7_REGISTER_OP_EXTRA(a);
+ eb = GET_ARMV7_REGISTER_OP_EXTRA(b);
- result = operand->write_back;
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
+
+ result = sort_unsigned_long(ea->alignment, eb->alignment);
+
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_register_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_armv7_register_operand_print(const GArmV7RegisterOperand *operand, GBufferLine *line)
+{
+ GArchOperandClass *parent; /* Classe parente */
+
+ parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
+
+ parent->print(G_ARCH_OPERAND(operand), line);
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
+ if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_WRITE_BACK))
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL);
+
+}
/******************************************************************************
* *
-* 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 = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static guint g_armv7_register_operand_hash(const GArmV7RegisterOperand *operand, bool lock)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
+ guint result; /* Valeur à retourner */
+ a7regop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
- parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+ class = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
- if (result)
- operand->has_alignment = (boolean == 1 ? true : false);
+ result ^= extra->alignment;
- }
+ 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 : - *
+* *
+******************************************************************************/
- if (result && operand->has_alignment)
- result = extract_packed_buffer(pbuf, &operand->alignment, sizeof(unsigned int), true);
+static bool g_armv7_register_operand_load(GArmV7RegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ a7regop_extra_data_t *extra; /* Données internes à manipuler*/
+
+ parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
- if (result)
+ if (result && g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT))
{
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
- if (result)
- operand->write_back = (boolean == 1 ? true : false);
+ result = extract_packed_buffer(pbuf, &extra->alignment, sizeof(uint8_t), false);
}
@@ -347,11 +445,11 @@ static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand,
/******************************************************************************
* *
-* 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. *
* *
@@ -359,29 +457,22 @@ static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand,
* *
******************************************************************************/
-static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_armv7_register_operand_store(GArmV7RegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
+ a7regop_extra_data_t *extra; /* Données internes à manipuler*/
parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
- if (result)
+ if (result && g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT))
{
- boolean = (operand->has_alignment ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
- if (result && operand->has_alignment)
- result = extend_packed_buffer(pbuf, &operand->alignment, sizeof(unsigned int), true);
+ result = extend_packed_buffer(pbuf, &extra->alignment, sizeof(uint8_t), false);
- if (result)
- {
- boolean = (operand->write_back ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
}
return result;
diff --git a/plugins/arm/v7/operands/register.h b/plugins/arm/v7/operands/register.h
index 241c101..26e03c0 100644
--- a/plugins/arm/v7/operands/register.h
+++ b/plugins/arm/v7/operands/register.h
@@ -36,6 +36,15 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _A7RegOpFlag
+{
+ A7ROF_HAS_ALIGNMENT = AOF_USER_FLAG(0), /* Validité de l'alignement */
+ A7ROF_WRITE_BACK = AOF_USER_FLAG(1), /* Mise à jour du registre ? */
+
+} A7RegOpFlag;
+
+
#define G_TYPE_ARMV7_REGISTER_OPERAND g_armv7_register_operand_get_type()
#define G_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_REGISTER_OPERAND, GArmV7RegisterOperand))
#define G_IS_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_REGISTER_OPERAND))
@@ -63,9 +72,6 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *, unsigne
/* Détermine si le registre est mis à jour après l'opération. */
void g_armv7_register_operand_write_back(GArmV7RegisterOperand *, bool);
-/* Indique si le registre est mis à jour après coup. */
-bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *);
-
#endif /* _PLUGINS_ARM_V7_OPERANDS_REGISTER_H */
diff --git a/plugins/arm/v7/operands/reglist.c b/plugins/arm/v7/operands/reglist.c
index 9b9a817..b525f28 100644
--- a/plugins/arm/v7/operands/reglist.c
+++ b/plugins/arm/v7/operands/reglist.c
@@ -28,21 +28,24 @@
#include <malloc.h>
-#include <arch/operand-int.h>
#include <arch/register.h>
#include <arch/storage.h>
#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
#include "../registers/basic.h"
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
+
/* Définition d'un opérande listant une série de registres ARM (instance) */
struct _GArmV7RegListOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
GArmV7Register **registers; /* Liste de registres intégrés */
size_t count; /* Taille de cette liste */
@@ -53,7 +56,7 @@ struct _GArmV7RegListOperand
/* Définition d'un opérande listant une série de registres ARM (classe) */
struct _GArmV7RegListOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -70,27 +73,35 @@ static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const GArmV7RegListOperand *);
+static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const GArmV7RegListOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_reglist_operand_hash(const GArmV7RegListOperand *, bool);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_armv7_reglist_operand_load(GArmV7RegListOperand *, GObjectStorage *, packed_buffer_t *);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
-
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_armv7_reglist_operand_store(GArmV7RegListOperand *, GObjectStorage *, packed_buffer_t *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour une liste de registres ARM. */
-G_DEFINE_TYPE(GArmV7RegListOperand, g_armv7_reglist_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7RegListOperand, g_armv7_reglist_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -119,8 +130,10 @@ static void g_armv7_reglist_operand_class_init(GArmV7RegListOperandClass *klass)
operand->compare = (operand_compare_fc)g_armv7_reglist_operand_compare;
operand->print = (operand_print_fc)g_armv7_reglist_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_reglist_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_reglist_operand_serialize;
+ operand->hash = (operand_hash_fc)g_armv7_reglist_operand_hash;
+
+ operand->load = (load_operand_fc)g_armv7_reglist_operand_load;
+ operand->store = (store_operand_fc)g_armv7_reglist_operand_store;
}
@@ -162,7 +175,7 @@ static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *operand)
size_t i; /* Boucle de parcours */
for (i = 0; i < operand->count; i++)
- g_object_unref(G_OBJECT(operand->registers[i]));
+ g_clear_object(&operand->registers[i]);
G_OBJECT_CLASS(g_armv7_reglist_operand_parent_class)->dispose(G_OBJECT(operand));
@@ -193,88 +206,6 @@ static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *operand)
/******************************************************************************
* *
-* 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_armv7_reglist_operand_compare(const GArmV7RegListOperand *a, const GArmV7RegListOperand *b)
-{
- int result; /* Bilan à faire remonter */
- size_t i; /* Boucle de parcours */
- GArchRegister *ra; /* Registre de la liste A */
- GArchRegister *rb; /* Registre de la liste B */
-
- /* Création de l'objet... */
- if (b == NULL)
- {
- result = 1;
- goto garoc_done;
- }
-
- result = sort_unsigned_long(a->count, b->count);
- if (result != 0) goto garoc_done;
-
- for (i = 0; i < a->count && result == 0; i++)
- {
- ra = G_ARCH_REGISTER(a->registers[i]);
- rb = G_ARCH_REGISTER(b->registers[i]);
-
- result = g_arch_register_compare(ra, rb);
-
- }
-
- garoc_done:
-
- 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_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line)
-{
- size_t i; /* Boucle de parcours */
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL);
-
- for (i = 0; i < operand->count; i++)
- {
- if (i > 0)
- {
- g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
- }
-
- g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line);
-
- }
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL);
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : selected = masque de bits pour les registres à intégrer. *
* *
* Description : Crée une liste vierge de registres ARM. *
@@ -322,8 +253,7 @@ GArchOperand *g_armv7_reglist_operand_new(uint16_t selected)
void g_armv7_reglist_add_register(GArmV7RegListOperand *operand, GArmV7Register *reg)
{
- operand->registers = (GArmV7Register **)realloc(operand->registers,
- ++operand->count * sizeof(GArmV7Register *));
+ operand->registers = realloc(operand->registers, ++operand->count * sizeof(GArmV7Register *));
operand->registers[operand->count - 1] = reg;
@@ -408,68 +338,135 @@ bool g_armv7_reglist_operand_has_register(const GArmV7RegListOperand *operand, c
/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* 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 : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Charge un opérande depuis 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_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *a, const GArmV7RegListOperand *b, bool lock)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- size_t count; /* Quantité de registres */
- packed_buffer_t reg_pbuf; /* Tampon des données à écrire */
+ int result; /* Bilan à faire remonter */
size_t i; /* Boucle de parcours */
- off64_t pos; /* Position dans le flux */
- GArchRegister *reg; /* Registre restauré */
+ GArchRegister *ra; /* Registre de la liste A */
+ GArchRegister *rb; /* Registre de la liste B */
+ GArchOperandClass *class; /* Classe parente normalisée */
- parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class);
+ /* Création de l'objet... */
+ if (b == NULL)
+ {
+ result = 1;
+ goto done;
+ }
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
+ result = sort_unsigned_long(a->count, b->count);
- if (result)
- result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
+ for (i = 0; i < a->count && result == 0; i++)
+ {
+ ra = G_ARCH_REGISTER(a->registers[i]);
+ rb = G_ARCH_REGISTER(b->registers[i]);
- if (result)
+ result = g_arch_register_compare(ra, rb);
+
+ }
+
+ if (result == 0)
{
- init_packed_buffer(&reg_pbuf);
+ class = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
- for (i = 0; i < count && result; i++)
- {
- result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
+ done:
- if (result)
- result = g_asm_storage_load_register_data(storage, &reg_pbuf, pos);
+ return result;
- if (result)
- {
- reg = g_arch_register_load(storage, &reg_pbuf);
- result = (reg != NULL);
- }
+}
- if (result)
- g_armv7_reglist_add_register(operand, G_ARMV7_REGISTER(reg));
+/******************************************************************************
+* *
+* 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_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line)
+{
+ size_t i; /* Boucle de parcours */
+
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL);
+
+ for (i = 0; i < operand->count; i++)
+ {
+ if (i > 0)
+ {
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
}
- exit_packed_buffer(&reg_pbuf);
+ g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line);
}
+ g_buffer_line_append_text(line, DLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL);
+
+}
+
+
+/******************************************************************************
+* *
+* 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_armv7_reglist_operand_hash(const GArmV7RegListOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ operand_extra_data_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+ size_t i; /* Boucle de parcours */
+
+ extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand));
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= operand->count;
+
+ for (i = 0; i < operand->count; i++)
+ result ^= g_arch_register_hash(G_ARCH_REGISTER(operand->registers[i]));
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
return result;
}
@@ -477,11 +474,11 @@ static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, G
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -489,39 +486,69 @@ static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, G
* *
******************************************************************************/
-static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_armv7_reglist_operand_load(GArmV7RegListOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ size_t count; /* Quantité de registres */
size_t i; /* Boucle de parcours */
- off64_t pos; /* Position dans le flux */
- packed_buffer_t reg_pbuf; /* Tampon des données à écrire */
+ GSerializableObject *reg; /* Registre de la liste */
parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true);
+ result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
- if (result)
+ for (i = 0; i < count && result; i++)
{
- init_packed_buffer(&reg_pbuf);
+ reg = g_object_storage_unpack_object(storage, "registers", pbuf);
- for (i = 0; i < operand->count && result; i++)
- {
- result = g_arch_register_store(G_ARCH_REGISTER(operand->registers[i]), storage, &reg_pbuf);
+ result = (reg != NULL);
- if (result)
- result = g_asm_storage_store_register_data(storage, &reg_pbuf, &pos);
+ if (result)
+ g_armv7_reglist_add_register(operand, G_ARMV7_REGISTER(reg));
- if (result)
- result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
+ }
- }
+ return result;
- exit_packed_buffer(&reg_pbuf);
+}
+
+
+/******************************************************************************
+* *
+* 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_armv7_reglist_operand_store(GArmV7RegListOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ size_t i; /* Boucle de parcours */
+ GSerializableObject *reg; /* Registre de la liste */
+
+ parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class);
+
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true);
+
+ for (i = 0; i < operand->count && result; i++)
+ {
+ reg = G_SERIALIZABLE_OBJECT(operand->registers[i]);
+ result = g_object_storage_pack_object(storage, "registers", reg, pbuf);
}
return result;
diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c
index 05889f4..418e5a4 100644
--- a/plugins/arm/v7/operands/rotation.c
+++ b/plugins/arm/v7/operands/rotation.c
@@ -24,20 +24,26 @@
#include "rotation.h"
+#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include <arch/operand-int.h>
+#include <core/columns.h>
#include <core/logs.h>
-#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
/* Définition d'un opérande visant une opérande de rotation ARMv7 (instance) */
struct _GArmV7RotationOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
GArchOperand *value; /* Valeur du décalage */
@@ -47,7 +53,7 @@ struct _GArmV7RotationOperand
/* Définition d'un opérande visant une opérande de rotation ARMv7 (classe) */
struct _GArmV7RotationOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -64,8 +70,13 @@ static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *);
+static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *, bool);
/* Détermine le chemin conduisant à un opérande interne. */
static char *g_armv7_rotation_operand_find_inner_operand_path(const GArmV7RotationOperand *, const GArchOperand *);
@@ -76,21 +87,21 @@ static GArchOperand *g_armv7_rotation_operand_get_inner_operand_from_path(const
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *, GBufferLine *);
+/* Fournit une liste de candidats embarqués par un candidat. */
+static GArchOperand **g_armv7_rotation_operand_list_inner_instances(const GArmV7RotationOperand *, size_t *);
-
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Met à jour une liste de candidats embarqués par un candidat. */
+static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperand *, GArchOperand **, size_t);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini par la GLib pour une opérande de rotation ARMv7. */
-G_DEFINE_TYPE(GArmV7RotationOperand, g_armv7_rotation_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7RotationOperand, g_armv7_rotation_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -123,8 +134,11 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas
operand->print = (operand_print_fc)g_armv7_rotation_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_rotation_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_rotation_operand_serialize;
+ operand->list_inner = (operand_list_inners_fc)g_armv7_rotation_operand_list_inner_instances;
+ operand->update_inner = (operand_update_inners_fc)g_armv7_rotation_operand_update_inner_instances;
+
+ operand->load = g_arch_operand_load_generic_fixed_1;
+ operand->store = g_arch_operand_store_generic_fixed;
}
@@ -162,8 +176,7 @@ static void g_armv7_rotation_operand_init(GArmV7RotationOperand *operand)
static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *operand)
{
- if (operand->value != NULL)
- g_object_unref(G_OBJECT(operand->value));
+ g_clear_object(&operand->value);
G_OBJECT_CLASS(g_armv7_rotation_operand_parent_class)->dispose(G_OBJECT(operand));
@@ -191,8 +204,65 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : - *
+* *
+* Description : Crée un réceptacle pour opérandes de rotation ARMv7. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value)
+{
+ GArmV7RotationOperand *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL);
+
+ result->value = value;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Founit la valeur utilisée pour une rotation. *
+* *
+* Retour : Opérande en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand)
+{
+ GArchOperand *result; /* Instance à retourner */
+
+ result = operand->value;
+
+ 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. *
* *
@@ -202,12 +272,19 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand)
* *
******************************************************************************/
-static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, const GArmV7RotationOperand *b)
+static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, const GArmV7RotationOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
+ GArchOperandClass *class; /* Classe parente normalisée */
result = g_arch_operand_compare(a->value, b->value);
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+
return result;
}
@@ -326,96 +403,27 @@ static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *operand,
/******************************************************************************
* *
-* Paramètres : - *
-* *
-* Description : Crée un réceptacle pour opérandes de rotation ARMv7. *
-* *
-* Retour : Opérande mis en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value)
-{
- GArmV7RotationOperand *result; /* Structure à retourner */
-
- result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL);
-
- result->value = value;
-
- return G_ARCH_OPERAND(result);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande à consulter. *
-* *
-* Description : Founit la valeur utilisée pour une rotation. *
-* *
-* Retour : Opérande en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand)
-{
- GArchOperand *result; /* Instance à retourner */
-
- result = operand->value;
-
- g_object_ref(G_OBJECT(result));
-
- 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 = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Charge un opérande depuis une mémoire tampon. *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Liste de candidats internes ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static GArchOperand **g_armv7_rotation_operand_list_inner_instances(const GArmV7RotationOperand *operand, size_t *count)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GArchOperand *value; /* Valeur à intégrer */
+ GArchOperand **result; /* Instances à retourner */
- parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class);
+ *count = 1;
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- {
- value = g_arch_operand_load(storage, format, pbuf);
+ result = malloc(*count * sizeof(GArchOperand *));
- if (value == NULL)
- result = false;
-
- else
- operand->value = value;
-
- }
+ result[0] = operand->value;
+ g_object_ref(G_OBJECT(result[0]));
return result;
@@ -424,30 +432,25 @@ static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand,
/******************************************************************************
* *
-* Paramètres : operand = opérande d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* 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 : Sauvegarde un opérande dans une mémoire tampon. *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperand *operand, GArchOperand **instances, size_t count)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class);
+ assert(count == 1);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ g_clear_object(&operand->value);
- if (result)
- result = g_arch_operand_store(operand->value, storage, pbuf);
-
- return result;
+ operand->value = instances[0];
+ g_object_ref(G_OBJECT(instances[0]));
}
diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c
index 852e677..ee18cf0 100644
--- a/plugins/arm/v7/operands/shift.c
+++ b/plugins/arm/v7/operands/shift.c
@@ -24,22 +24,37 @@
#include "shift.h"
+#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include <arch/operand-int.h>
#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+#include "../operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _a7shiftop_extra_data_t
+{
+ operand_extra_data_t parent; /* A laisser en premier */
+
+ SRType shift_type; /* Type de décalage */
+
+} a7shiftop_extra_data_t;
+
/* Définition d'un opérande visant une opérande de décalage ARMv7 (instance) */
struct _GArmV7ShiftOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
- SRType shift_type; /* Type de décalage */
GArchOperand *shift_value; /* Valeur du décalage */
};
@@ -48,11 +63,26 @@ struct _GArmV7ShiftOperand
/* Définition d'un opérande visant une opérande de décalage ARMv7 (classe) */
struct _GArmV7ShiftOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_SHIFT_OP_EXTRA(op) ((a7shiftop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_ARMV7_SHIFT_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7shiftop_extra_data_t)
+
+#endif
+
+
/* Initialise la classe des opérandes de décalage ARMv7. */
static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *);
@@ -65,8 +95,13 @@ static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *);
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
/* Compare un opérande avec un autre. */
-static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *);
+static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *, bool);
/* Détermine le chemin conduisant à un opérande interne. */
static char *g_armv7_shift_operand_find_inner_operand_path(const GArmV7ShiftOperand *, const GArchOperand *);
@@ -77,21 +112,30 @@ static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GAr
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *, GBufferLine *);
+/* Fournit une liste de candidats embarqués par un candidat. */
+static GArchOperand **g_armv7_shift_operand_list_inner_instances(const GArmV7ShiftOperand *, size_t *);
+/* Met à jour une liste de candidats embarqués par un candidat. */
+static void g_armv7_shift_operand_update_inner_instances(GArmV7ShiftOperand *, GArchOperand **, size_t);
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_shift_operand_hash(const GArmV7ShiftOperand *, bool);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *, GObjectStorage *, packed_buffer_t *);
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Sauvegarde un contenu dans une mémoire tampon. */
+static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *, GAsmStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
+
/* Indique le type défini par la GLib pour une opérande de décalage ARMv7. */
-G_DEFINE_TYPE(GArmV7ShiftOperand, g_armv7_shift_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7ShiftOperand, g_armv7_shift_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -124,8 +168,12 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_shift_operand_print;
- operand->unserialize = (unserialize_operand_fc)g_armv7_shift_operand_unserialize;
- operand->serialize = (serialize_operand_fc)g_armv7_shift_operand_serialize;
+ operand->list_inner = (operand_list_inners_fc)g_armv7_shift_operand_list_inner_instances;
+ operand->update_inner = (operand_update_inners_fc)g_armv7_shift_operand_update_inner_instances;
+ operand->hash = (operand_hash_fc)g_armv7_shift_operand_hash;
+
+ operand->load = (load_operand_fc)g_armv7_shift_operand_load;
+ operand->store = (store_operand_fc)g_armv7_shift_operand_store;
}
@@ -163,8 +211,7 @@ static void g_armv7_shift_operand_init(GArmV7ShiftOperand *operand)
static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *operand)
{
- if (operand->shift_value != NULL)
- g_object_unref(G_OBJECT(operand->shift_value));
+ g_clear_object(&operand->shift_value);
G_OBJECT_CLASS(g_armv7_shift_operand_parent_class)->dispose(G_OBJECT(operand));
@@ -192,8 +239,100 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : - *
+* *
+* Description : Crée un réceptacle pour opérande de décalage ARMv7. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_shift_operand_new(SRType type, GArchOperand *value)
+{
+ GArmV7ShiftOperand *result; /* Structure à retourner */
+ a7shiftop_extra_data_t *extra; /* Données insérées à modifier */
+
+ result = g_object_new(G_TYPE_ARMV7_SHIFT_OPERAND, NULL);
+
+ extra = GET_ARMV7_SHIFT_OP_EXTRA(result);
+
+ extra->shift_type = type;
+
+ result->shift_value = value;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Indique la forme de décalage représenté. *
+* *
+* Retour : Type de décalage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+SRType g_armv7_shift_operand_get_shift_type(const GArmV7ShiftOperand *operand)
+{
+ SRType result; /* Type à retourner */
+ a7shiftop_extra_data_t *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARMV7_SHIFT_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extra->shift_type;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Founit la valeur utilisée pour un décalage. *
+* *
+* Retour : Opérande en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *operand)
+{
+ GArchOperand *result; /* Instance à retourner */
+
+ result = operand->shift_value;
+
+ 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. *
* *
@@ -203,16 +342,38 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *operand)
* *
******************************************************************************/
-static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArmV7ShiftOperand *b)
+static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArmV7ShiftOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
+ a7shiftop_extra_data_t *ea; /* Données insérées à consulter*/
+ a7shiftop_extra_data_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ ea = GET_ARMV7_SHIFT_OP_EXTRA(a);
+ eb = GET_ARMV7_SHIFT_OP_EXTRA(b);
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
+
+ result = sort_unsigned_long(ea->shift_type, eb->shift_type);
- result = sort_unsigned_long(a->shift_type, b->shift_type);
- if (result != 0) goto gasoc_done;
+ if (result == 0)
+ result = g_arch_operand_compare(a->shift_value, b->shift_value);
- result = g_arch_operand_compare(a->shift_value, b->shift_value);
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
- gasoc_done:
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
return result;
@@ -299,7 +460,11 @@ static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GAr
static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBufferLine *line)
{
- switch (operand->shift_type)
+ SRType shift_type; /* Type porté par l'opérande */
+
+ shift_type = g_armv7_shift_operand_get_shift_type(operand);
+
+ switch (shift_type)
{
case SRType_LSL:
g_buffer_line_append_text(line, DLC_ASSEMBLY, "lsl", 3, RTT_KEY_WORD, NULL);
@@ -327,88 +492,106 @@ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBuff
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Crée un réceptacle pour opérande de décalage ARMv7. *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
* *
-* Retour : Opérande mis en place. *
+* Retour : Liste de candidats internes ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_armv7_shift_operand_new(SRType type, GArchOperand *value)
+static GArchOperand **g_armv7_shift_operand_list_inner_instances(const GArmV7ShiftOperand *operand, size_t *count)
{
- GArmV7ShiftOperand *result; /* Structure à retourner */
+ GArchOperand **result; /* Instances à retourner */
- result = g_object_new(G_TYPE_ARMV7_SHIFT_OPERAND, NULL);
+ *count = 1;
- result->shift_type = type;
- result->shift_value = value;
+ result = malloc(*count * sizeof(GArchOperand *));
- return G_ARCH_OPERAND(result);
+ result[0] = operand->shift_value;
+ g_object_ref(G_OBJECT(result[0]));
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : operand = opérande à consulter. *
+* 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 : Indique la forme de décalage représenté. *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
* *
-* Retour : Type de décalage. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-SRType g_armv7_shift_operand_get_shift_type(const GArmV7ShiftOperand *operand)
+static void g_armv7_shift_operand_update_inner_instances(GArmV7ShiftOperand *operand, GArchOperand **instances, size_t count)
{
- return operand->shift_type;
+ assert(count == 1);
+
+ g_clear_object(&operand->shift_value);
+
+ operand->shift_value = instances[0];
+ g_object_ref(G_OBJECT(instances[0]));
}
/******************************************************************************
* *
-* Paramètres : operand = opérande à consulter. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
-* Description : Founit la valeur utilisée pour un décalage. *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
-* Retour : Opérande en place. *
+* Retour : Empreinte de l'élément représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *operand)
+static guint g_armv7_shift_operand_hash(const GArmV7ShiftOperand *operand, bool lock)
{
- GArchOperand *result; /* Instance à retourner */
+ guint result; /* Valeur à retourner */
+ a7shiftop_extra_data_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+ a7shiftop_extra_data_t *op_extra; /* Données internes à manipuler*/
- result = operand->shift_value;
+ extra = GET_ARMV7_SHIFT_OP_EXTRA(G_ARMV7_SHIFT_OPERAND(operand));
- g_object_ref(G_OBJECT(result));
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- return result;
+ class = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
-}
+ op_extra = GET_ARMV7_SHIFT_OP_EXTRA(operand);
+ result ^= op_extra->shift_type;
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
-/* ---------------------------------------------------------------------------------- */
-/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
+ 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. *
* *
@@ -416,31 +599,31 @@ GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *op
* *
******************************************************************************/
-static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
- GArchOperand *value; /* Valeur à intégrer */
+ a7shiftop_extra_data_t *extra; /* Données insérées à modifier */
+ uleb128_t value; /* Valeur ULEB128 à charger */
parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class);
- result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
-
- if (result)
- result = extract_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true);
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
{
- value = g_arch_operand_load(storage, format, pbuf);
+ extra = GET_ARMV7_SHIFT_OP_EXTRA(operand);
- if (value == NULL)
- result = false;
+ result = unpack_uleb128(&value, pbuf);
- else
- operand->shift_value = value;
+ if (result)
+ extra->shift_type = value;
}
+ if (result)
+ result = _g_arch_operand_load_inner_instances(G_ARCH_OPERAND(operand), storage, pbuf, 1);
+
return result;
}
@@ -448,11 +631,11 @@ static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmS
/******************************************************************************
* *
-* 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. *
* *
@@ -460,20 +643,26 @@ static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmS
* *
******************************************************************************/
-static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
+static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ a7shiftop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class);
- result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extend_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true);
+ {
+ extra = GET_ARMV7_SHIFT_OP_EXTRA(operand);
+
+ result = pack_uleb128((uleb128_t []){ extra->shift_type }, pbuf);
+
+ }
if (result)
- result = g_arch_operand_store(operand->shift_value, storage, pbuf);
+ result = _g_arch_operand_store_inner_instances(G_ARCH_OPERAND(operand), storage, pbuf, true);
return result;