From 8ef66a1e0225c9e00175fbaf3f3038f537de511f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 10 Jan 2015 16:37:34 +0000
Subject: Extended the grammar to allow hooks inclusion.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@453 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                          |  34 ++++++++
 src/arch/arm/context.c             |  79 -----------------
 src/arch/arm/v7/link.c             |  28 ++----
 src/arch/arm/v7/link.h             |  27 +++++-
 src/arch/arm/v7/opdefs/Makefile.am |   2 +-
 src/arch/arm/v7/opdefs/bl_A8825.d  |  28 ++++++
 src/arch/arm/v7/processor.c        |  44 +---------
 tools/d2c/Makefile.am              |   1 +
 tools/d2c/d2c_gram.y               |  27 ++++--
 tools/d2c/d2c_tok.l                |  13 +++
 tools/d2c/hooks.c                  | 169 +++++++++++++++++++++++++++++++++++++
 tools/d2c/hooks.h                  |  51 +++++++++++
 tools/d2c/spec.c                   |  47 ++++++-----
 tools/d2c/spec.h                   |   4 +
 14 files changed, 378 insertions(+), 176 deletions(-)
 create mode 100644 tools/d2c/hooks.c
 create mode 100644 tools/d2c/hooks.h

diff --git a/ChangeLog b/ChangeLog
index 4c93b08..a1a901b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+15-01-10  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/arm/context.c:
+	Delete some debug code.
+
+	* src/arch/arm/v7/link.c:
+	* src/arch/arm/v7/link.h:
+	Clean and improve the track of instruction set when branching.
+
+	* src/arch/arm/v7/opdefs/bl_A8825.d:
+	Add the first hooks in the bl[x] definitions.
+
+	* src/arch/arm/v7/opdefs/Makefile.am:
+	Add the two 'link.h' and 'post.h' files to included headers.
+
+	* src/arch/arm/v7/processor.c:
+	Remove the manual hooks of some kind of instructions.
+
+	* tools/d2c/d2c_gram.y:
+	* tools/d2c/d2c_tok.l:
+	Clean and update the code for hooks.
+
+	* tools/d2c/hooks.c:
+	* tools/d2c/hooks.h:
+	New entries: extend the grammar to allow hooks inclusion.
+
+	* tools/d2c/Makefile.am:
+	Add the 'hooks.[ch]' files to d2c_SOURCES.
+
+	* tools/d2c/spec.c:
+	* tools/d2c/spec.h:
+	Clean and update the code for hooks.
+
+
 15-01-09  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/arm/context.c:
diff --git a/src/arch/arm/context.c b/src/arch/arm/context.c
index 24546c0..386f21a 100644
--- a/src/arch/arm/context.c
+++ b/src/arch/arm/context.c
@@ -224,8 +224,6 @@ static size_t find_disass_arm_area(disass_arm_area *areas, virt_t addr, size_t f
     size_t index;                           /* Indice de cellule idéale    */
     size_t mid;                             /* Division de l'espace        */
 
-    printf(" < 0x%08x > %zu / %zu...\n", addr, first, last);
-
     if (first == last)
         index = first;
 
@@ -233,8 +231,6 @@ static size_t find_disass_arm_area(disass_arm_area *areas, virt_t addr, size_t f
     {
         mid = first + (last - first + 1) / 2;
 
-        printf(" --looking-- %zu / %zu -> %zu\n", first, last, mid);
-
         if (areas[mid].start <= addr)
             index = find_disass_arm_area(areas, addr, mid, last);
         else
@@ -242,11 +238,6 @@ static size_t find_disass_arm_area(disass_arm_area *areas, virt_t addr, size_t f
 
     }
 
-    printf(" !! FOUND !! (for 0x%08x) --  [%zu] [%zu/%zu] 0x%08x <-> 0x%08x\n",
-           (unsigned int)addr, index, first, last,
-           (unsigned int)areas[index].start,
-           (unsigned int)areas[index].end);
-
     assert(areas[index].start <= addr && addr < areas[index].end);
 
     return index;
@@ -283,32 +274,6 @@ void _g_arm_context_define_encoding(GArmContext *ctx, virt_t addr, unsigned int
     /* Sinon on redivise... */
     else
     {
-
-
-
-
-
-    do
-    {
-        unsigned int i;
-
-        printf(" --sel-- %u for 0x%08x\n", (unsigned int)selected, (unsigned int)addr);
-
-        for (i = 0; i < ctx->acount; i++)
-            printf(" --def before-- [%u] 0x%08x <-> 0x%08x\n",
-                   i,
-                   (unsigned int)ctx->areas[i].start,
-                   (unsigned int)ctx->areas[i].end);
-
-    }
-    while (0);
-
-
-
-
-
-
-
         ctx->areas = (disass_arm_area *)realloc(ctx->areas, ++ctx->acount * sizeof(disass_arm_area));
 
         memmove(&ctx->areas[selected + 1], &ctx->areas[selected],
@@ -321,51 +286,7 @@ void _g_arm_context_define_encoding(GArmContext *ctx, virt_t addr, unsigned int
         ctx->areas[selected + 1].start = addr;
         ctx->areas[selected + 1].marker = marker;
 
-
-
-    do
-    {
-        unsigned int i;
-
-        for (i = 0; i < ctx->acount; i++)
-            printf(" --def after-- [%u] 0x%08x <-> 0x%08x\n",
-                   i,
-                   (unsigned int)ctx->areas[i].start,
-                   (unsigned int)ctx->areas[i].end);
-
-    }
-    while (0);
-
-
-
-
-
-
-    }
-
-
-
-
-    /*
-    do
-    {
-        unsigned int i;
-
-        printf(" --sel-- %u for 0x%08x\n", (unsigned int)selected, (unsigned int)addr);
-
-        for (i = 0; i < ctx->acount; i++)
-            printf(" --def-- [%u] 0x%08x <-> 0x%08x\n",
-                   i,
-                   (unsigned int)ctx->areas[i].start,
-                   (unsigned int)ctx->areas[i].end);
-
     }
-    while (0);
-    */
-
-
-
-
 
 }
 
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
index 69b43bc..fff0944 100644
--- a/src/arch/arm/v7/link.c
+++ b/src/arch/arm/v7/link.c
@@ -27,15 +27,13 @@
 #include <assert.h>
 
 
-#include "context.h"
-
-
 
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à faire suivre. *
 *                                                                             *
 *  Description : Complète un désassemblage accompli pour une instruction.     *
 *                                                                             *
@@ -45,14 +43,13 @@
 *                                                                             *
 ******************************************************************************/
 
-void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format)
+void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
     GArchOperand *op;                       /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
     virt_t target;                          /* Adresse virtuelle visée     */
-    ArmV7InstrSet iset;                     /* Type de jeu courant         */
 
     range = g_arch_instruction_get_range(instr);
 
@@ -72,11 +69,7 @@ void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GArmV7Conte
     if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
         g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
 
-
-    //printf("[@ 0x%08x] Add 0x%08x to %p\n", (uint32_t)get_virt_addr(get_mrange_addr(range)), (uint32_t)(pc + offset), context);
-
     target = pc + offset;
-    iset = g_armv7_context_find_encoding(context, get_virt_addr(get_mrange_addr(range)));
 
     g_armv7_context_define_encoding(context, target, iset);
 
@@ -88,6 +81,7 @@ void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GArmV7Conte
 *  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à inverser.     *
 *                                                                             *
 *  Description : Complète un désassemblage accompli pour une instruction.     *
 *                                                                             *
@@ -97,14 +91,13 @@ void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GArmV7Conte
 *                                                                             *
 ******************************************************************************/
 
-void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format)
+void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
     GArchOperand *op;                       /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
     virt_t target;                          /* Adresse virtuelle visée     */
-    ArmV7InstrSet iset;                     /* Type de jeu courant         */
 
     range = g_arch_instruction_get_range(instr);
 
@@ -125,19 +118,8 @@ void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GArmV7Cont
     if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
         g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
 
-
-    //printf("[@ 0x%08x] Add 0x%08x to %p\n", (uint32_t)get_virt_addr(get_mrange_addr(range)), (uint32_t)(pc + offset), context);
-
     target = pc + offset;
-    iset = g_armv7_context_find_encoding(context, get_virt_addr(get_mrange_addr(range)));
-
-    printf(" --link-- @ 0x%08x iset = %u\n", (unsigned int)target, (unsigned int)iset);
-
-    if (iset == AV7IS_ARM)
-        g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    else
-        g_armv7_context_define_encoding(context, target, AV7IS_ARM);
-
 
+    g_armv7_context_define_encoding(context, target, iset);
 
 }
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
index fa38f74..ef71bd6 100644
--- a/src/arch/arm/v7/link.h
+++ b/src/arch/arm/v7/link.h
@@ -32,10 +32,33 @@
 
 
 /* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_thumb_instruction_bl(GArchInstruction *, GArmV7Context *, GBinFormat *);
+void handle_links_with_instruction_bl_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void handle_links_with_instruction_bl_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void handle_links_with_instruction_bl_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_THUMB);
+}
+
 
 /* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_thumb_instruction_blx(GArchInstruction *, GArmV7Context *, GBinFormat *);
+void handle_links_with_instruction_blx_with_dest(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void handle_links_with_instruction_blx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_THUMB);
+}
+
+static inline void handle_links_with_instruction_blx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_ARM);
+}
 
 
 
diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am
index 2687a92..10deadb 100644
--- a/src/arch/arm/v7/opdefs/Makefile.am
+++ b/src/arch/arm/v7/opdefs/Makefile.am
@@ -92,7 +92,7 @@ generate_final_makefile:
 fix_includes_in_c_templates:
 	@for f in `find .gen/ -name '*tmpl.c'`; do			\
 		if grep -q '##INCLUDES##' $$f; then				\
-			$(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/instruction.h"\n#include "..\/..\/instruction.h"\n#include "..\/helpers.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f;	\
+			$(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/link.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f;	\
 		fi;												\
 	done
 
diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d
index dc9c922..96c782f 100644
--- a/src/arch/arm/v7/opdefs/bl_A8825.d
+++ b/src/arch/arm/v7/opdefs/bl_A8825.d
@@ -37,6 +37,13 @@
 
     }
 
+    @hooks {
+
+        link = handle_links_with_instruction_bl_from_thumb
+        post = post_process_branch_instructions
+
+    }
+
 }
 
 @encoding(T2) {
@@ -53,6 +60,13 @@
 
     }
 
+    @hooks {
+
+        link = handle_links_with_instruction_blx_from_thumb
+        post = post_process_branch_instructions
+
+    }
+
 }
 
 @encoding(A1) {
@@ -67,6 +81,13 @@
 
     }
 
+    @hooks {
+
+        link = handle_links_with_instruction_bl_from_arm
+        post = post_process_branch_instructions
+
+    }
+
 }
 
 @encoding(A2) {
@@ -81,4 +102,11 @@
 
     }
 
+    @hooks {
+
+        link = handle_links_with_instruction_blx_from_arm
+        post = post_process_branch_instructions
+
+    }
+
 }
diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c
index 45b53ae..d83c36d 100644
--- a/src/arch/arm/v7/processor.c
+++ b/src/arch/arm/v7/processor.c
@@ -240,31 +240,14 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
     phys_t diff;                            /* Avancée dans la lecture     */
     uint16_t raw16;                         /* Donnée 16 bits à analyser   */
     uint32_t raw32;                         /* Donnée 32 bits à analyser   */
-
-
-
-
-
-
-
-    ArmV7InstrSet iset;
-
-
+    ArmV7InstrSet iset;                     /* Type de jeu d'instructions  */
 
     iset = g_armv7_context_find_encoding(ctx, get_virt_addr(pos));
 
-
-
-    printf(" --decoding-- 0x%08x -> %u\n",
-           (unsigned int)get_virt_addr(pos),
-           (unsigned int)iset);
-
-
     start = get_phy_addr(pos);
 
     diff = 4;
 
-
     switch (iset)
     {
         case AV7IS_ARM:
@@ -319,31 +302,6 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
         result = g_raw_instruction_new_array(data, MDS_32_BITS, 1, pos, end,
                                              G_ARCH_PROCESSOR(proc)->endianness);
 
-
-
-
-
-    if (strcmp(g_arch_instruction_get_keyword(result, 0), "bl") == 0/* && pc == 0x000085b2*/)
-    {
-
-
-        g_arch_instruction_set_hook(result, IPH_LINK, (instr_hook_fc)handle_links_with_thumb_instruction_bl);
-        g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
-
-
-
-    }
-
-    if (strcmp(g_arch_instruction_get_keyword(result, 0), "blx") == 0/* && pc == 0x000085b2*/)
-    {
-
-        g_arch_instruction_set_hook(result, IPH_LINK, (instr_hook_fc)handle_links_with_thumb_instruction_blx);
-        g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
-
-
-    }
-
-
     return result;
 
 }
diff --git a/tools/d2c/Makefile.am b/tools/d2c/Makefile.am
index d0fdbe8..e997beb 100644
--- a/tools/d2c/Makefile.am
+++ b/tools/d2c/Makefile.am
@@ -13,6 +13,7 @@ d2c_SOURCES =							\
 	d2c_tok.l							\
 	d2c_gram.y							\
 	helpers.h helpers.c					\
+	hooks.h hooks.c						\
 	pproc.h pproc.c						\
 	rules.h rules.c						\
 	spec.h spec.c						\
diff --git a/tools/d2c/d2c_gram.y b/tools/d2c/d2c_gram.y
index b1519a1..12eff11 100644
--- a/tools/d2c/d2c_gram.y
+++ b/tools/d2c/d2c_gram.y
@@ -41,8 +41,6 @@ struct action_tmp
 };
 
 
-
-
 #define register_named_field_in_coder(c, n, l)              \
     ({                                                      \
         encoding_spec *__spec;                              \
@@ -88,6 +86,15 @@ struct action_tmp
         register_conversion(__list, f);                     \
     })
 
+#define register_hook_in_coder(c, t, f)                     \
+    ({                                                      \
+        encoding_spec *__spec;                              \
+        instr_hooks *__hooks;;                              \
+        __spec = get_current_encoding_spec(c);              \
+        __hooks = get_hooks_in_encoding_spec(__spec);       \
+        register_hook_function(__hooks, t, f);              \
+    })
+
 #define add_conditional_rule_to_coder(c, e, a, d)           \
     ({                                                      \
         encoding_spec *__spec;                              \
@@ -97,11 +104,6 @@ struct action_tmp
         register_conditional_rule(__rules, e, a, d);        \
     })
 
-
-
-
-
-
 }
 
 %union {
@@ -142,6 +144,8 @@ struct action_tmp
 
 %token CONV EQ OP COMMA CP NOT EOR COLON
 
+%token HOOKS
+
 %token RULES IF EXPR_START EQUAL BINVAL IMMVAL EXPR_END AND THEN SEE UNPREDICTABLE
 
 
@@ -190,6 +194,7 @@ content : /* empty */
         | bitfield content
         | syntax content
         | conversions content
+        | hooks content
         | rules content
 
 
@@ -250,6 +255,14 @@ conv_arg_field : NAME   { $$ = $1; printf(" composed::name '%s'\n", $1); }
                | BINVAL { $$ = $1; printf(" composed::bin '%s'\n", $1); }
 
 
+hooks : HOOKS hookings
+
+hookings : /* empty */
+         | hookings hooking
+
+hooking : NAME EQ NAME { register_hook_in_coder(coder, $1, $3); }
+
+
 rules : RULES rules_list
 
 rules_list : /* empty */
diff --git a/tools/d2c/d2c_tok.l b/tools/d2c/d2c_tok.l
index 71f1a15..8f54c8d 100644
--- a/tools/d2c/d2c_tok.l
+++ b/tools/d2c/d2c_tok.l
@@ -33,6 +33,8 @@ void free_flex_memory(void) ;
 
 %x conv_begin conv_content conv_arg conv_arg_binval
 
+%x hooks_begin hooks_content
+
 %x rules_begin rules_content rules_cond rules_cond_binval rules_action rules_action_see
 
 
@@ -145,6 +147,17 @@ void free_flex_memory(void) ;
 
 
 
+<encoding_content>"@hooks"          { BEGIN(hooks_begin); return HOOKS; }
+<hooks_begin>[ ]+                   { }
+<hooks_begin>"{"                    { BEGIN(hooks_content); }
+<hooks_content>"}"                  { BEGIN(encoding_content); }
+
+<hooks_content>[ \t\n]+             { }
+<hooks_content>[a-z_][a-z0-9_]*     { d2c_lval.string = strdup(yytext); return NAME; }
+<hooks_content>"="                  { return EQ; }
+
+
+
 <encoding_content>"@rules"          { BEGIN(rules_begin); return RULES; }
 <rules_content>\/\/[^\n]+           { printf("SKIP '%s'\n", yytext); }
 <rules_begin>[ ]+                   { }
diff --git a/tools/d2c/hooks.c b/tools/d2c/hooks.c
new file mode 100644
index 0000000..a110664
--- /dev/null
+++ b/tools/d2c/hooks.c
@@ -0,0 +1,169 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * syntax.c - prise en compte d'une syntaxe du langage d'assemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "hooks.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "helpers.h"
+
+
+
+/* Paramèter d'une fonction de renvoi */
+typedef struct _instr_func
+{
+    char *type;                             /* Type de fonction définie    */
+    char *name;                             /* Désignation humaine         */
+
+} instr_func;
+
+/* Liste des fonctions de renvoi pour une instruction */
+struct _instr_hooks
+{
+    instr_func *funcs;                      /* Liste de fonctions présentes*/
+    size_t func_count;                      /* Taille de cette liste       */
+
+};
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une liste de fonctions à lier à une instruction.        *
+*                                                                             *
+*  Retour      : Nouvelle structure prête à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+instr_hooks *create_instr_hooks(void)
+{
+    instr_hooks *result;                    /* Définition vierge à renvoyer*/
+
+    result = (instr_hooks *)calloc(1, sizeof(instr_hooks));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
+*                                                                             *
+*  Description : Supprime de la mémoire une liste de fonctions liées.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_instr_hooks(instr_hooks *hooks)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < hooks->func_count; i++)
+    {
+        free(hooks->funcs[i].type);
+        free(hooks->funcs[i].name);
+    }
+
+    if (hooks->funcs != NULL)
+        free(hooks->funcs);
+
+    free(hooks);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
+*                type  = type de fonction à enregistrer pour une instruction. *
+*                name  = désignation de la fonction à associer.               *
+*                                                                             *
+*  Description : Enregistre l'utilité d'une fonction pour une instruction.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_hook_function(instr_hooks *hooks, char *type, char *name)
+{
+    instr_func *func;                       /* Nouvelle prise en compte    */
+
+    hooks->funcs = (instr_func *)realloc(hooks->funcs, ++hooks->func_count * sizeof(instr_func));
+
+    func = &hooks->funcs[hooks->func_count - 1];
+
+    func->type = make_string_upper(type);
+    func->name = strdup(name);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
+*                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, int fd)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    instr_func *func;                       /* Nouvelle prise en compte    */
+
+    result = true;
+
+    for (i = 0; i < hooks->func_count && result; i++)
+    {
+        func = &hooks->funcs[i];
+
+        dprintf(fd, "\t\tg_arch_instruction_set_hook(instr, IPH_%s, (instr_hook_fc)%s);\n",
+                func->type, func->name);
+
+    }
+
+    if (hooks->func_count > 0 && result)
+        dprintf(fd, "\n");
+
+    return result;
+
+}
diff --git a/tools/d2c/hooks.h b/tools/d2c/hooks.h
new file mode 100644
index 0000000..5dbf223
--- /dev/null
+++ b/tools/d2c/hooks.h
@@ -0,0 +1,51 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * hooks.h - prototypes pour la prise en compte d'une hookse du langage d'assemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_HOOKS_H
+#define _TOOLS_HOOKS_H
+
+
+#include <stdbool.h>
+
+
+
+/* Liste des fonctions de renvoi pour une instruction */
+typedef struct _instr_hooks instr_hooks;
+
+
+
+/* Crée une liste de fonctions à lier à une instruction. */
+instr_hooks *create_instr_hooks(void);
+
+/* Supprime de la mémoire une liste de fonctions liées. */
+void delete_instr_hooks(instr_hooks *);
+
+/* Enregistre l'utilité d'une fonction pour une instruction. */
+void register_hook_function(instr_hooks *, char *, char *);
+
+/* Associe dans le code des fonctions à une instruction. */
+bool write_hook_functions(const instr_hooks *, int);
+
+
+
+#endif  /* _TOOLS_HOOKS_H */
diff --git a/tools/d2c/spec.c b/tools/d2c/spec.c
index 9990881..b56c6aa 100644
--- a/tools/d2c/spec.c
+++ b/tools/d2c/spec.c
@@ -33,22 +33,6 @@
 
 
 
-
-
-#define get_raw_bitfield_name(bf) ""
-
-
-
-
-
-#define get_syntax_item_name(si) ""
-
-
-
-
-
-
-
 /* Mémorisation d'un encodage complet */
 struct _encoding_spec
 {
@@ -59,17 +43,13 @@ struct _encoding_spec
     coding_bits *bits;                      /* Encodage des bits associés  */
     asm_syntax *syntax;                     /* Calligraphe d'assemblage    */
     conv_list *conversions;                 /* Conversions des données     */
+    instr_hooks *hooks;                     /* Fonctions complémentaires   */
     decoding_rules *rules;                  /* Règles supplémentaires      */
 
 };
 
 
 
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : -                                                            *
@@ -91,6 +71,7 @@ encoding_spec *create_encoding_spec(void)
     result->bits = create_coding_bits();
     result->syntax = create_asm_syntax();
     result->conversions = create_conv_list();
+    result->hooks = create_instr_hooks();
     result->rules = create_decoding_rules();
 
     return result;
@@ -115,6 +96,7 @@ void delete_encoding_spec(encoding_spec *spec)
     delete_coding_bits(spec->bits);
     delete_asm_syntax(spec->syntax);
     delete_conv_list(spec->conversions);
+    delete_instr_hooks(spec->hooks);
     delete_decoding_rules(spec->rules);
 
     free(spec);
@@ -226,6 +208,25 @@ conv_list *get_conversions_in_encoding_spec(const encoding_spec *spec)
 *                                                                             *
 *  Paramètres  : spec = spécification d'encodage à consulter.                 *
 *                                                                             *
+*  Description : Fournit la liste des fonctions à lier à une instruction.     *
+*                                                                             *
+*  Retour      : Structure assurant la gestion des fonctions de conversion.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+instr_hooks *get_hooks_in_encoding_spec(const encoding_spec *spec)
+{
+    return spec->hooks;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : spec = spécification d'encodage à consulter.                 *
+*                                                                             *
 *  Description : Fournit un ensemble de règles supplémentaires éventuel.      *
 *                                                                             *
 *  Retour      : Structure assurant la gestion de ces règles.                 *
@@ -313,6 +314,10 @@ bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *a
 
     dprintf(fd, "\n");
 
+    /* Inscriptions des éventuelles fonctions à lier */
+
+    result &= write_hook_functions(spec->hooks, fd);
+
     /* Création des opérandes */
 
     result &= define_syntax_items(spec->syntax, fd, arch, spec->bits, spec->conversions, pp);
diff --git a/tools/d2c/spec.h b/tools/d2c/spec.h
index 561fc32..39bfdb7 100644
--- a/tools/d2c/spec.h
+++ b/tools/d2c/spec.h
@@ -30,6 +30,7 @@
 
 #include "bits.h"
 #include "conv.h"
+#include "hooks.h"
 #include "pproc.h"
 #include "rules.h"
 #include "syntax.h"
@@ -61,6 +62,9 @@ asm_syntax *get_syntax_in_encoding_spec(const encoding_spec *);
 /* Fournit la liste des fonctions de conversion. */
 conv_list *get_conversions_in_encoding_spec(const encoding_spec *);
 
+/* Fournit la liste des fonctions à lier à une instruction. */
+instr_hooks *get_hooks_in_encoding_spec(const encoding_spec *);
+
 /* Fournit un ensemble de règles supplémentaires éventuel. */
 decoding_rules *get_rules_in_encoding_spec(const encoding_spec *);
 
-- 
cgit v0.11.2-87-g4458