summaryrefslogtreecommitdiff
path: root/src/analysis/disass/macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/disass/macro.c')
-rw-r--r--src/analysis/disass/macro.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c
index 8766ed9..ebd236a 100644
--- a/src/analysis/disass/macro.c
+++ b/src/analysis/disass/macro.c
@@ -303,6 +303,7 @@ static void find_next_jumps(GArchInstruction *instrs, vmpa_t start, const code_c
InstructionLinkType *types; /* Type de lien entre lignes */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours #2 */
+ vmpa_t daddr; /* Adresse de destination */
/* On évite de boucler... */
if (is_addr_in_branch(info, &start))
@@ -340,8 +341,14 @@ static void find_next_jumps(GArchInstruction *instrs, vmpa_t start, const code_c
case ILT_CASE_JUMP:
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
- find_next_jumps(instrs, addr, coverage, info);
+ g_arch_instruction_get_location(dests[i], NULL, NULL, &daddr);
+ find_next_jumps(instrs, daddr, coverage, info);
+ break;
+
+ case ILT_LOOP:
+ g_arch_instruction_get_location(dests[i], NULL, NULL, &daddr);
+ info->jumps = (vmpa_t *)realloc(info->jumps, ++(info->count) * sizeof(vmpa_t));
+ info->jumps[info->count - 1] = daddr;
break;
default:
@@ -681,30 +688,43 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, const code
/* Branche 'true' */
- sub_coverage = dup_code_coverage(true_branch.jumps[0], coverage);
- add_ending_address_code_coverage(sub_coverage, &next_addr);
- add_ending_address_code_coverage(sub_coverage, &false_branch.jumps[0]);
+ if (true_branch.count > 0)
+ {
+ sub_coverage = dup_code_coverage(true_branch.jumps[0], coverage);
+ add_ending_address_code_coverage(sub_coverage, &next_addr);
+ if (false_branch.count > 0)
+ add_ending_address_code_coverage(sub_coverage, &false_branch.jumps[0]);
- block = build_instruction_block(instrs, sub_coverage);
- if (block != NULL)
- g_virtual_block_add_child(G_VIRTUAL_BLOCK(group), block);
+ block = build_instruction_block(instrs, sub_coverage);
+ if (block != NULL)
+ g_virtual_block_add_child(G_VIRTUAL_BLOCK(group), block);
- delete_code_coverage(sub_coverage);
+ delete_code_coverage(sub_coverage);
+
+ }
/* Branche 'false' */
- sub_coverage = dup_code_coverage(false_branch.jumps[0], coverage);
- add_ending_address_code_coverage(sub_coverage, &next_addr);
- add_ending_address_code_coverage(sub_coverage, &true_branch.jumps[0]);
+ if (false_branch.count > 0)
+ {
+ sub_coverage = dup_code_coverage(false_branch.jumps[0], coverage);
+ add_ending_address_code_coverage(sub_coverage, &next_addr);
+ if (true_branch.count > 0)
+ add_ending_address_code_coverage(sub_coverage, &true_branch.jumps[0]);
- block = build_instruction_block(instrs, sub_coverage);
- if (block != NULL)
- g_virtual_block_add_child(G_VIRTUAL_BLOCK(group), block);
+ block = build_instruction_block(instrs, sub_coverage);
+ if (block != NULL)
+ g_virtual_block_add_child(G_VIRTUAL_BLOCK(group), block);
- delete_code_coverage(sub_coverage);
+ delete_code_coverage(sub_coverage);
+
+ }
/* Conclusion */
+ if (true_branch.count > 0) free(true_branch.jumps);
+ if (false_branch.count > 0) free(false_branch.jumps);
+
if (g_virtual_block_count_children(G_VIRTUAL_BLOCK(group)) > 0)
{
DELAYED_BLOCK_ADDING(result, result_cached, group);
@@ -713,9 +733,6 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, const code
else
g_object_unref(G_OBJECT(group));
- free(true_branch.jumps);
- free(false_branch.jumps);
-
}
/* Post-traitements de ILT_CATCH_EXCEPTION */