From 9dad150aedfae6423f1166665d47674df51014d2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 12 Jan 2016 22:31:50 +0100 Subject: Used all available CPUs to compute routines limits. --- ChangeLog | 12 ++ src/analysis/disass/disassembler.c | 2 +- src/analysis/disass/fetch.c | 1 - src/analysis/disass/limit.c | 292 ++++++++++++++++++++++++++++++++++--- src/analysis/disass/limit.h | 6 +- 5 files changed, 291 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61dd761..44486bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +16-01-12 Cyrille Bagard + + * src/analysis/disass/disassembler.c: + Update code. + + * src/analysis/disass/fetch.c: + Typo. + + * src/analysis/disass/limit.c: + * src/analysis/disass/limit.h: + Use all available CPUs to compute routines limits. + 16-01-10 Cyrille Bagard * src/analysis/disass/limit.c: 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 +#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); -- cgit v0.11.2-87-g4458