summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-01-10 16:37:34 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-01-10 16:37:34 (GMT)
commit8ef66a1e0225c9e00175fbaf3f3038f537de511f (patch)
treedd7112dd50c02e0ad1565ce7a890991b5e1270c6
parentcc3e31eecd90766ae4f0bb391428c5c59567ef4c (diff)
Extended the grammar to allow hooks inclusion.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@453 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog34
-rw-r--r--src/arch/arm/context.c79
-rw-r--r--src/arch/arm/v7/link.c28
-rw-r--r--src/arch/arm/v7/link.h27
-rw-r--r--src/arch/arm/v7/opdefs/Makefile.am2
-rw-r--r--src/arch/arm/v7/opdefs/bl_A8825.d28
-rw-r--r--src/arch/arm/v7/processor.c44
-rw-r--r--tools/d2c/Makefile.am1
-rw-r--r--tools/d2c/d2c_gram.y27
-rw-r--r--tools/d2c/d2c_tok.l13
-rw-r--r--tools/d2c/hooks.c169
-rw-r--r--tools/d2c/hooks.h51
-rw-r--r--tools/d2c/spec.c47
-rw-r--r--tools/d2c/spec.h4
14 files changed, 378 insertions, 176 deletions
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 *);