diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-07-23 07:45:44 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-07-23 07:45:44 (GMT) |
commit | 53213051036151645ae287436ad94dff92c7fa20 (patch) | |
tree | 874679c64017fcc7eafa8c5af447c9e15fcbaa5d /plugins/dex/pool.c | |
parent | e335c19df11cf013c8e515105ca2a13afa2b97de (diff) |
Changed the way Dex methods are loaded and displayed.
Diffstat (limited to 'plugins/dex/pool.c')
-rw-r--r-- | plugins/dex/pool.c | 122 |
1 files changed, 102 insertions, 20 deletions
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c index 8a421b2..75841df 100644 --- a/plugins/dex/pool.c +++ b/plugins/dex/pool.c @@ -711,6 +711,93 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) /****************************************************************************** * * +* Paramètres : format = représentation interne du format DEX à compléter. * +* gid = groupe de travail impliqué. * + status = barre de statut à tenir informée. * +* * +* Description : Charge toutes les classes listées dans le contenu binaire. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + bool result; /* Bilan à retourner */ + guint runs_count; /* Qté d'exécutions parallèles */ + 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 */ + 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*/ + + /** + * Il existe deux voies pour récupérer une méthode : + * + * - depuis 'method_id_item', qui précise classe d'appartenance, prototype + * et nom. + * + * - depuis 'encoded_method', qui contient une définition 'method_id_item', + * ainsi que des attributs propres à la méthode visée. + * + * Techniquement, il peut donc y avoir plusieurs variations d'un même + * 'method_id_item' selon différents 'encoded_method'. + * + * Dans la pratique, c'est hautement improbable : une méthode ne peut pas + * être privée et publique par exemple, ou renvoyer vers différents code. + * + * Donc on se permet d'associer une unique méthode par 'method_id_item', + * et de précharger le tout. + */ + + result = true; + + /* Préparation du réceptacle */ + + format->methods = (GDexMethod **)calloc(format->header.method_ids_size, sizeof(GDexMethod *)); + + /* Lancement des chargements */ + + runs_count = get_max_online_threads(); + + run_size = format->header.method_ids_size / runs_count; + + queue = get_work_queue(); + + msg = gtk_status_stack_add_activity(status, _("Loading all methods from the Dex pool..."), + format->header.method_ids_size); + + for (i = 0; i < runs_count; i++) + { + begin = i * run_size; + + if ((i + 1) == runs_count) + end = format->header.method_ids_size; + else + end = begin + run_size; + + loading = g_dex_loading_new(format, begin, end, msg, + (dex_loading_cb)get_method_from_dex_pool, &result); + + g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); + + } + + g_work_queue_wait_for_completion(queue, gid); + + gtk_status_stack_remove_activity(status, msg); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = représentation interne du format DEX à consulter. * * * * Description : Compte le nombre de méthodes dans une table DEX. * @@ -735,7 +822,7 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format) /****************************************************************************** * * * Paramètres : format = représentation interne du format DEX à consulter. * -* index = index de la classe recherchée. * +* index = index de la méthode recherchée. * * * * Description : Extrait une représentation de méthode d'une table DEX. * * * @@ -748,36 +835,31 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format) GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index) { GDexMethod *result; /* Instance à retourner */ - uint32_t count; /* Nombre d'éléments présents */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ method_id_item method_id; /* Définition de la méthode */ result = NULL; - count = count_methods_in_dex_pool(format); - - if (index >= count) + if (index >= format->header.method_ids_size) goto gmfdp_error; - /** - * On charge ici une méthode à partir de la définition de 'method_id_item'. - * - * C'est l'élément 'encoded_method' qui référence cette cette définition et qui - * applique ensuite les attributs finaux de la méthode. La classe parente est - * précisée en outre bien en amont. - * - * Comme une même définition peut donc servir à plusieurs instances, - * on ne peut pas conserver un tableau d'allocations communes. - */ + if (format->methods[index] == NULL) + { + pos = format->header.method_ids_off + index * sizeof(method_id_item); + init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); - pos = format->header.method_ids_off + index * sizeof(method_id_item); - init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); + if (!read_dex_method_id_item(format, &addr, &method_id)) + goto gmfdp_error; - if (!read_dex_method_id_item(format, &addr, &method_id)) - goto gmfdp_error; + format->methods[index] = g_dex_method_new_callable(format, &method_id); - result = g_dex_method_new_callable(format, &method_id); + } + + result = format->methods[index]; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); gmfdp_error: |