From b16071a35adaf95d5e67b0dd984e9ba9d7ba28f9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 29 Apr 2017 11:53:28 +0200 Subject: Improved the behavior of immediate operands display. --- ChangeLog | 13 +++ plugins/fmtp/parser.c | 1 - plugins/pychrysa/arch/immediate.c | 81 ++++++++++++++++ src/arch/immediate.c | 194 +++++++++++++++++++++++++++++++++----- src/arch/immediate.h | 8 +- src/format/symbol.h | 1 - 6 files changed, 273 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c46e8c..a005921 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +17-04-29 Cyrille Bagard + + * plugins/fmtp/parser.c: + * plugins/pychrysa/arch/immediate.c: + Update code. + + * src/arch/immediate.c: + * src/arch/immediate.h: + Improve the behavior of immediate operands display. + + * src/format/symbol.h: + Update code. + 17-04-28 Cyrille Bagard * src/arch/immediate.c: diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c index 2f469c1..b484a0e 100644 --- a/plugins/fmtp/parser.c +++ b/plugins/fmtp/parser.c @@ -95,7 +95,6 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, i)); g_imm_operand_set_default_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr)); - g_imm_operand_set_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr)); // TODO : unref(imm) diff --git a/plugins/pychrysa/arch/immediate.c b/plugins/pychrysa/arch/immediate.c index 363c3cc..69efa97 100644 --- a/plugins/pychrysa/arch/immediate.c +++ b/plugins/pychrysa/arch/immediate.c @@ -43,6 +43,12 @@ static PyObject *py_imm_operand_get_value(PyObject *, void *); /* Indique si l'affichage est complété avec des zéros. */ +static PyObject *py_imm_operand_get_padding_by_default(PyObject *self, void *); + +/* Précise si des zéro doivent compléter l'affichage ou non. */ +static int py_imm_operand_set_padding_by_default(PyObject *, PyObject *, void *); + +/* Indique si l'affichage est complété avec des zéros. */ static PyObject *py_imm_operand_get_padding(PyObject *self, void *); /* Précise si des zéro doivent compléter l'affichage ou non. */ @@ -195,6 +201,76 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure) * * ******************************************************************************/ +static PyObject *py_imm_operand_get_padding_by_default(PyObject *self, void *closure) +{ + PyObject *result; /* Instance Python à retourner */ + GImmOperand *operand; /* Version GLib de l'opérande */ + bool padding; /* Bourrage en préfixe ? */ + + operand = G_IMM_OPERAND(pygobject_get(self)); + assert(operand != NULL); + + padding = g_imm_operand_does_padding_by_default(operand); + + result = Py_BuildValue("p", padding); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Précise si des zéro doivent compléter l'affichage ou non. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_imm_operand_set_padding_by_default(PyObject *self, PyObject *value, void *closure) +{ + bool padding; /* Bourrage en préfixe ? */ + GImmOperand *operand; /* Version GLib de l'opérande */ + + if (!PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, _("Invalid padding state")); + return -1; + } + + padding = (value == Py_True); + + operand = G_IMM_OPERAND(pygobject_get(self)); + assert(operand != NULL); + + g_imm_operand_pad_by_default(&operand, padding, NULL); + + pygobject_set(self, operand); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique si l'affichage est complété avec des zéros. * +* * +* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + static PyObject *py_imm_operand_get_padding(PyObject *self, void *closure) { PyObject *result; /* Instance Python à retourner */ @@ -251,6 +327,7 @@ static int py_imm_operand_set_padding(PyObject *self, PyObject *value, void *clo } + /****************************************************************************** * * * Paramètres : self = objet Python concerné par l'appel. * @@ -562,6 +639,10 @@ PyTypeObject *get_python_imm_operand_type(void) "Status of padding with zeros in front of the textual representation.", NULL }, { + "default_padding", py_imm_operand_get_padding_by_default, py_imm_operand_set_padding_by_default, + "Status of default padding with zeros in front of the textual representation.", NULL + }, + { "default_display", py_imm_operand_get_default_display, py_imm_operand_set_default_display, "Definition of the immediate operand default textual representation.", NULL }, 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) -- cgit v0.11.2-87-g4458