diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-04-29 09:53:28 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-04-29 09:53:28 (GMT) |
commit | b16071a35adaf95d5e67b0dd984e9ba9d7ba28f9 (patch) | |
tree | 10470449f230593ea62f696e30e647a1c8d95ed2 /src | |
parent | aead324676d997c30aac2851f4a37125db195d3e (diff) |
Improved the behavior of immediate operands display.
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/immediate.c | 194 | ||||
-rw-r--r-- | src/arch/immediate.h | 8 | ||||
-rw-r--r-- | src/format/symbol.h | 1 |
3 files changed, 179 insertions, 24 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c index a6f080f..5d3b844 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -56,13 +56,26 @@ struct _GImmOperand uint64_t raw; /* Valeur transtypée */ MemoryDataSize size; /* Taille de l'opérande */ - bool zpad; /* Ajoute des 0 à l'impression */ ImmOperandDisplay def_display; /* Type par défaut d'affichage */ ImmOperandDisplay display; /* Format général d'affichage */ + unsigned char misc; /* Informations diverses */ }; +#define IMM_GET_DEF_ZERO_PADDING(op) ((op)->misc & (1 << 0)) +#define IMM_SET_DEF_ZERO_PADDING(op, v) (op)->misc = ((op)->misc & ~(1 << 0)) | ((v) ? (1 << 0) : 0) + +#define IMM_HAS_ZERO_PADDING(op) ((op)->misc & (1 << 1)) +#define IMM_SET_ZERO_PADDING(op) (op)->misc |= (1 << 1) + +#define IMM_GET_ZERO_PADDING_VALUE(op) ((op)->misc & (1 << 2)) +#define IMM_SET_ZERO_PADDING_VALUE(op, v) (op)->misc = ((op)->misc & ~(1 << 2)) | ((v) ? (1 << 2) : 0) + +#define IMM_HAS_DISPLAY(op) ((op)->misc & (1 << 3)) +#define IMM_SET_DISPLAY(op) (op)->misc |= (1 << 3) + + /* Définition d'un opérande de valeur numérique (classe) */ struct _GImmOperandClass { @@ -92,6 +105,9 @@ static void g_imm_operand_quickly_copy(const GImmOperand *, GImmOperand *); /* Compare un opérande avec un autre. */ static int g_imm_operand_compare(const GImmOperand * const *, const GImmOperand * const *); +/* Indique si une valeur est complétée par des zéros. */ +static bool g_imm_operand_does_padding_for_display(const GImmOperand *, ImmOperandDisplay); + /* Construit la chaîne de caractères correspondant à l'opérande. */ static size_t _g_imm_operand_to_string(const GImmOperand *, AsmSyntax, ImmOperandDisplay, char [IMM_MAX_SIZE]); @@ -168,10 +184,10 @@ static void g_imm_operand_class_init(GImmOperandClass *klass) static void g_imm_operand_init(GImmOperand *operand) { - operand->zpad = false; - operand->def_display = IOD_HEX; - operand->display = IOD_HEX; + operand->misc = 0; + + IMM_SET_DEF_ZERO_PADDING(operand, false); } @@ -403,9 +419,9 @@ static void g_imm_operand_quickly_copy(const GImmOperand *operand, GImmOperand * template->raw = operand->raw; template->size = operand->size; - template->zpad = operand->zpad; template->def_display = operand->def_display; template->display = operand->display; + template->misc = operand->misc; } @@ -454,12 +470,6 @@ static int g_imm_operand_compare(const GImmOperand * const *a, const GImmOperand goto gioc_done; } - if (imm_a->zpad != imm_b->zpad) - { - result = (imm_a->zpad ? 1 : -1); - goto gioc_done; - } - if (imm_a->def_display < imm_b->def_display) { result = -1; @@ -471,17 +481,47 @@ static int g_imm_operand_compare(const GImmOperand * const *a, const GImmOperand goto gioc_done; } - if (imm_a->display < imm_b->display) + if (IMM_HAS_DISPLAY(imm_a) != IMM_HAS_DISPLAY(imm_b)) { - result = -1; + result = (IMM_HAS_DISPLAY(imm_a) ? 1 : -1); goto gioc_done; } - else if (imm_a->display > imm_b->display) + + if (IMM_HAS_DISPLAY(imm_a)) { - result = 1; + if (imm_a->display < imm_b->display) + { + result = -1; + goto gioc_done; + } + else if (imm_a->display > imm_b->display) + { + result = 1; + goto gioc_done; + } + } + + if (IMM_GET_DEF_ZERO_PADDING(imm_a) != IMM_GET_DEF_ZERO_PADDING(imm_b)) + { + result = (IMM_GET_DEF_ZERO_PADDING(imm_a) ? 1 : -1); goto gioc_done; } + if (IMM_HAS_ZERO_PADDING(imm_a) != IMM_HAS_ZERO_PADDING(imm_b)) + { + result = (IMM_HAS_ZERO_PADDING(imm_a) ? 1 : -1); + goto gioc_done; + } + + if (IMM_HAS_ZERO_PADDING(imm_a)) + { + if (IMM_GET_ZERO_PADDING_VALUE(imm_a) != IMM_GET_ZERO_PADDING_VALUE(imm_b)) + { + result = (IMM_GET_ZERO_PADDING_VALUE(imm_a) ? 1 : -1); + goto gioc_done; + } + } + result = 0; gioc_done: @@ -660,6 +700,60 @@ void g_imm_operand_set_value(GImmOperand **operand, MemoryDataSize size, uint64_ * * ******************************************************************************/ +void g_imm_operand_pad_by_default(GImmOperand **operand, bool state, GShareContainer *container) +{ + GSharedInstance *shared; /* Instace de travail partagée */ + GImmOperand fake; /* Transport d'informations */ + + shared = G_SHARED_INSTANCE(*operand); + + g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); + + IMM_SET_DEF_ZERO_PADDING(&fake, state); + + shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container); + + *operand = G_IMM_OPERAND(shared); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* * +* Description : Indique si une valeur est complétée par des zéros par défaut.* +* * +* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_does_padding_by_default(const GImmOperand *operand) +{ + bool result; /* Statut à retourner */ + + result = IMM_GET_DEF_ZERO_PADDING(operand); + + return result; + +} + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à actualiser. [OUT]* +* state = true si des zéro sont à ajouter, false sinon. * +* container = propriétaire d'origine à tenir au courant. * +* * +* Description : Précise si des zéro doivent compléter l'affichage ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *container) { GSharedInstance *shared; /* Instace de travail partagée */ @@ -669,7 +763,8 @@ void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *conta g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); - fake.zpad = state; + IMM_SET_ZERO_PADDING(&fake); + IMM_SET_ZERO_PADDING_VALUE(&fake, state); shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container); @@ -682,7 +777,7 @@ void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *conta * * * Paramètres : operand = structure dont le contenu est à consulter. * * * -* Description : Indique le signe d'une valeur immédiate. * +* Description : Indique si une valeur est complétée par des zéros. * * * * Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * * * @@ -692,7 +787,47 @@ void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *conta bool g_imm_operand_does_padding(const GImmOperand *operand) { - return operand->zpad; + bool result; /* Statut à retourner */ + + if (IMM_HAS_ZERO_PADDING(operand)) + result = IMM_GET_ZERO_PADDING_VALUE(operand); + else + result = IMM_GET_DEF_ZERO_PADDING(operand); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à consulter. * +* display = type d'affichage à considérer. * +* * +* Description : Indique si une valeur est complétée par des zéros. * +* * +* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, ImmOperandDisplay display) +{ + bool result; /* Statut à retourner */ + + result = g_imm_operand_does_padding(operand); + + if (result) + { + display = g_imm_operand_get_display(operand); + + if (display != IOD_BIN && display != IOD_HEX) + result = false; + + } + + return result; } @@ -771,6 +906,7 @@ void g_imm_operand_set_display(GImmOperand **operand, ImmOperandDisplay display, g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); + IMM_SET_DISPLAY(&fake); fake.display = display; shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container); @@ -794,7 +930,14 @@ void g_imm_operand_set_display(GImmOperand **operand, ImmOperandDisplay display, ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) { - return operand->display; + ImmOperandDisplay result; /* Affichage à retourner */ + + if (IMM_HAS_DISPLAY(operand)) + result = operand->display; + else + result = operand->def_display; + + return result; } @@ -880,6 +1023,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn const char *suffix; /* Sortie de matière */ const char *alternate; /* Préfixe de forme alternative*/ const char *intro; /* Introduction du formatage */ + bool do_padding; /* Indication de bourrage */ const char *zpad; /* Remplissage par des zéros */ const char *lmod; /* Modification de longueur */ const char *conv; /* Opérateur de conversion */ @@ -933,6 +1077,9 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn intro = ""; /* Drapeau de remplissage ? */ + + do_padding = g_imm_operand_does_padding_for_display(operand, display); + switch (display) { case IOD_BIN: @@ -942,7 +1089,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn zpad = ""; break; default: - zpad = (operand->zpad ? zpad_defs[range] : ""); + zpad = (do_padding ? zpad_defs[range] : ""); break; } @@ -965,7 +1112,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn } else { - if (operand->zpad) + if (do_padding) max = range * 8; else @@ -1071,8 +1218,11 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syn size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[IMM_MAX_SIZE]) { size_t result; /* Longueur à retourner */ + ImmOperandDisplay display; /* Type d'affichage courant */ + + display = g_imm_operand_get_display(operand); - result = _g_imm_operand_to_string(operand, syntax, operand->display, value); + result = _g_imm_operand_to_string(operand, syntax, display, value); return result; diff --git a/src/arch/immediate.h b/src/arch/immediate.h index 450ceef..9becf91 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -97,9 +97,15 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *); void g_imm_operand_set_value(GImmOperand **, MemoryDataSize, uint64_t, GShareContainer *); /* Précise si des zéro doivent compléter l'affichage ou non. */ +void g_imm_operand_pad_by_default(GImmOperand **, bool, GShareContainer *); + +/* Indique si une valeur est complétée par des zéros par défaut. */ +bool g_imm_operand_does_padding_by_default(const GImmOperand *); + +/* Précise si des zéro doivent compléter l'affichage ou non. */ void g_imm_operand_pad(GImmOperand **, bool, GShareContainer *); -/* Indique le signe d'une valeur immédiate. */ +/* Indique si une valeur est complétée par des zéros. */ bool g_imm_operand_does_padding(const GImmOperand *); /* Définit le format textuel par défaut de la valeur. */ diff --git a/src/format/symbol.h b/src/format/symbol.h index 7929bc9..694a9ee 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -139,7 +139,6 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *); GImmOperand *_imm; \ _imm = G_IMM_OPERAND(g_arch_instruction_get_operand(_ins, _idx)); \ g_imm_operand_set_default_display(&_imm, _dsp, G_SHARE_CONTAINER(_ins)); \ - g_imm_operand_set_display(&_imm, _dsp, G_SHARE_CONTAINER(_ins)); \ _op = G_ARCH_OPERAND(_imm); \ } \ while (0) |