diff options
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++; | 
