diff options
Diffstat (limited to 'plugins/arm/v7/operands/register.c')
-rw-r--r-- | plugins/arm/v7/operands/register.c | 155 |
1 files changed, 149 insertions, 6 deletions
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; |