diff options
Diffstat (limited to 'plugins/arm/v7/operands/limitation.c')
-rw-r--r-- | plugins/arm/v7/operands/limitation.c | 271 |
1 files changed, 203 insertions, 68 deletions
diff --git a/plugins/arm/v7/operands/limitation.c b/plugins/arm/v7/operands/limitation.c index 0d29545..d9e11cf 100644 --- a/plugins/arm/v7/operands/limitation.c +++ b/plugins/arm/v7/operands/limitation.c @@ -26,28 +26,57 @@ #include <arch/operand-int.h> #include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" -/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ -struct _GArmV7LimitationOperand + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7limop_extra_data_t { - GArchOperand parent; /* Instance parente */ + operand_extra_data_t parent; /* A laisser en premier */ BarrierLimitationType type; /* Type de limitation */ +} a7limop_extra_data_t; + + +/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ +struct _GArmV7LimitationOperand +{ + GArmV7Operand parent; /* Instance parente */ + }; /* Définition d'un opérande déterminant une limitation de domaine et d'accès (classe) */ struct _GArmV7LimitationOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_LIMITATION_OP_EXTRA(op) ((a7limop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +# define GET_ARMV7_LIMITATION_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7limop_extra_data_t) + +#endif + + /* Initialise la classe des co-processeurs ARM. */ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass *); @@ -60,27 +89,35 @@ static void g_armv7_limitation_operand_dispose(GArmV7LimitationOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, const GArmV7LimitationOperand *); +static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, const GArmV7LimitationOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_limitation_operand_hash(const GArmV7LimitationOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une limitation de domaine et d'accès. */ -G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -107,10 +144,13 @@ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass * object->finalize = (GObjectFinalizeFunc)g_armv7_limitation_operand_finalize; operand->compare = (operand_compare_fc)g_armv7_limitation_operand_compare; + operand->print = (operand_print_fc)g_armv7_limitation_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_limitation_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_limitation_operand_serialize; + operand->hash = (operand_hash_fc)g_armv7_limitation_operand_hash; + + operand->load = (load_operand_fc)g_armv7_limitation_operand_load; + operand->store = (store_operand_fc)g_armv7_limitation_operand_store; } @@ -173,8 +213,77 @@ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : raw = valeur brute de la limitation à considérer. * +* * +* Description : Crée une représentation d'une limitation pour barrière. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_limitation_operand_new(uint8_t raw) +{ + GArmV7LimitationOperand *result; /* Structure à retourner */ + a7limop_extra_data_t *extra; /* Données insérées à modifier */ + + result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL); + + extra = GET_ARMV7_LIMITATION_OP_EXTRA(result); + + if (raw < 0b0010 || raw > 0b1111) + extra->type = BLT_RESERVED; + + else + extra->type = raw; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique le type de limitation représentée. * +* * +* Retour : Type de limitation d'accès et de domaine. * +* * +* Remarques : - * +* * +******************************************************************************/ + +BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand) +{ + BarrierLimitationType result; /* Type à retourner */ + a7limop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->type; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -184,11 +293,35 @@ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand * * ******************************************************************************/ -static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, const GArmV7LimitationOperand *b) +static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, const GArmV7LimitationOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + a7limop_extra_data_t *ea; /* Données insérées à consulter*/ + a7limop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ - result = sort_unsigned_long(a->type, b->type); + ea = GET_ARMV7_LIMITATION_OP_EXTRA(a); + eb = GET_ARMV7_LIMITATION_OP_EXTRA(b); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + + result = sort_unsigned_long(ea->type, eb->type); + + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } return result; @@ -210,7 +343,11 @@ static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *operand, GBufferLine *line) { - switch (operand->type) + BarrierLimitationType type; /* Type porté par l'opérande */ + + type = g_armv7_limitation_operand_get_value(operand); + + switch (type) { case BLT_SY: g_buffer_line_append_text(line, DLC_ASSEMBLY, "SY", 2, RTT_KEY_WORD, NULL); @@ -255,66 +392,48 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *oper /****************************************************************************** * * -* Paramètres : raw = valeur brute de la limitation à considérer. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Crée une représentation d'une limitation pour barrière. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Opérande mis en place. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_limitation_operand_new(uint8_t raw) +static guint g_armv7_limitation_operand_hash(const GArmV7LimitationOperand *operand, bool lock) { - GArmV7LimitationOperand *result; /* Structure à retourner */ + guint result; /* Valeur à retourner */ + a7limop_extra_data_t *extra; /* Données internes à manipuler*/ + GArchOperandClass *class; /* Classe parente normalisée */ - result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL); + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); - if (raw < 0b0010 || raw > 0b1111) - result->type = BLT_RESERVED; + if (lock) + LOCK_GOBJECT_EXTRA(extra); - else - result->type = raw; + class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - return G_ARCH_OPERAND(result); + result ^= extra->type; -} + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique le type de limitation représentée. * -* * -* Retour : Type de limitation d'accès et de domaine. * -* * -* Remarques : - * -* * -******************************************************************************/ - -BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand) -{ - return operand->type; + return result; } - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -322,17 +441,27 @@ BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7Limitatio * * ******************************************************************************/ -static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + a7limop_extra_data_t *extra; /* Données insérées à modifier */ + uleb128_t value; /* Valeur ULEB128 à charger */ parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extract_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + { + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); + + result = unpack_uleb128(&value, pbuf); + + if (result) + extra->type = value; + + } return result; @@ -341,11 +470,11 @@ static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *oper /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -353,17 +482,23 @@ static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *oper * * ******************************************************************************/ -static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + a7limop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + { + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); + + result = pack_uleb128((uleb128_t []){ extra->type }, pbuf); + + } return result; |