summaryrefslogtreecommitdiff
path: root/src/analysis/disass/fetch.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-12-19 20:22:14 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-12-19 20:22:14 (GMT)
commit5710f9d5be56b427ccfa48f6a730d70396817efe (patch)
tree4b694774ce446295ef5b01a7df28bd8160b97025 /src/analysis/disass/fetch.c
parent8ff010a34762737016624a68f593d0e6736d4349 (diff)
Fixed several bugs when processing concurrent delayed works.
Diffstat (limited to 'src/analysis/disass/fetch.c')
-rw-r--r--src/analysis/disass/fetch.c88
1 files changed, 75 insertions, 13 deletions
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 5caf573..29d8923 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -309,7 +309,8 @@ static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusB
/* Poursuit l'analyse à partir des points d'entrée découverts. */
static void follow_execution_flow_v2(GProcContext *, const GDelayedFetching *);
-
+/* Etudie le besoin d'attendre d'avantage de prochaines tâches. */
+static bool check_if_extra_wait_is_needed(GWorkQueue *, wgroup_id_t, GProcContext *);
@@ -331,11 +332,14 @@ static void follow_execution_flow_v2(GProcContext *, const GDelayedFetching *);
static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *template)
{
GWorkQueue *queue; /* Gestionnaire de différés */
+ gint *remaining_counter; /* Compteur à considérer */
virt_t virt; /* Adresse de départ dépilée */
GDelayedFetching *fetching; /* Récupération à mener */
queue = get_work_queue();
+ remaining_counter = (gint *)g_object_get_data(G_OBJECT(ctx), "remaining_counter");
+
while (g_proc_context_pop_drop_point(ctx, &virt))
{
fetching = g_delayed_fetching_new(template, virt);
@@ -351,6 +355,16 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *
g_work_queue_schedule_work(queue, G_DELAYED_WORK(fetching), template->gid);
+ /**
+ * Le décompte n'est réalisé qu'après la programmation de la tâche.
+ * Ainsi, lors de l'attente de la fin des traitements, on a la garantie
+ * de ne pas avoir de trou entre le dépilement des points et la programmation
+ * des tâches de traitement associées.
+ */
+
+ if (g_atomic_int_dec_and_test(remaining_counter))
+ g_work_queue_wake_up_waiters(queue, template->gid);
+
}
}
@@ -358,6 +372,45 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *
/******************************************************************************
* *
+* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail. *
+* id = identifiant d'un groupe de travail. *
+* ctx = contexte de désass. avec une nouvelle entrée. *
+* *
+* Description : Etudie le besoin d'attendre d'avantage de prochaines tâches. *
+* *
+* Retour : true pour attendre d'avantage, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GProcContext *ctx)
+{
+ bool result; /* Bilan à retourner */
+ gint *remaining_counter; /* Compteur à considérer */
+
+ remaining_counter = (gint *)g_object_get_data(G_OBJECT(ctx), "remaining_counter");
+
+ result = (g_atomic_int_get(remaining_counter) > 0);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
* Paramètres : binary = représentation de binaire chargé. *
* ctx = contexte offert en soutien à un désassemblage. *
* areas = liste de zones contenant des données à traiter. *
@@ -435,15 +488,9 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup
GBinContent *content; /* Contenu binaire à manipuler */
phys_t length; /* Taille des données à lire */
GWorkQueue *queue; /* Gestionnaire de différés */
+ gint remaining_counter; /* Quantité de points restants */
double done; /* Portion de travail accompli */
-
-
-
-
-
-
-
/* Constitution du modèle de référence */
template.gid = gid;
@@ -463,24 +510,33 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup
/* Amorce des traitements */
- g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow_v2), &template);
-
queue = get_work_queue();
+ g_atomic_int_set(&remaining_counter, 0);
+
+ g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", &remaining_counter);
+
+ g_proc_context_attach_counter(template.ctx, &remaining_counter);
+
/**
* 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);
+
+ g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow_v2), &template);
+
template.info = init_progessive_status(statusbar,
_("Disassembling following the execution flow..."),
0, length);
-
+
g_binary_format_setup_disassembling_context(format, template.ctx);
g_work_queue_wait_for_completion(queue, gid);
- printf("===================== DONE !\n");
-
done = get_current_progessive_status(template.info);
fini_progessive_status(template.info);
@@ -495,6 +551,12 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup
ensure_all_mem_areas_are_filled(template.areas, template.count, template.ctx, template.info);
+ g_work_queue_wait_for_completion(queue, gid);
+
+ g_work_queue_set_extra_wait_callback(queue, gid, NULL, NULL);
+
+ g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", NULL);
+
fini_progessive_status(template.info);
/**