summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--src/arch/instruction-int.h2
-rw-r--r--src/arch/instruction.c8
-rw-r--r--src/arch/instruction.h2
-rw-r--r--tools/d2c/hooks/manager.c90
-rw-r--r--tools/d2c/hooks/manager.h3
-rw-r--r--tools/d2c/spec.c4
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 <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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);