summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-12-26 00:26:28 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-12-26 00:26:28 (GMT)
commit98570719ff25a4dcde917056e55490bf2a6b1453 (patch)
tree4a01b57580aa05f8a55d37abbc4ddd178fb55a99 /plugins
parent94efb7bf5239cf984a0dda9949a26719a8ae2090 (diff)
Provide a method to hash all ARMv7 operands.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/arm/v7/Makefile.am2
-rw-r--r--plugins/arm/v7/operand-int.h51
-rw-r--r--plugins/arm/v7/operand.c188
-rw-r--r--plugins/arm/v7/operand.h55
-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
14 files changed, 1069 insertions, 56 deletions
diff --git a/plugins/arm/v7/Makefile.am b/plugins/arm/v7/Makefile.am
index 5d30876..f75e9b3 100644
--- a/plugins/arm/v7/Makefile.am
+++ b/plugins/arm/v7/Makefile.am
@@ -9,6 +9,8 @@ libarmv7_la_SOURCES = \
helpers.h \
instruction.h instruction.c \
link.h link.c \
+ operand-int.h \
+ operand.h operand.c \
post.h post.c \
processor.h processor.c \
pseudo.h pseudo.c \
diff --git a/plugins/arm/v7/operand-int.h b/plugins/arm/v7/operand-int.h
new file mode 100644
index 0000000..1832c32
--- /dev/null
+++ b/plugins/arm/v7/operand-int.h
@@ -0,0 +1,51 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand-int.h - prototypes pour la définition interne des opérandes ARMv7
+ *
+ * Copyright (C) 2021 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_ARM_V7_OPERAND_INT_H
+#define _PLUGINS_ARM_V7_OPERAND_INT_H
+
+
+#include "operand.h"
+
+
+#include <arch/operand-int.h>
+
+
+
+/* Définition générique d'un opérande ARMv7 (instance) */
+struct _GArmV7Operand
+{
+ GArchOperand parent; /* A laisser en premier */
+
+};
+
+/* Définition générique d'un opérande ARMv7 (classe) */
+struct _GArmV7OperandClass
+{
+ GArchOperandClass parent; /* A laisser en premier */
+
+};
+
+
+
+#endif /* _PLUGINS_ARM_V7_OPERAND_INT_H */
diff --git a/plugins/arm/v7/operand.c b/plugins/arm/v7/operand.c
new file mode 100644
index 0000000..8f93e78
--- /dev/null
+++ b/plugins/arm/v7/operand.c
@@ -0,0 +1,188 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand.c - opérandes ARMv7
+ *
+ * Copyright (C) 2021 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "operand.h"
+
+
+#include "operand-int.h"
+
+
+
+/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
+
+
+/* Initialise la classe des affichages de boutisme. */
+static void g_armv7_operand_class_init(GArmV7OperandClass *);
+
+/* Initialise une instance d'affichage de boutisme. */
+static void g_armv7_operand_init(GArmV7Operand *);
+
+/* Supprime toutes les références externes. */
+static void g_armv7_operand_dispose(GArmV7Operand *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_armv7_operand_finalize(GArmV7Operand *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_operand_hash(const GArmV7Operand *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEAU TYPE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour une de domaine et d'accès. */
+G_DEFINE_TYPE(GArmV7Operand, g_armv7_operand, G_TYPE_ARCH_OPERAND);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des affichages de boutisme. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_operand_class_init(GArmV7OperandClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GArchOperandClass *operand; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_operand_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_armv7_operand_finalize;
+
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
+ operand->hash = (operand_hash_fc)g_armv7_operand_hash;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise une instance d'affichage de boutisme. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_operand_init(GArmV7Operand *operand)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_operand_dispose(GArmV7Operand *operand)
+{
+ G_OBJECT_CLASS(g_armv7_operand_parent_class)->dispose(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_armv7_operand_finalize(GArmV7Operand *operand)
+{
+ G_OBJECT_CLASS(g_armv7_operand_parent_class)->finalize(G_OBJECT(operand));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* 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_operand_hash(const GArmV7Operand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ lockable_obj_extra_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_armv7_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
diff --git a/plugins/arm/v7/operand.h b/plugins/arm/v7/operand.h
new file mode 100644
index 0000000..8c80365
--- /dev/null
+++ b/plugins/arm/v7/operand.h
@@ -0,0 +1,55 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand.h - prototypes pour les opérandes ARMv7
+ *
+ * Copyright (C) 2017-2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_ARM_V7_OPERAND_H
+#define _PLUGINS_ARM_V7_OPERAND_H
+
+
+#include <glib-object.h>
+
+
+#include <arch/operand.h>
+
+
+
+#define G_TYPE_ARMV7_OPERAND g_armv7_operand_get_type()
+#define G_ARMV7_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_OPERAND, GArmV7Operand))
+#define G_IS_ARMV7_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_OPERAND))
+#define G_ARMV7_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_OPERAND, GArmV7OperandClass))
+#define G_IS_ARMV7_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_OPERAND))
+#define G_ARMV7_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_OPERAND, GArmV7OperandClass))
+
+
+/* Définition générique d'un opérande ARMv7 (instance) */
+typedef struct _GArmV7Operand GArmV7Operand;
+
+/* Définition générique d'un opérande ARMv7 (classe) */
+typedef struct _GArmV7OperandClass GArmV7OperandClass;
+
+
+/* Indique le type défini par la GLib pour un opérande ARMv7. */
+GType g_armv7_operand_get_type(void);
+
+
+
+#endif /* _PLUGINS_ARM_V7_OPERAND_H */
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. *