diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-18 15:32:27 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-18 15:32:27 (GMT) |
commit | b0bcf250999b2242019f137e38f52390a86e71cd (patch) | |
tree | f3436a3ddbbd4773005ecb891630a815ed001341 /src/arch/dalvik | |
parent | 6bde4016160057a22234d4ed698903dca52ce162 (diff) |
Shared all Dalvik operands between all their users.
Diffstat (limited to 'src/arch/dalvik')
-rw-r--r-- | src/arch/dalvik/context.c | 2 | ||||
-rw-r--r-- | src/arch/dalvik/core.c | 35 | ||||
-rw-r--r-- | src/arch/dalvik/core.h | 5 | ||||
-rw-r--r-- | src/arch/dalvik/instruction.c | 2 | ||||
-rw-r--r-- | src/arch/dalvik/operand.c | 14 | ||||
-rw-r--r-- | src/arch/dalvik/operands/args.c | 222 | ||||
-rw-r--r-- | src/arch/dalvik/operands/args.h | 22 | ||||
-rw-r--r-- | src/arch/dalvik/operands/pool.c | 194 | ||||
-rw-r--r-- | src/arch/dalvik/operands/pool.h | 31 | ||||
-rw-r--r-- | src/arch/dalvik/operands/register.c | 190 | ||||
-rw-r--r-- | src/arch/dalvik/operands/register.h | 34 | ||||
-rw-r--r-- | src/arch/dalvik/register.c | 82 | ||||
-rw-r--r-- | src/arch/dalvik/register.h | 5 |
13 files changed, 771 insertions, 67 deletions
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c index 3b79ffa..997d899 100644 --- a/src/arch/dalvik/context.c +++ b/src/arch/dalvik/context.c @@ -638,7 +638,7 @@ static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx, GDexFormat *format; /* Recherche de méthode */ GBinRoutine *routine; /* Objet des recherches */ GDexMethod *method; /* Méthode décompilée */ - GDalvikRegister *reg; /* Registre Dalvik représenté */ + const GDalvikRegister *reg; /* Registre Dalvik représenté */ uint16_t index; /* Identifiant du registre */ DexVariableIndex info; /* Nature du registre */ GBinVariable *this; /* Définition de "this" */ diff --git a/src/arch/dalvik/core.c b/src/arch/dalvik/core.c index ba07c97..9438d17 100644 --- a/src/arch/dalvik/core.c +++ b/src/arch/dalvik/core.c @@ -25,6 +25,9 @@ #include "register.h" +#include "operands/args.h" +#include "operands/pool.h" +#include "operands/register.h" @@ -48,6 +51,10 @@ bool init_dalvik_core(void) result &= init_dalvik_register_sharing(); + result &= init_dalvik_args_operand_sharing(); + result &= init_dalvik_pool_operand_sharing(); + result &= init_dalvik_register_operand_sharing(); + return result; } @@ -57,6 +64,30 @@ bool init_dalvik_core(void) * * * Paramètres : - * * * +* Description : Imprime des statistiques quant aux partages dans l'archi. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_share_stats(void) +{ + dump_dalvik_register_share_stats(); + + dump_dalvik_args_operand_share_stats(); + dump_dalvik_pool_operand_share_stats(); + dump_dalvik_register_operand_share_stats(); + +} +#endif + + +/****************************************************************************** +* * +* Paramètres : - * +* * * Description : Supprime les mécanismes internes de l'architecture Dalvik. * * * * Retour : - * @@ -69,4 +100,8 @@ void exit_dalvik_core(void) { exit_dalvik_register_sharing(); + exit_dalvik_args_operand_sharing(); + exit_dalvik_pool_operand_sharing(); + exit_dalvik_register_operand_sharing(); + } diff --git a/src/arch/dalvik/core.h b/src/arch/dalvik/core.h index e7a5e1e..4d7577a 100644 --- a/src/arch/dalvik/core.h +++ b/src/arch/dalvik/core.h @@ -32,6 +32,11 @@ /* Met en place les mécanismes internes de l'architecture. */ bool init_dalvik_core(void); +/* Imprime des statistiques quant aux partages dans l'archi. */ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_share_stats(void); +#endif + /* Supprime les mécanismes internes de l'architecture Dalvik. */ void exit_dalvik_core(void); diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c index cc1cab2..77fdd11 100644 --- a/src/arch/dalvik/instruction.c +++ b/src/arch/dalvik/instruction.c @@ -525,7 +525,7 @@ static void g_dalvik_instruction_get_rw_registers(const GDalvikInstruction *inst GArchInstruction *base; /* Version basique à manipuler */ size_t i; /* Boucle de parcours */ GArchOperand *operand; /* Operande à analyser */ - GDalvikRegister *reg; /* Registre concerné */ + const GDalvikRegister *reg; /* Registre concerné */ base = G_ARCH_INSTRUCTION(instr); diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index 802ce1e..e1a910c 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -474,14 +474,13 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form /* Mise en place des arguments */ args = g_dalvik_args_operand_new(); - g_arch_instruction_attach_extra_operand(instr, args); for (i = 0; i < MIN(a, 4); i++) { op = g_dalvik_register_operand_new(content, pos, low, MDS_4_BITS, endian); if (op == NULL) goto err_registers; - g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); + args = G_ARCH_OPERAND(g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op, NULL)); } @@ -494,7 +493,7 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form /* Rajout des éléments finaux déjà chargés */ if (a == 5) - g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), opg); + args = G_ARCH_OPERAND(g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), opg, NULL)); else { @@ -502,6 +501,10 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form g_object_unref(G_OBJECT(opg)); } + g_arch_instruction_attach_extra_operand(instr, args); + + /* Rajout de la cible */ + g_arch_instruction_attach_extra_operand(instr, target); return true; @@ -564,17 +567,18 @@ static bool dalvik_read_variatic_operands(GArchInstruction *instr, GDexFormat *f /* Mise en place des arguments */ args = g_dalvik_args_operand_new(); - g_arch_instruction_attach_extra_operand(instr, args); for (i = 0; i < a; i++) { op = g_dalvik_register_operand_new_from_existing(g_dalvik_register_new(c + i)); if (op == NULL) goto drvo_registers; - g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); + args = G_ARCH_OPERAND(g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op, NULL)); } + g_arch_instruction_attach_extra_operand(instr, args); + /* Rajout de la cible */ g_arch_instruction_attach_extra_operand(instr, target); diff --git a/src/arch/dalvik/operands/args.c b/src/arch/dalvik/operands/args.c index 6e1725c..9e75604 100644 --- a/src/arch/dalvik/operands/args.c +++ b/src/arch/dalvik/operands/args.c @@ -24,13 +24,18 @@ #include "args.h" +#include <assert.h> #include <malloc.h> #include "../../operand-int.h" +#include "../../sharing/manager.h" +/* --------------------- MANIPULATION D'OPERANDES INDIVIDUELLES --------------------- */ + + /* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ struct _GDalvikArgsOperand { @@ -62,11 +67,33 @@ static void g_dalvik_args_operand_dispose(GDalvikArgsOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *); +/* Initialise un nouvel objet partagé avec des informations. */ +static bool g_dalvik_args_operand_do_init(GDalvikArgsOperand *, const GDalvikArgsOperand *); + +/* Indique l'objet partagé correspond à une description donnée. */ +static gboolean g_dalvik_args_operand_compare_info(const GDalvikArgsOperand *, const GDalvikArgsOperand *); + +/* Compare un opérande avec un autre. */ +static bool g_dalvik_args_operand_compare(const GDalvikArgsOperand *, const GDalvikArgsOperand *); + /* Traduit un opérande en version humainement lisible. */ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *, GBufferLine *, AsmSyntax); +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Gestionnaire des partages d'instances */ +static GShareManager *_dalvik_args_operand_manager = NULL; + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION D'OPERANDES INDIVIDUELLES */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ G_DEFINE_TYPE(GDalvikArgsOperand, g_dalvik_args_operand, G_TYPE_ARCH_OPERAND); @@ -94,6 +121,10 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_args_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_dalvik_args_operand_finalize; + operand->init = (init_shared_fc)g_dalvik_args_operand_do_init; + operand->cmp_info = (compare_shared_info_fc)g_dalvik_args_operand_compare_info; + + operand->compare = (operand_compare_fc)g_dalvik_args_operand_compare; operand->print = (operand_print_fc)g_dalvik_args_operand_print; } @@ -174,11 +205,107 @@ static void g_dalvik_args_operand_finalize(GDalvikArgsOperand *operand) GArchOperand *g_dalvik_args_operand_new(void) { - GDalvikArgsOperand *result; /* Structure à retourner */ + GArchOperand *result; /* Structure à retourner */ + + result = G_ARCH_OPERAND(g_share_manager_get(_dalvik_args_operand_manager, NULL)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet partagé à initialiser. * +* fake = coquille vide contenant les infos à enregistrer. * +* * +* Description : Initialise un nouvel objet partagé avec des informations. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dalvik_args_operand_do_init(GDalvikArgsOperand *operand, const GDalvikArgsOperand *fake) +{ + size_t i; /* Boucle de parcours */ + + if (fake == NULL) + { + operand->args = NULL; + operand->count = 0; + } + + else + { + operand->args = (GArchOperand **)calloc(fake->count, sizeof(GArchOperand *)); + + for (i = 0; i < fake->count; i++) + operand->args[i] = fake->args[i]; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet partagé à consulter. * +* fake = coquille vide contenant les infos à comparer. * +* * +* Description : Indique l'objet partagé correspond à une description donnée. * +* * +* Retour : TRUE si les détails centraux sont partagés, FALSE sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean g_dalvik_args_operand_compare_info(const GDalvikArgsOperand *operand, const GDalvikArgsOperand *fake) +{ + gboolean result; /* Bilan à retourner */ + + result = g_dalvik_args_operand_compare(operand, fake); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dalvik_args_operand_compare(const GDalvikArgsOperand *a, const GDalvikArgsOperand *b) +{ + bool result; /* Bilan à renvoyer */ + size_t i; /* Boucle de parcours */ + + if (b == NULL) + result = (a->count == 0); - result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); + else + { + result = (a->count == b->count); + + for (i = 0; i < a->count && result; i++) + result = g_arch_operand_compare(a->args[i], b->args[i]); + + } - return G_ARCH_OPERAND(result); + return result; } @@ -236,12 +363,25 @@ static void g_dalvik_args_operand_print(const GDalvikArgsOperand *operand, GBuff * * ******************************************************************************/ -void g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg) +GDalvikArgsOperand *g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg, GShareContainer *container) { - operand->args = (GArchOperand **)realloc(operand->args, - ++operand->count * sizeof(GArchOperand *)); + GSharedInstance *result; /* Nouvelle version à renvoyer */ + GDalvikArgsOperand fake; /* Transport d'informations */ + size_t i; /* Boucle de parcours */ + + fake.count = operand->count + 1; + fake.args = (GArchOperand **)calloc(fake.count, sizeof(GArchOperand *)); + + for (i = 0; i < operand->count; i++) + fake.args[i] = operand->args[i]; - operand->args[operand->count - 1] = arg; + fake.args[i] = arg; + + result = g_share_manager_update(_dalvik_args_operand_manager, G_SHARED_INSTANCE(operand), &fake, container); + + free(fake.args); + + return G_DALVIK_ARGS_OPERAND(result); } @@ -280,8 +420,74 @@ size_t g_dalvik_args_count(const GDalvikArgsOperand *operand) GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *operand, size_t index) { - /* BUG_ON(index >= operand->count) */ + assert(index < operand->count); return operand->args[index]; } + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTAGES DE CONTENUS UNIQUES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Met en place les mécanismes de partage des opérandes Dalvik. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_dalvik_args_operand_sharing(void) +{ + _dalvik_args_operand_manager = g_share_manager_new(G_TYPE_DALVIK_ARGS_OPERAND); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Imprime des statistiques quant aux partages dans l'archi. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_args_operand_share_stats(void) +{ + g_share_manager_dump_stats(_dalvik_args_operand_manager); + +} +#endif + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Supprime les mécanismes de partage des opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_dalvik_args_operand_sharing(void) +{ + g_object_unref(G_OBJECT(_dalvik_args_operand_manager)); + +} diff --git a/src/arch/dalvik/operands/args.h b/src/arch/dalvik/operands/args.h index 993e551..b4f5e69 100644 --- a/src/arch/dalvik/operands/args.h +++ b/src/arch/dalvik/operands/args.h @@ -29,9 +29,13 @@ #include "../../operand.h" +#include "../../sharing/container.h" +/* --------------------- MANIPULATION D'OPERANDES INDIVIDUELLES --------------------- */ + + #define G_TYPE_DALVIK_ARGS_OPERAND g_dalvik_args_operand_get_type() #define G_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_args_operand_get_type(), GDalvikArgsOperand)) #define G_IS_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_args_operand_get_type())) @@ -54,7 +58,7 @@ GType g_dalvik_args_operand_get_type(void); GArchOperand *g_dalvik_args_operand_new(void); /* Ajoute un élément à la liste d'arguments Dalvik. */ -void g_dalvik_args_operand_add(GDalvikArgsOperand *, GArchOperand *); +GDalvikArgsOperand *g_dalvik_args_operand_add(GDalvikArgsOperand *, GArchOperand *, GShareContainer *); /* Fournit le nombre d'arguments pris en charge. */ size_t g_dalvik_args_count(const GDalvikArgsOperand *); @@ -64,4 +68,20 @@ GArchOperand *g_dalvik_args_operand_get(const GDalvikArgsOperand *, size_t); +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Met en place les mécanismes de partage des opérandes Dalvik. */ +bool init_dalvik_args_operand_sharing(void); + +/* Imprime des statistiques quant aux partages dans l'archi. */ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_args_operand_share_stats(void); +#endif + +/* Supprime les mécanismes de partage des opérandes Dalvik. */ +void exit_dalvik_args_operand_sharing(void); + + + #endif /* _ARCH_DALVIK_OPERANDS_ARGS_H */ diff --git a/src/arch/dalvik/operands/pool.c b/src/arch/dalvik/operands/pool.c index e737a0b..4884867 100644 --- a/src/arch/dalvik/operands/pool.c +++ b/src/arch/dalvik/operands/pool.c @@ -32,10 +32,14 @@ #include "../../operand-int.h" +#include "../../sharing/manager.h" #include "../../../format/dex/pool.h" +/* --------------------- MANIPULATION D'OPERANDES INDIVIDUELLES --------------------- */ + + /* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ struct _GDalvikPoolOperand { @@ -68,11 +72,33 @@ static void g_dalvik_pool_operand_dispose(GDalvikPoolOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *); +/* Initialise un nouvel objet partagé avec des informations. */ +static bool g_dalvik_pool_operand_do_init(GDalvikPoolOperand *, const GDalvikPoolOperand *); + +/* Indique l'objet partagé correspond à une description donnée. */ +static gboolean g_dalvik_pool_operand_compare_info(const GDalvikPoolOperand *, const GDalvikPoolOperand *); + +/* Compare un opérande avec un autre. */ +static bool g_dalvik_pool_operand_compare(const GDalvikPoolOperand *, const GDalvikPoolOperand *); + /* Traduit un opérande en version humainement lisible. */ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *, GBufferLine *, AsmSyntax); +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Gestionnaire des partages d'instances */ +static GShareManager *_dalvik_pool_operand_manager = NULL; + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION D'OPERANDES INDIVIDUELLES */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini par la GLib pour un un élément de table de constantes Dalvik. */ G_DEFINE_TYPE(GDalvikPoolOperand, g_dalvik_pool_operand, G_TYPE_ARCH_OPERAND); @@ -95,11 +121,16 @@ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) GArchOperandClass *operand; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); - operand = G_ARCH_OPERAND_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_pool_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_dalvik_pool_operand_finalize; + operand = G_ARCH_OPERAND_CLASS(klass); + + operand->init = (init_shared_fc)g_dalvik_pool_operand_do_init; + operand->cmp_info = (compare_shared_info_fc)g_dalvik_pool_operand_compare_info; + + operand->compare = (operand_compare_fc)g_dalvik_pool_operand_compare; operand->print = (operand_print_fc)g_dalvik_pool_operand_print; } @@ -182,10 +213,13 @@ static void g_dalvik_pool_operand_finalize(GDalvikPoolOperand *operand) GArchOperand *g_dalvik_pool_operand_new(GDexFormat *format, DalvikPoolType type, const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian) { - GDalvikPoolOperand *result; /* Structure à retourner */ + GArchOperand *result; /* Structure à retourner */ uint8_t index8; /* Indice sur 8 bits */ uint16_t index16; /* Indice sur 16 bits */ bool test; /* Bilan de lecture */ + GDalvikPoolOperand fake; /* Transport d'informations */ + + result = NULL; switch (size) { @@ -201,17 +235,93 @@ GArchOperand *g_dalvik_pool_operand_new(GDexFormat *format, DalvikPoolType type, } if (!test) - return NULL; + goto gdpon_exit; + + fake.format = format; + fake.type = type; + fake.index = (size == MDS_8_BITS ? index8 : index16); + + result = G_ARCH_OPERAND(g_share_manager_get(_dalvik_pool_operand_manager, &fake)); + + gdpon_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet partagé à initialiser. * +* fake = coquille vide contenant les infos à enregistrer. * +* * +* Description : Initialise un nouvel objet partagé avec des informations. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dalvik_pool_operand_do_init(GDalvikPoolOperand *operand, const GDalvikPoolOperand *fake) +{ + operand->format = fake->format; + g_object_ref(G_OBJECT(fake->format)); + + operand->type = fake->type; + operand->index = fake->index; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet partagé à consulter. * +* fake = coquille vide contenant les infos à comparer. * +* * +* Description : Indique l'objet partagé correspond à une description donnée. * +* * +* Retour : TRUE si les détails centraux sont partagés, FALSE sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean g_dalvik_pool_operand_compare_info(const GDalvikPoolOperand *operand, const GDalvikPoolOperand *fake) +{ + gboolean result; /* Bilan à retourner */ + + result = g_dalvik_pool_operand_compare(operand, fake); + + return result; + +} + - result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ - g_object_ref(G_OBJECT(format)); +static bool g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDalvikPoolOperand *b) +{ + bool result; /* Bilan à renvoyer */ - result->format = format; - result->type = type; - result->index = (size == MDS_8_BITS ? index8 : index16); + result = (a->format == b->format); + result &= (a->type == b->type); + result &= (a->index == b->index); - return G_ARCH_OPERAND(result); + return result; } @@ -413,3 +523,69 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand) return operand->index; } + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTAGES DE CONTENUS UNIQUES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Met en place les mécanismes de partage des opérandes Dalvik. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_dalvik_pool_operand_sharing(void) +{ + _dalvik_pool_operand_manager = g_share_manager_new(G_TYPE_DALVIK_POOL_OPERAND); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Imprime des statistiques quant aux partages dans l'archi. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_pool_operand_share_stats(void) +{ + g_share_manager_dump_stats(_dalvik_pool_operand_manager); + +} +#endif + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Supprime les mécanismes de partage des opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_dalvik_pool_operand_sharing(void) +{ + g_object_unref(G_OBJECT(_dalvik_pool_operand_manager)); + +} diff --git a/src/arch/dalvik/operands/pool.h b/src/arch/dalvik/operands/pool.h index 8223d1c..98d2d41 100644 --- a/src/arch/dalvik/operands/pool.h +++ b/src/arch/dalvik/operands/pool.h @@ -35,12 +35,15 @@ -#define G_TYPE_DALVIK_POOL_OPERAND g_dalvik_pool_operand_get_type() -#define G_DALVIK_POOL_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_pool_operand_get_type(), GDalvikPoolOperand)) -#define G_IS_DALVIK_POOL_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_pool_operand_get_type())) -#define G_DALVIK_POOL_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_POOL_OPERAND, GDalvikPoolOperandClass)) -#define G_IS_DALVIK_POOL_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_POOL_OPERAND)) -#define G_DALVIK_POOL_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_POOL_OPERAND, GDalvikPoolOperandClass)) +/* --------------------- MANIPULATION D'OPERANDES INDIVIDUELLES --------------------- */ + + +#define G_TYPE_DALVIK_POOL_OPERAND g_dalvik_pool_operand_get_type() +#define G_DALVIK_POOL_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DALVIK_POOL_OPERAND, GDalvikPoolOperand)) +#define G_IS_DALVIK_POOL_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DALVIK_POOL_OPERAND)) +#define G_DALVIK_POOL_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_POOL_OPERAND, GDalvikPoolOperandClass)) +#define G_IS_DALVIK_POOL_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_POOL_OPERAND)) +#define G_DALVIK_POOL_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_POOL_OPERAND, GDalvikPoolOperandClass)) /* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ @@ -77,4 +80,20 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *); +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Met en place les mécanismes de partage des opérandes Dalvik. */ +bool init_dalvik_pool_operand_sharing(void); + +/* Imprime des statistiques quant aux partages dans l'archi. */ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_pool_operand_share_stats(void); +#endif + +/* Supprime les mécanismes de partage des opérandes Dalvik. */ +void exit_dalvik_pool_operand_sharing(void); + + + #endif /* _ARCH_DALVIK_OPERANDS_POOL_H */ diff --git a/src/arch/dalvik/operands/register.c b/src/arch/dalvik/operands/register.c index 1fc5782..dcdcbac 100644 --- a/src/arch/dalvik/operands/register.c +++ b/src/arch/dalvik/operands/register.c @@ -26,15 +26,19 @@ #include "../../operand-int.h" #include "../../register.h" +#include "../../sharing/manager.h" +/* --------------------- MANIPULATION D'OPERANDES INDIVIDUELLES --------------------- */ + + /* Définition d'un opérande visant un registre Dalvik (instance) */ struct _GDalvikRegisterOperand { GArchOperand parent; /* Instance parente */ - GDalvikRegister *reg; /* Registre représenté */ + const GDalvikRegister *reg; /* Registre représenté */ bool is_written; /* Changement de contenu */ }; @@ -60,6 +64,12 @@ static void g_dalvik_register_operand_dispose(GDalvikRegisterOperand *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_register_operand_finalize(GDalvikRegisterOperand *); +/* Initialise un nouvel objet partagé avec des informations. */ +static bool g_dalvik_register_operand_do_init(GDalvikRegisterOperand *, const GDalvikRegister *); + +/* Indique l'objet partagé correspond à une description donnée. */ +static gboolean g_dalvik_register_operand_compare_info(const GDalvikRegisterOperand *, const GDalvikRegister *); + /* Compare un opérande avec un autre. */ static bool g_dalvik_register_operand_compare(const GDalvikRegisterOperand *, const GDalvikRegisterOperand *); @@ -68,6 +78,19 @@ static void g_dalvik_register_operand_print(const GDalvikRegisterOperand *, GBuf +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Gestionnaire des partages d'instances */ +static GShareManager *_dalvik_register_operand_manager = NULL; + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION D'OPERANDES INDIVIDUELLES */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ G_DEFINE_TYPE(GDalvikRegisterOperand, g_dalvik_register_operand, G_TYPE_ARCH_OPERAND); @@ -90,11 +113,15 @@ static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *kl GArchOperandClass *operand; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); - operand = G_ARCH_OPERAND_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_register_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_dalvik_register_operand_finalize; + operand = G_ARCH_OPERAND_CLASS(klass); + + operand->init = (init_shared_fc)g_dalvik_register_operand_do_init; + operand->cmp_info = (compare_shared_info_fc)g_dalvik_register_operand_compare_info; + operand->compare = (operand_compare_fc)g_dalvik_register_operand_compare; operand->print = (operand_print_fc)g_dalvik_register_operand_print; @@ -122,7 +149,7 @@ static void g_dalvik_register_operand_init(GDalvikRegisterOperand *operand) /****************************************************************************** * * -* Paramètres : binary = instance d'objet GLib à traiter. * +* Paramètres : operand = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * @@ -141,7 +168,7 @@ static void g_dalvik_register_operand_dispose(GDalvikRegisterOperand *operand) /****************************************************************************** * * -* Paramètres : binary = instance d'objet GLib à traiter. * +* Paramètres : operand = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * @@ -176,10 +203,13 @@ static void g_dalvik_register_operand_finalize(GDalvikRegisterOperand *operand) GArchOperand *g_dalvik_register_operand_new(const GBinContent *content, vmpa2t *pos, bool *low, MemoryDataSize size, SourceEndian endian) { - GDalvikRegisterOperand *result; /* Structure à retourner */ + GArchOperand *result; /* Structure à retourner */ uint8_t index8; /* Indice sur 8 bits */ uint16_t index16; /* Indice sur 16 bits */ bool test; /* Bilan de lecture */ + GDalvikRegister *reg; /* Registre à représenter */ + + result = NULL; switch (size) { @@ -198,24 +228,34 @@ GArchOperand *g_dalvik_register_operand_new(const GBinContent *content, vmpa2t * } if (!test) - return NULL; - - result = g_object_new(G_TYPE_DALVIK_REGISTER_OPERAND, NULL); + goto gdron_exit; switch (size) { case MDS_4_BITS: case MDS_8_BITS: - result->reg = g_dalvik_register_new(index8); + reg = g_dalvik_register_new(index8); break; case MDS_16_BITS: - result->reg = g_dalvik_register_new(index16); + reg = g_dalvik_register_new(index16); break; default: + reg = NULL; break; } - return G_ARCH_OPERAND(result); + if (reg != NULL) + { + result = g_dalvik_register_operand_new_from_existing(reg); + + if (result == NULL) + g_object_unref(G_OBJECT(reg)); + + } + + gdron_exit: + + return result; } @@ -234,32 +274,57 @@ GArchOperand *g_dalvik_register_operand_new(const GBinContent *content, vmpa2t * GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *reg) { - GDalvikRegisterOperand *result; /* Structure à retourner */ + GArchOperand *result; /* Structure à retourner */ + + result = G_ARCH_OPERAND(g_share_manager_get(_dalvik_register_operand_manager, reg)); + + return result; + +} - result = g_object_new(G_TYPE_DALVIK_REGISTER_OPERAND, NULL); - result->reg = reg; +/****************************************************************************** +* * +* Paramètres : operand = objet partagé à initialiser. * +* reg = registre Dalvik à associer à l'opérande. * +* * +* Description : Initialise un nouvel objet partagé avec des informations. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dalvik_register_operand_do_init(GDalvikRegisterOperand *operand, const GDalvikRegister *reg) +{ + operand->reg = reg; - return G_ARCH_OPERAND(result); + return true; } /****************************************************************************** * * -* Paramètres : operand = opérande représentant un registre. * +* Paramètres : operand = objet partagé à consulter. * +* reg = registre Dalvik utilisé comme description. * * * -* Description : Fournit le registre Dalvik associé à l'opérande. * +* Description : Indique l'objet partagé correspond à une description donnée. * * * -* Retour : Représentation interne du registre. * +* Retour : TRUE si les détails centraux sont partagés, FALSE sinon. * * * * Remarques : - * * * ******************************************************************************/ -GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *operand) +static gboolean g_dalvik_register_operand_compare_info(const GDalvikRegisterOperand *operand, const GDalvikRegister *reg) { - return operand->reg; + gboolean result; /* Bilan à retourner */ + + result = g_arch_register_equal(G_ARCH_REGISTER(operand->reg), G_ARCH_REGISTER(reg)); + + return result; } @@ -307,6 +372,25 @@ static void g_dalvik_register_operand_print(const GDalvikRegisterOperand *operan /****************************************************************************** * * +* Paramètres : operand = opérande représentant un registre. * +* * +* Description : Fournit le registre Dalvik associé à l'opérande. * +* * +* Retour : Représentation interne du registre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *operand) +{ + return operand->reg; + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande représentant un registre à mettre à jour. * * * * Description : Marque l'opérande comme étant écrit plutôt que consulté. * @@ -341,3 +425,69 @@ bool g_dalvik_register_operand_is_written(const GDalvikRegisterOperand *operand) return operand->is_written; } + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTAGES DE CONTENUS UNIQUES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Met en place les mécanismes de partage des opérandes Dalvik. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_dalvik_register_operand_sharing(void) +{ + _dalvik_register_operand_manager = g_share_manager_new(G_TYPE_DALVIK_REGISTER_OPERAND); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Imprime des statistiques quant aux partages dans l'archi. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_register_operand_share_stats(void) +{ + g_share_manager_dump_stats(_dalvik_register_operand_manager); + +} +#endif + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Supprime les mécanismes de partage des opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_dalvik_register_operand_sharing(void) +{ + g_object_unref(G_OBJECT(_dalvik_register_operand_manager)); + +} diff --git a/src/arch/dalvik/operands/register.h b/src/arch/dalvik/operands/register.h index e8f28d1..9c6c61b 100644 --- a/src/arch/dalvik/operands/register.h +++ b/src/arch/dalvik/operands/register.h @@ -26,6 +26,7 @@ #include <glib-object.h> +#include <stdbool.h> #include "../register.h" @@ -34,12 +35,15 @@ -#define G_TYPE_DALVIK_REGISTER_OPERAND g_dalvik_register_operand_get_type() -#define G_DALVIK_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_register_operand_get_type(), GDalvikRegisterOperand)) -#define G_IS_DALVIK_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_register_operand_get_type())) -#define G_DALVIK_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_REGISTER_OPERAND, GDalvikRegisterOperandClass)) -#define G_IS_DALVIK_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_REGISTER_OPERAND)) -#define G_DALVIK_REGISTER_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_REGISTER_OPERAND, GDalvikRegisterOperandClass)) +/* --------------------- MANIPULATION D'OPERANDES INDIVIDUELLES --------------------- */ + + +#define G_TYPE_DALVIK_REGISTER_OPERAND g_dalvik_register_operand_get_type() +#define G_DALVIK_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DALVIK_REGISTER_OPERAND, GDalvikRegisterOperand)) +#define G_IS_DALVIK_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DALVIK_REGISTER_OPERAND)) +#define G_DALVIK_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_REGISTER_OPERAND, GDalvikRegisterOperandClass)) +#define G_IS_DALVIK_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_REGISTER_OPERAND)) +#define G_DALVIK_REGISTER_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_REGISTER_OPERAND, GDalvikRegisterOperandClass)) /* Définition d'un opérande visant un registre Dalvik (instance) */ @@ -59,7 +63,7 @@ GArchOperand *g_dalvik_register_operand_new(const GBinContent *, vmpa2t *, bool GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *); /* Fournit le registre Dalvik associé à l'opérande. */ -GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *); +const GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *); /* Marque l'opérande comme étant écrit plutôt que consulté. */ void g_dalvik_register_operand_mark_as_written(GDalvikRegisterOperand *); @@ -69,4 +73,20 @@ bool g_dalvik_register_operand_is_written(const GDalvikRegisterOperand *); +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Met en place les mécanismes de partage des opérandes Dalvik. */ +bool init_dalvik_register_operand_sharing(void); + +/* Imprime des statistiques quant aux partages dans l'archi. */ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_register_operand_share_stats(void); +#endif + +/* Supprime les mécanismes de partage des opérandes Dalvik. */ +void exit_dalvik_register_operand_sharing(void); + + + #endif /* _ARCH_DALVIK_OPERANDS_REGISTER_H */ diff --git a/src/arch/dalvik/register.c b/src/arch/dalvik/register.c index d112a86..d455eb2 100644 --- a/src/arch/dalvik/register.c +++ b/src/arch/dalvik/register.c @@ -62,6 +62,12 @@ static void g_dalvik_register_class_init(GDalvikRegisterClass *); /* Initialise une instance de registre Dalvik. */ static void g_dalvik_register_init(GDalvikRegister *); +/* Supprime toutes les références externes. */ +static void g_dalvik_register_dispose(GDalvikRegister *); + +/* Procède à la libération totale de la mémoire. */ +static void g_dalvik_register_finalize(GDalvikRegister *); + /* Initialise un nouvel objet partagé avec des informations. */ static bool g_dalvik_register_do_init(GDalvikRegister *, const uint16_t *); @@ -110,8 +116,14 @@ G_DEFINE_TYPE(GDalvikRegister, g_dalvik_register, G_TYPE_ARCH_REGISTER); static void g_dalvik_register_class_init(GDalvikRegisterClass *klass) { + GObjectClass *object; /* Autre version de la classe */ GArchRegisterClass *register_class; /* Classe de haut niveau */ + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_register_dispose; + object->finalize = (GObjectFinalizeFunc)g_dalvik_register_finalize; + register_class = G_ARCH_REGISTER_CLASS(klass); register_class->init = (init_shared_fc)g_dalvik_register_do_init; @@ -144,6 +156,44 @@ static void g_dalvik_register_init(GDalvikRegister *reg) /****************************************************************************** * * +* Paramètres : reg = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_dispose(GDalvikRegister *reg) +{ + G_OBJECT_CLASS(g_dalvik_register_parent_class)->dispose(G_OBJECT(reg)); + +} + + +/****************************************************************************** +* * +* Paramètres : reg = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_finalize(GDalvikRegister *reg) +{ + G_OBJECT_CLASS(g_dalvik_register_parent_class)->finalize(G_OBJECT(reg)); + +} + + +/****************************************************************************** +* * * Paramètres : index = indice du registre correspondant. * * * * Description : Crée une réprésentation de registre Dalvik. * @@ -160,10 +210,6 @@ GDalvikRegister *g_dalvik_register_new(uint16_t index) result = G_DALVIK_REGISTER(g_share_manager_get(_dalvik_register_manager, &index)); - //result = g_object_new(G_TYPE_DALVIK_REGISTER, NULL); - - //result->index = index; - return result; } @@ -198,7 +244,7 @@ static bool g_dalvik_register_do_init(GDalvikRegister *reg, const uint16_t *inde * * * Description : Indique l'objet partagé correspond à une description donnée. * * * -* Retour : true si les détails centraux sont partagés, false sinon. * +* Retour : TRUE si les détails centraux sont partagés, FALSE sinon. * * * * Remarques : - * * * @@ -206,7 +252,7 @@ static bool g_dalvik_register_do_init(GDalvikRegister *reg, const uint16_t *inde static gboolean g_dalvik_register_compare_info(const GDalvikRegister *reg, const uint16_t *index) { - bool result; /* Bilan à retourner */ + gboolean result; /* Bilan à retourner */ result = (reg->index == *index); @@ -355,18 +401,36 @@ bool init_dalvik_register_sharing(void) * * * Paramètres : - * * * -* Description : Supprime les mécanismes de partage des registres Dalvik. * +* Description : Imprime des statistiques quant aux partages dans l'archi. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ - -void exit_dalvik_register_sharing(void) +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_register_share_stats(void) { + g_share_manager_dump_stats(_dalvik_register_manager); +} +#endif +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Supprime les mécanismes de partage des registres Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_dalvik_register_sharing(void) +{ + g_object_unref(G_OBJECT(_dalvik_register_manager)); } diff --git a/src/arch/dalvik/register.h b/src/arch/dalvik/register.h index ab7368f..03faf76 100644 --- a/src/arch/dalvik/register.h +++ b/src/arch/dalvik/register.h @@ -69,6 +69,11 @@ uint16_t g_dalvik_register_get_index(const GDalvikRegister *); /* Met en place les mécanismes de partage des registres Dalvik. */ bool init_dalvik_register_sharing(void); +/* Imprime des statistiques quant aux partages dans l'archi. */ +#ifdef DEBUG_DUMP_STATS +void dump_dalvik_register_share_stats(void); +#endif + /* Supprime les mécanismes de partage des registres Dalvik. */ void exit_dalvik_register_sharing(void); |