summaryrefslogtreecommitdiff
path: root/src/analysis/disass/limit.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-01-12 21:31:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-01-12 21:31:50 (GMT)
commit9dad150aedfae6423f1166665d47674df51014d2 (patch)
tree2876c1b1bae754f46d8b9c804920e24329e152d9 /src/analysis/disass/limit.c
parent810de6edb44a18601d0a958be11e48252114d2ad (diff)
Used all available CPUs to compute routines limits.
Diffstat (limited to 'src/analysis/disass/limit.c')
-rw-r--r--src/analysis/disass/limit.c292
1 files changed, 273 insertions, 19 deletions
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);