summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/disass/disassembler.c2
-rw-r--r--src/analysis/disass/fetch.c1
-rw-r--r--src/analysis/disass/limit.c292
-rw-r--r--src/analysis/disass/limit.h6
4 files changed, 279 insertions, 22 deletions
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index c563b2e..272529c 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -341,7 +341,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
//qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
- limit_all_routines(disass->format, proc, routines, routines_count, statusbar, id);
+ limit_all_routines(disass->format, proc, routines, routines_count, gid, id);
gtk_extended_status_bar_remove(statusbar, id);
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 29d8923..e9098eb 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -522,7 +522,6 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup
* Première phase de désassemblage : suivi des chemins tracés.
*/
-
g_work_queue_set_extra_wait_callback(queue, gid,
(wait_for_incoming_works_cb)check_if_extra_wait_is_needed,
template.ctx);
diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c
index dd99643..4fd931d 100644
--- a/src/analysis/disass/limit.c
+++ b/src/analysis/disass/limit.c
@@ -27,10 +27,206 @@
#include <malloc.h>
+#include "../../glibext/delayed-int.h"
+
+
+
+/* ------------------------- CALCULS DE LIMITES DE ROUTINES ------------------------- */
+
+
+#define G_TYPE_LIMIT_COMPUTING g_limit_computing_get_type()
+#define G_LIMIT_COMPUTING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_limit_computing_get_type(), GLimitComputing))
+#define G_IS_LIMIT_COMPUTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_limit_computing_get_type()))
+#define G_LIMIT_COMPUTING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LIMIT_COMPUTING, GLimitComputingClass))
+#define G_IS_LIMIT_COMPUTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LIMIT_COMPUTING))
+#define G_LIMIT_COMPUTING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LIMIT_COMPUTING, GLimitComputingClass))
+
+
+/* Fraction de routines à limiter (instance) */
+typedef struct _GLimitComputing
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ const GArchProcessor *proc; /* Processeurs avec ses instr. */
+
+ mrange_t *exe_ranges; /* Liste de zones exécutables */
+ size_t exe_count; /* Nombre de ces zones */
+
+ GBinRoutine **routines; /* Liste de routines à traiter */
+ size_t count; /* Taille de cette liste */
+ size_t begin; /* Point de départ du parcours */
+ size_t end; /* Point d'arrivée exclu */
+
+ bstatus_id_t id; /* Identifiant pour messages */
+
+} GLimitComputing;
+
+/* Fraction de routines à limiter (classe) */
+typedef struct _GLimitComputingClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+} GLimitComputingClass;
+
+
+/* Indique le type défini pour les tâches de calculs de limites. */
+GType g_limit_computing_get_type(void);
+
+/* Initialise la classe des tâches de calculs de limites. */
+static void g_limit_computing_class_init(GLimitComputingClass *);
+
+/* Initialise une tâche de calculs de limites. */
+static void g_limit_computing_init(GLimitComputing *);
+
+/* Supprime toutes les références externes. */
+static void g_limit_computing_dispose(GLimitComputing *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_limit_computing_finalize(GLimitComputing *);
+
+/* Crée une tâche de calculs de limites différée. */
+static GLimitComputing *g_limit_computing_new(const GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, bstatus_id_t);
/* Recherche la zone correspond à une adresse donnée. */
static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *);
+/* Assure le calcul de limites de routines en différé. */
+static void g_limit_computing_process(GLimitComputing *, GtkExtStatusBar *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CALCULS DE LIMITES DE ROUTINES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de calculs de limites. */
+G_DEFINE_TYPE(GLimitComputing, g_limit_computing, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches de calculs de limites. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_limit_computing_class_init(GLimitComputingClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_limit_computing_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_limit_computing_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_limit_computing_process;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : computing = instance à initialiser. *
+* *
+* Description : Initialise une tâche de calculs de limites. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_limit_computing_init(GLimitComputing *computing)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : computing = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_limit_computing_dispose(GLimitComputing *computing)
+{
+ G_OBJECT_CLASS(g_limit_computing_parent_class)->dispose(G_OBJECT(computing));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : computing = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_limit_computing_finalize(GLimitComputing *computing)
+{
+ G_OBJECT_CLASS(g_limit_computing_parent_class)->finalize(G_OBJECT(computing));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = ensemble d'instructions désassemblées. *
+* routines = prototypes existants à insérer. *
+* count = quantité de ces prototypes. *
+* begin = point de départ du parcours de liste. *
+* end = point d'arrivée exclu du parcours. *
+* id = identifiant du message affiché à l'utilisateur. *
+* *
+* Description : Crée une tâche de calculs de limites différée. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GLimitComputing *g_limit_computing_new(const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, bstatus_id_t id)
+{
+ GLimitComputing *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_LIMIT_COMPUTING, NULL);
+
+ result->proc = proc;
+
+ result->exe_ranges = exe_ranges;
+ result->exe_count = exe_count;
+
+ result->routines = routines;
+ result->count = count;
+ result->begin = begin;
+ result->end = end;
+
+ result->id = id;
+
+ return result;
+
+}
/******************************************************************************
@@ -64,14 +260,10 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun
/******************************************************************************
* *
-* Paramètres : format = format du binaire concerné par la procédure. *
-* proc = ensemble d'instructions désassemblées. *
-* routines = prototypes existants à insérer. *
-* count = quantité de ces prototypes. *
-* statusbar = barre de statut avec progression à mettre à jour.*
-* id = identifiant du message affiché à l'utilisateur. *
+* Paramètres : computing = récupération à mener. *
+* statusbar = barre de statut à tenir informée. *
* *
-* Description : S'assure que toutes les routines ont une taille définie. *
+* Description : Assure le calcul de limites de routines en différé. *
* *
* Retour : - *
* *
@@ -79,31 +271,30 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun
* *
******************************************************************************/
-void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+static void g_limit_computing_process(GLimitComputing *computing, GtkExtStatusBar *statusbar)
{
- mrange_t *exe_ranges; /* Liste de zones exécutables */
- size_t exe_count; /* Nombre de ces zones */
size_t i; /* Boucle de parcours */
+ GBinRoutine *routine; /* Routine en traitement */
const mrange_t *range; /* Emplacement courant */
vmpa2t addr; /* Adresse à conserver */
GArchInstruction *start; /* Première instruction */
phys_t diff; /* Taille définie par déduction*/
mrange_t new; /* Nouvel emplacement taillé */
- exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
-
- for (i = 0; i < count; i++)
+ for (i = computing->begin; i < computing->end; i++)
{
//gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count);
- range = g_binary_routine_get_range(routines[i]);
+ routine = computing->routines[i];
+
+ range = g_binary_routine_get_range(routine);
if (get_mrange_length(range) > 0) continue;
copy_vmpa(&addr, get_mrange_addr(range));
/* Marquage de la première instruction */
- start = g_arch_processor_find_instr_by_address(proc, &addr);
+ start = g_arch_processor_find_instr_by_address(computing->proc, &addr);
if (start == NULL) continue;
@@ -112,9 +303,9 @@ void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRout
g_arch_instruction_set_flag(start, AIF_ROUTINE_START);
/* Si on peut se raccrocher à la routine suivante... */
- if ((i + 1) < count)
+ if ((i + 1) < computing->count)
{
- range = g_binary_routine_get_range(routines[i + 1]);
+ range = g_binary_routine_get_range(computing->routines[i + 1]);
diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
@@ -123,7 +314,7 @@ void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRout
/* Sinon on va jusqu'à la fin de la zone ! */
else
{
- range = find_x_range_for_addr(exe_ranges, exe_count, &addr);
+ range = find_x_range_for_addr(computing->exe_ranges, computing->exe_count, &addr);
if (range == NULL) continue;
diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
@@ -133,10 +324,73 @@ void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRout
init_mrange(&new, &addr, diff);
- g_binary_routine_set_range(routines[i], &new);
+ g_binary_routine_set_range(routine, &new);
}
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* POINT D'ENTREE ET DECOUPAGES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format du binaire concerné par la procédure. *
+* proc = ensemble d'instructions désassemblées. *
+* routines = prototypes existants à insérer. *
+* count = quantité de ces prototypes. *
+* gid = identifiant du groupe de travail à utiliser. *
+* id = identifiant du message affiché à l'utilisateur. *
+* *
+* Description : S'assure que toutes les routines ont une taille définie. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRoutine **routines, size_t count, wgroup_id_t gid, bstatus_id_t id)
+{
+ mrange_t *exe_ranges; /* Liste de zones exécutables */
+ size_t exe_count; /* Nombre de ces zones */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ size_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ guint i; /* Boucle de parcours */
+ size_t begin; /* Début de bloc de traitement */
+ size_t end; /* Fin d'un bloc de traitement */
+ GLimitComputing *computing; /* Tâche de calcul à programmer*/
+
+ exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
+
+ runs_count = g_get_num_processors();
+
+ run_size = count / runs_count;
+
+ queue = get_work_queue();
+
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = i * run_size;
+
+ if ((i + 1) < runs_count)
+ end = count - begin;
+ else
+ end = begin + run_size;
+
+ computing = g_limit_computing_new(proc, exe_ranges, exe_count, routines, count, begin, end, id);
+
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(computing), gid);
+
+ }
+
+ g_work_queue_wait_for_completion(queue, gid);
+
if (exe_ranges != NULL)
free(exe_ranges);
diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h
index eeffc71..2fa3303 100644
--- a/src/analysis/disass/limit.h
+++ b/src/analysis/disass/limit.h
@@ -28,12 +28,16 @@
#include "../routine.h"
#include "../../arch/processor.h"
#include "../../format/executable.h"
+#include "../../glibext/delayed.h"
#include "../../gtkext/gtkextstatusbar.h"
+/* -------------------------- POINT D'ENTREE ET DECOUPAGES -------------------------- */
+
+
/* S'assure que toutes les routines ont une taille définie. */
-void limit_all_routines(GExeFormat *, const GArchProcessor *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
+void limit_all_routines(GExeFormat *, const GArchProcessor *, GBinRoutine **, size_t, wgroup_id_t, bstatus_id_t);