From 518ce6e1594ba80be4286bd3e561b0b7f73ce4b0 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 21 Mar 2017 22:18:53 +0100
Subject: Restricted an instruction iterator to a given memory range if
 requested.

---
 ChangeLog                    |  9 ++++++
 src/analysis/disass/dragon.c | 13 ++------
 src/arch/instriter.c         | 75 ++++++++++++++++++++++++++++++++++++++++++++
 src/arch/instriter.h         |  3 ++
 4 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f3c4e88..f41802b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,15 @@
 
 17-03-21  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/analysis/disass/dragon.c:
+	Update code.
+
+	* src/arch/instriter.c:
+	* src/arch/instriter.h:
+	Restrict an instruction iterator to a given memory range if requested.
+
+17-03-21  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/glibext/gbufferline.c:
 	* src/glibext/linecolumn.c:
 	* src/glibext/linecolumn.h:
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c
index 80329dc..b4c85c0 100644
--- a/src/analysis/disass/dragon.c
+++ b/src/analysis/disass/dragon.c
@@ -101,7 +101,6 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
     GArchInstruction *last;                 /* Mémorisation du passé       */
     instr_iter_t *iter;                     /* Boucle de parcours          */
     GArchInstruction *instr;                /* Instruction analysée        */
-    const mrange_t *irange;                 /* Emplacement d'instruction   */
     instr_link_t *sources;                  /* Liste des instructions liées*/
     size_t scount;                          /* Nombre de liens de source   */
     bool cut;                               /* Un découpage a été réalisé ?*/
@@ -119,20 +118,12 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
     iter = g_arch_processor_get_covered_iter_from_address(proc, coverage, start);
     if (iter == NULL) goto cdn_no_coverage;
 
+    restrict_instruction_iterator(iter, range);
+
     for (last = NULL, instr = get_instruction_iterator_current(iter);
          instr != NULL;
          last = instr, instr = get_instruction_iterator_next(iter))
     {
-        /* L'instruction sort-elle des clous ? */
-
-        irange = g_arch_instruction_get_range(instr);
-
-        if (!mrange_contains_mrange(range, irange))
-        {
-            g_object_unref(G_OBJECT(instr));
-            break;
-        }
-
         /* Découpage en blocs */
 
         if (need_alloc)
diff --git a/src/arch/instriter.c b/src/arch/instriter.c
index 2c922d8..23525f3 100644
--- a/src/arch/instriter.c
+++ b/src/arch/instriter.c
@@ -39,6 +39,9 @@ typedef struct _instr_iter_t
 
     size_t index;                           /* Instruction courante        */
 
+    mrange_t restriction;                   /* Enventuelle limite de zone  */
+    bool is_restricted;                     /* Validité de l'étendue       */
+
 } instr_iter_t;
 
 
@@ -69,6 +72,8 @@ instr_iter_t *create_instruction_iterator(GArchProcessor *proc, size_t index)
 
     result->index = index;
 
+    result->is_restricted = false;
+
     return result;
 
 }
@@ -97,6 +102,28 @@ void delete_instruction_iterator(instr_iter_t *iter)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iter  = itérateur à traiter.                                 *
+*                range = bornes de l'espace de parcours.                      *
+*                                                                             *
+*  Description : Limite le parcours des instructions à une zone donnée.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void restrict_instruction_iterator(instr_iter_t *iter, const mrange_t *range)
+{
+    copy_mrange(&iter->restriction, range);
+
+    iter->is_restricted = true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : iter = itérateur à manipuler.                                *
 *                                                                             *
 *  Description : Fournit l'instruction courante de l'itérateur.               *
@@ -110,6 +137,7 @@ void delete_instruction_iterator(instr_iter_t *iter)
 GArchInstruction *get_instruction_iterator_current(instr_iter_t *iter)
 {
     GArchInstruction *result;               /* Résultat à retourner        */
+    const mrange_t *irange;                 /* Emplacement d'instruction   */
 
     g_arch_processor_lock(iter->proc);
 
@@ -119,7 +147,24 @@ GArchInstruction *get_instruction_iterator_current(instr_iter_t *iter)
     else
     {
         if (iter->index < g_arch_processor_count_instructions(iter->proc))
+        {
             result = g_arch_processor_get_instruction(iter->proc, iter->index);
+
+            /* L'instruction sort-elle des clous ? */
+            if (iter->is_restricted)
+            {
+                irange = g_arch_instruction_get_range(result);
+
+                if (!mrange_contains_mrange(&iter->restriction, irange))
+                {
+                    g_object_unref(G_OBJECT(result));
+                    result = NULL;
+                }
+
+            }
+
+        }
+
         else
             result = NULL;
 
@@ -147,6 +192,7 @@ GArchInstruction *get_instruction_iterator_current(instr_iter_t *iter)
 GArchInstruction *get_instruction_iterator_prev(instr_iter_t *iter)
 {
     GArchInstruction *result;               /* Résultat à retourner        */
+    const mrange_t *irange;                 /* Emplacement d'instruction   */
 
     g_arch_processor_lock(iter->proc);
 
@@ -159,6 +205,20 @@ GArchInstruction *get_instruction_iterator_prev(instr_iter_t *iter)
         {
             iter->index--;
             result = g_arch_processor_get_instruction(iter->proc, iter->index);
+
+            /* L'instruction sort-elle des clous ? */
+            if (iter->is_restricted)
+            {
+                irange = g_arch_instruction_get_range(result);
+
+                if (!mrange_contains_mrange(&iter->restriction, irange))
+                {
+                    g_object_unref(G_OBJECT(result));
+                    result = NULL;
+                }
+
+            }
+
         }
 
         else
@@ -188,6 +248,7 @@ GArchInstruction *get_instruction_iterator_prev(instr_iter_t *iter)
 GArchInstruction *get_instruction_iterator_next(instr_iter_t *iter)
 {
     GArchInstruction *result;               /* Résultat à retourner        */
+    const mrange_t *irange;                 /* Emplacement d'instruction   */
 
     g_arch_processor_lock(iter->proc);
 
@@ -200,6 +261,20 @@ GArchInstruction *get_instruction_iterator_next(instr_iter_t *iter)
         {
             iter->index++;
             result = g_arch_processor_get_instruction(iter->proc, iter->index);
+
+            /* L'instruction sort-elle des clous ? */
+            if (iter->is_restricted)
+            {
+                irange = g_arch_instruction_get_range(result);
+
+                if (!mrange_contains_mrange(&iter->restriction, irange))
+                {
+                    g_object_unref(G_OBJECT(result));
+                    result = NULL;
+                }
+
+            }
+
         }
 
         else
diff --git a/src/arch/instriter.h b/src/arch/instriter.h
index 479fcbe..23bc323 100644
--- a/src/arch/instriter.h
+++ b/src/arch/instriter.h
@@ -42,6 +42,9 @@ instr_iter_t *create_instruction_iterator(GArchProcessor *, size_t);
 /* Détruit un itérateur mis en place. */
 void delete_instruction_iterator(instr_iter_t *);
 
+/* Limite le parcours des instructions à une zone donnée. */
+void restrict_instruction_iterator(instr_iter_t *, const mrange_t *);
+
 /* Fournit l'instruction courante de l'itérateur. */
 GArchInstruction *get_instruction_iterator_current(instr_iter_t *);
 
-- 
cgit v0.11.2-87-g4458