diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2013-01-20 13:10:06 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2013-01-20 13:10:06 (GMT) |
commit | 37fd2f1329c56078bc8a8b2fc955aa001c109c01 (patch) | |
tree | 71bcce9a3eaf6b7569d1f1d3e057752ae517ebde /src/arch/dalvik/context.c | |
parent | a9bbd894bd25f7c2bb72fb7d4064b19377d90c6d (diff) |
Took care of shared allocations between blocks when converting registers.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@326 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/dalvik/context.c')
-rw-r--r-- | src/arch/dalvik/context.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c index e80ead3..7918467 100644 --- a/src/arch/dalvik/context.c +++ b/src/arch/dalvik/context.c @@ -123,8 +123,11 @@ static void g_dalvik_dcontext_finalize(GDalvikDContext *); /* Duplique un contexte de compilation. */ static GDalvikDContext *g_dalvik_dcontext_dup(GDalvikDContext *); +/* Propage un registre alloué et attendu par la suite. */ +static void g_dalvik_context_spread_allocated_shared_reg(GDalvikDContext *, GDalvikRegister *, GDecInstruction *); + /* Convertit un registre machine en un pseudo-registre. */ -static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *, GDalvikRegisterOperand *, bool); +static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *, GDalvikRegisterOperand *, bool, vmpa_t); @@ -335,6 +338,7 @@ static void g_dalvik_dcontext_init(GDalvikDContext *ctx) parent = G_DEC_CONTEXT(ctx); parent->dup = (dup_dec_context_fc)g_dalvik_dcontext_dup; + parent->spread = (spread_reg_fc)g_dalvik_context_spread_allocated_shared_reg; parent->convert_reg = (convert_register_fc)g_dalvik_dcontext_convert_register; } @@ -443,9 +447,46 @@ static GDalvikDContext *g_dalvik_dcontext_dup(GDalvikDContext *orig) /****************************************************************************** * * +* Paramètres : parent = instance à éventuellement compléter. * +* child = instance à venir consulter. * +* * +* Description : Propage un registre alloué et attendu par la suite. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_context_spread_allocated_shared_reg(GDalvikDContext *ctx, GDalvikRegister *reg, GDecInstruction *dinstr) +{ + GDexFormat *format; /* Recherche de méthode */ + GBinRoutine *routine; /* Objet des recherches */ + GDexMethod *method; /* Méthode décompilée */ + uint16_t index; /* Identifiant du registre */ + DexVariableIndex info; /* Nature du registre */ + + format = G_DEX_FORMAT(G_DEC_CONTEXT(ctx)->format); + routine = G_DEC_CONTEXT(ctx)->routine; + + method = g_dex_format_find_method_by_address(format, g_binary_routine_get_address(routine)); + + index = g_dalvik_register_get_index(reg); + info = g_dex_method_get_variable(method, index); + + g_object_ref(G_OBJECT(dinstr)); + g_hash_table_insert(ctx->locals, GUINT_TO_POINTER(DVI_INDEX(info)), dinstr); + ctx->locals_count++; + +} + + +/****************************************************************************** +* * * Paramètres : ctx = instance à consulter, voire mettre à jour. * * operand = opérande représentant un registre quelconque. * * assign = précise le sort prochain du registre. * +* addr = adresse de l'instruction décompilée. * * * * Description : Convertit un registre machine en un pseudo-registre. * * * @@ -455,7 +496,7 @@ static GDalvikDContext *g_dalvik_dcontext_dup(GDalvikDContext *orig) * * ******************************************************************************/ -static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx, GDalvikRegisterOperand *operand, bool assign) +static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx, GDalvikRegisterOperand *operand, bool assign, vmpa_t addr) { GDecInstruction *result; /* Instance à retourner */ GDexFormat *format; /* Recherche de méthode */ @@ -522,17 +563,37 @@ static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx, { found = g_hash_table_lookup(ctx->locals, GUINT_TO_POINTER(DVI_INDEX(info))); - if (/*!assign && */found != NULL) + if (!assign && found != NULL) { g_object_ref(G_OBJECT(found)); result = G_DEC_INSTRUCTION(found); } else { - result = g_pseudo_register_new(); - g_pseudo_register_set_basename(G_PSEUDO_REGISTER(result), "var"); - g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->locals_count); + /* + if (!assign) + { + printf("bug"); + exit(0); + } + */ + + result = g_dec_context_get_awaited_alloc(G_DEC_CONTEXT(ctx), G_ARCH_REGISTER(reg), addr); + + if (result == NULL) + { + result = g_pseudo_register_new(); + g_pseudo_register_set_basename(G_PSEUDO_REGISTER(result), "var"); + g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->locals_count); + + g_dec_context_notify_reg_alloc(G_DEC_CONTEXT(ctx), G_ARCH_REGISTER(reg), + result, addr); + + } + else + g_object_ref(G_OBJECT(result)); + g_object_ref(G_OBJECT(result)); g_hash_table_insert(ctx->locals, GUINT_TO_POINTER(DVI_INDEX(info)), result); ctx->locals_count++; |