From a6c0351774988094a51c9502f2a8e07633956263 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 14 Aug 2021 21:54:31 +0200 Subject: Improve the object padding exploitation for operands. --- plugins/dalvik/operand.c | 2 +- plugins/dalvik/operands/args.c | 53 ++- plugins/dalvik/operands/pool.c | 55 ++- plugins/pychrysalide/arch/instructions/undefined.c | 2 +- plugins/pychrysalide/arch/operand.c | 11 +- plugins/pychrysalide/arch/operands/immediate.c | 166 ------- plugins/pychrysalide/arch/operands/register.c | 41 -- plugins/pychrysalide/arch/operands/target.c | 8 +- src/analysis/type-int.h | 66 +-- src/analysis/type.c | 78 ++-- src/analysis/type.h | 2 +- src/analysis/types/proto.c | 6 +- src/arch/instruction-int.h | 80 ++-- src/arch/instruction.c | 74 ++- src/arch/instruction.h | 2 +- src/arch/instructions/raw.c | 62 +-- src/arch/instructions/undefined-int.h | 56 +-- src/arch/instructions/undefined.c | 30 +- src/arch/operand-int.h | 50 +- src/arch/operand.c | 232 +++++++++- src/arch/operand.h | 29 ++ src/arch/operands/immediate.c | 507 +++++++++------------ src/arch/operands/immediate.h | 21 +- src/arch/operands/proxy.c | 75 ++- src/arch/operands/register-int.h | 45 -- src/arch/operands/register.c | 92 +--- src/arch/operands/register.h | 14 +- src/arch/operands/target-int.h | 26 +- src/arch/operands/target.c | 162 +++++-- src/arch/operands/target.h | 8 + src/format/format-int.h | 75 +-- src/format/format.c | 30 +- src/format/symbol-int.h | 60 +-- src/format/symbol.c | 66 +-- src/glibext/objhole.h | 49 +- 35 files changed, 1264 insertions(+), 1071 deletions(-) diff --git a/plugins/dalvik/operand.c b/plugins/dalvik/operand.c index a176721..4db8fa9 100644 --- a/plugins/dalvik/operand.c +++ b/plugins/dalvik/operand.c @@ -749,7 +749,7 @@ void dalvik_mark_first_operand_as_written(GArchInstruction *instr) operand = g_arch_instruction_get_operand(instr, 0); - g_register_operand_mark_as_written(G_REGISTER_OPERAND(operand)); + g_arch_operand_set_flag(operand, ROF_IS_WRITTEN); g_object_unref(G_OBJECT(operand)); diff --git a/plugins/dalvik/operands/args.c b/plugins/dalvik/operands/args.c index 2c7bc57..9aa948d 100644 --- a/plugins/dalvik/operands/args.c +++ b/plugins/dalvik/operands/args.c @@ -69,7 +69,7 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *); static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *); /* Compare un opérande avec un autre. */ -static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *, const GDalvikArgsOperand *); +static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *, const GDalvikArgsOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_dalvik_args_operand_find_inner_operand_path(const GDalvikArgsOperand *, const GArchOperand *); @@ -92,7 +92,7 @@ static GArchOperand **g_dalvik_args_operand_list_inner_instances(const GDalvikAr static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *, GArchOperand **, size_t); /* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *); +static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *, bool); @@ -219,8 +219,9 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -230,10 +231,13 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) * * ******************************************************************************/ -static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDalvikArgsOperand *b) +static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDalvikArgsOperand *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*/ size_t i; /* Boucle de parcours */ + GArchOperandClass *class; /* Classe parente normalisée */ /* Création de l'objet... */ if (b == NULL) @@ -241,11 +245,32 @@ static int g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDal else { + ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t); + eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + result = sort_unsigned_long(a->count, b->count); for (i = 0; i < a->count && result == 0; i++) result = g_arch_operand_compare(a->args[i], b->args[i]); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_dalvik_args_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; @@ -575,6 +600,7 @@ static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *ope /****************************************************************************** * * * Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -584,11 +610,24 @@ static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *ope * * ******************************************************************************/ -static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand) +static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool lock) { guint result; /* Valeur à retourner */ + lockable_obj_extra_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= operand->count; - result = operand->count; + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); return result; diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index baab1f6..acec518 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -75,7 +75,7 @@ static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *); 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 *); +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 *); @@ -86,7 +86,7 @@ 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 *); +static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *, bool); @@ -230,8 +230,9 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -241,9 +242,21 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) * * ******************************************************************************/ -static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDalvikPoolOperand *b) +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*/ + 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); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } result = sort_unsigned_long((unsigned long)a->format, (unsigned long)b->format); @@ -253,6 +266,18 @@ static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDal if (result == 0) result = sort_unsigned_long(a->index, b->index); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_dalvik_pool_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; } @@ -547,6 +572,7 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) /****************************************************************************** * * * Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -556,17 +582,23 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) * * ******************************************************************************/ -static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand) +static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand, bool lock) { guint result; /* Valeur à retourner */ + lockable_obj_extra_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ DalvikPoolType type; /* Type porté par l'opérande */ uint32_t index; /* Indice de l'élément */ - result = (unsigned int)(unsigned long)operand->format; + extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t); -#if __SIZEOF_INT__ != __SIZEOF_LONG__ - result ^= ((unsigned long)operand->format) >> 32; -#endif + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_dalvik_pool_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= g_direct_hash(operand->format); type = g_dalvik_pool_operand_get_pool_type(operand); @@ -576,6 +608,9 @@ static guint g_dalvik_pool_operand_hash(const GDalvikPoolOperand *operand) result ^= index; + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + return result; } diff --git a/plugins/pychrysalide/arch/instructions/undefined.c b/plugins/pychrysalide/arch/instructions/undefined.c index 5741609..99fd2ff 100644 --- a/plugins/pychrysalide/arch/instructions/undefined.c +++ b/plugins/pychrysalide/arch/instructions/undefined.c @@ -130,7 +130,7 @@ static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *k unsigned long behavior; /* Conséquence pour l'instruct°*/ int ret; /* Bilan de lecture des args. */ GUndefInstruction *instr; /* Instruction à manipuler */ - undef_obj_extra *extra; /* Données insérées à modifier */ + undef_extra_data_t *extra; /* Données insérées à modifier */ static char *kwlist[] = { "behavior", NULL }; diff --git a/plugins/pychrysalide/arch/operand.c b/plugins/pychrysalide/arch/operand.c index f3eaa27..71e7cdc 100644 --- a/plugins/pychrysalide/arch/operand.c +++ b/plugins/pychrysalide/arch/operand.c @@ -49,7 +49,7 @@ static PyObject *py_arch_operand_new(PyTypeObject *, PyObject *, PyObject *); static void py_arch_operand_init_gclass(GArchOperandClass *, gpointer); /* Compare un opérande avec un autre. */ -static int py_arch_operand___cmp___wrapper(const GArchOperand *, const GArchOperand *); +static int py_arch_operand___cmp___wrapper(const GArchOperand *, const GArchOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *py_arch_operand_find_inner_operand_path_wrapper(const GArchOperand *, const GArchOperand *); @@ -193,8 +193,9 @@ static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unuse /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -204,7 +205,7 @@ static void py_arch_operand_init_gclass(GArchOperandClass *class, gpointer unuse * * ******************************************************************************/ -static int py_arch_operand___cmp___wrapper(const GArchOperand *a, const GArchOperand *b) +static int py_arch_operand___cmp___wrapper(const GArchOperand *a, const GArchOperand *b, bool lock) { int result; /* Empreinte à retourner */ PyGILState_STATE gstate; /* Sauvegarde d'environnement */ @@ -559,7 +560,7 @@ static PyObject *py_arch_operand_richcompare(PyObject *a, PyObject *b, int op) reg_a = G_ARCH_OPERAND(pygobject_get(a)); reg_b = G_ARCH_OPERAND(pygobject_get(b)); - status = py_arch_operand___cmp___wrapper(reg_a, reg_b); + status = py_arch_operand___cmp___wrapper(reg_a, reg_b, true); result = status_to_rich_cmp_state(status, op); diff --git a/plugins/pychrysalide/arch/operands/immediate.c b/plugins/pychrysalide/arch/operands/immediate.c index 2634352..5f59c6b 100644 --- a/plugins/pychrysalide/arch/operands/immediate.c +++ b/plugins/pychrysalide/arch/operands/immediate.c @@ -64,18 +64,6 @@ static PyObject *py_imm_operand_get_size(PyObject *, void *); /* Fournit la valeur portée par une opérande numérique. */ 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_default_padding(PyObject *self, void *); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -static int py_imm_operand_set_default_padding(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. */ -static int py_imm_operand_set_padding(PyObject *, PyObject *, void *); - /* Indique le format textuel par défaut de la valeur. */ static PyObject *py_imm_operand_get_default_display(PyObject *, void *); @@ -391,158 +379,6 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure) * 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_default_padding(PyObject *self, void *closure) -{ - PyObject *result; /* Instance Python à retourner */ - GImmOperand *operand; /* Version GLib de l'opérande */ - bool padding; /* Bourrage en préfixe ? */ - -#define IMM_OPERAND_DEFAULT_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL \ -( \ - default_padding, py_imm_operand, \ - "Get or set the status of default padding with zeros in front of the" \ - " textual representation." \ - "\n" \ - "The status is a boolean value." \ -) - - operand = G_IMM_OPERAND(pygobject_get(self)); - - padding = g_imm_operand_get_default_padding(operand); - - result = padding ? Py_True : Py_False; - Py_INCREF(result); - - 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_default_padding(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)); - - g_imm_operand_set_default_padding(operand, padding); - - 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 */ - GImmOperand *operand; /* Version GLib de l'opérande */ - bool padding; /* Bourrage en préfixe ? */ - -#define IMM_OPERAND_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL \ -( \ - padding, py_imm_operand, \ - "Get or set the status of padding with zeros in front of the" \ - " textual representation." \ - "\n" \ - "The status is a boolean value." \ -) - - operand = G_IMM_OPERAND(pygobject_get(self)); - - padding = g_imm_operand_does_padding(operand); - - result = padding ? Py_True : Py_False; - Py_INCREF(result); - - 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(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)); - - g_imm_operand_pad(operand, padding); - - return 0; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * * Description : Indique le format textuel par défaut de la valeur. * * * * Retour : Format global d'un affichage de valeur. * @@ -721,8 +557,6 @@ PyTypeObject *get_python_imm_operand_type(void) static PyGetSetDef py_imm_operand_getseters[] = { IMM_OPERAND_SIZE_ATTRIB, IMM_OPERAND_VALUE_ATTRIB, - IMM_OPERAND_DEFAULT_PADDING_ATTRIB, - IMM_OPERAND_PADDING_ATTRIB, IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB, IMM_OPERAND_DISPLAY_ATTRIB, { NULL } diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c index fcf838c..d032e04 100644 --- a/plugins/pychrysalide/arch/operands/register.c +++ b/plugins/pychrysalide/arch/operands/register.c @@ -67,9 +67,6 @@ static PyObject *py_register_operand__print(PyObject *, PyObject *); /* Fournit le registre associé à l'opérande. */ static PyObject *py_register_operand_get_register(PyObject *, void *); -/* Indique le type d'accès réalisé sur l'opérande. */ -static PyObject *py_register_operand_is_written(PyObject *, void *); - /* ---------------------------------------------------------------------------------- */ @@ -357,43 +354,6 @@ static PyObject *py_register_operand_get_register(PyObject *self, void *closure) /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Indique le type d'accès réalisé sur l'opérande. * -* * -* Retour : Type d'accès : True en cas d'écriture, False sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_register_operand_is_written(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GRegisterOperand *operand; /* Version GLib du type */ - bool status; /* Statut de la ligne */ - -#define REGISTER_OPERAND_IS_WRITTEN_ATTRIB PYTHON_IS_DEF_FULL \ -( \ - written, py_register_operand, \ - "Kind of access for the register when its instruction is executed." \ -) - - operand = G_REGISTER_OPERAND(pygobject_get(self)); - - status = g_register_operand_is_written(operand); - - result = status ? Py_True : Py_False; - Py_INCREF(result); - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -414,7 +374,6 @@ PyTypeObject *get_python_register_operand_type(void) static PyGetSetDef py_register_operand_getseters[] = { REGISTER_OPERAND_REGISTER_ATTRIB, - REGISTER_OPERAND_IS_WRITTEN_ATTRIB, { NULL } }; diff --git a/plugins/pychrysalide/arch/operands/target.c b/plugins/pychrysalide/arch/operands/target.c index 5cd9f59..76c8269 100644 --- a/plugins/pychrysalide/arch/operands/target.c +++ b/plugins/pychrysalide/arch/operands/target.c @@ -176,7 +176,8 @@ static int py_target_operand_init(PyObject *self, PyObject *args, PyObject *kwds MemoryDataSize size; /* Taille des adresses mémoire */ vmpa2t *addr; /* Emplacement de symbole */ int ret; /* Bilan de lecture des args. */ - GTargetOperand *operand; /* Opérande à manipuler */ + GTargetOperand *operand; /* Opérande à manipuler */ + tarop_extra_data_t *extra; /* Données insérées à modifier */ #define TARGET_OPERAND_DOC \ "The TargetOperand object translates immediate values as symbols.\n" \ @@ -203,7 +204,10 @@ static int py_target_operand_init(PyObject *self, PyObject *args, PyObject *kwds operand = G_TARGET_OPERAND(pygobject_get(self)); - operand->size = size; + extra = GET_TARGET_OP_EXTRA(operand); + + extra->size = size; + copy_vmpa(&operand->addr, addr); clean_vmpa_arg(addr); diff --git a/src/analysis/type-int.h b/src/analysis/type-int.h index 6c77954..8999b19 100644 --- a/src/analysis/type-int.h +++ b/src/analysis/type-int.h @@ -60,27 +60,34 @@ typedef bool (* type_is_reference_fc) (const GDataType *); /* Informations glissées dans la structure GObject de GBinSymbol */ -typedef union _type_obj_extra +typedef struct _type_extra_data_t { - struct - { - TypeQualifier qualifiers; /* Eventuels qualificatifs */ - char ns_sep[2]; /* Séparateur d'éléments */ - TypeFlag flags; /* Propriétés du type */ + char ns_sep[2]; /* Séparateur d'éléments */ + TypeFlag flags; /* Propriétés du type */ - }; + /** + * Afin de ne pas dépasser une taille de 31 bits, le champ de type + * TypeQualifier suivant est ramené à un champs de bits. + */ + + unsigned int qualifiers : 2; /* Eventuels qualificatifs */ + +} type_extra_data_t; + +/* Encapsulation avec un verrou d'accès */ +typedef union _type_obj_extra_t +{ + type_extra_data_t data; /* Données embarquées */ + lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */ - gint lock; /* Gestion d'accès aux fanions */ +} type_obj_extra_t; -} type_obj_extra; /* Description de type quelconque (instance) */ struct _GDataType { GObject parent; /* A laisser en premier */ - GDataType *namespace; /* Espace de noms / classe */ - #if __SIZEOF_INT__ == __SIZEOF_LONG__ /** @@ -90,29 +97,13 @@ struct _GDataType * ce dernier. */ - type_obj_extra extra; /* Externalisation embarquée */ + type_obj_extra_t extra; /* Externalisation embarquée */ #endif -}; - -/** - * Accès aux informations éventuellement déportées. - */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -# define INIT_DATA_TYPE_EXTRA(tp) tp->extra.lock = 0 - -# define GET_DATA_TYPE_EXTRA(tp) &tp->extra - -#else - -# define INIT_DATA_TYPE_EXTRA(tp) INIT_GOBJECT_EXTRA(G_OBJECT(tp)) - -# define GET_DATA_TYPE_EXTRA(tp) GET_GOBJECT_EXTRA(G_OBJECT(tp), type_obj_extra) + GDataType *namespace; /* Espace de noms / classe */ -#endif +}; /* Description de type quelconque (classe) */ struct _GDataTypeClass @@ -133,5 +124,20 @@ struct _GDataTypeClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_DATA_TYPE_EXTRA(tp) (type_extra_data_t *)&tp->extra + +#else + +# define GET_DATA_TYPE_EXTRA(tp) GET_GOBJECT_EXTRA(G_OBJECT(tp), type_extra_data_t) + +#endif + + #endif /* _ANALYSIS_TYPE_INT_H */ diff --git a/src/analysis/type.c b/src/analysis/type.c index ca14fdc..f05b9a8 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -111,7 +111,11 @@ static void g_data_type_class_init(GDataTypeClass *klass) static void g_data_type_init(GDataType *type) { - INIT_DATA_TYPE_EXTRA(type); + type_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + INIT_GOBJECT_EXTRA_LOCK(extra); g_data_type_set_qualifiers(type, TQF_NONE); @@ -280,7 +284,7 @@ static bool g_data_type_load(GDataType *type, GObjectStorage *storage, packed_bu static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ result = pack_uleb128((uleb128_t []){ g_data_type_get_qualifiers(type) }, pbuf); if (!result) goto exit; @@ -290,7 +294,7 @@ static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, p extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extend_packed_buffer(pbuf, extra->ns_sep, 2 * sizeof(char), false); if (!result) goto unlocking_exit; @@ -306,7 +310,7 @@ static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, p unlocking_exit: - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); exit: @@ -390,7 +394,7 @@ GDataType *g_data_type_dup(const GDataType *type) { GDataType *result; /* Copie à retourner */ GDataTypeClass *class; /* Classe du type */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ GDataType *ns; /* Eventuel espace de noms */ bool status; /* Bilan d'un rattachement */ @@ -404,7 +408,7 @@ GDataType *g_data_type_dup(const GDataType *type) extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (extra->ns_sep[0] != '\0') { @@ -422,7 +426,7 @@ GDataType *g_data_type_dup(const GDataType *type) } - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -446,7 +450,7 @@ char *g_data_type_to_string(const GDataType *type, bool include) { char *result; /* Chaîne à retourner */ GDataTypeClass *class; /* Classe du type */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ char *namespace; /* Groupe d'appartenance */ TypeQualifier qualifiers; /* Qualificatifs du type */ @@ -461,7 +465,7 @@ char *g_data_type_to_string(const GDataType *type, bool include) { extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (type->namespace != NULL && g_data_type_handle_namespaces(type)) { @@ -474,7 +478,7 @@ char *g_data_type_to_string(const GDataType *type, bool include) } - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -509,15 +513,15 @@ char *g_data_type_to_string(const GDataType *type, bool include) void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers) { - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->qualifiers = qualifiers; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -537,15 +541,15 @@ void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers) void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) { - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->qualifiers |= qualifier; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -565,15 +569,15 @@ void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) TypeQualifier g_data_type_get_qualifiers(const GDataType *type) { TypeQualifier result; /* Qualificatifs à renvoyer */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->qualifiers; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -597,7 +601,7 @@ TypeQualifier g_data_type_get_qualifiers(const GDataType *type) bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char *sep) { bool result; /* Bilan à retourner */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ result = ((namespace == NULL && sep == NULL) || (namespace != NULL && sep != NULL && sep[0] != '\0')); @@ -605,7 +609,7 @@ bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char { extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (sep == NULL) { @@ -625,7 +629,7 @@ bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char g_object_ref(G_OBJECT(namespace)); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -649,18 +653,18 @@ bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char GDataType *g_data_type_get_namespace(const GDataType *type) { GDataType *result; /* Espace à renvoyer */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = type->namespace; if (result != NULL) g_object_ref(G_OBJECT(result)); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -682,11 +686,11 @@ GDataType *g_data_type_get_namespace(const GDataType *type) char *g_data_type_get_namespace_separator(const GDataType *type) { char *result; /* Séparateur à retourner */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (extra->ns_sep[0] == '\0') result = NULL; @@ -697,7 +701,7 @@ char *g_data_type_get_namespace_separator(const GDataType *type) else result = strndup(extra->ns_sep, 2); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -748,15 +752,15 @@ bool g_data_type_handle_namespaces(const GDataType *type) void g_data_type_set_flags(GDataType *type, TypeFlag flags) { - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->flags = flags; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -776,15 +780,15 @@ void g_data_type_set_flags(GDataType *type, TypeFlag flags) void g_data_type_add_flag(GDataType *type, TypeFlag flag) { - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->flags |= flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -804,15 +808,15 @@ void g_data_type_add_flag(GDataType *type, TypeFlag flag) TypeFlag g_data_type_get_flags(const GDataType *type) { TypeFlag result; /* Propriétés à renvoyer */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_DATA_TYPE_EXTRA(type); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->flags; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; diff --git a/src/analysis/type.h b/src/analysis/type.h index 819af38..f5cc242 100644 --- a/src/analysis/type.h +++ b/src/analysis/type.h @@ -65,7 +65,7 @@ typedef enum _TypeFlag TFL_SINGLETON = (1 << 1), /* Singleton effectif */ TFL_USER_LOW_BIT = (1 << 2), /* Premier bit libre */ - TFL_USER_HIGH_BIT = (1 << 6) /* Dernier bit libre */ + TFL_USER_HIGH_BIT = (1 << 7) /* Dernier bit libre */ } TypeFlag; diff --git a/src/analysis/types/proto.c b/src/analysis/types/proto.c index aad073a..3cb074a 100644 --- a/src/analysis/types/proto.c +++ b/src/analysis/types/proto.c @@ -400,7 +400,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include) { char *result; /* Valeur à renvoyer */ GDataType *base; /* Version d'instance parente */ - type_obj_extra *extra; /* Données insérées à modifier */ + type_extra_data_t *extra; /* Données insérées à modifier */ char *namespace; /* Groupe d'appartenance */ size_t i; /* Boucle de parcours */ char *arg; /* Argument à décrire */ @@ -424,7 +424,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include) { extra = GET_DATA_TYPE_EXTRA(base); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (base->namespace != NULL) { @@ -438,7 +438,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include) } - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 6a3ccea..9a23bf2 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -59,26 +59,42 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *); -/* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _instr_obj_extra +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _instr_extra_data_t { - struct - { - itid_t uid; /* Identifiant unique du type */ + itid_t uid; /* Identifiant unique du type */ + + ArchInstrFlag flags; /* Informations complémentaires*/ - ArchInstrFlag flags; /* Informations complémentaires*/ +} instr_extra_data_t; - }; +/* Informations glissées dans la structure GObject de GArchInstruction */ +typedef union _instr_obj_extra_t +{ + instr_extra_data_t data; /* Données embarquées */ + lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */ - gint lock; /* Gestion d'accès aux fanions */ +} instr_obj_extra_t; -} instr_obj_extra; /* Définition générique d'une instruction d'architecture (instance) */ struct _GArchInstruction { GObject parent; /* A laisser en premier */ +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + + /** + * L'inclusion des informations suivantes dépend de l'architecture. + * + * Si la structure GObject possède un trou, on remplit de préférence + * ce dernier. + */ + + instr_obj_extra_t extra; /* Externalisation embarquée */ + +#endif + mrange_t range; /* Emplacement en mémoire */ flat_array_t *operands; /* Liste des opérandes */ @@ -108,39 +124,8 @@ struct _GArchInstruction flat_array_t *from; /* Origines des références */ flat_array_t *to; /* Instructions visées */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - - /** - * L'inclusion des informations suivantes dépend de l'architecture. - * - * Si la structure GObject possède un trou, on remplit de préférence - * ce dernier. - */ - - instr_obj_extra extra; /* Externalisation embarquée */ - -#endif - }; -/** - * Accès aux informations éventuellement déportées. - */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -# define INIT_ARCH_INSTR_EXTRA(ins) ins->extra.lock = 0 - -# define GET_ARCH_INSTR_EXTRA(ins) &ins->extra - -#else - -# define INIT_ARCH_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins)) - -# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_obj_extra) - -#endif - /* Définition générique d'une instruction d'architecture (classe) */ struct _GArchInstructionClass { @@ -163,6 +148,21 @@ struct _GArchInstructionClass /** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARCH_INSTR_EXTRA(ins) (instr_extra_data_t *)&ins->extra + +#else + +# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_extra_data_t) + +#endif + + +/** * Fournit une marge pour toutes les instructions particulières communes * à l'ensemble des architectures (GRawInstruction, GUndefInstruction). */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index cd9ccff..e0d1091 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -144,7 +144,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass) static void g_arch_instruction_init(GArchInstruction *instr) { - INIT_ARCH_INSTR_EXTRA(instr); + instr_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARCH_INSTR_EXTRA(instr); + + INIT_GOBJECT_EXTRA_LOCK(extra); instr->operands = NULL; @@ -286,19 +290,19 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr) bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag) { bool result; /* Bilan à retourner */ - instr_obj_extra *extra; /* Données insérées à modifier */ + instr_extra_data_t *extra; /* Données insérées à modifier */ assert(flag <= AIF_HIGH_USER); extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); - extra->flags |= flag; + result = !(extra->flags & flag); - result = true; + extra->flags |= flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -321,19 +325,19 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag) bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag) { bool result; /* Bilan à retourner */ - instr_obj_extra *extra; /* Données insérées à modifier */ + instr_extra_data_t *extra; /* Données insérées à modifier */ assert(flag <= AIF_HIGH_USER); extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); - extra->flags &= ~flag; + result = (extra->flags & flag); - result = true; + extra->flags &= ~flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -356,17 +360,17 @@ bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag) bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag) { bool result; /* Bilan à retourner */ - instr_obj_extra *extra; /* Données insérées à consulter*/ + instr_extra_data_t *extra; /* Données insérées à modifier */ assert(flag <= AIF_HIGH_USER); extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & flag); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -388,27 +392,15 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr) { ArchInstrFlag result; /* Fanions à retourner */ - instr_obj_extra *extra; /* Données insérées à consulter*/ + instr_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->flags; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - - /** - * La pose du verrou a entraîné la mise à 1 du bit de poids fort de la zone - * couverte par le champ "extra". - * - * Même si les fanions ne couvrent pas cet emplacement, leur stockage s'étend - * sur 16 bits, et contient donc le fameux bit de verrouillage. - * - * On efface ce marqueur après-coup ici. - */ - - result &= ((AIF_HIGH_USER << 1) - 1); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -430,15 +422,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr) void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid) { - instr_obj_extra *extra; /* Données insérées à modifier */ + instr_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->uid = uid; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -458,15 +450,15 @@ void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid) itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr) { itid_t result; /* Numéro à retourner */ - instr_obj_extra *extra; /* Données insérées à consulter*/ + instr_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->uid; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -1681,7 +1673,7 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage GArchOperand *op; /* Opérande à traiter */ instr_link_t link; /* Lien vers une instruction */ packed_buffer_t ins_pbuf; /* Tampon des données à écrire */ - instr_obj_extra *extra; /* Données insérées à consulter*/ + instr_extra_data_t *extra; /* Données insérées à consulter*/ result = unpack_mrange(&instr->range, pbuf); @@ -1765,14 +1757,14 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage { extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true); if (result) result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -1843,7 +1835,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s off64_t pos; /* Position dans le flux */ size_t kept; /* Nombre de liens conservés */ const instr_link_t *link; /* Lien vers une instruction */ - instr_obj_extra *extra; /* Données insérées à consulter*/ + instr_extra_data_t *extra; /* Données insérées à consulter*/ result = pack_mrange(&instr->range, pbuf); @@ -1947,14 +1939,14 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s { extra = GET_ARCH_INSTR_EXTRA(instr); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true); if (result) result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 80c500b..a9d66be 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -66,7 +66,7 @@ typedef enum _ArchInstrFlag AIF_CALL = (1 << 3), /* Instruction d'appel */ AIF_LOW_USER = (1 << AIF_USER_BIT), /* Premier bit disponible */ - AIF_HIGH_USER = (1 << 14), /* Dernier bit disponible */ + AIF_HIGH_USER = (1 << 7), /* Dernier bit disponible */ } ArchInstrFlag; diff --git a/src/arch/instructions/raw.c b/src/arch/instructions/raw.c index 481dd1c..6340e46 100644 --- a/src/arch/instructions/raw.c +++ b/src/arch/instructions/raw.c @@ -213,17 +213,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr) GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value) { GArchInstruction *result; /* Instruction à retourner */ - GImmOperand *operand; /* Octet non décodé à afficher */ + GArchOperand *operand; /* Octet non décodé à afficher */ mrange_t range; /* Couverture de l'instruction */ result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); - operand = G_IMM_OPERAND(g_imm_operand_new_from_value(size, value)); - if (operand == NULL) goto grinfv_error; + operand = g_imm_operand_new_from_value(size, value); + if (operand == NULL) goto error; - g_imm_operand_pad(operand, true); + g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); + g_arch_instruction_attach_extra_operand(result, operand); switch (size) { @@ -249,7 +249,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat default: assert(false); - goto grinfv_error; + goto error; break; } @@ -258,7 +258,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat return result; - grinfv_error: + error: g_object_unref(G_OBJECT(result)); @@ -287,13 +287,15 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa uleb128_t value; /* Valeur uleb128 à représenter*/ phys_t diff; /* Couverture de la lecture */ MemoryDataSize leb_size; /* Taille de la valeur */ - GImmOperand *operand; /* Octet non décodé à afficher */ + GArchOperand *operand; /* Octet non décodé à afficher */ mrange_t range; /* Couverture de l'instruction */ + result = NULL; + copy_vmpa(&start, addr); if (!g_binary_content_read_uleb128(content, addr, &value)) - goto grinu_error; + goto error; diff = compute_vmpa_diff(&start, addr); @@ -305,16 +307,18 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa init_mrange(&range, &start, diff); g_arch_instruction_set_range(result, &range); - operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value)); - if (operand == NULL) goto grinu_error; + operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value); + if (operand == NULL) goto error; - g_imm_operand_pad(operand, true); + g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); + g_arch_instruction_attach_extra_operand(result, operand); return result; - grinu_error: + error: + + g_clear_object(&result); return NULL; @@ -341,13 +345,15 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa uleb128_t value; /* Valeur uleb128 à représenter*/ phys_t diff; /* Couverture de la lecture */ MemoryDataSize leb_size; /* Taille de la valeur */ - GImmOperand *operand; /* Octet non décodé à afficher */ + GArchOperand *operand; /* Octet non décodé à afficher */ mrange_t range; /* Couverture de l'instruction */ + result = NULL; + copy_vmpa(&start, addr); if (!g_binary_content_read_uleb128(content, addr, &value)) - goto grins_error; + goto error; diff = compute_vmpa_diff(&start, addr); @@ -359,16 +365,18 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa init_mrange(&range, &start, diff); g_arch_instruction_set_range(result, &range); - operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value)); - if (operand == NULL) goto grins_error; + operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value); + if (operand == NULL) goto error; - g_imm_operand_pad(operand, true); + g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); + g_arch_instruction_attach_extra_operand(result, operand); return result; - grins_error: + error: + + g_clear_object(&result); return NULL; @@ -396,7 +404,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory GArchInstruction *result; /* Instruction à retourner */ vmpa2t old; /* Sauvegarde de la position */ size_t i; /* Boucle de parcours */ - GImmOperand *operand; /* Octet non décodé à afficher */ + GArchOperand *operand; /* Octet non décodé à afficher */ mrange_t range; /* Couverture de l'instruction */ /* Par soucis de cohérence */ @@ -408,12 +416,12 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory for (i = 0; i < count; i++) { - operand = G_IMM_OPERAND(g_imm_operand_new_from_data(size, content, addr, endian)); - if (operand == NULL) goto grina_error; + operand = g_imm_operand_new_from_data(size, content, addr, endian); + if (operand == NULL) goto error; - g_imm_operand_pad(operand, true); + g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); + g_arch_instruction_attach_extra_operand(result, operand); } @@ -423,7 +431,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory return result; - grina_error: + error: g_object_unref(G_OBJECT(result)); diff --git a/src/arch/instructions/undefined-int.h b/src/arch/instructions/undefined-int.h index 8a648cf..491ec31 100644 --- a/src/arch/instructions/undefined-int.h +++ b/src/arch/instructions/undefined-int.h @@ -32,63 +32,57 @@ /* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _undef_obj_extra +typedef struct _undef_extra_data_t { - struct - { - InstrExpectedBehavior behavior; /* Conséquences réelles */ + /** + * Le champ uid de la structure parente attendue conduit à une taille + * alignée sur 2 octets, donc à une taille totale de 4 octets ce qui + * représente la limite maximale de taille supportée. + * + * Pour 3 octets à la base, qui devraient laisser 8 - 1 octets disponbibles + * en incluant le bit de verrouillage. + * + * On reproduit donc la structure instr_extra_data_t ici, en basculant + * l'énumération InstrExpectedBehavior en champ de bits. + */ - }; + itid_t uid; /* Identifiant unique du type */ + ArchInstrFlag flags; /* Informations complémentaires*/ - gint lock; /* Gestion d'accès aux fanions */ + unsigned int behavior : 2; /* Conséquences réelles */ + +} undef_extra_data_t; -} undef_obj_extra; /* Définition générique d'une instruction au comportement non défini (instance) */ struct _GUndefInstruction { GArchInstruction parent; /* A laisser en premier */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - - /** - * L'inclusion des informations suivantes dépend de l'architecture. - * - * Si la structure GObject possède un trou, on remplit de préférence - * ce dernier. - */ - - undef_obj_extra extra; /* Externalisation embarquée */ +}; -#endif +/* Définition générique d'une instruction au comportement non défini (classe) */ +struct _GUndefInstructionClass +{ + GArchInstructionClass parent; /* A laisser en premier */ }; + /** * Accès aux informations éventuellement déportées. */ #if __SIZEOF_INT__ == __SIZEOF_LONG__ -# define INIT_UNDEF_INSTR_EXTRA(ins) ins->extra.lock = 0 - -# define GET_UNDEF_INSTR_EXTRA(ins) &ins->extra +# define GET_UNDEF_INSTR_EXTRA(ins) (undef_extra_data_t *)&ins->extra #else -# define INIT_UNDEF_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins)) - -# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_obj_extra) +# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_extra_data_t) #endif -/* Définition générique d'une instruction au comportement non défini (classe) */ -struct _GUndefInstructionClass -{ - GArchInstructionClass parent; /* A laisser en premier */ - -}; - #endif /* _ARCH_INSTRUCTIONS_UNDEFINED_INT_H */ diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c index 880e338..663a9eb 100644 --- a/src/arch/instructions/undefined.c +++ b/src/arch/instructions/undefined.c @@ -132,7 +132,7 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass) static void g_undef_instruction_init(GUndefInstruction *instr) { - INIT_ARCH_INSTR_EXTRA(instr); + GET_UNDEF_INSTR_EXTRA(instr)->behavior = IEB_UNDEFINED; } @@ -190,7 +190,7 @@ static void g_undef_instruction_finalize(GUndefInstruction *instr) GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior) { GArchInstruction *result; /* Instruction à retourner */ - undef_obj_extra *extra; /* Données insérées à modifier */ + undef_extra_data_t *extra; /* Données insérées à modifier */ result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL); @@ -241,7 +241,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *ins const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr) { const char *result; /* Désignation à retourner */ - undef_obj_extra *extra; /* Données insérées à consulter*/ + undef_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_UNDEF_INSTR_EXTRA(instr); @@ -300,7 +300,8 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag { bool result; /* Bilan à retourner */ GArchInstructionClass *parent; /* Classe parente à consulter */ - undef_obj_extra *extra; /* Données insérées à modifier */ + undef_extra_data_t *extra; /* Données insérées à consulter*/ + uint8_t val; /* Champ de bits manipulé */ parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); @@ -310,7 +311,12 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag { extra = GET_UNDEF_INSTR_EXTRA(instr); - result = extract_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true); + LOCK_GOBJECT_EXTRA(extra); + + result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); + extra->behavior = val; + + UNLOCK_GOBJECT_EXTRA(extra); } @@ -337,7 +343,7 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage { bool result; /* Bilan à retourner */ GArchInstructionClass *parent; /* Classe parente à consulter */ - undef_obj_extra *extra; /* Données insérées à consulter*/ + undef_extra_data_t *extra; /* Données insérées à consulter*/ parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); @@ -347,7 +353,11 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage { extra = GET_UNDEF_INSTR_EXTRA(instr); - result = extend_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true); + LOCK_GOBJECT_EXTRA(extra); + + result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false); + + UNLOCK_GOBJECT_EXTRA(extra); } @@ -417,12 +427,16 @@ static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *lin InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *instr) { InstrExpectedBehavior result; /* Comportement à retourner */ - undef_obj_extra *extra; /* Données insérées à consulter*/ + undef_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_UNDEF_INSTR_EXTRA(instr); + LOCK_GOBJECT_EXTRA(extra); + result = extra->behavior; + UNLOCK_GOBJECT_EXTRA(extra); + return result; } diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index ca5204c..c348654 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -26,11 +26,12 @@ #include "operand.h" +#include "../glibext/objhole.h" /* Compare un opérande avec un autre. */ -typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *); +typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ typedef char * (* find_inner_operand_fc) (const GArchOperand *, const GArchOperand *); @@ -51,7 +52,7 @@ typedef GArchOperand ** (* operand_list_inners_fc) (const GArchOperand *, size_t typedef void (* operand_update_inners_fc) (GArchOperand *, GArchOperand **, size_t); /* Fournit l'empreinte d'un candidat à une centralisation. */ -typedef guint (* operand_hash_fc) (const GArchOperand *); +typedef guint (* operand_hash_fc) (const GArchOperand *, bool); /* Charge un opérande depuis une mémoire tampon. */ typedef bool (* unserialize_operand_fc) (GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); @@ -60,15 +61,41 @@ typedef bool (* unserialize_operand_fc) (GArchOperand *, GAsmStorage *, GBinForm typedef bool (* serialize_operand_fc) (const GArchOperand *, GAsmStorage *, packed_buffer_t *); +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _operand_extra_data_t +{ + ArchOperandFlag flags; /* Informations diverses */ + +} operand_extra_data_t; + +/* Encapsulation avec un verrou d'accès */ +typedef union _operand_obj_extra_t +{ + operand_extra_data_t data; /* Données embarquées */ + lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */ + +} operand_obj_extra_t; + + /* Définition générique d'un opérande d'architecture (instance) */ struct _GArchOperand { GObject parent; /* A laisser en premier */ - bool read_only; /* Verrouillage du contenu */ +#if __SIZEOF_INT__ == __SIZEOF_LONG__ -}; + /** + * L'inclusion des informations suivantes dépend de l'architecture. + * + * Si la structure GObject possède un trou, on remplit de préférence + * ce dernier. + */ + operand_obj_extra_t extra; /* Externalisation embarquée */ + +#endif + +}; /* Définition générique d'un opérande d'architecture (classe) */ struct _GArchOperandClass @@ -92,5 +119,20 @@ struct _GArchOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARCH_OP_EXTRA(op) (operand_extra_data_t *)&op->extra + +#else + +# define GET_ARCH_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), operand_extra_data_t) + +#endif + + #endif /* _ARCH_OPERAND_INT_H */ diff --git a/src/arch/operand.c b/src/arch/operand.c index 66af6d2..944c34e 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -31,6 +31,7 @@ #include "operand-int.h" #include "storage.h" +#include "../common/fnv1a.h" #include "../common/sort.h" #include "../core/logs.h" #include "../glibext/singleton-int.h" @@ -55,6 +56,9 @@ static void g_arch_operand_dispose(GArchOperand *); /* Procède à la libération totale de la mémoire. */ static void g_arch_operand_finalize(GArchOperand *); +/* Compare un opérande avec un autre. */ +static int _g_arch_operand_compare(const GArchOperand *, const GArchOperand *, bool); + /* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ @@ -67,6 +71,9 @@ static GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, static void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t); /* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint _g_arch_operand_hash(const GArchOperand *, bool); + +/* Fournit l'empreinte d'un candidat à une centralisation. */ static guint g_arch_operand_hash(const GArchOperand *); /* Détermine si deux candidats à l'unicité sont identiques. */ @@ -91,12 +98,16 @@ static bool g_arch_operand_serialize(const GArchOperand *, GAsmStorage *, packed +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'OPERANDE QUELCONQUE */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini pour un opérande d'architecture. */ G_DEFINE_TYPE_WITH_CODE(GArchOperand, g_arch_operand, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_SINGLETON_CANDIDATE, g_arch_operand_singleton_interface_init)); - /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * @@ -121,6 +132,10 @@ static void g_arch_operand_class_init(GArchOperandClass *klass) operand = G_ARCH_OPERAND_CLASS(klass); + operand->compare = (operand_compare_fc)_g_arch_operand_compare; + + operand->hash = _g_arch_operand_hash; + operand->unserialize = (unserialize_operand_fc)g_arch_operand_unserialize; operand->serialize = (serialize_operand_fc)g_arch_operand_serialize; @@ -141,6 +156,11 @@ static void g_arch_operand_class_init(GArchOperandClass *klass) static void g_arch_operand_init(GArchOperand *operand) { + operand_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARCH_OP_EXTRA(operand); + + INIT_GOBJECT_EXTRA_LOCK(extra); } @@ -211,6 +231,38 @@ static void g_arch_operand_finalize(GArchOperand *operand) /****************************************************************************** * * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int _g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b, bool lock) +{ + int result; /* Bilan à faire remonter */ + operand_extra_data_t *ea; /* Données insérées à consulter*/ + operand_extra_data_t *eb; /* Données insérées à consulter*/ + + assert(!lock); + + ea = GET_ARCH_OP_EXTRA(a); + eb = GET_ARCH_OP_EXTRA(b); + + result = sort_unsigned_long(ea->flags, eb->flags); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : a = premier opérande à consulter. * * b = second opérande à consulter. * * * @@ -236,7 +288,7 @@ int g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b) result = sort_unsigned_long(type_a, type_b); if (result == 0) - result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b); + result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b, true); return result; @@ -355,6 +407,139 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin } +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir modifier. * +* flag = drapeau d'information complémentaire à planter. * +* * +* Description : Ajoute une information complémentaire à un opérande. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_set_flag(GArchOperand *operand, ArchOperandFlag flag) +{ + bool result; /* Bilan à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(flag <= AOF_HIGH_USER); + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = !(extra->flags & flag); + + extra->flags |= flag; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir modifier. * +* flag = drapeau d'information complémentaire à planter. * +* * +* Description : Retire une information complémentaire à un opérande. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_unset_flag(GArchOperand *operand, ArchOperandFlag flag) +{ + bool result; /* Bilan à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(flag <= AOF_HIGH_USER); + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = (extra->flags & flag); + + extra->flags &= ~flag; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir consulter. * +* flag = drapeau d'information à rechercher. * +* * +* Description : Détermine si un opérande possède un fanion particulier. * +* * +* Retour : Bilan de la détection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_has_flag(const GArchOperand *operand, ArchOperandFlag flag) +{ + bool result; /* Bilan à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(flag <= AOF_HIGH_USER); + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = (extra->flags & flag); + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir consulter. * +* * +* Description : Fournit les particularités de l'opérande. * +* * +* Retour : Somme de tous les fanions associés à l'opérande. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *operand) +{ + ArchOperandFlag result; /* Fanions à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->flags; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* CONTROLE DU VOLUME DES INSTANCES */ @@ -430,6 +615,43 @@ static void g_arch_operand_update_inner_instances(GArchOperand *operand, GArchOp /****************************************************************************** * * * Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint _g_arch_operand_hash(const GArchOperand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + const char *name; /* Désignation du type d'object*/ + fnv64_t name_hash; /* Empreinte du nom */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(!lock); + + name = G_OBJECT_TYPE_NAME(G_OBJECT(operand)); + name_hash = fnv_64a_hash(name); + + result = (name_hash & 0xffffffff); + result ^= (name_hash >> 32); + + extra = GET_ARCH_OP_EXTRA(operand); + + result ^= extra->flags; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet dont l'instance se veut unique. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -446,7 +668,7 @@ static guint g_arch_operand_hash(const GArchOperand *operand) class = G_ARCH_OPERAND_GET_CLASS(operand); - result = class->hash(operand); + result = class->hash(operand, true); return result; @@ -494,7 +716,7 @@ static gboolean g_arch_operand_is_equal(const GArchOperand *operand, const GArch static void g_arch_operand_set_read_only(GArchOperand *operand) { - operand->read_only = true; + g_arch_operand_set_flag(operand, AOF_READ_ONLY); } @@ -515,7 +737,7 @@ static bool g_arch_operand_is_read_only(GArchOperand *operand) { bool result; /* Etat à retourner */ - result = operand->read_only; + result = g_arch_operand_has_flag(operand, AOF_READ_ONLY); return result; diff --git a/src/arch/operand.h b/src/arch/operand.h index 9e1b5a8..f8d2536 100644 --- a/src/arch/operand.h +++ b/src/arch/operand.h @@ -41,6 +41,23 @@ typedef struct _GLoadedBinary GLoadedBinary; +/* Indications supplémentaires liées aux opérandes */ + +#define AOF_USER_BIT 1 + +typedef enum _ArchOperandFlag +{ + AOF_NONE = (0 << 0), /* Aucune propriété */ + AOF_READ_ONLY = (1 << 0), /* Indication de nature */ + + AOF_LOW_USER = (1 << AOF_USER_BIT), /* Premier bit disponible */ + AOF_HIGH_USER = (1 << 7), /* Dernier bit disponible */ + +} ArchOperandFlag; + +#define AOF_USER_FLAG(n) (1 << (AOF_USER_BIT + n)) + + #define G_TYPE_ARCH_OPERAND g_arch_operand_get_type() #define G_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARCH_OPERAND, GArchOperand)) #define G_IS_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARCH_OPERAND)) @@ -74,6 +91,18 @@ void g_arch_operand_print(const GArchOperand *, GBufferLine *); /* Construit un petit résumé concis de l'opérande. */ char *g_arch_operand_build_tooltip(const GArchOperand *, const GLoadedBinary *); +/* Ajoute une information complémentaire à un opérande. */ +bool g_arch_operand_set_flag(GArchOperand *, ArchOperandFlag); + +/* Retire une information complémentaire à un opérande. */ +bool g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag); + +/* Détermine si un opérande possède un fanion particulier. */ +bool g_arch_operand_has_flag(const GArchOperand *, ArchOperandFlag); + +/* Fournit les particularités de l'opérande. */ +ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *); + /* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c index ec81cfe..cb4e457 100644 --- a/src/arch/operands/immediate.c +++ b/src/arch/operands/immediate.c @@ -42,9 +42,9 @@ #include "../operand-int.h" #include "../../common/asm.h" #include "../../common/extstr.h" +#include "../../common/sort.h" #include "../../core/logs.h" #include "../../format/format.h" -#include "../../glibext/objhole.h" #include "../../gtkext/gtkblockdisplay.h" @@ -52,30 +52,24 @@ /* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ -/* Etats particuliers d'un opérande de valeur immédiate */ -typedef enum _ImmOpFlag +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _immop_extra_data_t { - IOF_ZERO_PADDING_BY_DEFAULT, /* Bourrage avec 0 par défaut ?*/ - IOF_ZERO_PADDING, /* Bourrage avec 0 ? */ + operand_extra_data_t parent; /* A laisser en premier */ -} ImmOpFlag; + MemoryDataSize size; /* Taille de l'opérande */ -/* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _immop_obj_extra -{ - struct - { - MemoryDataSize size; /* Taille de l'opérande */ - - ImmOperandDisplay def_display; /* Type par défaut d'affichage */ - ImmOperandDisplay display; /* Format général d'affichage */ - ImmOpFlag flags; /* Informations diverses */ + /** + * Les deux éléments suivants sont de type ImmOperandDisplay ; + * leur espace de conservation est réduit au maximum afin d'éviter + * un recouvrement . + */ - }; + unsigned int def_display : 3; /* Type par défaut d'affichage */ + unsigned int display : 3; /* Format général d'affichage */ - gint lock; /* Gestion d'accès aux fanions */ +} immop_extra_data_t; -} immop_obj_extra; /* Définition d'un opérande de valeur numérique (instance) */ struct _GImmOperand @@ -84,46 +78,30 @@ struct _GImmOperand uint64_t raw; /* Valeur transtypée */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - - /** - * L'inclusion des informations suivantes dépend de l'architecture. - * - * Si la structure GObject possède un trou, on remplit de préférence - * ce dernier. - */ - - immop_obj_extra extra; /* Externalisation embarquée */ +}; -#endif +/* Définition d'un opérande de valeur numérique (classe) */ +struct _GImmOperandClass +{ + GArchOperandClass parent; /* Classe parente */ }; + /** * Accès aux informations éventuellement déportées. */ #if __SIZEOF_INT__ == __SIZEOF_LONG__ -# define INIT_IMM_OP_EXTRA(op) op->extra.lock = 0 - -# define GET_IMM_OP_EXTRA(op) &op->extra +# define GET_IMM_OP_EXTRA(op) (immop_extra_data_t *)&op->extra #else -# define INIT_IMM_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op)) - -# define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_obj_extra) +# define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_extra_data_t) #endif -/* Définition d'un opérande de valeur numérique (classe) */ -struct _GImmOperandClass -{ - GArchOperandClass parent; /* Classe parente */ - -}; - /* Initialise la classe des opérandes de valeur immédiate. */ static void g_imm_operand_class_init(GImmOperandClass *); @@ -144,7 +122,7 @@ static void g_imm_operand_dispose(GImmOperand *); static void g_imm_operand_finalize(GImmOperand *); /* Compare un opérande avec un autre. */ -static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *); +static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *, bool); /* Construit la chaîne de caractères correspondant à l'opérande. */ static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]); @@ -156,7 +134,7 @@ static void g_imm_operand_print(const GImmOperand *, GBufferLine *); static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); /* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_imm_operand_hash(const GImmOperand *); +static guint g_imm_operand_hash(const GImmOperand *, bool); /* Charge un opérande depuis une mémoire tampon. */ static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); @@ -208,11 +186,14 @@ static void g_known_imm_operand_dispose(GKnownImmOperand *); static void g_known_imm_operand_finalize(GKnownImmOperand *); /* Compare un opérande avec un autre. */ -static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *); +static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_known_imm_operand_hash(const GKnownImmOperand *, bool); + /* Charge un opérande depuis une mémoire tampon. */ static bool g_known_imm_operand_unserialize(GKnownImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); @@ -284,13 +265,13 @@ static void g_imm_operand_class_init(GImmOperandClass *klass) static void g_imm_operand_init(GImmOperand *operand) { - operand->raw = 0; - - INIT_IMM_OP_EXTRA(operand); + GET_IMM_OP_EXTRA(operand)->size = MDS_UNDEFINED; GET_IMM_OP_EXTRA(operand)->def_display = IOD_HEX; GET_IMM_OP_EXTRA(operand)->display = IOD_COUNT; + operand->raw = 0; + } @@ -389,7 +370,7 @@ static void g_imm_operand_finalize(GImmOperand *operand) GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) { GImmOperand *result; /* Opérande à retourner */ - immop_obj_extra *extra; /* Données insérées à modifier */ + immop_extra_data_t *extra; /* Données insérées à modifier */ uint8_t uval8; /* Valeur sur 8 bits */ uint16_t uval16; /* Valeur sur 16 bits */ uint32_t uval32; /* Valeur sur 32 bits */ @@ -500,7 +481,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) { GImmOperand *result; /* Opérande à retourner */ - immop_obj_extra *extra; /* Données insérées à modifier */ + immop_extra_data_t *extra; /* Données insérées à modifier */ if (size == MDS_UNDEFINED) result = NULL; @@ -524,8 +505,9 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -535,80 +517,45 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) * * ******************************************************************************/ -static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) +static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b, bool lock) { int result; /* Bilan à retourner */ - immop_obj_extra *ea; /* Données insérées à modifier */ - immop_obj_extra *eb; /* Données insérées à modifier */ + immop_extra_data_t *ea; /* Données insérées à modifier */ + immop_extra_data_t *eb; /* Données insérées à modifier */ + GArchOperandClass *class; /* Classe parente normalisée */ ea = GET_IMM_OP_EXTRA(a); eb = GET_IMM_OP_EXTRA(b); - g_bit_lock(&ea->lock, HOLE_LOCK_BIT); - g_bit_lock(&eb->lock, HOLE_LOCK_BIT); - - if (ea->size < eb->size) - { - result = -1; - goto done; - } - else if (ea->size > eb->size) + if (lock) { - result = 1; - goto done; + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); } - if (a->raw < b->raw) - { - result = -1; - goto done; - } - else if (a->raw > b->raw) - { - result = 1; - goto done; - } + result = sort_unsigned_long(ea->size, eb->size); - if (ea->def_display < eb->def_display) - { - result = -1; - goto done; - } - else if (ea->def_display > eb->def_display) - { - result = 1; - goto done; - } + if (result == 0) + sort_uint64_t(a->raw, b->raw); - if (ea->display < eb->display) - { - result = -1; - goto done; - } - else if (ea->display > eb->display) - { - result = 1; - goto done; - } + if (result == 0) + result = sort_unsigned_long(ea->def_display, eb->def_display); - if (ea->flags < eb->flags) + if (result == 0) + result = sort_unsigned_long(ea->display, eb->display); + + if (result == 0) { - result = -1; - goto done; + class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); } - else if (ea->flags > eb->flags) + + if (lock) { - result = 1; - goto done; + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); } - result = 0; - - done: - - g_bit_unlock(&eb->lock, HOLE_LOCK_BIT); - g_bit_unlock(&ea->lock, HOLE_LOCK_BIT); - return result; } @@ -629,15 +576,15 @@ static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand) { MemoryDataSize result; /* Taille à retourner */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->size; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -661,7 +608,7 @@ MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand) bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...) { bool result; /* Bilan à retourner */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ va_list ap; /* Liste des compléments */ uint8_t *uval8; /* Valeur sur 8 bits */ uint16_t *uval16; /* Valeur sur 16 bits */ @@ -676,7 +623,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, .. extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (extra->size != size) goto exit; @@ -731,7 +678,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, .. exit: - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -773,141 +720,19 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand) void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value) { - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ assert(size != MDS_UNDEFINED); extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->size = size; operand->raw = value; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -* * -* 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_get_default_padding(const GImmOperand *operand) -{ - bool result; /* Statut à retourner */ - immop_obj_extra *extra; /* Données insérées à modifier */ - - extra = GET_IMM_OP_EXTRA(operand); - - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - - result = (extra->flags & IOF_ZERO_PADDING_BY_DEFAULT); - - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* state = true si des zéro sont à ajouter, false sinon. * -* * -* Description : Précise si des zéro doivent compléter l'affichage ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_default_padding(GImmOperand *operand, bool state) -{ - immop_obj_extra *extra; /* Données insérées à modifier */ - - extra = GET_IMM_OP_EXTRA(operand); - - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - - if (state) - extra->flags |= IOF_ZERO_PADDING_BY_DEFAULT; - else - extra->flags &= ~IOF_ZERO_PADDING_BY_DEFAULT; - - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* state = true si des zéro sont à ajouter, false sinon. * -* * -* 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) -{ - immop_obj_extra *extra; /* Données insérées à modifier */ - - extra = GET_IMM_OP_EXTRA(operand); - - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - - if (state) - extra->flags |= (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - else - extra->flags &= ~(IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* 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 : - * -* * -******************************************************************************/ - -bool g_imm_operand_does_padding(const GImmOperand *operand) -{ - bool result; /* Statut à retourner */ - immop_obj_extra *extra; /* Données insérées à modifier */ - - extra = GET_IMM_OP_EXTRA(operand); - - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - - result = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING)); - - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - - return result; + UNLOCK_GOBJECT_EXTRA(extra); } @@ -927,15 +752,15 @@ bool g_imm_operand_does_padding(const GImmOperand *operand) void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display) { - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->def_display = display; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -955,15 +780,15 @@ void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay d ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand) { ImmOperandDisplay result; /* Affichage à retourner */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->def_display; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -985,15 +810,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand) void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display) { - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->display = display; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -1013,18 +838,18 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display) ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) { ImmOperandDisplay result; /* Affichage à retourner */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); if (extra->display != IOD_COUNT) result = extra->display; else result = extra->def_display; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -1046,11 +871,11 @@ ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) bool g_imm_operand_is_negative(const GImmOperand *operand) { bool result; /* Bilan à renvoyer */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); switch (extra->size) { @@ -1070,7 +895,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand) break; } - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -1113,7 +938,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand) static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE]) { size_t result; /* Longueur à retourner */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ unsigned int range; /* Catégorie de la taille */ const char *prefix; /* Entrée en matière */ const char *suffix; /* Sortie de matière */ @@ -1137,7 +962,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + //LOCK_GOBJECT_EXTRA(extra); range = MDS_RANGE(extra->size); @@ -1178,7 +1003,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis /* Drapeau de remplissage ? */ - do_padding = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING)); + do_padding = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); if (do_padding) { @@ -1302,7 +1127,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis } - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + //UNLOCK_GOBJECT_EXTRA(extra); assert(result > 0); @@ -1468,18 +1293,18 @@ static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoad bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos) { bool result; /* Bilan à renvoyer */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = !MDS_IS_SIGNED(extra->size); if (result) *pos = operand->raw; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -1502,18 +1327,18 @@ bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos) bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) { bool result; /* Bilan à renvoyer */ - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = !MDS_IS_SIGNED(extra->size); if (result) *addr = operand->raw; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -1535,15 +1360,15 @@ bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) { - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); *val = operand->raw; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -1563,15 +1388,15 @@ void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) { - immop_obj_extra *extra; /* Données insérées à consulter*/ + immop_extra_data_t *extra; /* Données insérées à consulter*/ extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); *val = operand->raw; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -1579,6 +1404,7 @@ void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) /****************************************************************************** * * * Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -1588,13 +1414,26 @@ void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) * * ******************************************************************************/ -static guint g_imm_operand_hash(const GImmOperand *operand) +static guint g_imm_operand_hash(const GImmOperand *operand, bool lock) { guint result; /* Valeur à retourner */ + immop_extra_data_t *extra; /* Données insérées à modifier */ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_IMM_OP_EXTRA(operand); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); - result = (operand->raw & 0xffffffff); + class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= (operand->raw & 0xffffffff); result ^= (operand->raw >> 32); + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + return result; } @@ -1619,7 +1458,8 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - immop_obj_extra *extra; /* Données insérées à modifier */ + immop_extra_data_t *extra; /* Données insérées à modifier */ + uint8_t val; /* Champ de bits manipulé */ parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); @@ -1632,20 +1472,23 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage { extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extract_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true); if (result) - result = extract_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extract_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true); + { + result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); + extra->def_display = val; + } if (result) - result = extract_packed_buffer(pbuf, &extra->flags, sizeof(uint8_t), false); + { + result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); + extra->display = val; + } - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -1672,7 +1515,7 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - immop_obj_extra *extra; /* Données insérées à modifier */ + immop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); @@ -1685,20 +1528,17 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto { extra = GET_IMM_OP_EXTRA(operand); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extend_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true); if (result) - result = extend_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extend_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true); + result = extend_packed_buffer(pbuf, (uint8_t []) { extra->def_display }, sizeof(uint8_t), false); if (result) - result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ImmOpFlag), true); + result = extend_packed_buffer(pbuf, (uint8_t []) { extra->display }, sizeof(uint8_t), false); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -1799,6 +1639,8 @@ static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass) operand->compare = (operand_compare_fc)g_known_imm_operand_compare; operand->print = (operand_print_fc)g_known_imm_operand_print; + operand->hash = (operand_hash_fc)g_known_imm_operand_hash; + operand->unserialize = (unserialize_operand_fc)g_known_imm_operand_unserialize; operand->serialize = (serialize_operand_fc)g_known_imm_operand_serialize; @@ -1900,8 +1742,8 @@ static void g_known_imm_operand_finalize(GKnownImmOperand *operand) GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) { GKnownImmOperand *result; /* Remplacement à retourner */ - immop_obj_extra *src; /* Données insérées à consulter*/ - immop_obj_extra *dest; /* Données insérées à modifier */ + immop_extra_data_t *src; /* Données insérées à consulter*/ + immop_extra_data_t *dest; /* Données insérées à modifier */ result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL); @@ -1910,11 +1752,16 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) src = GET_IMM_OP_EXTRA(old); dest = GET_IMM_OP_EXTRA(&result->parent); - g_bit_lock(&src->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(src); + + *(&dest->parent) = *(&src->parent); - *dest = *src; + dest->size = src->size; - g_bit_unlock(&src->lock, HOLE_LOCK_BIT); + dest->def_display = src->def_display; + dest->display = src->display; + + UNLOCK_GOBJECT_EXTRA(src); result->alt_text = strdup(alt); @@ -1925,8 +1772,9 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -1936,17 +1784,35 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) * * ******************************************************************************/ -static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b) +static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b, bool lock) { int result; /* Bilan à retourner */ - GArchOperandClass *class; /* Classe parente à consulter */ + lockable_obj_extra_t *ea; /* Données insérées à consulter*/ + lockable_obj_extra_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ - class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); + ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t); + eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } - result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b)); + result = strcmp(a->alt_text, b->alt_text); if (result == 0) - result = strcmp(a->alt_text, b->alt_text); + { + class = G_ARCH_OPERAND_CLASS(g_known_imm_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; @@ -1979,6 +1845,43 @@ static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLi /****************************************************************************** * * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint g_known_imm_operand_hash(const GKnownImmOperand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + lockable_obj_extra_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= g_str_hash(operand->alt_text); + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande d'assemblage à constituer. * * storage = mécanisme de sauvegarde à manipuler. * * format = format binaire chargé associé à l'architecture. * diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h index e6fab96..1291962 100644 --- a/src/arch/operands/immediate.h +++ b/src/arch/operands/immediate.h @@ -39,6 +39,14 @@ /* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _ImmOpFlag +{ + IOF_ZERO_PADDING_BY_DEFAULT = AOF_USER_FLAG(0), /* Bourrage avec 0 par défaut ?*/ + IOF_ZERO_PADDING = AOF_USER_FLAG(1), /* Bourrage avec 0 ? */ + +} ImmOpFlag; + /* Grande ligne d'un format d'affichage */ typedef enum _ImmOperandDisplay { @@ -52,7 +60,6 @@ typedef enum _ImmOperandDisplay } ImmOperandDisplay; - #define IOD_LAST_VALID IOD_CHAR @@ -95,18 +102,6 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *); /* Définit la nouvelle valeur de l'opérande à une valeur. */ void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t); -/* Indique si une valeur est complétée par des zéros par défaut. */ -bool g_imm_operand_get_default_padding(const GImmOperand *); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -void g_imm_operand_set_default_padding(GImmOperand *, bool); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -void g_imm_operand_pad(GImmOperand *, bool); - -/* 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. */ void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay); diff --git a/src/arch/operands/proxy.c b/src/arch/operands/proxy.c index bf26a4f..992c481 100644 --- a/src/arch/operands/proxy.c +++ b/src/arch/operands/proxy.c @@ -44,11 +44,14 @@ static void g_proxy_operand_dispose(GProxyOperand *); static void g_proxy_operand_finalize(GProxyOperand *); /* Compare un opérande avec un autre. */ -static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *); +static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_proxy_operand_print(const GProxyOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_proxy_operand_hash(const GProxyOperand *, bool); + /* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ @@ -98,6 +101,8 @@ static void g_proxy_operand_class_init(GProxyOperandClass *klass) operand->compare = (operand_compare_fc)g_proxy_operand_compare; operand->print = (operand_print_fc)g_proxy_operand_print; + operand->hash = (operand_hash_fc)g_proxy_operand_hash; + operand->unserialize = (unserialize_operand_fc)g_proxy_operand_unserialize; operand->serialize = (serialize_operand_fc)g_proxy_operand_serialize; @@ -190,8 +195,9 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -201,12 +207,36 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder) * * ******************************************************************************/ -static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b) +static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b, bool lock) { int result; /* Bilan à retourner */ + lockable_obj_extra_t *ea; /* Données insérées à consulter*/ + lockable_obj_extra_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); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } result = g_proxy_feeder_compare(a->feeder, b->feeder); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_proxy_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; } @@ -234,6 +264,43 @@ static void g_proxy_operand_print(const GProxyOperand *operand, GBufferLine *lin /****************************************************************************** * * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint g_proxy_operand_hash(const GProxyOperand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + lockable_obj_extra_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= g_direct_hash(operand->feeder); + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande à consulter. * * * * Description : Fournit le fournisseur représenté par l'opérande. * diff --git a/src/arch/operands/register-int.h b/src/arch/operands/register-int.h index bf3e9d4..a887567 100644 --- a/src/arch/operands/register-int.h +++ b/src/arch/operands/register-int.h @@ -29,23 +29,9 @@ #include "../operand-int.h" -#include "../../glibext/objhole.h" -/* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _regop_obj_extra -{ - struct - { - bool is_written; /* Changement de contenu */ - - }; - - gint lock; /* Gestion d'accès aux fanions */ - -} regop_obj_extra; - /* Définition d'un opérande visant un registre (instance) */ struct _GRegisterOperand { @@ -53,39 +39,8 @@ struct _GRegisterOperand GArchRegister *reg; /* Registre représenté */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - - /** - * L'inclusion des informations suivantes dépend de l'architecture. - * - * Si la structure GObject possède un trou, on remplit de préférence - * ce dernier. - */ - - regop_obj_extra extra; /* Externalisation embarquée */ - -#endif - }; -/** - * Accès aux informations éventuellement déportées. - */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -# define INIT_REG_OP_EXTRA(op) op->extra.lock = 0 - -# define GET_REG_OP_EXTRA(op) &op->extra - -#else - -# define INIT_REG_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op)) - -# define GET_REG_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), regop_obj_extra) - -#endif - /* Définition d'un opérande visant un registre (classe) */ struct _GRegisterOperandClass { diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c index e457158..9c0a337 100644 --- a/src/arch/operands/register.c +++ b/src/arch/operands/register.c @@ -24,6 +24,9 @@ #include "register.h" +#include + + #include "register-int.h" #include "../storage.h" @@ -45,7 +48,7 @@ static void g_register_operand_dispose(GRegisterOperand *); static void g_register_operand_finalize(GRegisterOperand *); /* Compare un opérande avec un autre. */ -static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *); +static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_register_operand_print(const GRegisterOperand *, GBufferLine *); @@ -56,7 +59,7 @@ static void g_register_operand_print(const GRegisterOperand *, GBufferLine *); /* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_register_operand_hash(const GRegisterOperand *); +static guint g_register_operand_hash(const GRegisterOperand *, bool); @@ -132,8 +135,6 @@ static void g_register_operand_init(GRegisterOperand *operand) { operand->reg = NULL; - INIT_REG_OP_EXTRA(operand); - } @@ -179,8 +180,9 @@ static void g_register_operand_finalize(GRegisterOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -190,12 +192,19 @@ static void g_register_operand_finalize(GRegisterOperand *operand) * * ******************************************************************************/ -static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b) +static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock) { int result; /* Bilan à retourner */ + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_register_compare(a->reg, b->reg); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + return result; } @@ -246,63 +255,6 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand) } -/****************************************************************************** -* * -* Paramètres : operand = opérande représentant un registre à mettre à jour. * -* * -* Description : Marque l'opérande comme étant écrit plutôt que consulté. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_register_operand_mark_as_written(GRegisterOperand *operand) -{ - regop_obj_extra *extra; /* Données insérées à modifier */ - - extra = GET_REG_OP_EXTRA(operand); - - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - - extra->is_written = true; - - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande représentant un registre à consulter. * -* * -* Description : Indique le type d'accès réalisé sur l'opérande. * -* * -* Retour : Type d'accès : true en cas d'écriture, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_register_operand_is_written(const GRegisterOperand *operand) -{ - bool result; /* Statut à retourner */ - regop_obj_extra *extra; /* Données insérées à modifier */ - - extra = GET_REG_OP_EXTRA(operand); - - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - - result = extra->is_written; - - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - - return result; - -} - - /* ---------------------------------------------------------------------------------- */ /* CONTROLE DU VOLUME DES INSTANCES */ @@ -312,6 +264,7 @@ bool g_register_operand_is_written(const GRegisterOperand *operand) /****************************************************************************** * * * Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -321,20 +274,21 @@ bool g_register_operand_is_written(const GRegisterOperand *operand) * * ******************************************************************************/ -static guint g_register_operand_hash(const GRegisterOperand *operand) +static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock) { guint result; /* Valeur à retourner */ + GArchOperandClass *class; /* Classe parente normalisée */ GArchRegister *reg; /* Registre visé par l'opérande*/ + class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + reg = g_register_operand_get_register(operand); - result = g_arch_register_hash(reg); + result ^= g_arch_register_hash(reg); g_object_unref(G_OBJECT(reg)); - if (g_register_operand_is_written(operand)) - result ^= 1; - return result; } diff --git a/src/arch/operands/register.h b/src/arch/operands/register.h index 7f746b6..e2f2c46 100644 --- a/src/arch/operands/register.h +++ b/src/arch/operands/register.h @@ -37,6 +37,14 @@ /* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ +/* Etats particuliers d'un opérande de registre */ +typedef enum _RegOpFlag +{ + ROF_IS_WRITTEN = AOF_USER_FLAG(0), /* Opération d'écriture ? */ + +} RegOpFlag; + + #define G_TYPE_REGISTER_OPERAND g_register_operand_get_type() #define G_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperand)) #define G_IS_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTER_OPERAND)) @@ -58,12 +66,6 @@ GType g_register_operand_get_type(void); /* Fournit le registre associé à l'opérande. */ GArchRegister *g_register_operand_get_register(const GRegisterOperand *); -/* Marque l'opérande comme étant écrit plutôt que consulté. */ -void g_register_operand_mark_as_written(GRegisterOperand *); - -/* Indique le type d'accès réalisé sur l'opérande. */ -bool g_register_operand_is_written(const GRegisterOperand *); - #endif /* _ARCH_OPERANDS_REGISTER_H */ diff --git a/src/arch/operands/target-int.h b/src/arch/operands/target-int.h index f3ed447..ac4cdcd 100644 --- a/src/arch/operands/target-int.h +++ b/src/arch/operands/target-int.h @@ -30,15 +30,22 @@ +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _tarop_extra_data_t +{ + operand_extra_data_t parent; /* A laisser en premier */ + + MemoryDataSize size; /* Taille de l'opérande */ + +} tarop_extra_data_t; + /* Définition d'un opérande ciblant idéalement un symbole connu (instance) */ struct _GTargetOperand { GArchOperand parent; /* Instance parente */ - MemoryDataSize size; /* Taille de l'opérande */ vmpa2t addr; /* Adresse de l'élément visé */ - bool strict; /* Résolution stricte */ /* Référence circulaire */ GBinSymbol *symbol; /* Eventuel symbole associé */ phys_t diff; /* Position dans le symbole */ @@ -54,5 +61,20 @@ struct _GTargetOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_TARGET_OP_EXTRA(op) (tarop_extra_data_t *)&op->extra + +#else + +# define GET_TARGET_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), tarop_extra_data_t) + +#endif + + #endif /* _ARCH_OPERANDS_TARGET_INT_H */ diff --git a/src/arch/operands/target.c b/src/arch/operands/target.c index 5edc805..6450834 100644 --- a/src/arch/operands/target.c +++ b/src/arch/operands/target.c @@ -37,6 +37,7 @@ #include "targetable-int.h" #include "../../analysis/routine.h" #include "../../common/extstr.h" +#include "../../common/sort.h" #include "../../format/format.h" #include "../../format/strsym.h" #include "../../glibext/gbinarycursor.h" @@ -60,7 +61,7 @@ static void g_target_operand_dispose(GTargetOperand *); static void g_target_operand_finalize(GTargetOperand *); /* Compare un opérande avec un autre. */ -static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *); +static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_target_operand_print(const GTargetOperand *, GBufferLine *); @@ -68,6 +69,9 @@ static void g_target_operand_print(const GTargetOperand *, GBufferLine *); /* Construit un petit résumé concis de l'opérande. */ static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_target_operand_hash(const GTargetOperand *, bool); + /* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ @@ -122,6 +126,8 @@ static void g_target_operand_class_init(GTargetOperandClass *klass) operand->print = (operand_print_fc)g_target_operand_print; operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip; + operand->hash = (operand_hash_fc)g_target_operand_hash; + operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize; operand->serialize = (serialize_operand_fc)g_target_operand_serialize; @@ -142,10 +148,10 @@ static void g_target_operand_class_init(GTargetOperandClass *klass) static void g_target_operand_init(GTargetOperand *operand) { - operand->size = MDS_UNDEFINED; + GET_TARGET_OP_EXTRA(operand)->size = MDS_UNDEFINED; + init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); - operand->strict = true; operand->symbol = NULL; operand->diff = 0; @@ -211,8 +217,9 @@ static void g_target_operand_finalize(GTargetOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* 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. * * * @@ -222,56 +229,56 @@ static void g_target_operand_finalize(GTargetOperand *operand) * * ******************************************************************************/ -static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b) +static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b, bool lock) { int result; /* Bilan à retourner */ + tarop_extra_data_t *ea; /* Données insérées à modifier */ + tarop_extra_data_t *eb; /* Données insérées à modifier */ + GArchOperandClass *class; /* Classe parente normalisée */ - result = cmp_vmpa(&a->addr, &b->addr); - if (result != 0) goto gtoc_done; + ea = GET_TARGET_OP_EXTRA(a); + eb = GET_TARGET_OP_EXTRA(b); - if (a->size < b->size) + if (lock) { - result = -1; - goto gtoc_done; - } - else if (a->size > b->size) - { - result = 1; - goto gtoc_done; + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); } - if (a->symbol == NULL && b->symbol != NULL) - { - result = -1; - goto gtoc_done; - } - else if (a->symbol != NULL && b->symbol == NULL) - { - result = 1; - goto gtoc_done; - } - else if (a->symbol != NULL && b->symbol != NULL) + result = sort_unsigned_long(ea->size, eb->size); + + if (result == 0) + result = cmp_vmpa(&a->addr, &b->addr); + + if (result == 0) { - result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol }, - (const GBinSymbol *[]) { b->symbol }); - if (result != 0) goto gtoc_done; + if (a->symbol == NULL && b->symbol != NULL) + result = -1; + + else if (a->symbol != NULL && b->symbol == NULL) + result = 1; + + else if (a->symbol != NULL && b->symbol != NULL) + result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol }, + (const GBinSymbol *[]) { b->symbol }); + } - if (a->diff < b->diff) + if (result == 0) + result = sort_uint64_t(a->diff, b->diff); + + if (result == 0) { - result = -1; - goto gtoc_done; + class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); } - else if (a->diff > b->diff) + + if (lock) { - result = 1; - goto gtoc_done; + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); } - result = 0; - - gtoc_done: - return result; } @@ -296,6 +303,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l vmpa2t tmp; /* Coquille vide pour argument */ VMPA_BUFFER(value); /* Adresse brute à imprimer */ size_t len; /* Taille de l'élément inséré */ + MemoryDataSize size; /* Taille retenue */ label = g_binary_symbol_get_label(operand->symbol); @@ -322,7 +330,9 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l } else { - vmpa2_to_string(&operand->addr, operand->size, value, &len); + size = g_target_operand_get_size(operand); + + vmpa2_to_string(&operand->addr, size, value, &len); g_buffer_line_append_text(line, DLC_ASSEMBLY, value, len, RTT_LABEL, G_OBJECT(operand)); @@ -355,7 +365,8 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr) assert(size != MDS_UNDEFINED); - result->size = size; + GET_TARGET_OP_EXTRA(result)->size = size; + copy_vmpa(&result->addr, addr); return G_ARCH_OPERAND(result); @@ -457,7 +468,18 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand) { - return operand->size; + MemoryDataSize result; /* Taille à retourner */ + tarop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_TARGET_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->size; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; } @@ -485,7 +507,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool const mrange_t *range; /* Couverture du symbole */ #endif - operand->strict = strict; + if (strict) + g_arch_operand_set_flag(G_ARCH_OPERAND(operand), TOF_STRICT); + else + g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), TOF_STRICT); result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff); @@ -569,6 +594,48 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d } +/****************************************************************************** +* * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint g_target_operand_hash(const GTargetOperand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + tarop_extra_data_t *extra; /* Données insérées à modifier */ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_TARGET_OP_EXTRA(operand); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= extra->size; + + result ^= g_direct_hash(operand->symbol); + + result ^= (operand->diff & 0xffffffff); + result ^= (operand->diff >> 32); + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* TRANSPOSITIONS VIA CACHE DES OPERANDES */ @@ -632,6 +699,7 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ + MemoryDataSize size; /* Taille retenue */ GArchOperand *original; /* Opérande d'origine */ /** @@ -639,10 +707,12 @@ static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorag * par la position physique. */ + size = g_target_operand_get_size(operand); + if (has_virt_addr(&operand->addr)) - original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr)); + original = g_imm_operand_new_from_value(size, get_virt_addr(&operand->addr)); else - original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr)); + original = g_imm_operand_new_from_value(size, get_phy_addr(&operand->addr)); result = g_arch_operand_store(original, storage, pbuf); diff --git a/src/arch/operands/target.h b/src/arch/operands/target.h index 8810efa..40db610 100644 --- a/src/arch/operands/target.h +++ b/src/arch/operands/target.h @@ -35,6 +35,14 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _TargetOpFlag +{ + TOF_STRICT = AOF_USER_FLAG(0), /* Résolution stricte */ + +} TargetOpFlag; + + #define G_TYPE_TARGET_OPERAND g_target_operand_get_type() #define G_TARGET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGET_OPERAND, GTargetOperand)) #define G_IS_TARGET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGET_OPERAND)) diff --git a/src/format/format-int.h b/src/format/format-int.h index de29751..11505d0 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -45,18 +45,22 @@ typedef SourceEndian (* format_get_endian_fc) (const GBinFormat *); /* Rythme des allocations pour les entrées de code */ #define EXTRA_POINT_BLOCK 20 -/* Informations glissées dans la structure GObject de GBinFormat */ -typedef union _fmt_obj_extra + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _fmt_extra_data_t { - struct - { - FormatFlag flags; /* Informations complémentaires*/ + FormatFlag flags; /* Informations complémentaires*/ + +} fmt_extra_data_t; - }; +/* Encapsulation avec un verrou d'accès */ +typedef union _fmt_obj_extra_t +{ + fmt_extra_data_t data; /* Données embarquées */ + lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */ - gint lock; /* Gestion d'accès aux fanions */ +} fmt_obj_extra_t; -} fmt_obj_extra; /* Description d'une erreur */ typedef struct _fmt_error @@ -73,6 +77,19 @@ struct _GBinFormat { GKnownFormat parent; /* A laisser en premier */ +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + + /** + * L'inclusion des informations suivantes dépend de l'architecture. + * + * Si la structure GObject possède un trou, on remplit de préférence + * ce dernier. + */ + + fmt_obj_extra_t extra; /* Externalisation embarquée */ + +#endif + virt_t *start_points[DPL_COUNT]; /* Départ de désassemblage */ size_t pt_allocated[DPL_COUNT]; /* Taille d'inscription allouée*/ size_t pt_count[DPL_COUNT]; /* Nombre de points enregistrés*/ @@ -97,53 +114,37 @@ struct _GBinFormat gint error_locked; /* Statut d'accès à la liste */ #endif -#if __SIZEOF_INT__ == __SIZEOF_LONG__ +}; - /** - * L'inclusion des informations suivantes dépend de l'architecture. - * - * Si la structure GObject possède un trou, on remplit de préférence - * ce dernier. - */ +/* Format binaire générique (classe) */ +struct _GBinFormatClass +{ + GKnownFormatClass parent; /* A laisser en premier */ - fmt_obj_extra extra; /* Externalisation embarquée */ + format_get_endian_fc get_endian; /* Boutisme employé */ -#endif + /* Signaux */ + + void (* symbol_added) (GBinFormat *, GBinSymbol *); + void (* symbol_removed) (GBinFormat *, GBinSymbol *); }; + /** * Accès aux informations éventuellement déportées. */ #if __SIZEOF_INT__ == __SIZEOF_LONG__ -# define INIT_BIN_FORMAT_EXTRA(fmt) fmt->extra.lock = 0 - -# define GET_BIN_FORMAT_EXTRA(fmt) &fmt->extra +# define GET_BIN_FORMAT_EXTRA(fmt) (fmt_extra_data_t *)&fmt->extra #else -# define INIT_BIN_FORMAT_EXTRA(fmt) INIT_GOBJECT_EXTRA(G_OBJECT(fmt)) - -# define GET_BIN_FORMAT_EXTRA(fmt) GET_GOBJECT_EXTRA(G_OBJECT(fmt), fmt_obj_extra) +# define GET_BIN_FORMAT_EXTRA(fmt) GET_GOBJECT_EXTRA(G_OBJECT(fmt), fmt_extra_data_t) #endif -/* Format binaire générique (classe) */ -struct _GBinFormatClass -{ - GKnownFormatClass parent; /* A laisser en premier */ - - format_get_endian_fc get_endian; /* Boutisme employé */ - - /* Signaux */ - - void (* symbol_added) (GBinFormat *, GBinSymbol *); - void (* symbol_removed) (GBinFormat *, GBinSymbol *); - -}; - /* ------------------------------ DECODAGE DE SYMBOLES ------------------------------ */ diff --git a/src/format/format.c b/src/format/format.c index 045bc92..f8fe13a 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -123,7 +123,11 @@ static void g_binary_format_class_init(GBinFormatClass *klass) static void g_binary_format_init(GBinFormat *format) { - INIT_BIN_FORMAT_EXTRA(format); + fmt_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_BIN_FORMAT_EXTRA(format); + + INIT_GOBJECT_EXTRA_LOCK(extra); g_rw_lock_init(&format->pt_lock); @@ -235,17 +239,17 @@ static void g_binary_format_finalize(GBinFormat *format) bool g_binary_format_set_flag(GBinFormat *format, FormatFlag flag) { bool result; /* Bilan à retourner */ - fmt_obj_extra *extra; /* Données insérées à modifier */ + fmt_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_FORMAT_EXTRA(format); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = !(extra->flags & flag); extra->flags |= flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -268,17 +272,17 @@ bool g_binary_format_set_flag(GBinFormat *format, FormatFlag flag) bool g_binary_format_unset_flag(GBinFormat *format, FormatFlag flag) { bool result; /* Bilan à retourner */ - fmt_obj_extra *extra; /* Données insérées à modifier */ + fmt_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_FORMAT_EXTRA(format); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & flag); extra->flags &= ~flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -301,15 +305,15 @@ bool g_binary_format_unset_flag(GBinFormat *format, FormatFlag flag) bool g_binary_format_has_flag(const GBinFormat *format, FormatFlag flag) { bool result; /* Bilan à retourner */ - fmt_obj_extra *extra; /* Données insérées à modifier */ + fmt_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_FORMAT_EXTRA(format); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & flag); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -331,15 +335,15 @@ bool g_binary_format_has_flag(const GBinFormat *format, FormatFlag flag) FormatFlag g_binary_format_get_flags(const GBinFormat *format) { FormatFlag result; /* Fanions à retourner */ - fmt_obj_extra *extra; /* Données insérées à modifier */ + fmt_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_FORMAT_EXTRA(format); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & FFL_MASK); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; diff --git a/src/format/symbol-int.h b/src/format/symbol-int.h index 99cee88..7f5807c 100644 --- a/src/format/symbol-int.h +++ b/src/format/symbol-int.h @@ -35,32 +35,31 @@ typedef char * (* get_symbol_label_fc) (const GBinSymbol *); /* Informations glissées dans la structure GObject de GBinSymbol */ -typedef union _sym_obj_extra +typedef struct _sym_extra_data_t { - struct - { - SymbolType stype; /* Type du symbole */ - SymbolStatus status; /* Visibilité du symbole */ + SymbolType stype; /* Type du symbole */ + SymbolStatus status; /* Visibilité du symbole */ - char nm_prefix; /* Eventuel préfixe "nm" */ + char nm_prefix; /* Eventuel préfixe "nm" */ - SymbolFlag flags; /* Informations complémentaires*/ + SymbolFlag flags; /* Informations complémentaires*/ - }; +} sym_extra_data_t; - gint lock; /* Gestion d'accès aux fanions */ +/* Encapsulation avec un verrou d'accès */ +typedef union _symbol_obj_extra_t +{ + sym_extra_data_t data; /* Données embarquées */ + lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */ + +} symbol_obj_extra_t; -} sym_obj_extra; /* Symbole d'exécutable (instance) */ struct _GBinSymbol { GObject parent; /* A laisser en premier */ - mrange_t range; /* Couverture mémoire */ - - char *alt; /* Nom alternatif */ - #if __SIZEOF_INT__ == __SIZEOF_LONG__ /** @@ -70,39 +69,40 @@ struct _GBinSymbol * ce dernier. */ - sym_obj_extra extra; /* Externalisation embarquée */ + symbol_obj_extra_t extra; /* Externalisation embarquée */ #endif + mrange_t range; /* Couverture mémoire */ + + char *alt; /* Nom alternatif */ + }; +/* Symbole d'exécutable (classe) */ +struct _GBinSymbolClass +{ + GObjectClass parent; /* A laisser en premier */ + + get_symbol_label_fc get_label; /* Obtention d'une étiquette */ + +}; + + /** * Accès aux informations éventuellement déportées. */ #if __SIZEOF_INT__ == __SIZEOF_LONG__ -# define INIT_BIN_SYMBOL_EXTRA(sym) sym->extra.lock = 0 - -# define GET_BIN_SYMBOL_EXTRA(sym) &sym->extra +# define GET_BIN_SYMBOL_EXTRA(sym) (sym_extra_data_t *)&sym->extra #else -# define INIT_BIN_SYMBOL_EXTRA(sym) INIT_GOBJECT_EXTRA(G_OBJECT(sym)) - -# define GET_BIN_SYMBOL_EXTRA(sym) GET_GOBJECT_EXTRA(G_OBJECT(sym), sym_obj_extra) +# define GET_BIN_SYMBOL_EXTRA(sym) GET_GOBJECT_EXTRA(G_OBJECT(sym), sym_extra_data_t) #endif -/* Symbole d'exécutable (classe) */ -struct _GBinSymbolClass -{ - GObjectClass parent; /* A laisser en premier */ - - get_symbol_label_fc get_label; /* Obtention d'une étiquette */ - -}; - #endif /* _FORMAT_SYMBOL_INT_H */ diff --git a/src/format/symbol.c b/src/format/symbol.c index eb61db8..d3d5285 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -124,7 +124,11 @@ static void g_binary_symbol_class_init(GBinSymbolClass *klass) static void g_binary_symbol_init(GBinSymbol *symbol) { - INIT_BIN_SYMBOL_EXTRA(symbol); + sym_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_BIN_SYMBOL_EXTRA(symbol); + + INIT_GOBJECT_EXTRA_LOCK(extra); g_binary_symbol_set_stype(symbol, STP_COUNT); @@ -331,15 +335,15 @@ const mrange_t *g_binary_symbol_get_range(const GBinSymbol *symbol) void g_binary_symbol_set_stype(GBinSymbol *symbol, SymbolType type) { - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->stype = type; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -359,15 +363,15 @@ void g_binary_symbol_set_stype(GBinSymbol *symbol, SymbolType type) SymbolType g_binary_symbol_get_stype(const GBinSymbol *symbol) { SymbolType result; /* Type à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->stype; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -389,15 +393,15 @@ SymbolType g_binary_symbol_get_stype(const GBinSymbol *symbol) void g_binary_symbol_set_status(GBinSymbol *symbol, SymbolStatus status) { - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->status = status; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } @@ -417,15 +421,15 @@ void g_binary_symbol_set_status(GBinSymbol *symbol, SymbolStatus status) SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol) { SymbolStatus result; /* Visibilité à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->status; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -448,17 +452,17 @@ SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol) bool g_binary_symbol_set_flag(GBinSymbol *symbol, SymbolFlag flag) { bool result; /* Bilan à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = !(extra->flags & flag); extra->flags |= flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -481,17 +485,17 @@ bool g_binary_symbol_set_flag(GBinSymbol *symbol, SymbolFlag flag) bool g_binary_symbol_unset_flag(GBinSymbol *symbol, SymbolFlag flag) { bool result; /* Bilan à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & flag); extra->flags &= ~flag; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -514,15 +518,15 @@ bool g_binary_symbol_unset_flag(GBinSymbol *symbol, SymbolFlag flag) bool g_binary_symbol_has_flag(const GBinSymbol *symbol, SymbolFlag flag) { bool result; /* Bilan à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & flag); - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -544,15 +548,15 @@ bool g_binary_symbol_has_flag(const GBinSymbol *symbol, SymbolFlag flag) SymbolFlag g_binary_symbol_get_flags(const GBinSymbol *symbol) { SymbolFlag result; /* Fanions à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = extra->flags; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -575,18 +579,18 @@ SymbolFlag g_binary_symbol_get_flags(const GBinSymbol *symbol) bool g_binary_symbol_get_nm_prefix(const GBinSymbol *symbol, char *prefix) { bool result; /* Validité à retourner */ - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); result = (extra->flags & SFL_HAS_NM_PREFIX); if (result) *prefix = extra->nm_prefix; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -607,16 +611,16 @@ bool g_binary_symbol_get_nm_prefix(const GBinSymbol *symbol, char *prefix) void g_binary_symbol_set_nm_prefix(const GBinSymbol *symbol, char prefix) { - sym_obj_extra *extra; /* Données insérées à modifier */ + sym_extra_data_t *extra; /* Données insérées à modifier */ extra = GET_BIN_SYMBOL_EXTRA(symbol); - g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + LOCK_GOBJECT_EXTRA(extra); extra->nm_prefix = prefix; extra->flags |= SFL_HAS_NM_PREFIX; - g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + UNLOCK_GOBJECT_EXTRA(extra); } diff --git a/src/glibext/objhole.h b/src/glibext/objhole.h index cf9fc28..c256cfb 100644 --- a/src/glibext/objhole.h +++ b/src/glibext/objhole.h @@ -25,6 +25,7 @@ #define _GLIBEXT_OBJHOLE_H +#include #include @@ -46,17 +47,6 @@ */ -#define INIT_GOBJECT_EXTRA(obj) \ - do \ - { \ - guint *___space; \ - ___space = (((guint *)&obj->ref_count) + 1); \ - BUILD_BUG_ON((___space + 1) == (guint *)&obj->qdata); \ - *___space = 0; \ - } \ - while (0) - - #define GET_GOBJECT_EXTRA(obj, tp) \ ({ \ BUILD_BUG_ON(sizeof(tp) > sizeof(guint)); \ @@ -67,7 +57,6 @@ }) - /** * Choix du bit de verrou pour le champ "lock". * @@ -90,5 +79,41 @@ #endif +/* Verrou d'accès pour une encapsulation */ +typedef struct _lockable_obj_extra_t +{ + gint lock; /* Gestion d'accès aux fanions */ + +} lockable_obj_extra_t; + + +#define INIT_GOBJECT_EXTRA_LOCK(xtr) \ + do \ + { \ + lockable_obj_extra_t *__lockable; \ + __lockable = (lockable_obj_extra_t *)xtr; \ + __lockable->lock = 0; \ + } \ + while (0) + +#define LOCK_GOBJECT_EXTRA(xtr) \ + do \ + { \ + lockable_obj_extra_t *__lockable; \ + __lockable = (lockable_obj_extra_t *)xtr; \ + g_bit_lock(&__lockable->lock, HOLE_LOCK_BIT); \ + } \ + while (0) + +#define UNLOCK_GOBJECT_EXTRA(xtr) \ + do \ + { \ + lockable_obj_extra_t *__lockable; \ + __lockable = (lockable_obj_extra_t *)xtr; \ + g_bit_unlock(&__lockable->lock, HOLE_LOCK_BIT); \ + } \ + while (0) + + #endif /* _GLIBEXT_OBJHOLE_H */ -- cgit v0.11.2-87-g4458