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/estate.c11
-rw-r--r--plugins/arm/v7/operands/iflags.c10
-rw-r--r--plugins/arm/v7/operands/it.c153
-rw-r--r--plugins/arm/v7/operands/limitation.c52
-rw-r--r--plugins/arm/v7/operands/maccess.c194
-rw-r--r--plugins/arm/v7/operands/offset.c10
-rw-r--r--plugins/arm/v7/operands/register.c155
-rw-r--r--plugins/arm/v7/operands/reglist.c54
-rw-r--r--plugins/arm/v7/operands/rotation.c73
-rw-r--r--plugins/arm/v7/operands/shift.c117
10 files changed, 773 insertions, 56 deletions
diff --git a/plugins/arm/v7/operands/estate.c b/plugins/arm/v7/operands/estate.c
index bf142af..d82ffa1 100644
--- a/plugins/arm/v7/operands/estate.c
+++ b/plugins/arm/v7/operands/estate.c
@@ -24,10 +24,12 @@
#include "estate.h"
-#include <arch/operand-int.h>
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -35,7 +37,7 @@
/* Définition d'un opérande affichant le choix d'un boutisme (instance) */
struct _GArmV7EndianOperand
{
- GArchOperand parent; /* Instance parente */
+ 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 */
};
@@ -61,6 +63,7 @@ static void g_armv7_endian_operand_dispose(GArmV7EndianOperand *);
static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *);
+
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
@@ -75,7 +78,7 @@ static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLin
/* 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);
/******************************************************************************
diff --git a/plugins/arm/v7/operands/iflags.c b/plugins/arm/v7/operands/iflags.c
index f24f2f4..2e26810 100644
--- a/plugins/arm/v7/operands/iflags.c
+++ b/plugins/arm/v7/operands/iflags.c
@@ -24,10 +24,12 @@
#include "iflags.h"
-#include <arch/operand-int.h>
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -35,7 +37,7 @@
/* Définition d'un opérande précisant un masque d'interruption ARMv7 (instance) */
struct _GArmV7IFlagsOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
};
@@ -43,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 */
};
@@ -75,7 +77,7 @@ static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLin
/* 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);
/******************************************************************************
diff --git a/plugins/arm/v7/operands/it.c b/plugins/arm/v7/operands/it.c
index 54e15ed..b2fb2f6 100644
--- a/plugins/arm/v7/operands/it.c
+++ b/plugins/arm/v7/operands/it.c
@@ -27,30 +27,55 @@
#include <assert.h>
-#include <arch/operand-int.h>
#include <common/sort.h>
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
-/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */
-struct _GArmV7ITCondOperand
+/* 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 __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_ITCOND_OP_EXTRA(op) (a7itcop_extra_data_t *)&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 */
};
@@ -78,6 +103,9 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GAr
/* 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 *);
@@ -92,7 +120,7 @@ static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *, GObjectStorage *
/* 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);
/******************************************************************************
@@ -120,8 +148,11 @@ static void g_armv7_itcond_operand_class_init(GArmV7ITCondOperandClass *klass)
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->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;
@@ -200,14 +231,17 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand)
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);
- result->firstcond = firstcond;
- result->mask = mask;
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(result);
+
+ extra->firstcond = firstcond;
+ extra->mask = mask;
return G_ARCH_OPERAND(result);
@@ -229,8 +263,11 @@ GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask)
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 = operand->firstcond;
+ result = extra->firstcond;
return result;
@@ -252,8 +289,11 @@ ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *oper
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 */
- result = operand->mask;
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ result = extra->mask;
return result;
@@ -283,12 +323,23 @@ uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand)
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 */
- result = sort_boolean(a->firstcond, b->firstcond);
+ 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);
if (result == 0)
- result = sort_unsigned_long(a->mask, b->mask);
+ result = sort_unsigned_long(ea->mask, eb->mask);
if (result == 0)
{
@@ -296,6 +347,12 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GA
result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
}
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
+
return result;
}
@@ -316,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;
@@ -352,6 +412,45 @@ static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBu
/******************************************************************************
* *
+* 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_itcond_operand_hash(const GArmV7ITCondOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ a7itcop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= extra->firstcond;
+
+ result ^= extra->mask;
+
+ 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. *
@@ -368,16 +467,26 @@ static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *operand, GObjectSto
{
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->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;
@@ -402,16 +511,22 @@ static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *operand, GObjectSt
{
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->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 5d22681..b3c6d07 100644
--- a/plugins/arm/v7/operands/limitation.c
+++ b/plugins/arm/v7/operands/limitation.c
@@ -29,6 +29,9 @@
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -46,7 +49,7 @@ typedef struct _a7limop_extra_data_t
/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */
struct _GArmV7LimitationOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
};
@@ -54,7 +57,7 @@ struct _GArmV7LimitationOperand
/* 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 */
};
@@ -97,6 +100,9 @@ static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, c
/* 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 *);
@@ -111,7 +117,7 @@ static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *, GObjectS
/* 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);
/******************************************************************************
@@ -138,8 +144,11 @@ 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->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;
@@ -383,6 +392,43 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *oper
/******************************************************************************
* *
+* 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_limitation_operand_hash(const GArmV7LimitationOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ a7limop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= extra->type;
+
+ 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. *
diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c
index 0b0d0b4..3eb3116 100644
--- a/plugins/arm/v7/operands/maccess.c
+++ b/plugins/arm/v7/operands/maccess.c
@@ -29,12 +29,14 @@
#include <stdlib.h>
-#include <arch/operand-int.h>
#include <common/cpp.h>
#include <core/logs.h>
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -42,7 +44,7 @@
/* 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 */
@@ -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 */
};
@@ -88,6 +90,15 @@ 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);
+
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *, bool);
+
/* Charge un contenu depuis une mémoire tampon. */
static bool g_armv7_maccess_operand_load(GArmV7MAccessOperand *, GObjectStorage *, packed_buffer_t *);
@@ -102,7 +113,7 @@ static bool g_armv7_maccess_operand_store(GArmV7MAccessOperand *, GObjectStorage
/* 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);
/******************************************************************************
@@ -135,6 +146,10 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_maccess_operand_print;
+ 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 = (load_operand_fc)g_armv7_maccess_operand_load;
operand->store = (store_operand_fc)g_armv7_maccess_operand_store;
@@ -534,6 +549,177 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
+* *
+* Retour : Liste de candidats internes ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand **g_armv7_maccess_operand_list_inner_instances(const GArmV7MAccessOperand *operand, size_t *count)
+{
+ GArchOperand **result; /* Instances à retourner */
+ size_t idx; /* Indice de traitement */
+
+ *count = 1;
+
+ if (operand->offset != NULL)
+ (*count)++;
+
+ if (operand->shift != NULL)
+ (*count)++;
+
+ result = malloc(*count * sizeof(GArchOperand *));
+
+ result[0] = operand->base;
+ g_object_ref(G_OBJECT(result[0]));
+
+ if (operand->offset != NULL)
+ {
+ result[1] = operand->offset;
+ g_object_ref(G_OBJECT(result[1]));
+
+ idx = 2;
+
+ }
+ else
+ idx = 1;
+
+ if (operand->shift != NULL)
+ {
+ result[idx] = operand->shift;
+ g_object_ref(G_OBJECT(result[idx]));
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* instances = liste de candidats internes devenus singletons. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand *operand, GArchOperand **instances, size_t count)
+{
+#ifndef NDEBUG
+ size_t idx_check; /* Décompte des éléments utiles*/
+#endif
+ size_t i; /* Boucle de parcours */
+
+#ifndef NDEBUG
+ idx_check = 1;
+
+ if (operand->offset != NULL)
+ (idx_check)++;
+
+ if (operand->shift != NULL)
+ (idx_check)++;
+
+ assert(count == idx_check);
+#endif
+
+ for (i = 0; i < count; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ g_object_unref(G_OBJECT(operand->base));
+ operand->base = instances[i];
+ break;
+
+ case 1:
+ if (operand->offset != NULL)
+ {
+ g_object_unref(G_OBJECT(operand->offset));
+ operand->offset = instances[i];
+ }
+ else
+ {
+ assert(count == 2);
+
+ g_object_unref(G_OBJECT(operand->shift));
+ operand->shift = instances[i];
+
+ }
+ break;
+
+ case 2:
+ g_object_unref(G_OBJECT(operand->shift));
+ operand->shift = instances[i];
+ break;
+
+ }
+
+ g_object_ref(G_OBJECT(instances[i]));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* 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_maccess_operand_hash(const GArmV7MAccessOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ lockable_obj_extra_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+ size_t count; /* Quantité d'éléments utiles */
+
+ extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t);
+
+ 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);
+
+ count = 1;
+
+ if (operand->offset != NULL)
+ (count)++;
+
+ if (operand->shift != NULL)
+ (count)++;
+
+ result ^= count;
+
+ 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. *
diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c
index fc68638..1634230 100644
--- a/plugins/arm/v7/operands/offset.c
+++ b/plugins/arm/v7/operands/offset.c
@@ -28,10 +28,12 @@
#include <string.h>
-#include <arch/operand-int.h>
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -39,7 +41,7 @@
/* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (instance) */
struct _GArmV7OffsetOperand
{
- GArchOperand parent; /* Instance parente */
+ GArmV7Operand parent; /* Instance parente */
GArchOperand *value; /* Valeur du décalage */
@@ -49,7 +51,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 */
};
@@ -97,7 +99,7 @@ static bool g_armv7_offset_operand_store(GArmV7OffsetOperand *, GObjectStorage *
/* 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);
/******************************************************************************
diff --git a/plugins/arm/v7/operands/register.c b/plugins/arm/v7/operands/register.c
index dce8fef..026d0d5 100644
--- a/plugins/arm/v7/operands/register.c
+++ b/plugins/arm/v7/operands/register.c
@@ -25,6 +25,7 @@
#include <arch/operands/register-int.h>
+#include <common/sort.h>
#include <gtkext/gtkblockdisplay.h>
@@ -32,13 +33,21 @@
/* -------------------------- 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 */
-
};
@@ -50,6 +59,21 @@ struct _GArmV7RegisterOperandClass
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_REGISTER_OP_EXTRA(op) (a7regop_extra_data_t *)&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 *);
@@ -67,9 +91,15 @@ 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 *);
@@ -111,8 +141,12 @@ 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->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;
@@ -215,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);
- g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT);
+ extra->alignment = align;
+
+ 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);
}
@@ -250,6 +295,55 @@ void g_armv7_register_operand_write_back(GArmV7RegisterOperand *operand, bool wb
/******************************************************************************
* *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Compare un opérande avec un autre. *
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_armv7_register_operand_compare(const GArmV7RegisterOperand *a, const GArmV7RegisterOperand *b, bool lock)
+{
+ 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);
+
+ 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é. *
* *
@@ -277,6 +371,43 @@ static void g_armv7_register_operand_print(const GArmV7RegisterOperand *operand,
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_armv7_register_operand_hash(const GArmV7RegisterOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ a7regop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), 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. *
@@ -293,13 +424,19 @@ static bool g_armv7_register_operand_load(GArmV7RegisterOperand *operand, GObjec
{
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 && g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT))
- result = extract_packed_buffer(pbuf, &operand->alignment, sizeof(unsigned int), true);
+ {
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
+
+ result = extract_packed_buffer(pbuf, &extra->alignment, sizeof(uint8_t), false);
+
+ }
return result;
@@ -324,13 +461,19 @@ static bool g_armv7_register_operand_store(GArmV7RegisterOperand *operand, GObje
{
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->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result && g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT))
- result = extend_packed_buffer(pbuf, &operand->alignment, sizeof(unsigned int), true);
+ {
+ extra = GET_ARMV7_REGISTER_OP_EXTRA(operand);
+
+ result = extend_packed_buffer(pbuf, &extra->alignment, sizeof(uint8_t), false);
+
+ }
return result;
diff --git a/plugins/arm/v7/operands/reglist.c b/plugins/arm/v7/operands/reglist.c
index 21407a4..d53a7e1 100644
--- a/plugins/arm/v7/operands/reglist.c
+++ b/plugins/arm/v7/operands/reglist.c
@@ -28,13 +28,13 @@
#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 "../operand-int.h"
#include "../registers/basic.h"
@@ -45,7 +45,7 @@
/* 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 */
@@ -56,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 */
};
@@ -84,6 +84,9 @@ static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const G
/* 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 *);
@@ -98,7 +101,7 @@ static bool g_armv7_reglist_operand_store(GArmV7RegListOperand *, GObjectStorage
/* 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);
/******************************************************************************
@@ -127,6 +130,8 @@ 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->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;
@@ -428,6 +433,47 @@ static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, G
/******************************************************************************
* *
+* 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 */
+ lockable_obj_extra_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+ size_t i; /* Boucle de parcours */
+
+ extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t);
+
+ 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;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = élément GLib à constuire. *
* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à lire. *
diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c
index 85f7290..f90c76b 100644
--- a/plugins/arm/v7/operands/rotation.c
+++ b/plugins/arm/v7/operands/rotation.c
@@ -24,15 +24,18 @@
#include "rotation.h"
+#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include <arch/operand-int.h>
#include <core/logs.h>
#include <gtkext/gtkblockdisplay.h>
+#include "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -40,7 +43,7 @@
/* 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 */
@@ -50,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 */
};
@@ -84,6 +87,12 @@ 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 *);
+
+/* 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 contenu depuis une mémoire tampon. */
static bool g_armv7_rotation_operand_load(GArmV7RotationOperand *, GObjectStorage *, packed_buffer_t *);
@@ -98,7 +107,7 @@ static bool g_armv7_rotation_operand_store(GArmV7RotationOperand *, GObjectStora
/* 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);
/******************************************************************************
@@ -131,6 +140,9 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas
operand->print = (operand_print_fc)g_armv7_rotation_operand_print;
+ 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 = (load_operand_fc)g_armv7_rotation_operand_load;
operand->store = (store_operand_fc)g_armv7_rotation_operand_store;
@@ -397,6 +409,59 @@ static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *operand,
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
+* *
+* Retour : Liste de candidats internes ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand **g_armv7_rotation_operand_list_inner_instances(const GArmV7RotationOperand *operand, size_t *count)
+{
+ GArchOperand **result; /* Instances à retourner */
+
+ *count = 1;
+
+ result = malloc(*count * sizeof(GArchOperand *));
+
+ result[0] = operand->value;
+ g_object_ref(G_OBJECT(result[0]));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* instances = liste de candidats internes devenus singletons. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperand *operand, GArchOperand **instances, size_t count)
+{
+ assert(count == 1);
+
+ g_object_unref(G_OBJECT(operand->value));
+ operand->value = instances[0];
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = élément GLib à constuire. *
* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à lire. *
diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c
index 8c00753..55f2a22 100644
--- a/plugins/arm/v7/operands/shift.c
+++ b/plugins/arm/v7/operands/shift.c
@@ -24,15 +24,18 @@
#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 "../operand-int.h"
+
+
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
@@ -50,7 +53,7 @@ typedef struct _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 */
GArchOperand *shift_value; /* Valeur du décalage */
@@ -60,7 +63,7 @@ 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 */
};
@@ -109,6 +112,15 @@ 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);
+
+/* 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 *);
@@ -123,7 +135,7 @@ static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *, GObjectStorage *,
/* 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);
/******************************************************************************
@@ -156,6 +168,10 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_shift_operand_print;
+ 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;
@@ -476,6 +492,99 @@ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBuff
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
+* *
+* Retour : Liste de candidats internes ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand **g_armv7_shift_operand_list_inner_instances(const GArmV7ShiftOperand *operand, size_t *count)
+{
+ GArchOperand **result; /* Instances à retourner */
+
+ *count = 1;
+
+ result = malloc(*count * sizeof(GArchOperand *));
+
+ result[0] = operand->shift_value;
+ g_object_ref(G_OBJECT(result[0]));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* instances = liste de candidats internes devenus singletons. *
+* count = quantité d'instances à l'unicité internes. *
+* *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_shift_operand_update_inner_instances(GArmV7ShiftOperand *operand, GArchOperand **instances, size_t count)
+{
+ assert(count == 1);
+
+ g_object_unref(G_OBJECT(operand->shift_value));
+ operand->shift_value = instances[0];
+
+}
+
+
+/******************************************************************************
+* *
+* 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_shift_operand_hash(const GArmV7ShiftOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ lockable_obj_extra_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+ a7shiftop_extra_data_t *op_extra; /* Données internes à manipuler*/
+
+ extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ 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);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = élément GLib à constuire. *
* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à lire. *