diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/arm/v7/operands/estate.c | 167 | ||||
-rw-r--r-- | plugins/arm/v7/operands/estate.h | 11 | ||||
-rw-r--r-- | plugins/arm/v7/operands/iflags.c | 167 | ||||
-rw-r--r-- | plugins/arm/v7/operands/iflags.h | 10 | ||||
-rw-r--r-- | plugins/arm/v7/operands/it.c | 210 | ||||
-rw-r--r-- | plugins/arm/v7/operands/limitation.c | 263 | ||||
-rw-r--r-- | plugins/arm/v7/operands/maccess.c | 441 | ||||
-rw-r--r-- | plugins/arm/v7/operands/maccess.h | 9 | ||||
-rw-r--r-- | plugins/arm/v7/operands/offset.c | 240 | ||||
-rw-r--r-- | plugins/arm/v7/operands/offset.h | 11 | ||||
-rw-r--r-- | plugins/arm/v7/operands/register.c | 150 | ||||
-rw-r--r-- | plugins/arm/v7/operands/register.h | 12 | ||||
-rw-r--r-- | plugins/arm/v7/operands/reglist.c | 279 | ||||
-rw-r--r-- | plugins/arm/v7/operands/rotation.c | 197 | ||||
-rw-r--r-- | plugins/arm/v7/operands/shift.c | 331 | ||||
-rw-r--r-- | plugins/dalvik/operands/args.c | 279 | ||||
-rw-r--r-- | plugins/dalvik/operands/pool.c | 404 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/register.c | 4 | ||||
-rw-r--r-- | plugins/pychrysalide/format/symbol.c | 4 |
19 files changed, 1573 insertions, 1616 deletions
diff --git a/plugins/arm/v7/operands/estate.c b/plugins/arm/v7/operands/estate.c index a76b464..bf142af 100644 --- a/plugins/arm/v7/operands/estate.c +++ b/plugins/arm/v7/operands/estate.c @@ -25,18 +25,18 @@ #include <arch/operand-int.h> -#include <common/sort.h> #include <gtkext/gtkblockdisplay.h> +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande affichant le choix d'un boutisme (instance) */ struct _GArmV7EndianOperand { GArchOperand parent; /* Instance parente */ - bool big; /* Grand boutisme à afficher ? */ - }; @@ -60,23 +60,18 @@ static void g_armv7_endian_operand_dispose(GArmV7EndianOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *); -/* Compare un opérande avec un autre. */ -static int g_armv7_endian_operand_compare(const GArmV7EndianOperand *, const GArmV7EndianOperand *); - -/* Traduit un opérande en version humainement lisible. */ -static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *); - +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_endian_operand_unserialize(GArmV7EndianOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une endian de domaine et d'accès. */ @@ -106,12 +101,8 @@ static void g_armv7_endian_operand_class_init(GArmV7EndianOperandClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_endian_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_armv7_endian_operand_finalize; - operand->compare = (operand_compare_fc)g_armv7_endian_operand_compare; operand->print = (operand_print_fc)g_armv7_endian_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_endian_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_endian_operand_serialize; - } @@ -173,53 +164,6 @@ static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * -* * -* Description : Compare un opérande avec un autre. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int g_armv7_endian_operand_compare(const GArmV7EndianOperand *a, const GArmV7EndianOperand *b) -{ - int result; /* Bilan à faire remonter */ - - result = sort_boolean(a->big, b->big); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line) -{ - if (operand->big) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL); - else - g_buffer_line_append_text(line, DLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : big = indication sur le boutisme à représenter. * * * * Description : Crée une représentation de boutisme ARMv7. * @@ -236,107 +180,38 @@ GArchOperand *g_armv7_endian_operand_new(bool big) result = g_object_new(G_TYPE_ARMV7_ENDIAN_OPERAND, NULL); - result->big = big; + if (big) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7ESOF_BIG); return G_ARCH_OPERAND(result); } -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique le type de boutisme représenté. * -* * -* Retour : Type de boutisme. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *operand) -{ - return operand->big; - -} - - /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un opérande depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_armv7_endian_operand_unserialize(GArmV7EndianOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t big; /* Grand boutisme à afficher ? */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - result = extract_packed_buffer(pbuf, &big, sizeof(uint8_t), false); - - if (result) - operand->big = (big == 1 ? true : false); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Traduit un opérande en version humainement lisible. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t big; /* Grand boutisme à afficher ? */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - { - big = (operand->big ? 1 : 0); - result = extend_packed_buffer(pbuf, &big, sizeof(uint8_t), false); - } - - return result; + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ESOF_BIG)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL); + else + g_buffer_line_append_text(line, DLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL); } diff --git a/plugins/arm/v7/operands/estate.h b/plugins/arm/v7/operands/estate.h index d049357..9b75f9c 100644 --- a/plugins/arm/v7/operands/estate.h +++ b/plugins/arm/v7/operands/estate.h @@ -32,6 +32,14 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7EStateOpFlag +{ + A7ESOF_BIG = AOF_USER_FLAG(0), /* Grand boutisme à afficher ? */ + +} A7EStateOpFlag; + + #define G_TYPE_ARMV7_ENDIAN_OPERAND g_armv7_endian_operand_get_type() #define G_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperand)) #define G_IS_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_ENDIAN_OPERAND)) @@ -53,9 +61,6 @@ GType g_armv7_endian_operand_get_type(void); /* Crée une représentation de boutisme ARMv7. */ GArchOperand *g_armv7_endian_operand_new(bool); -/* Indique le type de boutisme représenté. */ -bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *); - #endif /* _PLUGINS_ARM_V7_OPERANDS_ESTATE_H */ diff --git a/plugins/arm/v7/operands/iflags.c b/plugins/arm/v7/operands/iflags.c index 019fd21..f24f2f4 100644 --- a/plugins/arm/v7/operands/iflags.c +++ b/plugins/arm/v7/operands/iflags.c @@ -29,15 +29,14 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande précisant un masque d'interruption ARMv7 (instance) */ struct _GArmV7IFlagsOperand { GArchOperand parent; /* Instance parente */ - bool abort_bit; /* Interruption d'arrêt async. */ - bool irq_bit; /* Interruption IRQ */ - bool fiq_bit; /* Interruption FIQ */ - }; @@ -61,20 +60,18 @@ static void g_armv7_iflags_operand_dispose(GArmV7IFlagsOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_iflags_operand_finalize(GArmV7IFlagsOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLine *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLine *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_iflags_operand_unserialize(GArmV7IFlagsOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_iflags_operand_serialize(const GArmV7IFlagsOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un opérande de masque d'interruption ARMv7. */ @@ -107,9 +104,6 @@ static void g_armv7_iflags_operand_class_init(GArmV7IFlagsOperandClass *klass) operand->print = (operand_print_fc)g_armv7_iflags_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_iflags_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_iflags_operand_serialize; - } @@ -127,9 +121,6 @@ static void g_armv7_iflags_operand_class_init(GArmV7IFlagsOperandClass *klass) static void g_armv7_iflags_operand_init(GArmV7IFlagsOperand *operand) { - operand->abort_bit = false; - operand->irq_bit = false; - operand->fiq_bit = false; } @@ -174,33 +165,6 @@ static void g_armv7_iflags_operand_finalize(GArmV7IFlagsOperand *operand) /****************************************************************************** * * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *operand, GBufferLine *line) -{ - if (operand->abort_bit) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "A", 1, RTT_REGISTER, NULL); - - if (operand->irq_bit) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "I", 1, RTT_REGISTER, NULL); - - if (operand->fiq_bit) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "F", 1, RTT_REGISTER, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : a = bit d'arrêt asynchrone. * * i = bit d'interruption IRQ. * * f = bit d'interruption FIQ. * @@ -219,119 +183,48 @@ GArchOperand *g_armv7_iflags_operand_new(bool a, bool i, bool f) result = g_object_new(G_TYPE_ARMV7_IFLAGS_OPERAND, NULL); - result->abort_bit = a; - result->irq_bit = i; - result->fiq_bit = f; + if (a) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_ABORT); + + if (i) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_IRQ); + + if (f) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_FIQ); return G_ARCH_OPERAND(result); } + /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un opérande depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_armv7_iflags_operand_unserialize(GArmV7IFlagsOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_iflags_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->abort_bit = (boolean == 1 ? true : false); - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->irq_bit = (boolean == 1 ? true : false); - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->fiq_bit = (boolean == 1 ? true : false); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Traduit un opérande en version humainement lisible. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_iflags_operand_serialize(const GArmV7IFlagsOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *operand, GBufferLine *line) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_iflags_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - { - boolean = (operand->abort_bit ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } - - if (result) - { - boolean = (operand->irq_bit ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_ABORT)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "A", 1, RTT_REGISTER, NULL); - if (result) - { - boolean = (operand->fiq_bit ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_IRQ)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "I", 1, RTT_REGISTER, NULL); - return result; + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_FIQ)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "F", 1, RTT_REGISTER, NULL); } diff --git a/plugins/arm/v7/operands/iflags.h b/plugins/arm/v7/operands/iflags.h index c0155a1..a198c85 100644 --- a/plugins/arm/v7/operands/iflags.h +++ b/plugins/arm/v7/operands/iflags.h @@ -33,6 +33,16 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7IFlagsOpFlag +{ + A7IFOF_ABORT = AOF_USER_FLAG(0), /* Interruption d'arrêt async. */ + A7IFOF_IRQ = AOF_USER_FLAG(1), /* Interruption IRQ */ + A7IFOF_FIQ = AOF_USER_FLAG(2), /* Interruption FIQ */ + +} A7IFlagsOpFlag; + + #define G_TYPE_ARMV7_IFLAGS_OPERAND g_armv7_iflags_operand_get_type() #define G_ARMV7_IFLAGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_IFLAGS_OPERAND, GArmV7IFlagsOperand)) #define G_IS_ARMV7_IFLAGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_IFLAGS_OPERAND)) diff --git a/plugins/arm/v7/operands/it.c b/plugins/arm/v7/operands/it.c index 6fab598..54e15ed 100644 --- a/plugins/arm/v7/operands/it.c +++ b/plugins/arm/v7/operands/it.c @@ -33,6 +33,9 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande organisant l'application d'une instruction IT (instance) */ struct _GArmV7ITCondOperand { @@ -64,23 +67,28 @@ static void g_armv7_itcond_operand_dispose(GArmV7ITCondOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GArmV7ITCondOperand *); +static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GArmV7ITCondOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *, GBufferLine *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_itcond_operand_serialize(const GArmV7ITCondOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour l'application d'une instruction IT. */ @@ -105,16 +113,17 @@ static void g_armv7_itcond_operand_class_init(GArmV7ITCondOperandClass *klass) GArchOperandClass *operand; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); - operand = G_ARCH_OPERAND_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_itcond_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_armv7_itcond_operand_finalize; + operand = G_ARCH_OPERAND_CLASS(klass); + operand->compare = (operand_compare_fc)g_armv7_itcond_operand_compare; operand->print = (operand_print_fc)g_armv7_itcond_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_itcond_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_itcond_operand_serialize; + operand->load = (load_operand_fc)g_armv7_itcond_operand_load; + operand->store = (store_operand_fc)g_armv7_itcond_operand_store; } @@ -177,127 +186,115 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : firstcond = valeur brute de la condition d'exécution. * +* mask = masque d'interprétation pour l'instruction. * * * -* Description : Compare un opérande avec un autre. * +* Description : Crée un opérande lié à une instruction IT. * * * -* Retour : Bilan de la comparaison. * +* Retour : Opérande mis en place. * * * * Remarques : - * * * ******************************************************************************/ -static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b) +GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask) { - int result; /* Bilan à faire remonter */ + GArmV7ITCondOperand *result; /* Structure à retourner */ - result = sort_boolean(a->firstcond, b->firstcond); + if (firstcond > ACC_NV) + return NULL; - if (result == 0) - result = sort_unsigned_long(a->mask, b->mask); + result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL); - return result; + result->firstcond = firstcond; + result->mask = mask; + + return G_ARCH_OPERAND(result); } /****************************************************************************** * * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * +* Paramètres : operand = opérande à consulter. * * * -* Description : Traduit un opérande en version humainement lisible. * +* Description : Fournit la condition associée à l'opérande. * * * -* Retour : - * +* Retour : Condition classique pour ARMv7. * * * * Remarques : - * * * ******************************************************************************/ -static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBufferLine *line) +ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand) { - const char *kw; /* Mot clef à imprimer */ - - switch (operand->firstcond) - { - case ACC_EQ: kw = "EQ"; break; - case ACC_NE: kw = "NE"; break; - case ACC_HS: kw = "HS"; break; - case ACC_LO: kw = "LO"; break; - case ACC_MI: kw = "MI"; break; - case ACC_PL: kw = "PL"; break; - case ACC_VS: kw = "VS"; break; - case ACC_VC: kw = "VC"; break; - case ACC_HI: kw = "HI"; break; - case ACC_LS: kw = "LS"; break; - case ACC_GE: kw = "GE"; break; - case ACC_LT: kw = "LT"; break; - case ACC_GT: kw = "GT"; break; - case ACC_LE: kw = "LE"; break; - case ACC_AL: kw = NULL; break; - case ACC_NV: kw = "NV"; break; - - default: /* Pour GCC... */ - assert(false); - kw = NULL; - break; + ArmCondCode result; /* Condition à renvoyer */ - } + result = operand->firstcond; - if (kw != NULL) - g_buffer_line_append_text(line, DLC_ASSEMBLY, kw, 2, RTT_KEY_WORD, NULL); + return result; } /****************************************************************************** * * -* Paramètres : firstcond = valeur brute de la condition d'exécution. * -* mask = masque d'interprétation pour l'instruction. * +* Paramètres : operand = opérande à consulter. * * * -* Description : Crée un opérande lié à une instruction IT. * +* Description : Fournit le masque d'interprétation de la condition. * * * -* Retour : Opérande mis en place. * +* Retour : Masque de bits. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask) +uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand) { - GArmV7ITCondOperand *result; /* Structure à retourner */ + uint8_t result; /* Valeur à retourner */ - if (firstcond > ACC_NV) - return NULL; + result = operand->mask; - result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL); + return result; - result->firstcond = firstcond; - result->mask = mask; +} - return G_ARCH_OPERAND(result); -} + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : operand = opérande à consulter. * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * -* Description : Fournit la condition associée à l'opérande. * +* Description : Compare un opérande avec un autre. * * * -* Retour : Condition classique pour ARMv7. * +* Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ -ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand) +static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b, bool lock) { - ArmCondCode result; /* Condition à renvoyer */ + int result; /* Bilan à faire remonter */ + GArchOperandClass *class; /* Classe parente normalisée */ - result = operand->firstcond; + result = sort_boolean(a->firstcond, b->firstcond); + + if (result == 0) + result = sort_unsigned_long(a->mask, b->mask); + + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } return result; @@ -306,41 +303,60 @@ ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *oper /****************************************************************************** * * -* Paramètres : operand = opérande à consulter. * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Fournit le masque d'interprétation de la condition. * +* Description : Traduit un opérande en version humainement lisible. * * * -* Retour : Masque de bits. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand) +static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBufferLine *line) { - uint8_t result; /* Valeur à retourner */ - - result = operand->mask; + const char *kw; /* Mot clef à imprimer */ - return result; + switch (operand->firstcond) + { + case ACC_EQ: kw = "EQ"; break; + case ACC_NE: kw = "NE"; break; + case ACC_HS: kw = "HS"; break; + case ACC_LO: kw = "LO"; break; + case ACC_MI: kw = "MI"; break; + case ACC_PL: kw = "PL"; break; + case ACC_VS: kw = "VS"; break; + case ACC_VC: kw = "VC"; break; + case ACC_HI: kw = "HI"; break; + case ACC_LS: kw = "LS"; break; + case ACC_GE: kw = "GE"; break; + case ACC_LT: kw = "LT"; break; + case ACC_GT: kw = "GT"; break; + case ACC_LE: kw = "LE"; break; + case ACC_AL: kw = NULL; break; + case ACC_NV: kw = "NV"; break; -} + default: /* Pour GCC... */ + assert(false); + kw = NULL; + break; + } + if (kw != NULL) + g_buffer_line_append_text(line, DLC_ASSEMBLY, kw, 2, RTT_KEY_WORD, NULL); -/* ---------------------------------------------------------------------------------- */ -/* 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. * * * @@ -348,14 +364,14 @@ uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand) * * ******************************************************************************/ -static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) result = extract_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true); @@ -370,11 +386,11 @@ static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAs /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -382,14 +398,14 @@ static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAs * * ******************************************************************************/ -static bool g_armv7_itcond_operand_serialize(const GArmV7ITCondOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) result = extend_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true); diff --git a/plugins/arm/v7/operands/limitation.c b/plugins/arm/v7/operands/limitation.c index 0d29545..5d22681 100644 --- a/plugins/arm/v7/operands/limitation.c +++ b/plugins/arm/v7/operands/limitation.c @@ -30,13 +30,24 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7limop_extra_data_t +{ + 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 { GArchOperand parent; /* Instance parente */ - BarrierLimitationType type; /* Type de limitation */ - }; @@ -48,6 +59,21 @@ struct _GArmV7LimitationOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_LIMITATION_OP_EXTRA(op) (a7limop_extra_data_t *)&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,23 +86,28 @@ 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 *); +/* 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. */ @@ -109,8 +140,8 @@ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass * 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->load = (load_operand_fc)g_armv7_limitation_operand_load; + operand->store = (store_operand_fc)g_armv7_limitation_operand_store; } @@ -173,8 +204,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 +284,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 */ + + 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); - result = sort_unsigned_long(a->type, b->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 +334,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 +383,56 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *oper /****************************************************************************** * * -* Paramètres : raw = valeur brute de la limitation à considérer. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Crée une représentation d'une limitation pour barrière. * +* Description : Charge un contenu depuis une mémoire tampon. * * * -* Retour : Opérande mis en place. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_limitation_operand_new(uint8_t raw) +static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { - GArmV7LimitationOperand *result; /* Structure à retourner */ + 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 */ - result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL); + parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); - if (raw < 0b0010 || raw > 0b1111) - result->type = BLT_RESERVED; + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); - else - result->type = raw; + if (result) + { + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); - return G_ARCH_OPERAND(result); + LOCK_GOBJECT_EXTRA(extra); -} + result = unpack_uleb128(&value, pbuf); + if (result) + extra->type = value; -/****************************************************************************** -* * -* 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; - -} + UNLOCK_GOBJECT_EXTRA(extra); + } + 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. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -322,48 +440,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_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->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extract_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Sauvegarde un opérande dans une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ + { + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); -static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ + LOCK_GOBJECT_EXTRA(extra); - parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + result = pack_uleb128((uleb128_t []){ extra->type }, pbuf); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + UNLOCK_GOBJECT_EXTRA(extra); - if (result) - result = extend_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + } return result; diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c index 07f38a6..0b0d0b4 100644 --- a/plugins/arm/v7/operands/maccess.c +++ b/plugins/arm/v7/operands/maccess.c @@ -31,12 +31,14 @@ #include <arch/operand-int.h> #include <common/cpp.h> -#include <common/sort.h> #include <core/logs.h> #include <gtkext/gtkblockdisplay.h> +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande offrant un accès à la mémoire depuis une base (instance) */ struct _GArmV7MAccessOperand { @@ -45,8 +47,6 @@ struct _GArmV7MAccessOperand GArchOperand *base; /* Base de l'accès en mémoire */ GArchOperand *offset; /* Décalage pour l'adresse */ GArchOperand *shift; /* Décalage supplémentaire ? */ - bool post_indexed; /* Position du décalage */ - bool write_back; /* Mise à jour de la base */ }; @@ -71,8 +71,13 @@ static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *); +static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_maccess_operand_find_inner_operand_path(const GArmV7MAccessOperand *, const GArchOperand *); @@ -83,17 +88,17 @@ 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 *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_maccess_operand_load(GArmV7MAccessOperand *, GObjectStorage *, packed_buffer_t *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_maccess_operand_store(GArmV7MAccessOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un accès à la mémoire depuis une base. */ @@ -130,8 +135,8 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass) operand->print = (operand_print_fc)g_armv7_maccess_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_maccess_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_maccess_operand_serialize; + operand->load = (load_operand_fc)g_armv7_maccess_operand_load; + operand->store = (store_operand_fc)g_armv7_maccess_operand_store; } @@ -171,14 +176,9 @@ static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand) static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *operand) { - if (operand->base != NULL) - g_object_unref(G_OBJECT(operand->base)); - - if (operand->offset != NULL) - g_object_unref(G_OBJECT(operand->offset)); - - if (operand->shift != NULL) - g_object_unref(G_OBJECT(operand->shift)); + g_clear_object(&operand->base); + g_clear_object(&operand->offset); + g_clear_object(&operand->shift); G_OBJECT_CLASS(g_armv7_maccess_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -206,8 +206,109 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : base = représente le registre de la base d'accès. * +* offset = détermine le décalage entre l'adresse et la base. * +* shift = opération de décalage pour jouer sur le décalage. * +* post = précise la forme donnée au décalage à appliquer. * +* wback = indique une mise à jour de la base après usage. * +* * +* Description : Crée un accès à la mémoire depuis une base et un décalage. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool post, bool wback) +{ + GArmV7MAccessOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_MACCESS_OPERAND, NULL); + + result->base = base; + result->offset = offset; + result->shift = shift; + + if (post) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7MAOF_POST_INDEXED); + + if (wback) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7MAOF_WRITE_BACK); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la base d'un accès à la mémoire. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *operand) +{ + return operand->base; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit le décalage d'un accès à la mémoire depuis la base. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *operand) +{ + return operand->offset; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit le décalage d'un décalage pour un accès mémoire. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *operand) +{ + return operand->shift; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -217,25 +318,24 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand) * * ******************************************************************************/ -static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const GArmV7MAccessOperand *b) +static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const GArmV7MAccessOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_operand_compare(a->base, b->base); - if (result != 0) goto gamoc_done; - - result = sort_pointer(a->offset, b->offset, (__compar_fn_t)g_arch_operand_compare); - if (result != 0) goto gamoc_done; - result = sort_pointer(a->shift, b->shift, (__compar_fn_t)g_arch_operand_compare); - if (result != 0) goto gamoc_done; - - result = sort_boolean(a->post_indexed, b->post_indexed); - if (result != 0) goto gamoc_done; + if (result) + result = g_arch_operand_compare(a->offset, b->offset); - result = sort_boolean(a->write_back, b->write_back); + if (result) + result = g_arch_operand_compare(a->shift, b->shift); - gamoc_done: + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } return result; @@ -392,11 +492,17 @@ static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const G static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, GBufferLine *line) { + bool post; /* Forme post-indexée ? */ + bool wback; /* Ecriture après coup ? */ + + post = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7MAOF_POST_INDEXED); + wback = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7MAOF_WRITE_BACK); + g_buffer_line_append_text(line, DLC_ASSEMBLY, "[", 1, RTT_HOOK, NULL); g_arch_operand_print(operand->base, line); - if (operand->post_indexed) + if (post) g_buffer_line_append_text(line, DLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL); if (operand->offset != NULL) @@ -417,10 +523,10 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G } - if (!operand->post_indexed) + if (!post) g_buffer_line_append_text(line, DLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL); - if (operand->post_indexed && operand->write_back) + if (post && wback) g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); } @@ -428,147 +534,11 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G /****************************************************************************** * * -* Paramètres : base = représente le registre de la base d'accès. * -* offset = détermine le décalage entre l'adresse et la base. * -* shift = opération de décalage pour jouer sur le décalage. * -* post = précise la forme donnée au décalage à appliquer. * -* wback = indique une mise à jour de la base après usage. * -* * -* Description : Crée un accès à la mémoire depuis une base et un décalage. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool post, bool wback) -{ - GArmV7MAccessOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV7_MACCESS_OPERAND, NULL); - - result->base = base; - result->offset = offset; - result->shift = shift; - - result->post_indexed = post; - result->write_back = wback; - - return G_ARCH_OPERAND(result); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit la base d'un accès à la mémoire. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *operand) -{ - return operand->base; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit le décalage d'un accès à la mémoire depuis la base. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *operand) -{ - return operand->offset; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit le décalage d'un décalage pour un accès mémoire. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *operand) -{ - return operand->shift; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique si le décalage est post-indexé. * -* * -* Retour : Statut des opérations menées. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_armv7_maccess_operand_is_post_indexed(const GArmV7MAccessOperand *operand) -{ - return operand->post_indexed; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique si la base est mise à jour après usage. * -* * -* Retour : Statut des opérations menées. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *operand) -{ - return operand->write_back; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -576,80 +546,46 @@ bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *opera * * ******************************************************************************/ -static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_maccess_operand_load(GArmV7MAccessOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *subop; /* Sous-opérande à intégrer */ - uint8_t boolean; /* Valeur booléenne */ + GSerializableObject *obj; /* Instance à manipuler */ parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - subop = g_arch_operand_load(storage, format, pbuf); - - if (subop == NULL) - result = false; - - else - operand->base = subop; - - } + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result && boolean == 1) - { - subop = g_arch_operand_load(storage, format, pbuf); + obj = g_object_storage_unpack_object(storage, "operands", pbuf); - if (subop == NULL) - result = false; + result = (obj != NULL); - else - operand->offset = subop; - - } + if (result) + operand->base = G_ARCH_OPERAND(obj); } if (result) { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result && boolean == 1) - { - subop = g_arch_operand_load(storage, format, pbuf); - - if (subop == NULL) - result = false; + obj = g_object_storage_unpack_object(storage, "operands", pbuf); - else - operand->shift = subop; - - } - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + result = (obj != NULL); if (result) - operand->post_indexed = (boolean == 1 ? true : false); + operand->offset = G_ARCH_OPERAND(obj); } if (result) { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + obj = g_object_storage_unpack_object(storage, "operands", pbuf); + + result = (obj != NULL); if (result) - operand->write_back = (boolean == 1 ? true : false); + operand->shift = G_ARCH_OPERAND(obj); } @@ -660,11 +596,11 @@ static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, G /****************************************************************************** * * -* 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. * * * @@ -672,61 +608,32 @@ static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, G * * ******************************************************************************/ -static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_maccess_operand_store(GArmV7MAccessOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ + GSerializableObject *obj; /* Instance à manipuler */ parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - result = g_arch_operand_store(operand->base, storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - if (operand->offset == NULL) - result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false); - - else - { - result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false); - - if (result) - result = g_arch_operand_store(operand->offset, storage, pbuf); - - } - - } - - if (result) - { - if (operand->shift == NULL) - result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false); - - else - { - result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false); - - if (result) - result = g_arch_operand_store(operand->shift, storage, pbuf); - - } - + obj = G_SERIALIZABLE_OBJECT(operand->base); + result = g_object_storage_pack_object(storage, "operands", obj, pbuf); } if (result) { - boolean = (operand->post_indexed ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + obj = G_SERIALIZABLE_OBJECT(operand->offset); + result = g_object_storage_pack_object(storage, "operands", obj, pbuf); } if (result) { - boolean = (operand->write_back ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + obj = G_SERIALIZABLE_OBJECT(operand->shift); + result = g_object_storage_pack_object(storage, "operands", obj, pbuf); } return result; diff --git a/plugins/arm/v7/operands/maccess.h b/plugins/arm/v7/operands/maccess.h index bc80cfa..eb39c30 100644 --- a/plugins/arm/v7/operands/maccess.h +++ b/plugins/arm/v7/operands/maccess.h @@ -36,6 +36,15 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7MAccessOpFlag +{ + A7MAOF_POST_INDEXED = AOF_USER_FLAG(0), /* Position du décalage */ + A7MAOF_WRITE_BACK = AOF_USER_FLAG(1), /* Mise à jour de la base */ + +} A7MAccessOpFlag; + + #define G_TYPE_ARMV7_MACCESS_OPERAND g_armv7_maccess_operand_get_type() #define G_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperand)) #define G_IS_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_MACCESS_OPERAND)) diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c index 615e296..fc68638 100644 --- a/plugins/arm/v7/operands/offset.c +++ b/plugins/arm/v7/operands/offset.c @@ -29,17 +29,18 @@ #include <arch/operand-int.h> -#include <common/sort.h> #include <gtkext/gtkblockdisplay.h> +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (instance) */ struct _GArmV7OffsetOperand { GArchOperand parent; /* Instance parente */ - bool positive; /* Sens du décalage */ GArchOperand *value; /* Valeur du décalage */ }; @@ -65,8 +66,13 @@ static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *); +static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_offset_operand_find_inner_operand_path(const GArmV7OffsetOperand *, const GArchOperand *); @@ -77,17 +83,17 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA /* Traduit un opérande en version humainement lisible. */ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *, GBufferLine *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_offset_operand_load(GArmV7OffsetOperand *, GObjectStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_offset_operand_store(GArmV7OffsetOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un décalage relatif ARMv7. */ @@ -124,8 +130,8 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass) operand->print = (operand_print_fc)g_armv7_offset_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_offset_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_offset_operand_serialize; + operand->load = (load_operand_fc)g_armv7_offset_operand_load; + operand->store = (store_operand_fc)g_armv7_offset_operand_store; } @@ -163,8 +169,7 @@ static void g_armv7_offset_operand_init(GArmV7OffsetOperand *operand) static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *operand) { - if (operand->value != NULL) - g_object_unref(G_OBJECT(operand->value)); + g_clear_object(&operand->value); G_OBJECT_CLASS(g_armv7_offset_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -192,8 +197,69 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : positive = indique si la quantité doit être ajoutée ou non. * +* value = valeur du décalage à appliquer. * +* * +* Description : Crée un décalage selon un sens et une valeur donnés. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value) +{ + GArmV7OffsetOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_OFFSET_OPERAND, NULL); + + if (positive) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7OOF_POSITIVE); + + result->value = value; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la valeur utilisée pour un décalage. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operand) +{ + GArchOperand *result; /* Instance à retourner */ + + result = operand->value; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -203,16 +269,18 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *operand) * * ******************************************************************************/ -static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GArmV7OffsetOperand *b) +static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GArmV7OffsetOperand *b, bool lock) { int result; /* Bilan à faire remonter */ - - result = sort_boolean(a->positive, b->positive); - if (result != 0) goto gaooc_done; + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_operand_compare(a->value, b->value); - gaooc_done: + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } return result; @@ -299,7 +367,7 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBufferLine *line) { - if (!operand->positive) + if (!g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7OOF_POSITIVE)) g_buffer_line_append_text(line, DLC_ASSEMBLY, "-", 1, RTT_KEY_WORD, NULL); g_arch_operand_print(operand->value, line); @@ -309,89 +377,11 @@ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBu /****************************************************************************** * * -* Paramètres : positive = indique si la quantité doit être ajoutée ou non. * -* value = valeur du décalage à appliquer. * -* * -* Description : Crée un décalage selon un sens et une valeur donnés. * -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value) -{ - GArmV7OffsetOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV7_OFFSET_OPERAND, NULL); - - result->positive = positive; - result->value = value; - - return G_ARCH_OPERAND(result); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique le sens du décalage représenté. * -* * -* Retour : Indication d'ajout ou de retrait. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Remarques : - * -* * -******************************************************************************/ - -bool g_armv7_offset_operand_is_positive(const GArmV7OffsetOperand *operand) -{ - return operand->positive; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit la valeur utilisée pour un décalage. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operand) -{ - GArchOperand *result; /* Instance à retourner */ - - result = operand->value; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -399,35 +389,24 @@ GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operan * * ******************************************************************************/ -static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_offset_operand_load(GArmV7OffsetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *value; /* Valeur à intégrer */ - uint8_t positive; /* Sens du décalage */ + GSerializableObject *value; /* Valeur du décalage */ parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - value = g_arch_operand_load(storage, format, pbuf); - - if (value == NULL) - result = false; + value = g_object_storage_unpack_object(storage, "operands", pbuf); - else - operand->value = value; - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &positive, sizeof(uint8_t), false); + result = (value != NULL); if (result) - operand->positive = (positive == 1 ? true : false); + operand->value = G_ARCH_OPERAND(value); } @@ -438,11 +417,11 @@ static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAs /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -450,25 +429,22 @@ static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAs * * ******************************************************************************/ -static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_offset_operand_store(GArmV7OffsetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t positive; /* Sens du décalage */ + GSerializableObject *value; /* Valeur du décalage */ parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - positive = (operand->positive ? 1 : 0); - result = extend_packed_buffer(pbuf, &positive, sizeof(uint8_t), false); + value = G_SERIALIZABLE_OBJECT(operand->value); + result = g_object_storage_pack_object(storage, "operands", value, pbuf); } - if (result) - result = g_arch_operand_store(operand->value, storage, pbuf); - return result; } diff --git a/plugins/arm/v7/operands/offset.h b/plugins/arm/v7/operands/offset.h index aa4df5e..0b5f1bf 100644 --- a/plugins/arm/v7/operands/offset.h +++ b/plugins/arm/v7/operands/offset.h @@ -36,6 +36,14 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7OffOpFlag +{ + A7OOF_POSITIVE = AOF_USER_FLAG(0), /* Sens du décalage */ + +} A7OffOpFlag; + + #define G_TYPE_ARMV7_OFFSET_OPERAND g_armv7_offset_operand_get_type() #define G_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperand)) #define G_IS_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_OFFSET_OPERAND)) @@ -57,9 +65,6 @@ GType g_armv7_offset_operand_get_type(void); /* Crée un décalage selon un sens et une valeur donnés. */ GArchOperand *g_armv7_offset_operand_new(bool, GArchOperand *); -/* Indique le sens du décalage représenté. */ -bool g_armv7_offset_operand_is_positive(const GArmV7OffsetOperand *); - /* Founit la valeur utilisée pour un décalage. */ GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *); diff --git a/plugins/arm/v7/operands/register.c b/plugins/arm/v7/operands/register.c index bfbaa70..dce8fef 100644 --- a/plugins/arm/v7/operands/register.c +++ b/plugins/arm/v7/operands/register.c @@ -29,15 +29,15 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande visant un registre ARMv7 (instance) */ struct _GArmV7RegisterOperand { GRegisterOperand parent; /* Instance parente */ unsigned int alignment; /* Eventuel alignement */ - bool has_alignment; /* Validité du champ */ - - bool write_back; /* Mise à jour du registre ? */ }; @@ -62,22 +62,27 @@ static void g_armv7_register_operand_dispose(GArmV7RegisterOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_armv7_register_operand_print(const GArmV7RegisterOperand *, GBufferLine *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_register_operand_print(const GArmV7RegisterOperand *, GBufferLine *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_register_operand_load(GArmV7RegisterOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_register_operand_store(GArmV7RegisterOperand *, GObjectStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini par la GLib pour un opérande de registre ARMv7. */ G_DEFINE_TYPE(GArmV7RegisterOperand, g_armv7_register_operand, G_TYPE_REGISTER_OPERAND); @@ -108,8 +113,8 @@ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klas operand->print = (operand_print_fc)g_armv7_register_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_register_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_register_operand_serialize; + operand->load = (load_operand_fc)g_armv7_register_operand_load; + operand->store = (store_operand_fc)g_armv7_register_operand_store; } @@ -128,7 +133,6 @@ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klas static void g_armv7_register_operand_init(GArmV7RegisterOperand *operand) { - operand->write_back = false; } @@ -173,33 +177,6 @@ static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *operand) /****************************************************************************** * * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_register_operand_print(const GArmV7RegisterOperand *operand, GBufferLine *line) -{ - GArchOperandClass *parent; /* Classe parente */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); - - parent->print(G_ARCH_OPERAND(operand), line); - - if (operand->write_back) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : reg = registre déjà en place. * * * * Description : Crée un opérande visant un registre ARMv7. * @@ -240,7 +217,7 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *operand, { operand->alignment = align; - operand->has_alignment = true; + g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT); } @@ -260,48 +237,51 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *operand, void g_armv7_register_operand_write_back(GArmV7RegisterOperand *operand, bool wback) { - operand->write_back = wback; + g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_WRITE_BACK); } + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : operand = opérande représentant un registre. * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Indique si le registre est mis à jour après coup. * +* Description : Traduit un opérande en version humainement lisible. * * * -* Retour : Evolution du registre. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *operand) +static void g_armv7_register_operand_print(const GArmV7RegisterOperand *operand, GBufferLine *line) { - bool result; /* Statut à retourner */ - - result = operand->write_back; - - return result; + GArchOperandClass *parent; /* Classe parente */ -} + parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + parent->print(G_ARCH_OPERAND(operand), line); + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_WRITE_BACK)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); -/* ---------------------------------------------------------------------------------- */ -/* 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. * * * @@ -309,37 +289,18 @@ bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *opera * * ******************************************************************************/ -static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_register_operand_load(GArmV7RegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ parent = G_ARCH_OPERAND_CLASS(g_armv7_register_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, &boolean, sizeof(uint8_t), false); - - if (result) - operand->has_alignment = (boolean == 1 ? true : false); - - } - - if (result && operand->has_alignment) + 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); - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->write_back = (boolean == 1 ? true : false); - - } - return result; } @@ -347,11 +308,11 @@ static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -359,31 +320,18 @@ static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, * * ******************************************************************************/ -static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_register_operand_store(GArmV7RegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); - if (result) - { - boolean = (operand->has_alignment ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } - - if (result && operand->has_alignment) + 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); - if (result) - { - boolean = (operand->write_back ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } - return result; } diff --git a/plugins/arm/v7/operands/register.h b/plugins/arm/v7/operands/register.h index 241c101..26e03c0 100644 --- a/plugins/arm/v7/operands/register.h +++ b/plugins/arm/v7/operands/register.h @@ -36,6 +36,15 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7RegOpFlag +{ + A7ROF_HAS_ALIGNMENT = AOF_USER_FLAG(0), /* Validité de l'alignement */ + A7ROF_WRITE_BACK = AOF_USER_FLAG(1), /* Mise à jour du registre ? */ + +} A7RegOpFlag; + + #define G_TYPE_ARMV7_REGISTER_OPERAND g_armv7_register_operand_get_type() #define G_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_REGISTER_OPERAND, GArmV7RegisterOperand)) #define G_IS_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_REGISTER_OPERAND)) @@ -63,9 +72,6 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *, unsigne /* Détermine si le registre est mis à jour après l'opération. */ void g_armv7_register_operand_write_back(GArmV7RegisterOperand *, bool); -/* Indique si le registre est mis à jour après coup. */ -bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *); - #endif /* _PLUGINS_ARM_V7_OPERANDS_REGISTER_H */ diff --git a/plugins/arm/v7/operands/reglist.c b/plugins/arm/v7/operands/reglist.c index 2b2ee10..21407a4 100644 --- a/plugins/arm/v7/operands/reglist.c +++ b/plugins/arm/v7/operands/reglist.c @@ -39,6 +39,9 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande listant une série de registres ARM (instance) */ struct _GArmV7RegListOperand { @@ -70,23 +73,28 @@ static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const GArmV7RegListOperand *); +static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const GArmV7RegListOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *, GBufferLine *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_reglist_operand_load(GArmV7RegListOperand *, GObjectStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_reglist_operand_store(GArmV7RegListOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *, GAsmStorage *, packed_buffer_t *); - +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une liste de registres ARM. */ @@ -119,8 +127,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->unserialize = (unserialize_operand_fc)g_armv7_reglist_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_reglist_operand_serialize; + operand->load = (load_operand_fc)g_armv7_reglist_operand_load; + operand->store = (store_operand_fc)g_armv7_reglist_operand_store; } @@ -162,7 +170,7 @@ static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *operand) size_t i; /* Boucle de parcours */ for (i = 0; i < operand->count; i++) - g_object_unref(G_OBJECT(operand->registers[i])); + g_clear_object(&operand->registers[i]); G_OBJECT_CLASS(g_armv7_reglist_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -193,88 +201,6 @@ static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * -* * -* Description : Compare un opérande avec un autre. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *a, const GArmV7RegListOperand *b) -{ - int result; /* Bilan à faire remonter */ - size_t i; /* Boucle de parcours */ - GArchRegister *ra; /* Registre de la liste A */ - GArchRegister *rb; /* Registre de la liste B */ - - /* Création de l'objet... */ - if (b == NULL) - { - result = 1; - goto garoc_done; - } - - result = sort_unsigned_long(a->count, b->count); - if (result != 0) goto garoc_done; - - for (i = 0; i < a->count && result == 0; i++) - { - ra = G_ARCH_REGISTER(a->registers[i]); - rb = G_ARCH_REGISTER(b->registers[i]); - - result = g_arch_register_compare(ra, rb); - - } - - garoc_done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line) -{ - size_t i; /* Boucle de parcours */ - - g_buffer_line_append_text(line, DLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL); - - for (i = 0; i < operand->count; i++) - { - if (i > 0) - { - g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); - } - - g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line); - - } - - g_buffer_line_append_text(line, DLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : selected = masque de bits pour les registres à intégrer. * * * * Description : Crée une liste vierge de registres ARM. * @@ -322,8 +248,7 @@ GArchOperand *g_armv7_reglist_operand_new(uint16_t selected) void g_armv7_reglist_add_register(GArmV7RegListOperand *operand, GArmV7Register *reg) { - operand->registers = (GArmV7Register **)realloc(operand->registers, - ++operand->count * sizeof(GArmV7Register *)); + operand->registers = realloc(operand->registers, ++operand->count * sizeof(GArmV7Register *)); operand->registers[operand->count - 1] = reg; @@ -408,80 +333,106 @@ bool g_armv7_reglist_operand_has_register(const GArmV7RegListOperand *operand, c /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Compare un opérande avec un autre. * * * -* Retour : Bilan de l'opération. * +* Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *a, const GArmV7RegListOperand *b, bool lock) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - size_t count; /* Quantité de registres */ - packed_buffer_t reg_pbuf; /* Tampon des données à écrire */ + int result; /* Bilan à faire remonter */ size_t i; /* Boucle de parcours */ - off64_t pos; /* Position dans le flux */ - GArchRegister *reg; /* Registre restauré */ + GArchRegister *ra; /* Registre de la liste A */ + GArchRegister *rb; /* Registre de la liste B */ + GArchOperandClass *class; /* Classe parente normalisée */ - parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + /* Création de l'objet... */ + if (b == NULL) + { + result = 1; + goto done; + } - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = sort_unsigned_long(a->count, b->count); - if (result) - result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); + for (i = 0; i < a->count && result == 0; i++) + { + ra = G_ARCH_REGISTER(a->registers[i]); + rb = G_ARCH_REGISTER(b->registers[i]); - if (result) + result = g_arch_register_compare(ra, rb); + + } + + if (result == 0) { - init_packed_buffer(®_pbuf); + class = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } - for (i = 0; i < count && result; i++) - { - result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true); + done: - if (result) - result = g_asm_storage_load_register_data(storage, ®_pbuf, pos); + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - if (result) - { - reg = NULL;//g_arch_register_load(storage, ®_pbuf); - result = (reg != NULL); - } +static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line) +{ + size_t i; /* Boucle de parcours */ - if (result) - g_armv7_reglist_add_register(operand, G_ARMV7_REGISTER(reg)); + g_buffer_line_append_text(line, DLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL); + for (i = 0; i < operand->count; i++) + { + if (i > 0) + { + g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } - exit_packed_buffer(®_pbuf); + g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line); } - return result; + g_buffer_line_append_text(line, DLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL); } /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -489,39 +440,69 @@ static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, G * * ******************************************************************************/ -static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_reglist_operand_load(GArmV7RegListOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + size_t count; /* Quantité de registres */ size_t i; /* Boucle de parcours */ - off64_t pos; /* Position dans le flux */ - packed_buffer_t reg_pbuf; /* Tampon des données à écrire */ + GSerializableObject *reg; /* Registre de la liste */ parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); - if (result) + for (i = 0; i < count && result; i++) { - init_packed_buffer(®_pbuf); + reg = g_object_storage_unpack_object(storage, "registers", pbuf); - for (i = 0; i < operand->count && result; i++) - { - result = false;//g_arch_register_store(G_ARCH_REGISTER(operand->registers[i]), storage, ®_pbuf); + result = (reg != NULL); - if (result) - result = g_asm_storage_store_register_data(storage, ®_pbuf, &pos); + if (result) + g_armv7_reglist_add_register(operand, G_ARMV7_REGISTER(reg)); - if (result) - result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true); + } - } + return result; - exit_packed_buffer(®_pbuf); +} + +/****************************************************************************** +* * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un contenu dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_armv7_reglist_operand_store(GArmV7RegListOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + size_t i; /* Boucle de parcours */ + GSerializableObject *reg; /* Registre de la liste */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + + for (i = 0; i < operand->count && result; i++) + { + reg = G_SERIALIZABLE_OBJECT(operand->registers[i]); + result = g_object_storage_pack_object(storage, "registers", reg, pbuf); } return result; diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c index 05889f4..85f7290 100644 --- a/plugins/arm/v7/operands/rotation.c +++ b/plugins/arm/v7/operands/rotation.c @@ -34,6 +34,9 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande visant une opérande de rotation ARMv7 (instance) */ struct _GArmV7RotationOperand { @@ -64,8 +67,13 @@ static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *); +static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_rotation_operand_find_inner_operand_path(const GArmV7RotationOperand *, const GArchOperand *); @@ -76,17 +84,17 @@ 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 *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_rotation_operand_load(GArmV7RotationOperand *, GObjectStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_rotation_operand_store(GArmV7RotationOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une opérande de rotation ARMv7. */ @@ -123,8 +131,8 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas operand->print = (operand_print_fc)g_armv7_rotation_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_rotation_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_rotation_operand_serialize; + operand->load = (load_operand_fc)g_armv7_rotation_operand_load; + operand->store = (store_operand_fc)g_armv7_rotation_operand_store; } @@ -162,8 +170,7 @@ static void g_armv7_rotation_operand_init(GArmV7RotationOperand *operand) static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *operand) { - if (operand->value != NULL) - g_object_unref(G_OBJECT(operand->value)); + g_clear_object(&operand->value); G_OBJECT_CLASS(g_armv7_rotation_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -191,8 +198,65 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérandes de rotation ARMv7. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value) +{ + GArmV7RotationOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL); + + result->value = value; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la valeur utilisée pour une rotation. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand) +{ + GArchOperand *result; /* Instance à retourner */ + + result = operand->value; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -202,12 +266,19 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand) * * ******************************************************************************/ -static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, const GArmV7RotationOperand *b) +static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, const GArmV7RotationOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_operand_compare(a->value, b->value); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + return result; } @@ -326,68 +397,11 @@ static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *operand, /****************************************************************************** * * -* Paramètres : - * -* * -* Description : Crée un réceptacle pour opérandes de rotation ARMv7. * -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value) -{ - GArmV7RotationOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL); - - result->value = value; - - return G_ARCH_OPERAND(result); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Founit la valeur utilisée pour une rotation. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand) -{ - GArchOperand *result; /* Instance à retourner */ - - result = operand->value; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* 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. * * * @@ -395,25 +409,24 @@ GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *op * * ******************************************************************************/ -static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_rotation_operand_load(GArmV7RotationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *value; /* Valeur à intégrer */ + GSerializableObject *value; /* Valeur de la rotation */ parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - value = g_arch_operand_load(storage, format, pbuf); + value = g_object_storage_unpack_object(storage, "operands", pbuf); - if (value == NULL) - result = false; + result = (value != NULL); - else - operand->value = value; + if (result) + operand->value = G_ARCH_OPERAND(value); } @@ -424,11 +437,11 @@ static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -436,17 +449,21 @@ static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, * * ******************************************************************************/ -static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_rotation_operand_store(GArmV7RotationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + GSerializableObject *value; /* Valeur de la rotation */ parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = g_arch_operand_store(operand->value, storage, pbuf); + { + value = G_SERIALIZABLE_OBJECT(operand->value); + result = g_object_storage_pack_object(storage, "operands", value, pbuf); + } return result; diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c index 852e677..8c00753 100644 --- a/plugins/arm/v7/operands/shift.c +++ b/plugins/arm/v7/operands/shift.c @@ -34,12 +34,24 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7shiftop_extra_data_t +{ + operand_extra_data_t parent; /* A laisser en premier */ + + SRType shift_type; /* Type de décalage */ + +} a7shiftop_extra_data_t; + + /* Définition d'un opérande visant une opérande de décalage ARMv7 (instance) */ struct _GArmV7ShiftOperand { GArchOperand parent; /* Instance parente */ - SRType shift_type; /* Type de décalage */ GArchOperand *shift_value; /* Valeur du décalage */ }; @@ -53,6 +65,21 @@ struct _GArmV7ShiftOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_SHIFT_OP_EXTRA(op) (a7shiftop_extra_data_t *)&op->extra + +#else + +# define GET_ARMV7_SHIFT_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7shiftop_extra_data_t) + +#endif + + /* Initialise la classe des opérandes de décalage ARMv7. */ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *); @@ -65,8 +92,13 @@ static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *); +static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_shift_operand_find_inner_operand_path(const GArmV7ShiftOperand *, const GArchOperand *); @@ -77,17 +109,17 @@ 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 *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *, GObjectStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une opérande de décalage ARMv7. */ @@ -124,8 +156,8 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass) operand->print = (operand_print_fc)g_armv7_shift_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_shift_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_shift_operand_serialize; + operand->load = (load_operand_fc)g_armv7_shift_operand_load; + operand->store = (store_operand_fc)g_armv7_shift_operand_store; } @@ -163,8 +195,7 @@ static void g_armv7_shift_operand_init(GArmV7ShiftOperand *operand) static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *operand) { - if (operand->shift_value != NULL) - g_object_unref(G_OBJECT(operand->shift_value)); + g_clear_object(&operand->shift_value); G_OBJECT_CLASS(g_armv7_shift_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -192,8 +223,100 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérande de décalage ARMv7. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_shift_operand_new(SRType type, GArchOperand *value) +{ + GArmV7ShiftOperand *result; /* Structure à retourner */ + a7shiftop_extra_data_t *extra; /* Données insérées à modifier */ + + result = g_object_new(G_TYPE_ARMV7_SHIFT_OPERAND, NULL); + + extra = GET_ARMV7_SHIFT_OP_EXTRA(result); + + extra->shift_type = type; + + result->shift_value = value; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique la forme de décalage représenté. * +* * +* Retour : Type de décalage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +SRType g_armv7_shift_operand_get_shift_type(const GArmV7ShiftOperand *operand) +{ + SRType result; /* Type à retourner */ + a7shiftop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->shift_type; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la valeur utilisée pour un décalage. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *operand) +{ + GArchOperand *result; /* Instance à retourner */ + + result = operand->shift_value; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -203,16 +326,38 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *operand) * * ******************************************************************************/ -static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArmV7ShiftOperand *b) +static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArmV7ShiftOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + a7shiftop_extra_data_t *ea; /* Données insérées à consulter*/ + a7shiftop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ - result = sort_unsigned_long(a->shift_type, b->shift_type); - if (result != 0) goto gasoc_done; + ea = GET_ARMV7_SHIFT_OP_EXTRA(a); + eb = GET_ARMV7_SHIFT_OP_EXTRA(b); - result = g_arch_operand_compare(a->shift_value, b->shift_value); + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } - gasoc_done: + result = sort_unsigned_long(ea->shift_type, eb->shift_type); + + if (result == 0) + result = g_arch_operand_compare(a->shift_value, b->shift_value); + + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } return result; @@ -299,7 +444,11 @@ static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GAr static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBufferLine *line) { - switch (operand->shift_type) + SRType shift_type; /* Type porté par l'opérande */ + + shift_type = g_armv7_shift_operand_get_shift_type(operand); + + switch (shift_type) { case SRType_LSL: g_buffer_line_append_text(line, DLC_ASSEMBLY, "lsl", 3, RTT_KEY_WORD, NULL); @@ -327,88 +476,68 @@ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBuff /****************************************************************************** * * -* Paramètres : - * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Crée un réceptacle pour opérande de décalage ARMv7. * +* Description : Charge un contenu depuis une mémoire tampon. * * * -* Retour : Opérande mis en place. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_shift_operand_new(SRType type, GArchOperand *value) +static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { - GArmV7ShiftOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV7_SHIFT_OPERAND, NULL); + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + a7shiftop_extra_data_t *extra; /* Données insérées à modifier */ + uleb128_t value; /* Valeur ULEB128 à charger */ + GSerializableObject *shift_value; /* Valeur du décalage */ - result->shift_type = type; - result->shift_value = value; + parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); - return G_ARCH_OPERAND(result); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); -} + if (result) + { + extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); + LOCK_GOBJECT_EXTRA(extra); -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique la forme de décalage représenté. * -* * -* Retour : Type de décalage. * -* * -* Remarques : - * -* * -******************************************************************************/ + result = unpack_uleb128(&value, pbuf); -SRType g_armv7_shift_operand_get_shift_type(const GArmV7ShiftOperand *operand) -{ - return operand->shift_type; + if (result) + extra->shift_type = value; -} + UNLOCK_GOBJECT_EXTRA(extra); + } -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit la valeur utilisée pour un décalage. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ + if (result) + { + shift_value = g_object_storage_unpack_object(storage, "operands", pbuf); -GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *operand) -{ - GArchOperand *result; /* Instance à retourner */ + result = (shift_value != NULL); - result = operand->shift_value; + if (result) + operand->shift_value = G_ARCH_OPERAND(shift_value); - g_object_ref(G_OBJECT(result)); + } return result; } - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -416,64 +545,34 @@ GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *op * * ******************************************************************************/ -static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *value; /* Valeur à intégrer */ + a7shiftop_extra_data_t *extra; /* Données insérées à modifier */ + GSerializableObject *shift_value; /* Valeur du décalage */ parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - result = extract_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - value = g_arch_operand_load(storage, format, pbuf); - - if (value == NULL) - result = false; - - else - operand->shift_value = value; - - } + extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); - return result; + LOCK_GOBJECT_EXTRA(extra); -} + result = pack_uleb128((uleb128_t []){ extra->shift_type }, pbuf); + UNLOCK_GOBJECT_EXTRA(extra); -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Sauvegarde un opérande dans une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - result = extend_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true); + } if (result) - result = g_arch_operand_store(operand->shift_value, storage, pbuf); + { + shift_value = G_SERIALIZABLE_OBJECT(operand->shift_value); + result = g_object_storage_pack_object(storage, "operands", shift_value, pbuf); + } return result; diff --git a/plugins/dalvik/operands/args.c b/plugins/dalvik/operands/args.c index 9aa948d..7eec5d7 100644 --- a/plugins/dalvik/operands/args.c +++ b/plugins/dalvik/operands/args.c @@ -37,6 +37,9 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ struct _GDalvikArgsOperand { @@ -68,6 +71,11 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *, const GDalvikArgsOperand *, bool); @@ -80,11 +88,6 @@ static GArchOperand *g_dalvik_args_operand_get_inner_operand_from_path(const GDa /* Traduit un opérande en version humainement lisible. */ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *, GBufferLine *); - - -/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ - - /* Fournit une liste de candidats embarqués par un candidat. */ static GArchOperand **g_dalvik_args_operand_list_inner_instances(const GDalvikArgsOperand *, size_t *); @@ -94,17 +97,17 @@ static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *, G /* Fournit l'empreinte d'un candidat à une centralisation. */ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_dalvik_args_operand_load(GDalvikArgsOperand *, GObjectStorage *, packed_buffer_t *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_dalvik_args_operand_store(GDalvikArgsOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_dalvik_args_operand_serialize(const GDalvikArgsOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ @@ -145,8 +148,8 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) operand->update_inner = (operand_update_inners_fc)g_dalvik_args_operand_update_inner_instances; operand->hash = (operand_hash_fc)g_dalvik_args_operand_hash; - operand->unserialize = (unserialize_operand_fc)g_dalvik_args_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_dalvik_args_operand_serialize; + operand->load = (load_operand_fc)g_dalvik_args_operand_load; + operand->store = (store_operand_fc)g_dalvik_args_operand_store; } @@ -188,7 +191,7 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *operand) size_t i; for (i = 0; i < operand->count; i++) - g_object_unref(G_OBJECT(operand->args[i])); + g_clear_object(&operand->args[i]); G_OBJECT_CLASS(g_dalvik_args_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -219,6 +222,99 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) /****************************************************************************** * * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérandes Dalvik servant d'arguments.* +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_args_operand_new(void) +{ + GArchOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* arg = nouvel argument pour un appel. * +* * +* Description : Ajoute un élément à la liste d'arguments Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg) +{ + operand->count++; + operand->args = realloc(operand->args, operand->count * sizeof(GArchOperand *)); + + operand->args[operand->count - 1] = arg; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* * +* Description : Fournit le nombre d'arguments pris en charge. * +* * +* Retour : Nombre positif ou nul. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_dalvik_args_count(const GDalvikArgsOperand *operand) +{ + return operand->count; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* index = indice de l'argument recherché. * +* * +* Description : Founit un élément de la liste d'arguments Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *operand, size_t index) +{ + assert(index < operand->count); + + return operand->args[index]; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * * Paramètres : a = premier opérande à consulter. * * b = second opérande à consulter. * * lock = précise le besoin en verrouillage. * @@ -441,99 +537,6 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff /****************************************************************************** * * -* Paramètres : - * -* * -* Description : Crée un réceptacle pour opérandes Dalvik servant d'arguments.* -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_dalvik_args_operand_new(void) -{ - GArchOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à compléter. * -* arg = nouvel argument pour un appel. * -* * -* Description : Ajoute un élément à la liste d'arguments Dalvik. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg) -{ - operand->count++; - operand->args = (GArchOperand **)realloc(operand->args, operand->count * sizeof(GArchOperand *)); - - operand->args[operand->count - 1] = arg; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à compléter. * -* * -* Description : Fournit le nombre d'arguments pris en charge. * -* * -* Retour : Nombre positif ou nul. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_dalvik_args_count(const GDalvikArgsOperand *operand) -{ - return operand->count; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à compléter. * -* index = indice de l'argument recherché. * -* * -* Description : Founit un élément de la liste d'arguments Dalvik. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *operand, size_t index) -{ - assert(index < operand->count); - - return operand->args[index]; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONTROLE DU VOLUME DES INSTANCES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * * Paramètres : operand = objet dont l'instance se veut unique. * * count = quantité d'instances à l'unicité internes. * * * @@ -634,20 +637,13 @@ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool } - -/* ---------------------------------------------------------------------------------- */ -/* 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. * * * @@ -655,33 +651,38 @@ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool * * ******************************************************************************/ -static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_dalvik_args_operand_load(GDalvikArgsOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - size_t count; /* Nombre d'opérandes à charger*/ + uleb128_t value; /* Valeur ULEB128 à charger */ size_t i; /* Boucle de parcours */ - GArchOperand *arg; /* Nouvel argument à intégrer */ + GSerializableObject *arg; /* Nouvel argument à intégrer */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_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, &count, sizeof(size_t), true); + result = unpack_uleb128(&value, pbuf); - for (i = 0; i < count && result; i++) + if (result) { - arg = g_arch_operand_load(storage, format, pbuf); + operand->count = value; + operand->args = calloc(operand->count, sizeof(GArchOperand *)); + } - if (arg == NULL) - result = false; + for (i = 0; i < operand->count && result; i++) + { + arg = g_object_storage_unpack_object(storage, "operands", pbuf); + if (arg == NULL) break; - else - g_dalvik_args_operand_add(operand, arg); + operand->args[operand->count - 1] = G_ARCH_OPERAND(arg); } + result = (i == operand->count); + return result; } @@ -689,11 +690,11 @@ static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *operand, GAsmS /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -701,21 +702,25 @@ static bool g_dalvik_args_operand_unserialize(GDalvikArgsOperand *operand, GAsmS * * ******************************************************************************/ -static bool g_dalvik_args_operand_serialize(const GDalvikArgsOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_dalvik_args_operand_store(GDalvikArgsOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ size_t i; /* Boucle de parcours */ + GSerializableObject *arg; /* Nouvel argument à intégrer */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_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->count, sizeof(size_t), true); + result = pack_uleb128((uleb128_t []){ operand->count }, pbuf); for (i = 0; i < operand->count && result; i++) - result = g_arch_operand_store(operand->args[i], storage, pbuf); + { + arg = G_SERIALIZABLE_OBJECT(operand->args[i]); + result = g_object_storage_pack_object(storage, "operands", arg, pbuf); + } return result; diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index acec518..4570c86 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -39,13 +39,25 @@ +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _dpoolop_extra_data_t +{ + operand_extra_data_t parent; /* A laisser en premier */ + + DalvikPoolType type; /* Type de table visée */ + +} dpoolop_extra_data_t; + + /* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ struct _GDalvikPoolOperand { GArchOperand parent; /* Instance parente */ GDexFormat *format; /* Lien vers le contenu réel */ - DalvikPoolType type; /* Type de table visée */ uint32_t index; /* Indice de l'élément visé */ }; @@ -59,6 +71,21 @@ struct _GDalvikPoolOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_DALVIK_POOL_OP_EXTRA(op) (dpoolop_extra_data_t *)&op->extra + +#else + +# define GET_DALVIK_POOL_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), dpoolop_extra_data_t) + +#endif + + /* Initialise la classe des opérandes de constante Dalvik. */ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *); @@ -74,30 +101,28 @@ static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *); -/* Compare un opérande avec un autre. */ -static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *, const GDalvikPoolOperand *, bool); +/* Indique la nature de la table de constantes visée ici. */ +static DalvikPoolType _g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *, bool); -/* Traduit un opérande en version humainement lisible. */ -static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *, GBufferLine *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ +/* Compare un opérande avec un autre. */ +static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *, const GDalvikPoolOperand *, bool); + +/* Traduit un opérande en version humainement lisible. */ +static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *, GBufferLine *); /* Fournit l'empreinte d'un candidat à une centralisation. */ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_dalvik_pool_operand_load(GDalvikPoolOperand *, GObjectStorage *, packed_buffer_t *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_dalvik_pool_operand_store(GDalvikPoolOperand *, GObjectStorage *, packed_buffer_t *); @@ -109,6 +134,11 @@ static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *, const vmp +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini par la GLib pour un un élément de table de constantes Dalvik. */ G_DEFINE_TYPE_WITH_CODE(GDalvikPoolOperand, g_dalvik_pool_operand, G_TYPE_ARCH_OPERAND, G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_dalvik_pool_operand_targetable_interface_init)); @@ -143,8 +173,8 @@ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) operand->hash = (operand_hash_fc)g_dalvik_pool_operand_hash; - operand->unserialize = (unserialize_operand_fc)g_dalvik_pool_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_dalvik_pool_operand_serialize; + operand->load = (load_operand_fc)g_dalvik_pool_operand_load; + operand->store = (store_operand_fc)g_dalvik_pool_operand_store; } @@ -201,8 +231,7 @@ static void g_dalvik_pool_operand_targetable_interface_init(GTargetableOperandIn static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *operand) { - if (operand->format != NULL) - g_object_unref(G_OBJECT(operand->format)); + g_clear_object(&operand->format); G_OBJECT_CLASS(g_dalvik_pool_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -230,6 +259,152 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) /****************************************************************************** * * +* Paramètres : format = format du fichier contenant le code. * +* type = type de table visée avec la référence. * +* content = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* size = taille de l'opérande, et donc du registre. * +* endian = ordre des bits dans la source. * +* * +* Description : Crée un opérande visant un élément constant Dalvik. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_pool_operand_new(GDexFormat *format, DalvikPoolType type, const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian) +{ + GDalvikPoolOperand *result; /* Structure à retourner */ + uint16_t index16; /* Indice sur 16 bits */ + uint32_t index32; /* Indice sur 32 bits */ + bool test; /* Bilan de lecture */ + dpoolop_extra_data_t *extra; /* Données insérées à modifier */ + + switch (size) + { + case MDS_16_BITS: + test = g_binary_content_read_u16(content, pos, endian, &index16); + break; + case MDS_32_BITS: + test = g_binary_content_read_u32(content, pos, endian, &index32); + break; + default: + test = false; + break; + } + + if (!test) + goto gdpon_exit; + + result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); + + extra = GET_DALVIK_POOL_OP_EXTRA(result); + + extra->type = type; + + result->format = format; + g_object_ref(G_OBJECT(format)); + + result->index = (size == MDS_16_BITS ? index16 : index32); + + return G_ARCH_OPERAND(result); + + gdpon_exit: + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Indique la nature de la table de constantes visée ici. * +* * +* Retour : Type de table constantes visée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static DalvikPoolType _g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *operand, bool lock) +{ + DalvikPoolType result; /* Type à retourner */ + dpoolop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + result = extra->type; + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique la nature de la table de constantes visée ici. * +* * +* Retour : Type de table constantes visée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DalvikPoolType g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *operand) +{ + DalvikPoolType result; /* Type à retourner */ + + result = _g_dalvik_pool_operand_get_pool_type(operand, true); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique l'indice de l'élément dans la table de constantes. * +* * +* Retour : Indice de l'élément visé dans la table de constantes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) +{ + uint32_t result; /* Indice à retourner */ + + result = operand->index; + + 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. * @@ -245,12 +420,12 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDalvikPoolOperand *b, bool lock) { int result; /* Bilan à renvoyer */ - lockable_obj_extra_t *ea; /* Données insérées à consulter*/ - lockable_obj_extra_t *eb; /* Données insérées à consulter*/ + dpoolop_extra_data_t *ea; /* Données insérées à consulter*/ + dpoolop_extra_data_t *eb; /* Données insérées à consulter*/ GArchOperandClass *class; /* Classe parente normalisée */ - ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t); - eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t); + ea = GET_DALVIK_POOL_OP_EXTRA(a); + eb = GET_DALVIK_POOL_OP_EXTRA(b); if (lock) { @@ -261,7 +436,7 @@ static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDal result = sort_unsigned_long((unsigned long)a->format, (unsigned long)b->format); if (result == 0) - result = sort_unsigned_long(a->type, b->type); + result = sort_unsigned_long(ea->type, eb->type); if (result == 0) result = sort_unsigned_long(a->index, b->index); @@ -299,6 +474,7 @@ static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDal static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBufferLine *line) { GDexPool *pool; /* Table de ressources */ + DalvikPoolType pool_type; /* Type de table visé */ const char *string; /* Chaîne de caractères #1 */ GDataType *type; /* Type à représenter */ size_t len; /* Taille du texte à créer */ @@ -309,7 +485,9 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff pool = g_dex_format_get_pool(operand->format); - switch (operand->type) + pool_type = g_dalvik_pool_operand_get_pool_type(operand); + + switch (pool_type) { case DPT_NONE: g_buffer_line_append_text(line, DLC_ASSEMBLY, "????", 4, RTT_ERROR, NULL); @@ -470,107 +648,6 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff /****************************************************************************** * * -* Paramètres : format = format du fichier contenant le code. * -* type = type de table visée avec la référence. * -* content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* size = taille de l'opérande, et donc du registre. * -* endian = ordre des bits dans la source. * -* * -* Description : Crée un opérande visant un élément constant Dalvik. * -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_dalvik_pool_operand_new(GDexFormat *format, DalvikPoolType type, const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian) -{ - GDalvikPoolOperand *result; /* Structure à retourner */ - uint16_t index16; /* Indice sur 16 bits */ - uint32_t index32; /* Indice sur 32 bits */ - bool test; /* Bilan de lecture */ - - switch (size) - { - case MDS_16_BITS: - test = g_binary_content_read_u16(content, pos, endian, &index16); - break; - case MDS_32_BITS: - test = g_binary_content_read_u32(content, pos, endian, &index32); - break; - default: - test = false; - break; - } - - if (!test) - goto gdpon_exit; - - result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); - - g_object_ref(G_OBJECT(format)); - - result->format = format; - result->type = type; - result->index = (size == MDS_16_BITS ? index16 : index32); - - return G_ARCH_OPERAND(result); - - gdpon_exit: - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique la nature de la table de constantes visée ici. * -* * -* Retour : Type de table constantes visée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -DalvikPoolType g_dalvik_pool_operand_get_pool_type(const GDalvikPoolOperand *operand) -{ - return operand->type; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique l'indice de l'élément dans la table de constantes. * -* * -* Retour : Indice de l'élément visé dans la table de constantes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) -{ - return operand->index; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONTROLE DU VOLUME DES INSTANCES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * * Paramètres : operand = objet dont l'instance se veut unique. * * lock = précise le besoin en verrouillage. * * * @@ -600,7 +677,7 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool result ^= g_direct_hash(operand->format); - type = g_dalvik_pool_operand_get_pool_type(operand); + type = _g_dalvik_pool_operand_get_pool_type(operand, !lock); result ^= type; @@ -616,20 +693,13 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool } - -/* ---------------------------------------------------------------------------------- */ -/* 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. * * * @@ -637,26 +707,43 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool * * ******************************************************************************/ -static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_dalvik_pool_operand_load(GDalvikPoolOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + dpoolop_extra_data_t *extra; /* Données insérées à modifier */ + uleb128_t value; /* Valeur ULEB128 à charger */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + { + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = unpack_uleb128(&value, pbuf); + + if (result) + extra->type = value; + + UNLOCK_GOBJECT_EXTRA(extra); + + } if (result) { - operand->format = G_DEX_FORMAT(format); - g_object_ref(G_OBJECT(format)); + operand->format = get_storage_linked_format(storage); + result = G_IS_DEX_FORMAT(operand->format); } if (result) - result = extract_packed_buffer(pbuf, &operand->type, sizeof(DalvikPoolType), true); + result = unpack_uleb128(&value, pbuf); if (result) - result = extract_packed_buffer(pbuf, &operand->index, sizeof(uint32_t), true); + operand->index = value; return result; @@ -665,11 +752,11 @@ static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmS /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -677,20 +764,30 @@ static bool g_dalvik_pool_operand_unserialize(GDalvikPoolOperand *operand, GAsmS * * ******************************************************************************/ -static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_dalvik_pool_operand_store(GDalvikPoolOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + dpoolop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_dalvik_pool_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(DalvikPoolType), true); + { + extra = GET_DALVIK_POOL_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = pack_uleb128((uleb128_t []){ extra->type }, pbuf); + + UNLOCK_GOBJECT_EXTRA(extra); + + } if (result) - result = extend_packed_buffer(pbuf, &operand->index, sizeof(uint32_t), true); + result = pack_uleb128((uleb128_t []){ operand->index }, pbuf); return result; @@ -722,6 +819,7 @@ static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *operand, G static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) { bool result; /* Bilan à retourner */ + DalvikPoolType type; /* Type de table visé */ GDexPool *pool; /* Table de ressources */ GDexMethod *method; /* Méthode ciblée ici */ GBinRoutine *routine; /* Routine liée à la méthode */ @@ -729,7 +827,9 @@ static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *operand, co result = false; - if (operand->type == DPT_METHOD) + type = g_dalvik_pool_operand_get_pool_type(operand); + + if (type == DPT_METHOD) { pool = g_dex_format_get_pool(G_DEX_FORMAT(format)); diff --git a/plugins/pychrysalide/arch/register.c b/plugins/pychrysalide/arch/register.c index 61da77f..5d9e90b 100644 --- a/plugins/pychrysalide/arch/register.c +++ b/plugins/pychrysalide/arch/register.c @@ -36,6 +36,7 @@ #include "../access.h" #include "../helpers.h" +#include "../analysis/storage/serialize.h" @@ -682,6 +683,9 @@ bool ensure_python_arch_register_is_registered(void) dict = PyModule_GetDict(module); + if (!ensure_python_serializable_object_is_registered()) + return false; + if (!register_class_for_pygobject(dict, G_TYPE_ARCH_REGISTER, type, &PyGObject_Type)) return false; diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c index d6d6402..e2f2dda 100644 --- a/plugins/pychrysalide/format/symbol.c +++ b/plugins/pychrysalide/format/symbol.c @@ -43,6 +43,7 @@ #include "../helpers.h" #include "../analysis/routine.h" #include "../analysis/db/items/comment.h" +#include "../analysis/storage/serialize.h" #include "../arch/instruction.h" #include "../arch/vmpa.h" #include "../glibext/linegen.h" @@ -973,6 +974,9 @@ bool ensure_python_binary_symbol_is_registered(void) if (!ensure_python_line_generator_is_registered()) return false; + if (!ensure_python_serializable_object_is_registered()) + return false; + if (!register_class_for_pygobject(dict, G_TYPE_BIN_SYMBOL, type, &PyGObject_Type)) return false; |