summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-12-23 18:44:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-12-23 18:44:01 (GMT)
commit5e76e91ea41f9a7cf1a1a4a77e12277d45417e43 (patch)
tree67c8336ed33332bdea133290824a358c7072a0c8 /src
parent67ea22978ffb134a4b94e0c3cdb0802b3360a249 (diff)
Collected the loaded instructions using all available processors.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/binary.c3
-rw-r--r--src/analysis/disass/area.c361
-rw-r--r--src/analysis/disass/area.h12
-rw-r--r--src/analysis/disass/disassembler.c18
-rw-r--r--src/analysis/disass/disassembler.h2
-rw-r--r--src/analysis/disass/fetch.c19
-rw-r--r--src/analysis/disass/fetch.h2
-rw-r--r--src/arch/processor-int.h3
-rw-r--r--src/arch/processor.c45
-rw-r--r--src/arch/processor.h2
10 files changed, 384 insertions, 83 deletions
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);