diff options
Diffstat (limited to 'src/analysis/disass/macro.c')
-rw-r--r-- | src/analysis/disass/macro.c | 55 |
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 */ |