diff options
Diffstat (limited to 'plugins/dex')
-rw-r--r-- | plugins/dex/class.c | 143 | ||||
-rw-r--r-- | plugins/dex/class.h | 4 | ||||
-rw-r--r-- | plugins/dex/pool.c | 45 |
3 files changed, 134 insertions, 58 deletions
diff --git a/plugins/dex/class.c b/plugins/dex/class.c index dafa984..d549014 100644 --- a/plugins/dex/class.c +++ b/plugins/dex/class.c @@ -222,11 +222,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) uleb128_t index; /* Conservation du dernier id */ uleb128_t i; /* Boucle de parcours */ GDexField *field; /* Champ chargé */ - GDexPool *pool; /* Table de ressources */ - GDataType *ctype; /* Type créé par la classe */ - GBinFormat *base; /* Autre version du format */ GDexMethod *method; /* Méthode chargée */ - GBinRoutine *routine; /* Version interne de méthode */ result = g_object_new(G_TYPE_DEX_CLASS, NULL); @@ -292,16 +288,6 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) * Chargement des méthodes de classe. */ - pool = g_dex_format_get_pool(format); - - ctype = g_dex_pool_get_type_(pool, def->class_idx); - - g_object_unref(G_OBJECT(pool)); - - if (ctype == NULL) goto gdcn_unknown_type; - - base = G_BIN_FORMAT(format); - index = 0; result->dmethods_count = data.direct_methods_size; @@ -314,18 +300,6 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) result->direct_methods[i] = method; - /* Ajout à la liste des symboles */ - if (g_dex_method_has_dex_body(method)) - { - routine = g_dex_method_get_routine(method); - - g_object_ref(G_OBJECT(ctype)); - g_binary_routine_set_namespace(routine, ctype, strdup(".")); - - g_binary_format_add_symbol(base, G_BIN_SYMBOL(routine)); - - } - } index = 0; @@ -340,32 +314,14 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) result->virtual_methods[i] = method; - /* Ajout à la liste des symboles */ - if (g_dex_method_has_dex_body(method)) - { - routine = g_dex_method_get_routine(method); - - g_object_ref(G_OBJECT(ctype)); - g_binary_routine_set_namespace(routine, ctype, strdup(".")); - - g_binary_format_add_symbol(base, G_BIN_SYMBOL(routine)); - - } - } - g_object_unref(G_OBJECT(ctype)); - gdcn_done: return result; gdcn_bad_method: - g_object_unref(G_OBJECT(ctype)); - - gdcn_unknown_type: - gdcn_bad_field: gdcn_bad_item: @@ -379,7 +335,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) /****************************************************************************** * * -* Paramètres : class = informations chargées à consulter. * +* Paramètres : class = informations chargées à consulter. * * * * Description : Fournit la définition brute d'une classe. * * * @@ -398,7 +354,7 @@ const class_def_item *g_dex_class_get_definition(const GDexClass *class) /****************************************************************************** * * -* Paramètres : class = informations chargées à consulter. * +* Paramètres : class = informations chargées à consulter. * * * * Description : Fournit la définition brute des données d'une classe. * * * @@ -660,6 +616,101 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t /****************************************************************************** * * +* Paramètres : class = informations chargées à consulter. * +* symbols = liste de symboles complétée. [OUT] * +* count = taille de cette liste. [OUT] * +* * +* Description : Etablit une liste de tous les symboles d'une classe. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dex_class_get_collect_symbols(const GDexClass *class, GBinSymbol ***symbols, size_t *count) +{ + bool result; /* Bilan à retourner */ + GDexPool *pool; /* Table de ressources */ + GDataType *ctype; /* Type créé par la classe */ + size_t slots_used; /* Compteur d'utilisations */ + size_t i; /* Boucle de parcours */ + GDexMethod *method; /* Méthode chargée */ + GBinRoutine *routine; /* Version interne de méthode */ + + result = false; + + /* Contexte des méthodes */ + + pool = g_dex_format_get_pool(class->format); + + ctype = g_dex_pool_get_type_(pool, class->definition.class_idx); + + g_object_unref(G_OBJECT(pool)); + + if (ctype == NULL) goto unknown_type; + + /* Intégration des méthodes */ + + *symbols = realloc(*symbols, (*count + class->dmethods_count + class->vmethods_count) * sizeof(GBinSymbol *)); + + result = true; + + slots_used = 0; + + for (i = 0; i < class->dmethods_count; i++) + { + method = class->direct_methods[i]; + + if (g_dex_method_has_dex_body(method)) + { + routine = g_dex_method_get_routine(method); + + g_object_ref(G_OBJECT(ctype)); + g_binary_routine_set_namespace(routine, ctype, strdup(".")); + + (*symbols)[*count + slots_used] = G_BIN_SYMBOL(routine); + slots_used++; + + } + + } + + *count += slots_used; + + slots_used = 0; + + for (i = 0; i < class->vmethods_count; i++) + { + method = class->virtual_methods[i]; + + if (g_dex_method_has_dex_body(method)) + { + routine = g_dex_method_get_routine(method); + + g_object_ref(G_OBJECT(ctype)); + g_binary_routine_set_namespace(routine, ctype, strdup(".")); + + (*symbols)[*count + slots_used] = G_BIN_SYMBOL(routine); + slots_used++; + + } + + } + + *count += slots_used; + + g_object_unref(G_OBJECT(ctype)); + + unknown_type: + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : class = informations chargées à consulter. * * format = format permettant d'obtenir une adresse complète. * * * diff --git a/plugins/dex/class.h b/plugins/dex/class.h index cae4a5a..a7874a7 100644 --- a/plugins/dex/class.h +++ b/plugins/dex/class.h @@ -50,7 +50,6 @@ typedef struct _GDexClass GDexClass; typedef struct _GDexClassClass GDexClassClass; - /* Détermine le type d'une classe issue du code source. */ GType g_dex_class_get_type(void); @@ -84,6 +83,9 @@ size_t g_dex_class_count_methods(const GDexClass *, bool); /* Fournit une méthode chargée correspondant à un type donné. */ GDexMethod *g_dex_class_get_method(const GDexClass *, bool, size_t); +/* Etablit une liste de tous les symboles d'une classe. */ +bool g_dex_class_get_collect_symbols(const GDexClass *, GBinSymbol ***, size_t *); + /* Intègre la méthode en tant que portion de code. */ void g_dex_class_include_as_portion(const GDexClass *, GExeFormat *); diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c index c24617a..d800e8f 100644 --- a/plugins/dex/pool.c +++ b/plugins/dex/pool.c @@ -251,6 +251,11 @@ bool g_dex_pool_load_all_string_symbols(GDexPool *pool, wgroup_id_t gid, GtkStat gtk_status_stack_remove_activity(status, msg); + /* Insertion en tant que symboles */ + + if (result) + result = g_binary_format_add_symbols(G_BIN_FORMAT(pool->format), pool->strings, count); + return result; } @@ -367,7 +372,6 @@ GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *pool, uint32_t index) const char *string; /* Chaîne de caractères liée */ GBinFormat *base; /* Autre version du format */ GBinSymbol *new; /* Nouveau symbol créé */ - bool inserted; /* Bilan d'une insertion */ result = NULL; @@ -385,16 +389,10 @@ GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *pool, uint32_t index) new = g_string_symbol_new_read_only(base, &range, SET_MUTF_8); - g_string_symbol_build_label(G_STR_SYMBOL(new), base); - - g_object_ref(G_OBJECT(new)); - inserted = g_binary_format_add_symbol(base, new); - - if (inserted) - pool->strings[index] = new; + if (new != NULL) + g_string_symbol_build_label(G_STR_SYMBOL(new), base); - else - g_object_unref(G_OBJECT(new)); + pool->strings[index] = new; } @@ -1175,10 +1173,14 @@ bool g_dex_pool_load_all_classes(GDexPool *pool, wgroup_id_t gid, GtkStatusStack uint32_t run_size; /* Volume réparti par exécution*/ GWorkQueue *queue; /* Gestionnaire de différés */ activity_id_t msg; /* Message de progression */ - guint i; /* Boucle de parcours */ + guint i; /* Boucle de parcours #1 */ uint32_t begin; /* Début de bloc de traitement */ uint32_t end; /* Fin d'un bloc de traitement */ GDexLoading *loading; /* Tâche de chargement à lancer*/ + GBinSymbol **symbols; /* Symboles présents à injecter*/ + size_t scount; /* Quantité de ces symboles */ + uint32_t j; /* Boucle de parcours #2 */ + size_t k; /* Boucle de parcours #3 */ result = true; @@ -1216,6 +1218,27 @@ bool g_dex_pool_load_all_classes(GDexPool *pool, wgroup_id_t gid, GtkStatusStack gtk_status_stack_remove_activity(status, msg); + /* Insertion en tant que symboles */ + + if (result) + { + symbols = NULL; + scount = 0; + + for (j = 0; j < count && result; j++) + result = g_dex_class_get_collect_symbols(pool->classes[j], &symbols, &scount); + + if (result) + result = g_binary_format_add_symbols(G_BIN_FORMAT(pool->format), symbols, count); + + for (k = 0; k < scount; k++) + g_object_unref(symbols[k]); + + if (symbols != NULL) + free(symbols); + + } + return result; } |