From 1c0e64604b6c49c413f1be02b40071820007c774 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 24 Jun 2018 22:08:13 +0200
Subject: Used more threads to disassemble binary areas.

---
 src/analysis/disass/area.c  | 214 ++++++++++++++++++++++++++++++++++----------
 src/analysis/disass/area.h  |   6 +-
 src/analysis/disass/fetch.c |  12 +--
 3 files changed, 173 insertions(+), 59 deletions(-)

diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 7050c9c..65024b2 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -99,13 +99,13 @@ static GArchInstruction *load_raw_instruction_from_mem_area(mem_area *, phys_t,
 static void update_address_as_routine(GBinFormat *, const vmpa2t *);
 
 /* Procède au désassemblage d'un contenu binaire non exécutable. */
-static void load_data_from_mem_area(mem_area *, GProcContext *, const vmpa2t *, GtkStatusStack *, activity_id_t);
+static void load_data_from_mem_area(mem_area *, const vmpa2t *, GtkStatusStack *, activity_id_t);
 
 /* S'assure qu'une aire contient toutes ses instructions. */
 static void fill_mem_area_with_code(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
 
 /* S'assure qu'une aire contient toutes ses instructions. */
-static void fill_mem_area_with_data(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
+static void fill_mem_area_with_data(mem_area *, mem_area *, size_t, GtkStatusStack *, activity_id_t);
 
 /* Rassemble les instructions conservées dans une zone donnée. */
 static GArchInstruction **get_instructions_from_mem_area(const mem_area *, GArchInstruction **, size_t *);
@@ -173,6 +173,17 @@ typedef struct _GAreaCollector
 
         struct
         {
+            size_t count;                   /* Nombre de zones présentes   */
+
+            GProcContext *ctx;              /* Contexte de désassemblage   */
+
+            size_t fill_start;              /* Première zone à remplir     */
+            size_t fill_stop;               /* Première zone à écarter     */
+
+        };
+
+        struct
+        {
             size_t begin;                   /* Début du parcours à mener   */
             size_t end;                     /* Fin de ce même parcours     */
 
@@ -223,6 +234,12 @@ static GAreaCollector *g_area_collector_new_insert(activity_id_t, mem_area *, si
 /* Insère dans les zones contigües les instructions préchargées. */
 static void g_area_collector_do_insert(GAreaCollector *, GtkStatusStack *);
 
+/* Crée une tâche de fin de désassemblage pour zones binaires. */
+static GAreaCollector *g_area_collector_new_filling(activity_id_t, mem_area *, size_t, GProcContext *, size_t, size_t);
+
+/* Remplit de code ou de données une série de zones. */
+static void g_area_collector_do_fill(GAreaCollector *, GtkStatusStack *);
+
 /* Crée une tâche de récupération d'instructions différée. */
 static GAreaCollector *g_area_collector_new_outro(activity_id_t, mem_area *, size_t, size_t);
 
@@ -803,7 +820,6 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : area   = aire représentant à contenu à parcourir.            *
-*                ctx    = contexte offert en soutien à un désassemblage.      *
 *                start  = démarrage de l'exécution au sein de la zone.        *
 *                status = barre de statut à actualiser.                       *
 *                id     = identifiant du groupe de progression à l'affichage. *
@@ -816,7 +832,7 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
 *                                                                             *
 ******************************************************************************/
 
-static void load_data_from_mem_area(mem_area *area, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
+static void load_data_from_mem_area(mem_area *area, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
 {
     phys_t diff;                            /* Volume de données traité    */
     phys_t alen;                            /* Taille de l'aire utilisée   */
@@ -935,8 +951,6 @@ static void fill_mem_area_with_code(mem_area *area, mem_area *list, size_t count
 *  Paramètres  : area   = aire représentant à contenu à parcourir.            *
 *                list   = liste de zones délimitant des contenus à traiter.   *
 *                count  = nombre de zones à disposition.                      *
-*                binary = représentation de binaire chargé.                   *
-*                ctx    = contexte offert en soutien à un désassemblage.      *
 *                status = barre de statut à actualiser.                       *
 *                id     = identifiant du groupe de progression à l'affichage. *
 *                                                                             *
@@ -948,7 +962,7 @@ static void fill_mem_area_with_code(mem_area *area, mem_area *list, size_t count
 *                                                                             *
 ******************************************************************************/
 
-static void fill_mem_area_with_data(mem_area *area, mem_area *list, size_t count, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
+static void fill_mem_area_with_data(mem_area *area, mem_area *list, size_t count, GtkStatusStack *status, activity_id_t id)
 {
     const vmpa2t *addr;                     /* Début de la zone à traiter  */
     phys_t len;                             /* Taille de la zone à remplir */
@@ -977,7 +991,7 @@ static void fill_mem_area_with_data(mem_area *area, mem_area *list, size_t count
 
             }
 
-            load_data_from_mem_area(area, ctx, &start, status, id);
+            load_data_from_mem_area(area, &start, status, id);
 
         }
 
@@ -1524,38 +1538,6 @@ static void insert_instr_into_mem_areas_forced(mem_area *areas, size_t count, GA
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : areas  = liste de zones délimitant des contenus à traiter.   *
-*                count  = nombre de zones à disposition.                      *
-*                code   = nature des instructions à utiliser pour le comble.  *
-*                ctx    = contexte offert en soutien à un désassemblage.      *
-*                status = barre de statut à actualiser.                       *
-*                id     = identifiant du groupe de progression à l'affichage. *
-*                                                                             *
-*  Description : S'assure que l'ensemble des aires est entièrement décodé.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void ensure_all_mem_areas_are_filled(mem_area *areas, size_t count, bool code, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    if (code)
-        for (i = 0; i < count; i++)
-            fill_mem_area_with_code(&areas[i], areas, count, ctx, status, id);
-
-    else
-        for (i = 0; i < count; i++)
-            fill_mem_area_with_data(&areas[i], areas, count, ctx, status, id);
-
-}
-
-
 
 /* ---------------------------------------------------------------------------------- */
 /*                         MANIPULATIONS PARALLELES DES ZONES                         */
@@ -1633,6 +1615,12 @@ static void g_area_collector_dispose(GAreaCollector *collector)
     else if (collector->run == (run_task_fc)g_area_collector_do_insert)
         g_object_unref(G_OBJECT(collector->info));
 
+    else if (collector->run == (run_task_fc)g_area_collector_do_fill)
+    {
+        if (collector->ctx != NULL)
+            g_object_unref(G_OBJECT(collector->ctx));
+    }
+
     G_OBJECT_CLASS(g_area_collector_parent_class)->dispose(G_OBJECT(collector));
 
 }
@@ -1744,8 +1732,8 @@ static GAreaCollector *g_area_collector_new_intro(activity_id_t id, GLoadedBinar
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : fetching = récupération à mener.                             *
-*                status   = barre de statut à tenir informée.                 *
+*  Paramètres  : collector = opération à mener.                               *
+*                status    = barre de statut à tenir informée.                *
 *                                                                             *
 *  Description : Construit une liste bornée de zones contigües.               *
 *                                                                             *
@@ -2058,8 +2046,8 @@ static GAreaCollector *g_area_collector_new_insert(activity_id_t id, mem_area *a
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : fetching = récupération à mener.                             *
-*                status   = barre de statut à tenir informée.                 *
+*  Paramètres  : collector = opération à mener.                               *
+*                status    = barre de statut à tenir informée.                *
 *                                                                             *
 *  Description : Insère dans les zones contigües les instructions préchargées.*
 *                                                                             *
@@ -2181,6 +2169,140 @@ void populate_fresh_memory_areas(wgroup_id_t gid, GtkStatusStack *status, mem_ar
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : id    = identifiant pour signaler la progression courante.   *
+*                areas = liste complète des zones à traiter.                  *
+*                count = taille de cette liste.                               *
+*                ctx   = éventuel contexte pour du code ou NULL si données.   *
+*                start = première zone à traiter.                             *
+*                stop  = première zone à écarter.                             *
+*                                                                             *
+*  Description : Crée une tâche de fin de désassemblage pour zones binaires.  *
+*                                                                             *
+*  Retour      : Tâche créée.                                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GAreaCollector *g_area_collector_new_filling(activity_id_t id, mem_area *areas, size_t count, GProcContext *ctx, size_t start, size_t stop)
+{
+    GAreaCollector *result;            /* Tâche à retourner           */
+
+    result = g_object_new(G_TYPE_AREA_COLLECTOR, NULL);
+
+    result->id = id;
+    result->run = (run_task_fc)g_area_collector_do_fill;
+
+    result->areas = areas;
+
+    result->count = count;
+
+    result->ctx = ctx;
+
+    if (ctx != NULL)
+        g_object_ref(G_OBJECT(ctx));
+
+    result->fill_start = start;
+    result->fill_stop = stop;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collector = opération à mener.                               *
+*                status    = barre de statut à tenir informée.                *
+*                                                                             *
+*  Description : Remplit de code ou de données une série de zones.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_area_collector_do_fill(GAreaCollector *collector, GtkStatusStack *status)
+{
+    mem_area *areas;                        /* Zone de productions         */
+    size_t count;                           /* Nombre de ces zones         */
+    size_t i;                               /* Boucle de parcours          */
+
+    areas = collector->areas;
+    count = collector->count;
+
+    if (collector->ctx != NULL)
+        for (i = collector->fill_start; i < collector->fill_stop; i++)
+            fill_mem_area_with_code(&areas[i], areas, count, collector->ctx, status, collector->id);
+
+    else
+        for (i = collector->fill_start; i < collector->fill_stop; i++)
+            fill_mem_area_with_data(&areas[i], areas, count, status, collector->id);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : gid    = groupe de travail impliqué.                         *
+*                status = barre de statut à tenir informée.                   *
+*                id     = identifiant d'activité à modifier.                  *
+*                area   = nombre de zones mises en place.                     *
+*                count  = quantité de ces zones.                              *
+*                ctx    = contexte de désassemblage pour du code, ou NULL.    *
+*                                                                             *
+*  Description : Remplit les espaces vacants des zones à désassembler.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void ensure_all_mem_areas_are_filled(wgroup_id_t gid, GtkStatusStack *status, activity_id_t id, mem_area *areas, size_t count, GProcContext *ctx)
+{
+    guint runs_count;                       /* Qté d'exécutions parallèles */
+    phys_t run_size;                        /* Volume réparti par exécution*/
+    GWorkQueue *queue;                      /* Gestionnaire de différés    */
+    guint i;                                /* Boucle de parcours          */
+    size_t start;                           /* Premier indice à traiter    */
+    size_t stop;                            /* Premier indice à ignorer    */
+    GAreaCollector *collector;              /* Collecteur à lancer         */
+
+    runs_count = get_max_online_threads();
+
+    run_size = count / runs_count;
+
+    queue = get_work_queue();
+
+    if (ctx != NULL)
+        gtk_status_stack_update_activity(status, id, _("Disassembling the remaining instructions..."));
+    else
+        gtk_status_stack_update_activity(status, id, _("Filling holes with data..."));
+
+    for (i = 0; i < runs_count; i++)
+    {
+        start = i * run_size;
+
+        if ((i + 1) == runs_count)
+            stop = count;
+        else
+            stop = start + run_size;
+
+        collector = g_area_collector_new_filling(id, areas, count, ctx, start, stop);
+
+        g_work_queue_schedule_work(queue, G_DELAYED_WORK(collector), gid);
+
+    }
+
+    g_work_queue_wait_for_completion(queue, gid);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : id    = identifiant pour signaler la progression courante.   *
 *                list  = liste des zones en place à parcourir.                *
 *                begin = indice de la première zone à traiter.                *
 *                end   = indice de la première zone à ne pas traiter.         *
@@ -2217,8 +2339,8 @@ static GAreaCollector *g_area_collector_new_outro(activity_id_t id, mem_area *li
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : fetching = récupération à mener.                             *
-*                status   = barre de statut à tenir informée.                 *
+*  Paramètres  : collector = opération à mener.                               *
+*                status    = barre de statut à tenir informée.                *
 *                                                                             *
 *  Description : Assure la récupération d'instructions en différé.            *
 *                                                                             *
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index dc84277..8c143a7 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -52,9 +52,6 @@ void load_code_from_mem_area(mem_area *, mem_area *, size_t, GProcContext *, con
 /* Détermine une liste de zones contigües à traiter. */
 mem_area *find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *);
 
-/* S'assure que l'ensemble des aires est entièrement décodé. */
-void ensure_all_mem_areas_are_filled(mem_area *, size_t, bool, GProcContext *, GtkStatusStack *, activity_id_t);
-
 
 
 /* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */
@@ -66,6 +63,9 @@ mem_area *collect_memory_areas(wgroup_id_t, GtkStatusStack *, GLoadedBinary *, p
 /* Intègre toutes les instructions préchargées dans des zones. */
 void populate_fresh_memory_areas(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, GPreloadInfo *);
 
+/* Remplit les espaces vacants des zones à désassembler. */
+void ensure_all_mem_areas_are_filled(wgroup_id_t, GtkStatusStack *, activity_id_t, mem_area *, size_t, GProcContext *);
+
 /* Rassemble les instructions conservées dans des zones données. */
 GArchInstruction **collect_disassembled_instructions(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, size_t *);
 
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index fc1c2ab..f179860 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -461,21 +461,13 @@ GArchInstruction **disassemble_binary_content(GLoadedBinary *binary, GProcContex
      * Troisième phase : on comble les trous laissés.
      */
 
-    gtk_status_stack_update_activity(status, template.id, _("Disassembling the remaining instructions..."));
-
-    ensure_all_mem_areas_are_filled(template.areas, template.count, true, template.ctx, status, template.id);
-
-    g_work_queue_wait_for_completion(queue, gid);
+    ensure_all_mem_areas_are_filled(gid, status, template.id, template.areas, template.count, template.ctx);
 
     g_work_queue_set_extra_wait_callback(queue, gid, NULL, NULL);
 
     g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", NULL);
 
-    gtk_status_stack_update_activity(status, template.id, _("Filling holes with data..."));
-
-    ensure_all_mem_areas_are_filled(template.areas, template.count, false, template.ctx, status, template.id);
-
-    g_work_queue_wait_for_completion(queue, gid);
+    ensure_all_mem_areas_are_filled(gid, status, template.id, template.areas, template.count, NULL);
 
     gtk_status_stack_remove_activity(status, template.id);
 
-- 
cgit v0.11.2-87-g4458