From 5e76e91ea41f9a7cf1a1a4a77e12277d45417e43 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 23 Dec 2016 19:44:01 +0100
Subject: Collected the loaded instructions using all available processors.

---
 ChangeLog                          |  20 ++
 src/analysis/binary.c              |   3 +-
 src/analysis/disass/area.c         | 361 ++++++++++++++++++++++++++++++++++---
 src/analysis/disass/area.h         |  12 +-
 src/analysis/disass/disassembler.c |  18 +-
 src/analysis/disass/disassembler.h |   2 +-
 src/analysis/disass/fetch.c        |  19 +-
 src/analysis/disass/fetch.h        |   2 +-
 src/arch/processor-int.h           |   3 +-
 src/arch/processor.c               |  45 +++--
 src/arch/processor.h               |   2 +-
 11 files changed, 404 insertions(+), 83 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 62a4158..abc2950 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+16-12-23  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/binary.c:
+	Do not save loaded instructions into the loaded binary.
+
+	* src/analysis/disass/area.c:
+	* src/analysis/disass/area.h:
+	Collect the loaded instructions using all available processors.
+
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/disassembler.h:
+	* src/analysis/disass/fetch.c:
+	* src/analysis/disass/fetch.h:
+	Update code.
+
+	* src/arch/processor-int.h:
+	* src/arch/processor.c:
+	* src/arch/processor.h:
+	Update code as the instructions are already provided using an array.
+
 16-12-18  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/dalvik/operands/args.c:
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 61f775c..3af62cf 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -78,7 +78,6 @@ struct _GLoadedBinary
     GDbgFormat *debug;                      /* Informations de débogage    */ //// REMME
     GArchProcessor *proc;                   /* Architecture du binaire     */
 
-    GArchInstruction *instrs;               /* Instructions d'assemblage   */
     GCodeBuffer *disass_buffer;             /* Instructions lisibles       */
     GCodeBuffer **dec_buffers;              /* Sources sous forme de texte */
     size_t decbuf_count;                    /* Taille des tableaux         */
@@ -1378,7 +1377,7 @@ void g_loaded_binary_analyse(GLoadedBinary *binary)
     g_loaded_binary_connect_internal(binary);
 
 
-    disassemble_binary(binary, &binary->instrs, &binary->disass_buffer, ack_completed_disassembly);
+    disassemble_binary(binary, &binary->disass_buffer, ack_completed_disassembly);
 
 
 
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 48ac6ec..71e2784 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -25,6 +25,8 @@
 
 
 #include <assert.h>
+#include <malloc.h>
+#include <string.h>
 
 
 #include <i18n.h>
@@ -34,10 +36,14 @@
 #include "../../arch/raw.h"
 #include "../../common/bits.h"
 #include "../../format/format.h"
+#include "../../glibext/delayed-int.h"
 #include "../../gui/panels/log.h"
 
 
 
+/* ------------------------- TRAITEMENT DES ZONES DE DONNES ------------------------- */
+
+
 /* Zone mémoire bien bornée */
 typedef struct _mem_area
 {
@@ -52,6 +58,7 @@ typedef struct _mem_area
 
     bitfield_t *processed;                  /* Octets traités dans la zone */
     GArchInstruction **instructions;        /* Instructions en place       */
+    size_t count;                           /* Quantité d'instructions     */
 
     bool is_exec;                           /* Zone exécutable ?           */
 
@@ -83,8 +90,76 @@ static void load_data_from_mem_area(mem_area *, GProcContext *, const vmpa2t *,
 static void fill_mem_area(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
 
 /* Rassemble les instructions conservées dans une zone donnée. */
-static GArchInstruction *get_instructions_from_mem_area(const mem_area *);
+static GArchInstruction **get_instructions_from_mem_area(const mem_area *, GArchInstruction **, size_t *);
+
+
+
+/* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */
+
+
+#define G_TYPE_AREA_COLLECTOR            g_area_collector_get_type()
+#define G_AREA_COLLECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_AREA_COLLECTOR, GAreaCollector))
+#define G_IS_AREA_COLLECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_AREA_COLLECTOR))
+#define G_AREA_COLLECTOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_AREA_COLLECTOR, GAreaCollectorClass))
+#define G_IS_AREA_COLLECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_AREA_COLLECTOR))
+#define G_AREA_COLLECTOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_AREA_COLLECTOR, GAreaCollectorClass))
+
+
+/* Ensembles binaires à désassembler (instance) */
+typedef struct _GAreaCollector
+{
+    GDelayedWork parent;                    /* A laisser en premier        */
+
+    activity_id_t id;                       /* Groupe de progression       */
+    run_task_fc run;                        /* Activité dans la pratique   */
+
+    mem_area *areas;                        /* Zone de productions         */
+
+    size_t begin;                           /* Début du parcours à mener   */
+    size_t end;                             /* Fin de ce même parcours     */
+
+    GArchInstruction **collected;           /* Instructions collectées     */
+    size_t count;                           /* Quantité de ces instructions*/
+
+} GAreaCollector;
+
+/* Ensembles binaires à désassembler (classe) */
+typedef struct _GAreaCollectorClass
+{
+    GDelayedWorkClass parent;               /* A laisser en premier        */
+
+} GAreaCollectorClass;
+
+
+/* Indique le type défini pour les tâches de traitement des zones. */
+GType g_area_collector_get_type(void);
+
+/* Initialise la classe des manipulations parallèles de zones. */
+static void g_area_collector_class_init(GAreaCollectorClass *);
+
+/* Initialise des manipulations parallèles de zones. */
+static void g_area_collector_init(GAreaCollector *);
+
+/* Supprime toutes les références externes. */
+static void g_area_collector_dispose(GAreaCollector *);
 
+/* Procède à la libération totale de la mémoire. */
+static void g_area_collector_finalize(GAreaCollector *);
+
+/* Assure un traitement particulier concernant les zones. */
+static void g_area_collector_process(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);
+
+/* Assure la récupération d'instructions en différé. */
+static void g_area_collector_do_collect(GAreaCollector *, GtkStatusStack *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            RAITEMENT DES ZONES DE DONNES                           */
+/* ---------------------------------------------------------------------------------- */
 
 
 /******************************************************************************
@@ -123,6 +198,7 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l
 
     area->processed = create_bit_field(len, false);
     area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *));
+    area->count = 0;
 
 }
 
@@ -226,7 +302,13 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction
     result |= force;
 
     if (result)
+    {
+        assert(area->instructions[offset] == NULL);
+
         area->instructions[offset] = instr;
+        g_atomic_pointer_add(&area->count, 1);
+
+    }
 
     return result;
 
@@ -642,7 +724,9 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcCon
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : area = aire représentant à contenu à parcourir.              *
+*  Paramètres  : area  = aire représentant à contenu à parcourir.             *
+*                list  = liste d'instructions à compléter.                    *
+*                count = taille de cette liste. [OUT]                         *
 *                                                                             *
 *  Description : Rassemble les instructions conservées dans une zone donnée.  *
 *                                                                             *
@@ -652,17 +736,24 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcCon
 *                                                                             *
 ******************************************************************************/
 
-static GArchInstruction *get_instructions_from_mem_area(const mem_area *area)
+static GArchInstruction **get_instructions_from_mem_area(const mem_area *area, GArchInstruction **list, size_t *count)
 {
-    GArchInstruction *result;               /* Liste d'instr. à renvoyer   */
+    GArchInstruction **result;              /* Liste d'instr. à renvoyer   */
     phys_t len;                             /* Nombre d'instructions au max*/
+#ifndef NDEBUG
+    size_t check;                           /* Verification de débordement */
+#endif
     phys_t i;                               /* Boucle de parcours          */
     GArchInstruction *instr;                /* Instruction décodée         */
 
-    result = NULL;
+    result = (GArchInstruction **)realloc(list, (*count + area->count) * sizeof(GArchInstruction *));
 
     len = get_mrange_length(&area->range);
 
+#ifndef NDEBUG
+    check = 0;
+#endif
+
     for (i = 0; i < len; i++)
     {
         instr = area->instructions[i];
@@ -670,7 +761,13 @@ static GArchInstruction *get_instructions_from_mem_area(const mem_area *area)
         if (instr != NULL)
         {
             g_object_ref(G_OBJECT(instr));
-            g_arch_instruction_add_to_list(&result, instr);
+            result[(*count)++] = instr;
+
+#ifndef NDEBUG
+            check++;
+            assert(check <= area->count);
+#endif
+
         }
 
     }
@@ -1044,32 +1141,152 @@ void ensure_all_mem_areas_are_filled(mem_area *list, size_t count, GProcContext
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                         MANIPULATIONS PARALLELES DES ZONES                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de traitement des zones. */
+G_DEFINE_TYPE(GAreaCollector, g_area_collector, G_TYPE_DELAYED_WORK);
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : list  = série d'aires représentant du contenu à parcourir.   *
-*                count = nombre de ces zones présentes.                       *
+*  Paramètres  : klass = classe à initialiser.                                *
 *                                                                             *
-*  Description : Rassemble les instructions conservées dans des zones données.*
+*  Description : Initialise la classe des manipulations parallèles de zones.  *
 *                                                                             *
-*  Retour      : Liste d'instructions prêtes à emploi.                        *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size_t count)
+static void g_area_collector_class_init(GAreaCollectorClass *klass)
 {
-    GArchInstruction *result;               /* Liste d'instr. à renvoyer   */
-    size_t i;                               /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Instruction(s) à insérer    */
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GDelayedWorkClass *work;                /* Version en classe parente   */
 
-    result = NULL;
+    object = G_OBJECT_CLASS(klass);
 
-    for (i = 0; i < count; i++)
-    {
-        instr = get_instructions_from_mem_area(&list[i]);
-        g_arch_instruction_merge_lists(&result, &instr);
-    }
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_area_collector_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_area_collector_finalize;
+
+    work = G_DELAYED_WORK_CLASS(klass);
+
+    work->run = (run_task_fc)g_area_collector_process;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collector = instance à initialiser.                          *
+*                                                                             *
+*  Description : Initialise des manipulations parallèles de zones.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_area_collector_init(GAreaCollector *collector)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collector = instance d'objet GLib à traiter.                 *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_area_collector_dispose(GAreaCollector *collector)
+{
+    G_OBJECT_CLASS(g_area_collector_parent_class)->dispose(G_OBJECT(collector));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collector = instance d'objet GLib à traiter.                 *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_area_collector_finalize(GAreaCollector *collector)
+{
+    G_OBJECT_CLASS(g_area_collector_parent_class)->finalize(G_OBJECT(collector));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collector = opérations à mener.                              *
+*                status    = barre de statut à tenir informée.                *
+*                                                                             *
+*  Description : Assure un traitement particulier concernant les zones.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_area_collector_process(GAreaCollector *collector, GtkStatusStack *status)
+{
+    collector->run(G_DELAYED_WORK(collector), status);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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.         *
+*                                                                             *
+*  Description : Crée une tâche de récupération d'instructions différée.      *
+*                                                                             *
+*  Retour      : Tâche créée.                                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GAreaCollector *g_area_collector_new_outro(activity_id_t id, mem_area *list, size_t begin, size_t end)
+{
+    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_collect;
+
+    result->areas = list;
+
+    result->begin = begin;
+    result->end = end;
+
+    result->collected = NULL;
+    result->count = 0;
 
     return result;
 
@@ -1078,10 +1295,10 @@ GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : list  = série d'aires représentant du contenu à libérer.     *
-*                count = nombre de ces zones présentes.                       *
+*  Paramètres  : fetching = récupération à mener.                             *
+*                status   = barre de statut à tenir informée.                 *
 *                                                                             *
-*  Description : Libère la mémoire occupée par des zones de données.          *
+*  Description : Assure la récupération d'instructions en différé.            *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1089,13 +1306,105 @@ GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size
 *                                                                             *
 ******************************************************************************/
 
-void release_mem_areas(mem_area *list, size_t count)
+static void g_area_collector_do_collect(GAreaCollector *collector, GtkStatusStack *status)
 {
     size_t i;                               /* Boucle de parcours          */
 
-    for (i = 0; i < count; i++)
-        fini_mem_area(&list[i]);
+    for (i = collector->begin; i < collector->end; i++)
+    {
+        collector->collected = get_instructions_from_mem_area(&collector->areas[i],
+                                                              collector->collected, &collector->count);
+
+        fini_mem_area(&collector->areas[i]);
+
+        gtk_status_stack_update_activity_value(status, collector->id, 1);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : gid      = groupe de travail impliqué.                       *
+*                status   = barre de statut à tenir informée.                 *
+*                list   = liste des zones de données à relire puis libérer.   *
+*                acount = taille de cette liste de zones.                     *
+*                icount = nombre d'instructions récupérées. [OUT]             *
+*                                                                             *
+*  Description : Rassemble les instructions conservées dans des zones données.*
+*                                                                             *
+*  Retour      : Liste d'instructions rassemblées.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction **collect_disassembled_instructions(wgroup_id_t gid, GtkStatusStack *status, mem_area *list, size_t acount, size_t *icount)
+{
+    GArchInstruction **result;              /* Liste finale à retourner    */
+    guint runs_count;                       /* Qté d'exécutions parallèles */
+    GAreaCollector **collectors;            /* Collecteurs à suivre        */
+    size_t run_size;                        /* Volume réparti par exécution*/
+    GWorkQueue *queue;                      /* Gestionnaire de différés    */
+    activity_id_t id;                       /* Identifiant de progression  */
+    guint i;                                /* Boucle de parcours          */
+    size_t begin;                           /* Début de bloc de traitement */
+    size_t end;                             /* Fin d'un bloc de traitement */
+
+    runs_count = g_get_num_processors();
+
+    collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *));
+
+    run_size = acount / runs_count;
+
+    queue = get_work_queue();
+
+    id = gtk_status_stack_add_activity(status, _("Collecting all disassembled instructions"), acount);
+
+    for (i = 0; i < runs_count; i++)
+    {
+        begin = i * run_size;
+
+        if ((i + 1) == runs_count)
+            end = acount;
+        else
+            end = begin + run_size;
+
+        collectors[i] = g_area_collector_new_outro(id, list, begin, end);
+
+        g_object_ref(G_OBJECT(collectors[i]));
+        g_work_queue_schedule_work(queue, G_DELAYED_WORK(collectors[i]), gid);
+
+    }
+
+    g_work_queue_wait_for_completion(queue, gid);
+
+    /* Récupération des instructions */
+
+    result = NULL;
+    *icount = 0;
+
+    for (i = 0; i < runs_count; i++)
+    {
+        result = (GArchInstruction **)realloc(result,
+                                              (*icount + collectors[i]->count) * sizeof(GArchInstruction *));
+
+        memcpy(&result[*icount], collectors[i]->collected, collectors[i]->count * sizeof(GArchInstruction *));
+        *icount += collectors[i]->count;
+
+        g_object_unref(G_OBJECT(collectors[i]));
+
+    }
+
+    /* Fin */
+
+    free(collectors);
 
     free(list);
 
+    gtk_status_stack_remove_activity(status, id);
+
+    return result;
+
 }
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index 39313fd..725b9a8 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -32,6 +32,9 @@
 
 
 
+/* ------------------------- TRAITEMENT DES ZONES DE DONNES ------------------------- */
+
+
 /* Zone mémoire bien bornée */
 typedef struct _mem_area mem_area;
 
@@ -51,11 +54,12 @@ void insert_extra_symbol_into_mem_areas(mem_area *, size_t, const GBinSymbol *);
 /* S'assure que l'ensemble des aires est entièrement décodé. */
 void ensure_all_mem_areas_are_filled(mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
 
-/* Rassemble les instructions conservées dans des zones données. */
-GArchInstruction *collect_instructions_from_mem_areas(const mem_area *, size_t);
 
-/* Libère la mémoire occupée par des zones de données. */
-void release_mem_areas(mem_area *, size_t);
+/* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */
+
+
+/* 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/disassembler.c b/src/analysis/disass/disassembler.c
index f210bd1..172ee1c 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -55,7 +55,6 @@ struct _GDelayedDisassembly
     GLoadedBinary *binary;                  /* Destinataire final          */
     GExeFormat *format;                     /* Format du binaire représenté*/
 
-    GArchInstruction **instrs;              /* Instructions résultantes    */
     GCodeBuffer *buffer;                    /* Tampon pour le rendu        */
 
 };
@@ -81,7 +80,7 @@ static void g_delayed_disassembly_dispose(GDelayedDisassembly *);
 static void g_delayed_disassembly_finalize(GDelayedDisassembly *);
 
 /* Crée une tâche de désassemblage différé. */
-static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GArchInstruction **, GCodeBuffer *);
+static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GCodeBuffer *);
 
 /* Opère sur toutes les instructions. */
 static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *);
@@ -202,7 +201,6 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass)
 *                                                                             *
 *  Paramètres  : binary = binaire chargé en attente des résultats.            *
 *                format = format du binaire représenté.                       *
-*                instrs = emplacement pour la liste d'instructions.           *
 *                buffer = tampon de sortie pour les instructions.             *
 *                                                                             *
 *  Description : Crée une tâche de désassemblage différé.                     *
@@ -213,7 +211,7 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass)
 *                                                                             *
 ******************************************************************************/
 
-static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GArchInstruction **instrs, GCodeBuffer *buffer)
+static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCodeBuffer *buffer)
 {
     GDelayedDisassembly *result;            /* Tâche à retourner           */
 
@@ -222,7 +220,6 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr
     result->binary = binary;
     result->format = g_loaded_binary_get_format(binary);
 
-    result->instrs = instrs;
     result->buffer = buffer;
 
     return result;
@@ -389,7 +386,8 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 
     //size_t i;                               /* Boucle de parcours          */
 
-
+    GArchInstruction **instrs;              /* Instructions résultantes    */
+    size_t count;                           /* Quantité de ces instructions*/
 
 
 
@@ -417,10 +415,10 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 
 
 
-    *disass->instrs = disassemble_binary_content(disass->binary, ctx, gid, status);
+    instrs = disassemble_binary_content(disass->binary, ctx, gid, status, &count);
 
 
-    g_arch_processor_set_disassembled_instructions(proc, *disass->instrs);
+    g_arch_processor_set_instructions(proc, instrs, count);
 
 
     // plugins //////////////////////////
@@ -739,7 +737,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
 *                                                                             *
 ******************************************************************************/
 
-void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeBuffer **buffer, disassembly_ack_fc ack)
+void disassemble_binary(GLoadedBinary *binary, GCodeBuffer **buffer, disassembly_ack_fc ack)
 {
     GBinFormat *format;                     /* Format associé au binaire   */
     GBinContent *content;                   /* Contenu bianire manipulé    */
@@ -759,7 +757,7 @@ void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeB
 
     build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum);
 
-    disass = g_delayed_disassembly_new(binary, instrs, *buffer);
+    disass = g_delayed_disassembly_new(binary, *buffer);
     g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary);
 
     queue = get_work_queue();
diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h
index dd9e362..9151d23 100644
--- a/src/analysis/disass/disassembler.h
+++ b/src/analysis/disass/disassembler.h
@@ -59,7 +59,7 @@ GType g_delayed_disassembly_get_type(void);
 typedef void (* disassembly_ack_fc) (GDelayedDisassembly *, GLoadedBinary *);
 
 /* Procède à la décompilation des routines d'un fichier donné. */
-void disassemble_binary(GLoadedBinary *, GArchInstruction **, GCodeBuffer **, disassembly_ack_fc);
+void disassemble_binary(GLoadedBinary *, GCodeBuffer **, disassembly_ack_fc);
 
 
 
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 1a55eeb..784e103 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -163,8 +163,6 @@ static void g_delayed_fetching_class_init(GDelayedFetchingClass *klass)
 static void g_delayed_fetching_init(GDelayedFetching *fetching)
 {
 
-
-
 }
 
 
@@ -384,6 +382,7 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr
 *                ctx    = contexte fourni pour suivre le désassemblage.       *
 *                gid    = identifiant du groupe de travail à utiliser.        *
 *                status = barre de statut avec progression à mettre à jour.   *
+*                count  = nombre d'instructions récupérées.                   *
 *                                                                             *
 *  Description : Procède au désassemblage basique d'un contenu binaire.       *
 *                                                                             *
@@ -393,9 +392,9 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status)
+GArchInstruction **disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status, size_t *count)
 {
-    GArchInstruction *result;               /* Instruction désassemblées   */
+    GArchInstruction **result;               /* Instruction désassemblées   */
     GDelayedFetching template;              /* Patron des tâches à venir   */
     GBinFormat *format;                     /* Format du fichier binaire   */
     GBinContent *content;                   /* Contenu binaire à manipuler */
@@ -462,22 +461,18 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcC
 
     g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", NULL);
 
+    gtk_status_stack_remove_activity(status, template.id);
+
     /**
      * Troisième et dernière phase : récolte des fruits.
      */
 
-    gtk_status_stack_update_activity(status, template.id, _("Collecting disassembled instructions..."));
+    result = collect_disassembled_instructions(gid, status, template.areas, template.count, count);
 
-    result = collect_instructions_from_mem_areas(template.areas, template.count);
-
-    gtk_status_stack_remove_activity(status, template.id);
-
-    /* Libérations finales */
+    /* Libération finale */
 
     g_object_unref(G_OBJECT(template.format));
 
-    release_mem_areas(template.areas, template.count);
-
     return result;
 
 }
diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h
index 11b2890..bf2b52f 100644
--- a/src/analysis/disass/fetch.h
+++ b/src/analysis/disass/fetch.h
@@ -32,7 +32,7 @@
 
 
 /* Procède au désassemblage basique d'un contenu binaire. */
-GArchInstruction *disassemble_binary_content(const GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *);
+GArchInstruction **disassemble_binary_content(const GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *, size_t *);
 
 
 
diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h
index b170cad..4eaa690 100644
--- a/src/arch/processor-int.h
+++ b/src/arch/processor-int.h
@@ -44,7 +44,7 @@
 
 
 /* Taille des pré-allocations pour les instructions */
-#define INSTR_ALLOC_BLOCK 100
+#define COV_ALLOC_BLOCK 100
 
 
 
@@ -85,7 +85,6 @@ struct _GArchProcessor
     //get_decomp_context_fc get_dec_ctx;      /* Obtention d'un contexte #2  */
 
     GArchInstruction **instructions;        /* Instructions désassemblées  */
-    size_t instr_allocated;                 /* Taille de la liste allouée  */
     size_t instr_count;                     /* Taille de la liste aplatie  */
     unsigned int stamp;                     /* Marque de suivi des modifs  */
     GMutex mutex;                           /* Verrou pour l'accès         */
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 24e2db6..5cc1951 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -405,8 +405,9 @@ size_t g_arch_processor_count_instructions(const GArchProcessor *proc)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc = architecture visée par la procédure.                  *
-*                list = liste des instructions désassemblées.                 *
+*  Paramètres  : proc  = architecture visée par la procédure.                 *
+*                list  = liste des instructions désassemblées.                *
+*                count = taille de cette liste.                               *
 *                                                                             *
 *  Description : Note les instructions désassemblées avec une architecture.   *
 *                                                                             *
@@ -416,48 +417,44 @@ size_t g_arch_processor_count_instructions(const GArchProcessor *proc)
 *                                                                             *
 ******************************************************************************/
 
-void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchInstruction *list)
+void g_arch_processor_set_instructions(GArchProcessor *proc, GArchInstruction **list, size_t count)
 {
     GArchInstruction *last;                 /* Dernière instruction traitée*/
-    GArchInstruction *iter;                 /* Boucle de parcours          */
+    size_t i;                               /* Boucle de parcours          */
+    GArchInstruction *instr;                /* Instruction à analyser      */
+
+    g_arch_processor_lock(proc);
 
-    /* TODO : vider une éventuelle liste existante */
-    /* TODO : incrémenter les références (cf. code Python) */
+    proc->instructions = list;
+    proc->instr_count = count;
+    proc->stamp++;
 
     last = NULL;
 
-    ainstr_list_for_each(iter, list)
+    for (i = 0; i < count; i++)
     {
-        /* Mise à disposition de d'avantage d'espace */
-        if (proc->instr_allocated == proc->instr_count)
-        {
-            proc->instr_allocated += INSTR_ALLOC_BLOCK;
-
-            proc->instructions = (GArchInstruction **)realloc(proc->instructions,
-                                                              proc->instr_allocated * sizeof(GArchInstruction  *));
-
-        }
+        instr = list[i];
 
         /* Constitution des groupes */
-        if (last == NULL || g_arch_instruction_get_flags(iter) & AIF_ROUTINE_START)
+
+        if (last == NULL || g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START)
         {
             if (last != NULL)
-                g_arch_processor_finish_last_coverage(proc, last, proc->instr_count - 1);
+                g_arch_processor_finish_last_coverage(proc, last, i - 1);
 
-            g_arch_processor_add_new_coverage(proc, iter, proc->instr_count);
+            g_arch_processor_add_new_coverage(proc, instr, i);
 
         }
 
-        /* Enregistrement */
-        proc->instructions[proc->instr_count++] = iter;
-
-        last = iter;
+        last = instr;
 
     }
 
     if (last != NULL)
         g_arch_processor_finish_last_coverage(proc, last, proc->instr_count - 1);
 
+    g_arch_processor_unlock(proc);
+
 }
 
 
@@ -527,7 +524,7 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruc
     /* Mise à disposition de d'avantage d'espace */
     if (proc->cov_allocated == proc->cov_count)
     {
-        proc->cov_allocated += INSTR_ALLOC_BLOCK;
+        proc->cov_allocated += COV_ALLOC_BLOCK;
 
         proc->coverages = (instr_coverage *)realloc(proc->coverages,
                                                     proc->cov_allocated * sizeof(instr_coverage));
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 05ea77a..76691ec 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -91,7 +91,7 @@ unsigned int g_arch_processor_get_stamp(const GArchProcessor *);
 size_t g_arch_processor_count_instructions(const GArchProcessor *);
 
 /* Note les instructions désassemblées avec une architecture. */
-void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
+void g_arch_processor_set_instructions(GArchProcessor *, GArchInstruction **, size_t);
 
 /* Fournit une instruction désassemblée pour une architecture. */
 GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *, size_t);
-- 
cgit v0.11.2-87-g4458