From ee0ff01247738e847ae3faa44dcb5168d7b758ba Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 25 Apr 2015 21:35:19 +0000 Subject: Registered suitable linkage hooks and defined right links between instructions. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@519 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 28 ++++++++++++++++++++++++++++ src/analysis/disass/macro.c | 20 ++++++++++++++++---- src/arch/arm/v7/opdefs/bl_A8825.d | 4 ++++ src/arch/arm/v7/opdefs/cbnz_A8829.d | 2 ++ src/arch/instruction.c | 2 +- src/arch/instruction.h | 2 +- src/arch/link.c | 9 +++++---- src/arch/link.h | 14 +++++++++++++- src/arch/target.c | 23 +++++++++++++++++++++++ src/arch/target.h | 3 +++ src/gtkext/graph/layout.c | 36 ++++++++++++++++++++++++++++++++++-- src/gtkext/graph/nodes/flow.c | 19 +++++++++++++++++++ src/gtkext/graph/nodes/flow.h | 3 +++ 13 files changed, 152 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83d8022..479f470 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,33 @@ 15-04-25 Cyrille Bagard + * src/analysis/disass/macro.c: + Use an uniq coverage memory for all visited branches. + + * src/arch/arm/v7/opdefs/bl_A8825.d: + * src/arch/arm/v7/opdefs/cbnz_A8829.d: + Register suitable linkage hooks and define right links between instructions. + + * src/arch/instruction.c: + * src/arch/instruction.h: + Remove a GCC compilation warning about a return value. + + * src/arch/link.c: + * src/arch/link.h: + Refine the linkage hooks: allow to choose the right operand. + + * src/arch/target.c: + * src/arch/target.h: + Give an access to the resolved symbol if needed. + + * src/gtkext/graph/layout.c: + Improve the final debug message. + + * src/gtkext/graph/nodes/flow.c: + * src/gtkext/graph/nodes/flow.h: + Give an access to the raw basic block. + +15-04-25 Cyrille Bagard + * src/analysis/disass/area.c: * src/analysis/disass/output.c: * src/arch/arm/v7/context.c: diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 96a3b25..9527457 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -40,6 +40,8 @@ /* Bornes d'une zone à couvrir */ typedef struct _code_coverage { + bool initial; /* Couverture racine ? */ + mrange_t range; /* Couverture totale */ vmpa2t start; /* Position butoir de début */ @@ -209,6 +211,8 @@ static code_coverage *create_code_coverage(const mrange_t *range) result = (code_coverage *)calloc(1, sizeof(code_coverage)); + result->initial = true; + copy_mrange(&result->range, range); copy_vmpa(&result->start, get_mrange_addr(range)); @@ -251,6 +255,8 @@ static code_coverage *dup_code_coverage(const code_coverage *src, const vmpa2t * result = (code_coverage *)calloc(1, sizeof(code_coverage)); + result->initial = false; + copy_mrange(&result->range, &src->range); copy_vmpa(&result->start, new); @@ -261,10 +267,15 @@ static code_coverage *dup_code_coverage(const code_coverage *src, const vmpa2t * for (i = 0; i < result->ends_count; i++) copy_vmpa(&result->ends[i], &src->ends[i]); - result->processed = (unsigned long *)calloc(src->allocated, sizeof(unsigned long)); - result->allocated = src->allocated; + /** + * Les blocs produits par le découpage sont à accès global, et ne sont donc pas + * la propriété d'une branche particulière. + * Il ne faut donc pas créer deux blocs identiques à partir de deux chemins + * différents ; aussi on partage la couverture de code plutôt que la copier. + * Et, par ailleurs, c'est plus simple & efficace. + */ - memcpy(result->processed, src->processed, src->allocated * sizeof(unsigned long)); + result->processed = src->processed; return result; @@ -287,7 +298,8 @@ static void delete_code_coverage(code_coverage *coverage) { free(coverage->ends); - free(coverage->processed); + if (coverage->initial) + free(coverage->processed); free(coverage); diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d index 62ac8f9..ce4870c 100644 --- a/src/arch/arm/v7/opdefs/bl_A8825.d +++ b/src/arch/arm/v7/opdefs/bl_A8825.d @@ -40,6 +40,7 @@ @hooks { fetch = help_fetching_with_instruction_bl_from_thumb + link = handle_call_as_link post = post_process_branch_and_link_instructions } @@ -69,6 +70,7 @@ @hooks { fetch = help_fetching_with_instruction_blx_from_thumb + link = handle_call_as_link post = post_process_branch_and_link_instructions } @@ -96,6 +98,7 @@ @hooks { fetch = help_fetching_with_instruction_bl_from_arm + link = handle_call_as_link post = post_process_branch_and_link_instructions } @@ -123,6 +126,7 @@ @hooks { fetch = help_fetching_with_instruction_blx_from_arm + link = handle_call_as_link post = post_process_branch_and_link_instructions } diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cbnz_A8829.d index d9815c1..f5f9602 100644 --- a/src/arch/arm/v7/opdefs/cbnz_A8829.d +++ b/src/arch/arm/v7/opdefs/cbnz_A8829.d @@ -39,6 +39,7 @@ @hooks { fetch = help_fetching_with_instruction_cb_n_z + link = handle_comp_and_branch_if_true_as_link post = post_process_comp_and_branch_instructions } @@ -61,6 +62,7 @@ @hooks { fetch = help_fetching_with_instruction_cb_n_z + link = handle_comp_and_branch_if_true_as_link post = post_process_comp_and_branch_instructions } diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 475c038..7391af1 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -636,7 +636,7 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des * * ******************************************************************************/ -void g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType old, InstructionLinkType new) +bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType old, InstructionLinkType new) { size_t count; /* Raccourci pour la lecture */ size_t i; /* Boucle de parcours */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 9123b6f..b570d92 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -189,7 +189,7 @@ bool g_arch_instruction_is_return(const GArchInstruction *instr); void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType, ...); /* Change la nature d'un lien entre deux instructions. */ -void g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType); +bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType); /* Indique si l'instruction a une ou plusieurs origines. */ bool g_arch_instruction_has_sources(const GArchInstruction *); diff --git a/src/arch/link.c b/src/arch/link.c index bc80e39..02cda22 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -79,6 +79,7 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon * proc = représentation de l'architecture utilisée. * * context = contexte associé à la phase de désassemblage. * * format = acès aux données du binaire d'origine. * +* index = indice de l'opérande à traiter dans l'instruction. * * * * Description : Etablit un lien d'appel selon une instruction donnée. * * * @@ -87,8 +88,8 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon * Remarques : - * * * ******************************************************************************/ -#include "instruction-int.h" -void handle_branch_if_true_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +#include "instruction-int.h" // REMME +void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format, size_t index) { GArchOperand *op; /* Opérande numérique en place */ virt_t virt; /* Adresse virtuelle */ @@ -96,9 +97,9 @@ void handle_branch_if_true_as_link(GArchInstruction *instr, GArchProcessor *proc GArchInstruction *target; /* Ligne visée par la référence*/ GArchInstruction *list; /* Ensemble des instructions */ - assert(g_arch_instruction_count_operands(instr) > 0); + assert(g_arch_instruction_count_operands(instr) > index); - op = g_arch_instruction_get_operand(instr, 0); + op = g_arch_instruction_get_operand(instr, index); virt = VMPA_NO_VIRTUAL; diff --git a/src/arch/link.h b/src/arch/link.h index 1923e0b..319b3a0 100644 --- a/src/arch/link.h +++ b/src/arch/link.h @@ -35,7 +35,19 @@ void handle_jump_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); /* Etablit un lien d'appel selon une instruction donnée. */ -void handle_branch_if_true_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); +void handle_branch_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *, size_t); + + +static inline void handle_branch_if_true_as_link(GArchInstruction *ins, GArchProcessor *proc, GProcContext *ctx, GBinFormat *fmt) +{ + handle_branch_as_link(ins, proc, ctx, fmt, 0); +} + +static inline void handle_comp_and_branch_if_true_as_link(GArchInstruction *ins, GArchProcessor *proc, GProcContext *ctx, GBinFormat *fmt) +{ + handle_branch_as_link(ins, proc, ctx, fmt, 1); +} + /* Etablit un lien d'appel selon une instruction donnée. */ void handle_call_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); diff --git a/src/arch/target.c b/src/arch/target.c index 7509711..01c2bfe 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -328,3 +328,26 @@ bool g_target_operand_resolve(GTargetOperand *operand, const GBinFormat *format) return result; } + + +/****************************************************************************** +* * +* Paramètres : operand = opérande dont le contenu est à raffiner. * +* diff = décallage entre le symbole et l'adresse initiale. * +* * +* Description : Fournit les indications concernant le symbole associé. * +* * +* Retour : Symbole résolu ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *diff) +{ + if (diff != NULL) + *diff = operand->diff; + + return operand->symbol; + +} diff --git a/src/arch/target.h b/src/arch/target.h index ada1a6c..f226ee1 100644 --- a/src/arch/target.h +++ b/src/arch/target.h @@ -66,6 +66,9 @@ virt_t g_target_operand_get_addr(const GTargetOperand *); /* Tente une résolution de symbole. */ bool g_target_operand_resolve(GTargetOperand *, const GBinFormat *); +/* Fournit les indications concernant le symbole associé. */ +GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *, phys_t *); + #endif /* _ARCH_TARGET_H */ diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c index de83a22..d2e3b51 100644 --- a/src/gtkext/graph/layout.c +++ b/src/gtkext/graph/layout.c @@ -169,7 +169,8 @@ static void g_graph_layout_finalize(GGraphLayout *layout) * Remarques : - * * * ******************************************************************************/ - +#include "../../arch/instruction-int.h" // REMME +#include "nodes/flow.h" GGraphLayout *g_graph_layout_new(GInstrBlock *blocks, GtkBufferView **views, size_t count) { GGraphLayout *result; /* Structure à retourner */ @@ -222,18 +223,49 @@ GGraphLayout *g_graph_layout_new(GInstrBlock *blocks, GtkBufferView **views, siz bool _print_dbg_ext_cb(GGraphNode *node, GNodeVisitState state, int *depth) { int i; + PendingPositionFlags pending_flag; + char *flags; GtkAllocation alloc; + GArchInstruction *first; + GArchInstruction *last; + + char *flags_list[] = { + "NONE", + "DIRECT_X", + "LEFT_MARGIN", + "RIGHT_MARGIN", + "LEFT_NODE", + "RIGHT_NODE" + }; + if (state == GVS_ENTER || state == GVS_NODE) { + + + for (i = 0; i < *depth; i++) printf(" "); + g_graph_node_get_pending_position(node, &pending_flag, (pending_position []) { { 0 } }); + flags = flags_list[pending_flag]; + alloc = g_graph_node_get_allocation(node); - printf("- %p - (%d ; %d) - (%d ; %d)\n", node, + printf("- %p - \"%s\" - (%d ; %d) - (%d ; %d)", node, + flags, alloc.x, alloc.y, alloc.width, alloc.height); + if (G_IS_FLOW_NODE(node)) + { + printf(" - rank = %u -", g_graph_node_get_rank(node)); + + g_flow_block_get_boundary(g_flow_node_get_block(node), &first, &last); + printf(" - 0x%08x <-> 0x%08x", first->range.addr.virtual, last->range.addr.virtual); + } + + printf("\n"); + } if (state == GVS_ENTER) (*depth)++; diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c index 558913e..e502293 100644 --- a/src/gtkext/graph/nodes/flow.c +++ b/src/gtkext/graph/nodes/flow.c @@ -462,6 +462,25 @@ static bool g_flow_node_visit_flow_nodes(GFlowNode *node, graph_node_visitor_cb /****************************************************************************** * * +* Paramètres : node = noeud graphique à consulter. * +* * +* Description : Fournit le bloc basique à l'origine du bloc graphique. * +* * +* Retour : Bloc brut encapsulé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GFlowBlock *g_flow_node_get_block(const GFlowNode *node) +{ + return node->block; + +} + + +/****************************************************************************** +* * * Paramètres : node = noeud graphique à consulter. * * instr = instruction à considérer. * * * diff --git a/src/gtkext/graph/nodes/flow.h b/src/gtkext/graph/nodes/flow.h index 413a8f2..f659a77 100644 --- a/src/gtkext/graph/nodes/flow.h +++ b/src/gtkext/graph/nodes/flow.h @@ -59,6 +59,9 @@ GType g_flow_node_get_type(void); /* Encapsule graphiquement un bloc d'exécution. */ GGraphNode *g_flow_node_new(GFlowBlock *, GtkBufferView *); +/* Fournit le bloc basique à l'origine du bloc graphique. */ +GFlowBlock *g_flow_node_get_block(const GFlowNode *); + /* Précise si le noeud a pour première instruction celle donnée. */ bool g_flow_node_start_with(const GFlowNode *, GArchInstruction *); -- cgit v0.11.2-87-g4458