diff options
Diffstat (limited to 'src/analysis/decomp')
-rw-r--r-- | src/analysis/decomp/il.c | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c index 60e86b6..642c921 100644 --- a/src/analysis/decomp/il.c +++ b/src/analysis/decomp/il.c @@ -40,7 +40,8 @@ static bool track_used_registers(GFlowBlock *, BlockFollowPosition, GRAccessList /* Etablit le relévé des allocations de registre. */ static void setup_awaited_regs_allocation(const GInstrBlock *, vmpa_t); - +/* Met en place un contexte adapté aux sous-blocs d'un bloc. */ +static GDecContext *create_new_context_for_sub_block(GDecContext *, GInstrBlock *); @@ -185,12 +186,9 @@ static bool track_used_registers(GFlowBlock *block, BlockFollowPosition pos, GRA static void setup_awaited_regs_allocation(const GInstrBlock *list, vmpa_t start) { - GDecContext *result; /* Contexte pour la décompil. */ GInstrBlock *first; /* Bloc de départ du flot */ GRAccessList *needed; /* Registres inter-blocs */ - result = NULL; - first = g_instr_block_find_by_addr(list, start, true); needed = g_raccess_list_new(); @@ -200,11 +198,31 @@ static void setup_awaited_regs_allocation(const GInstrBlock *list, vmpa_t start) g_object_unref(G_OBJECT(needed)); +} - return result; -} +/****************************************************************************** +* * +* Paramètres : ctx = contexte de décompilation courant. * +* block = block regroupant les branches de division. * +* * +* Description : Met en place un contexte adapté aux sous-blocs d'un bloc. * +* * +* Retour : Nouveau contexte près à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDecContext *create_new_context_for_sub_block(GDecContext *ctx, GInstrBlock *block) +{ + + return g_dec_context_dup(ctx); + + + +} /* ---------------------------------------------------------------------------------- */ @@ -272,11 +290,13 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon vmpa_t max; /* Adresse de fin du bloc */ GArchInstruction *iter; /* Boucle de parcours */ GDecInstruction *decomp; /* Dernier résultat de décomp. */ + GInstrBlock *sub_parent; /* Groupe des sous-branches */ + GDecContext *sub_ctx; /* Sous-contexte pour branche */ GDecInstruction *true_dinstr; /* Décompilation 'cond vraie' */ GDecInstruction *false_dinstr; /* Décompilation 'cond fausse' */ GArchInstruction *next; /* Instruction de branchement */ vmpa_t next_addr; /* Adresse de cette instruct° */ - GInstrBlock *next_parent; /* Bloc basique correspondant */ + //GInstrBlock *next_parent; /* Bloc basique correspondant */ GInstrBlock *next_block; /* Sous-bloc basique direct */ instrs = g_flow_block_get_all_instructions_list(block); @@ -297,43 +317,47 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon /* Post-traitement selon les types de lien */ - res = g_dec_context_get_decomp_instrs(ctx); + //res = g_dec_context_get_decomp_instrs(ctx); /* if ... then ... else ... */ if (G_IS_ITE_INSTRUCTION(decomp)) { - next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_TRUE); - - printf("@ 0x%08llx : true : %p\n", max, next); + sub_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); true_dinstr = NULL; + next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_TRUE); if (next != NULL) { g_arch_instruction_get_location(next, NULL, NULL, &next_addr); - next_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); - next_block = g_instr_block_find_by_addr(next_parent, next_addr, false); + next_block = g_instr_block_find_by_addr(sub_parent, next_addr, false); if (next_block != NULL) - true_dinstr = decompiled_basic_block(next_block, ctx); + { + sub_ctx = create_new_context_for_sub_block(ctx, sub_parent); + true_dinstr = decompiled_basic_block(next_block, sub_ctx); + /* TODO : merge awaited */ + g_object_unref(G_OBJECT(sub_ctx)); + } } - next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE); - - printf("@ 0x%08llx : false : %p\n", max, next); - false_dinstr = NULL; + next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE); if (next != NULL) { g_arch_instruction_get_location(next, NULL, NULL, &next_addr); - next_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); - next_block = g_instr_block_find_by_addr(next_parent, next_addr, false); + next_block = g_instr_block_find_by_addr(sub_parent, next_addr, false); if (next_block != NULL) - false_dinstr = decompiled_basic_block(next_block, ctx); + { + sub_ctx = create_new_context_for_sub_block(ctx, sub_parent); + false_dinstr = decompiled_basic_block(next_block, sub_ctx); + /* TODO : merge awaited */ + g_object_unref(G_OBJECT(sub_ctx)); + } } @@ -350,9 +374,9 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon /* Renvoi des instructions mises en place */ - return res; + //return res; - //return g_dec_context_get_decomp_instrs(ctx); + return g_dec_context_get_decomp_instrs(ctx); } @@ -393,13 +417,15 @@ static GDecInstruction *decompiled_instructions_blocks(GVirtualBlock *block, GDe if (!G_IS_FLOW_BLOCK(sub_block)) continue; /* FIXME */ - g_dec_context_set_decomp_instrs(ctx, NULL); + //g_dec_context_set_decomp_instrs(ctx, NULL); dinstrs = decompiled_instructions_block(G_FLOW_BLOCK(sub_block), ctx); - result = merge_decompiled_instructions(result, dinstrs); + //result = merge_decompiled_instructions(result, dinstrs); } + result = merge_decompiled_instructions(result, dinstrs); + return result; } @@ -422,9 +448,6 @@ static GDecInstruction *decompiled_basic_block(GInstrBlock *block, GDecContext * { GDecInstruction *result; /* Instructions à retourner */ - /* FIXME */ - g_dec_context_set_decomp_instrs(ctx, NULL); - if (G_IS_VIRTUAL_BLOCK(block)) result = decompiled_instructions_blocks(G_VIRTUAL_BLOCK(block), ctx); |