From 0f0cb560006c0ef5eb690f89c4ce720936c9d6f6 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 28 Oct 2016 21:40:19 +0200 Subject: Stored instruction hooks in the data section rather than in the heap. --- ChangeLog | 10 ++++++ src/arch/instruction-int.h | 2 +- src/arch/instruction.c | 8 ++--- src/arch/instruction.h | 2 +- tools/d2c/hooks/manager.c | 90 +++++++++++++++++++++++++++++++++++++++++----- tools/d2c/hooks/manager.h | 3 ++ tools/d2c/spec.c | 4 +++ 7 files changed, 103 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52e0a39..169362f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +16-10-28 Cyrille Bagard + + * src/arch/instruction-int.h: + * src/arch/instruction.c: + * src/arch/instruction.h: + * tools/d2c/hooks/manager.c: + * tools/d2c/hooks/manager.h: + * tools/d2c/spec.c: + Store instruction hooks in the data section rather than in the heap. + 16-10-26 Cyrille Bagard * src/analysis/disass/loop.c: diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index dca63e7..8eb6b68 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -63,7 +63,7 @@ struct _GArchInstruction phys_t max_displayed_len; /* Quantité de code affichée */ ArchInstrFlag flags; /* Informations complémentaires*/ - instr_hook_fc hooks[IPH_COUNT]; /* Traitements complémentaires */ + const instr_hook_fc *hooks; /* Traitements complémentaires */ mrange_t range; /* Emplacement en mémoire */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 8264f5b..4c0fdb9 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -281,11 +281,9 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr) * * ******************************************************************************/ -void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type, instr_hook_fc hook) +void g_arch_instruction_set_hooks(GArchInstruction *instr, const instr_hook_fc hooks[IPH_COUNT]) { - assert(type < IPH_COUNT); - - instr->hooks[type] = hook; + instr->hooks = hooks; } @@ -310,7 +308,7 @@ void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type { assert(type < IPH_COUNT); - if (instr->hooks[type] != NULL) + if (instr->hooks != NULL && instr->hooks[type] != NULL) instr->hooks[type](instr, proc, context, format); } diff --git a/src/arch/instruction.h b/src/arch/instruction.h index e902849..93dfa52 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -117,7 +117,7 @@ typedef enum _InstrProcessHook typedef void (* instr_hook_fc) (GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); /* Définit un traitement complémentare au désassemblage. */ -void g_arch_instruction_set_hook(GArchInstruction *, InstrProcessHook, instr_hook_fc); +void g_arch_instruction_set_hooks(GArchInstruction *, const instr_hook_fc [IPH_COUNT]); /* Complète un désassemblage accompli pour une instruction. */ void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GBinFormat *); diff --git a/tools/d2c/hooks/manager.c b/tools/d2c/hooks/manager.c index 67c09f8..2db4bbc 100644 --- a/tools/d2c/hooks/manager.c +++ b/tools/d2c/hooks/manager.c @@ -137,7 +137,7 @@ void register_hook_function(instr_hooks *hooks, char *type, char *name) * top = indique si l'écriture se réalise au plus haut niveau.* * fd = descripteur d'un flux ouvert en écriture. * * * -* Description : Associe dans le code des fonctions à une instruction. * +* Description : Déclare des opérations complémentaires pour une instruction. * * * * Retour : Bilan de l'opération. * * * @@ -145,29 +145,101 @@ void register_hook_function(instr_hooks *hooks, char *type, char *name) * * ******************************************************************************/ -bool write_hook_functions(const instr_hooks *hooks, bool top, int fd) +bool declare_hook_functions(const instr_hooks *hooks, bool top, int fd) { bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - instr_func *func; /* Nouvelle prise en compte */ + size_t i; /* Boucle de parcours #1 */ + const instr_func *func; /* Nouvelle prise en compte */ + + static const char *hook_types[] = { + "FETCH", + "LINK", + "POST" + }; + + const instr_func *find_hook_by_name(const instr_hooks *list, const char *type) + { + const instr_func *hook; /* Trouvaille à retourner */ + size_t k; /* Boucle de parcours #2 */ + + hook = NULL; + + for (k = 0; k < list->func_count && hook == NULL; k++) + if (strcmp(list->funcs[k].type, type) == 0) + hook = &list->funcs[k]; + + return hook; + + } result = true; - for (i = 0; i < hooks->func_count && result; i++) + if (hooks->func_count > 0) { - func = &hooks->funcs[i]; + if (!top) + dprintf(fd, "\t"); + + dprintf(fd, "\tstatic const instr_hook_fc hooks[IPH_COUNT] = {\n\n"); + + for (i = 0; i < (sizeof(hook_types) / sizeof(hook_types[0])); i++) + { + func = find_hook_by_name(hooks, hook_types[i]); + + if (!top) + dprintf(fd, "\t"); + + dprintf(fd, "\t\t[IPH_%s] = (instr_hook_fc)%s,\n", hook_types[i], func != NULL ? func->name : "NULL"); + + } + + dprintf(fd, "\n"); if (!top) dprintf(fd, "\t"); - dprintf(fd, "\tg_arch_instruction_set_hook(%s, IPH_%s, (instr_hook_fc)%s);\n", - top ? "result" : "instr", func->type, func->name); + dprintf(fd, "\t};\n"); + + dprintf(fd, "\n"); } - if (hooks->func_count > 0 && result) + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : hooks = gestionnaire d'un ensemble de fonctions associées. * +* top = indique si l'écriture se réalise au plus haut niveau.* +* fd = descripteur d'un flux ouvert en écriture. * +* * +* Description : Associe dans le code des fonctions à une instruction. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_hook_functions(const instr_hooks *hooks, bool top, int fd) +{ + bool result; /* Bilan à retourner */ + + result = true; + + if (hooks->func_count > 0) + { + if (!top) + dprintf(fd, "\t"); + + dprintf(fd, "\tg_arch_instruction_set_hooks(%s, hooks);\n", + top ? "result" : "instr"); + dprintf(fd, "\n"); + } + return result; } diff --git a/tools/d2c/hooks/manager.h b/tools/d2c/hooks/manager.h index 97bd388..1a50d0a 100644 --- a/tools/d2c/hooks/manager.h +++ b/tools/d2c/hooks/manager.h @@ -43,6 +43,9 @@ void delete_instr_hooks(instr_hooks *); /* Enregistre l'utilité d'une fonction pour une instruction. */ void register_hook_function(instr_hooks *, char *, char *); +/* Déclare des opérations complémentaires pour une instruction. */ +bool declare_hook_functions(const instr_hooks *, bool, int); + /* Associe dans le code des fonctions à une instruction. */ bool write_hook_functions(const instr_hooks *, bool, int); diff --git a/tools/d2c/spec.c b/tools/d2c/spec.c index 1d91fed..5aa7066 100644 --- a/tools/d2c/spec.c +++ b/tools/d2c/spec.c @@ -332,6 +332,8 @@ bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *a dprintf(fd, "\n"); + result &= declare_hook_functions(spec->hooks, false, fd); + /* Vérification que le décodage est possible */ result &= check_bits_correctness(spec->bits, fd); @@ -457,6 +459,8 @@ bool write_encoding_spec_format_disass(const encoding_spec *spec, int fd, const dprintf(fd, "\n"); + result &= declare_hook_functions(spec->hooks, true, fd); + /* Création de l'instruction en elle-même */ new_ins = get_new_keyword_from_syntax_items(spec->syntax); -- cgit v0.11.2-87-g4458