From 124c8410dbfcad59d66b850c50c96ec73a607ab7 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 15 Dec 2016 14:40:28 +0100
Subject: Defined proper accesses to instructions loaded by a processor.

---
 ChangeLog                          |  37 +++++
 plugins/androhelpers/params.c      |   2 +-
 plugins/androhelpers/switch.c      |   2 +-
 plugins/androhelpers/try_n_catch.c |   4 +-
 plugins/libcsem/exit.c             |   7 +
 plugins/pychrysa/arch/instriter.c  |   4 +-
 plugins/pychrysa/arch/processor.c  | 109 +-----------
 src/analysis/db/items/comment.c    |   2 +
 src/analysis/db/items/switcher.c   |   6 +-
 src/analysis/disass/disassembler.c |   6 +-
 src/analysis/disass/dragon.c       |  51 +++---
 src/analysis/disass/dragon.h       |   2 +-
 src/analysis/disass/instructions.c |  32 +++-
 src/analysis/disass/limit.c        |   4 +-
 src/analysis/disass/limit.h        |   2 +-
 src/analysis/disass/links.c        |   5 +-
 src/analysis/disass/links.h        |   2 +-
 src/analysis/disass/output.c       |  10 +-
 src/analysis/disass/routines.c     |   4 +-
 src/analysis/disass/routines.h     |   2 +-
 src/arch/dalvik/link.c             |   7 +
 src/arch/instriter.c               |  81 ++++++++-
 src/arch/instriter.h               |   6 +
 src/arch/link.c                    |  34 +++-
 src/arch/processor.c               | 329 +++++++++++++++++++++----------------
 src/arch/processor.h               |  60 ++++---
 src/gtkext/gtkgraphview.c          |  68 +++++---
 src/gui/menus/edition.c            |  11 +-
 src/gui/panels/strings.c           |   7 +-
 src/gui/status.c                   |   2 +
 30 files changed, 550 insertions(+), 348 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 00d2f12..7271d7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,42 @@
 16-12-15  Cyrille Bagard <nocbos@gmail.com>
 
+	* plugins/androhelpers/params.c:
+	* plugins/androhelpers/switch.c:
+	* plugins/androhelpers/try_n_catch.c:
+	* plugins/libcsem/exit.c:
+	* plugins/pychrysa/arch/instriter.c:
+	* plugins/pychrysa/arch/processor.c:
+	* src/analysis/db/items/comment.c:
+	* src/analysis/db/items/switcher.c:
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/dragon.c:
+	* src/analysis/disass/dragon.h:
+	* src/analysis/disass/instructions.c:
+	* src/analysis/disass/limit.c:
+	* src/analysis/disass/limit.h:
+	* src/analysis/disass/links.c:
+	* src/analysis/disass/links.h:
+	* src/analysis/disass/output.c:
+	* src/analysis/disass/routines.c:
+	* src/analysis/disass/routines.h:
+	* src/arch/dalvik/link.c:
+	* src/arch/instriter.c:
+	* src/arch/instriter.h:
+	* src/arch/link.c:
+	Update code.
+
+	* src/arch/processor.c:
+	* src/arch/processor.h:
+	Define proper accesses to instructions loaded by a processor.
+
+	* src/gtkext/gtkgraphview.c:
+	* src/gui/menus/edition.c:
+	* src/gui/panels/strings.c:
+	* src/gui/status.c:
+	Update code.
+
+16-12-15  Cyrille Bagard <nocbos@gmail.com>
+
 	* plugins/pychrysa/arch/Makefile.am:
 	Add the 'instriter.[ch]' files to libpychrysaarch_la_SOURCES.
 
diff --git a/plugins/androhelpers/params.c b/plugins/androhelpers/params.c
index c9b1109..20e0da9 100644
--- a/plugins/androhelpers/params.c
+++ b/plugins/androhelpers/params.c
@@ -194,7 +194,7 @@ bool replace_parameters(GLoadedBinary *binary)
 
     format = G_DEX_FORMAT(g_loaded_binary_get_format(binary));
     proc = g_loaded_binary_get_processor(binary);
-    instrs = g_arch_processor_get_disassembled_instructions(proc);
+    instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
 
     cls_count = g_dex_format_count_classes(format);
     for (i = 0; i < cls_count; i++)
diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c
index 43b6ae1..0700cc8 100644
--- a/plugins/androhelpers/switch.c
+++ b/plugins/androhelpers/switch.c
@@ -398,7 +398,7 @@ bool extract_switch_info(GLoadedBinary *binary, bool link)
 
     format = G_DEX_FORMAT(g_loaded_binary_get_format(binary));
     proc = g_loaded_binary_get_processor(binary);
-    instrs = g_arch_processor_get_disassembled_instructions(proc);
+    instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
 
     cls_count = g_dex_format_count_classes(format);
     for (i = 0; i < cls_count; i++)
diff --git a/plugins/androhelpers/try_n_catch.c b/plugins/androhelpers/try_n_catch.c
index 28f7061..dbe0ef4 100644
--- a/plugins/androhelpers/try_n_catch.c
+++ b/plugins/androhelpers/try_n_catch.c
@@ -125,7 +125,7 @@ static void attach_caught_code(const GLoadedBinary *binary, const GBinRoutine *r
     end = start + try->insn_count * sizeof(uint16_t);
 
     proc = g_loaded_binary_get_processor(binary);
-    instrs = g_arch_processor_get_disassembled_instructions(proc);
+    instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
 
     first = g_arch_instruction_find_by_address(instrs, start, true);
     next = g_arch_instruction_find_by_address(instrs, end, true);
@@ -253,7 +253,7 @@ static caught_exception **build_all_destinations_list(const GLoadedBinary *binar
     format = G_DEX_FORMAT(g_loaded_binary_get_format(binary));
 
     proc = g_loaded_binary_get_processor(binary);
-    instrs = g_arch_processor_get_disassembled_instructions(proc);
+    instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
     instrs = g_arch_instruction_find_by_address(instrs, start, true);
 
     /* Création d'un espace mémoire pour les listes */
diff --git a/plugins/libcsem/exit.c b/plugins/libcsem/exit.c
index cbfec64..20511aa 100644
--- a/plugins/libcsem/exit.c
+++ b/plugins/libcsem/exit.c
@@ -70,6 +70,9 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
 
     instr = g_arch_processor_find_instr_by_address(proc,  get_mrange_addr(range));
 
+    if (instr == NULL)
+        goto mokoear_not_found;
+
     g_arch_instruction_rlock_src(instr);
     count = g_arch_instruction_get_sources(instr, &sources);
 
@@ -83,6 +86,10 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
 
     g_arch_instruction_runlock_src(instr);
 
+    g_object_unref(G_OBJECT(instr));
+
+ mokoear_not_found:
+
     g_object_unref(G_OBJECT(proc));
 
  mokoear_done_with_sym:
diff --git a/plugins/pychrysa/arch/instriter.c b/plugins/pychrysa/arch/instriter.c
index 1e5346e..0d65f26 100644
--- a/plugins/pychrysa/arch/instriter.c
+++ b/plugins/pychrysa/arch/instriter.c
@@ -28,7 +28,6 @@
 #include <pygobject.h>
 
 
-#include <arch/instriter.h>
 #include <arch/processor.h>
 
 
@@ -101,7 +100,10 @@ static PyObject *py_instr_iterator_next(PyInstrIterator *self)
     next = get_instruction_iterator_next(self->native);
 
     if (next != NULL)
+    {
         result = pygobject_new(G_OBJECT(next));
+        g_object_unref(G_OBJECT(next));
+    }
 
     else
     {
diff --git a/plugins/pychrysa/arch/processor.c b/plugins/pychrysa/arch/processor.c
index 3ef56e4..e34bf1f 100644
--- a/plugins/pychrysa/arch/processor.c
+++ b/plugins/pychrysa/arch/processor.c
@@ -68,12 +68,6 @@ static PyObject *py_arch_processor_get_instrs(PyObject *, void *);
 /* Recherche une instruction d'après son adresse. */
 static PyObject *py_arch_processor_find_instr_by_addr(PyObject *, PyObject *);
 
-/* Fournit l'instruction qui en précède une autre. */
-static PyObject *py_arch_processor_get_prev_instr(PyObject *, PyObject *);
-
-/* Fournit l'instruction qui en suit une autre. */
-static PyObject *py_arch_processor_get_next_instr(PyObject *, PyObject *);
-
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -182,102 +176,11 @@ static PyObject *py_arch_processor_find_instr_by_addr(PyObject *self, PyObject *
     found = g_arch_processor_find_instr_by_address(proc, addr);
 
     if (found != NULL)
-        result = pygobject_new(G_OBJECT(found));
-
-    else
     {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = processeur d'architecture à manipuler.                *
-*                args = instruction représentant le point de départ.          *
-*                                                                             *
-*  Description : Fournit l'instruction qui en précède une autre.              *
-*                                                                             *
-*  Retour      : Instruction précédente trouvée, ou NULL.                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_arch_processor_get_prev_instr(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Instance à retourner        */
-    PyObject *instr_obj;                    /* Objet pour une instruction  */
-    int ret;                                /* Bilan de lecture des args.  */
-    GArchProcessor *proc;                   /* Processeur manipulé         */
-    GArchInstruction *instr;                /* Instruction de référence    */
-    GArchInstruction *found;                /* Instruction liée trouvée    */
-
-    ret = PyArg_ParseTuple(args, "O", &instr_obj);
-    if (!ret) return NULL;
-
-    ret = PyObject_IsInstance(instr_obj, (PyObject *)get_python_arch_instruction_type());
-    if (!ret) return NULL;
-
-    proc = G_ARCH_PROCESSOR(pygobject_get(self));
-    instr = G_ARCH_INSTRUCTION(pygobject_get(instr_obj));
-
-    found = g_arch_processor_get_prev_instr(proc, instr);
-
-    if (found != NULL)
         result = pygobject_new(G_OBJECT(found));
-
-    else
-    {
-        result = Py_None;
-        Py_INCREF(result);
+        g_object_unref(G_OBJECT(found));
     }
 
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = processeur d'architecture à manipuler.                *
-*                args = instruction représentant le point de départ.          *
-*                                                                             *
-*  Description : Fournit l'instruction qui en suit une autre.                 *
-*                                                                             *
-*  Retour      : Instruction suivante trouvée, ou NULL.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_arch_processor_get_next_instr(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Instance à retourner        */
-    PyObject *instr_obj;                    /* Objet pour une instruction  */
-    int ret;                                /* Bilan de lecture des args.  */
-    GArchProcessor *proc;                   /* Processeur manipulé         */
-    GArchInstruction *instr;                /* Instruction de référence    */
-    GArchInstruction *found;                /* Instruction liée trouvée    */
-
-    ret = PyArg_ParseTuple(args, "O", &instr_obj);
-    if (!ret) return NULL;
-
-    ret = PyObject_IsInstance(instr_obj, (PyObject *)get_python_arch_instruction_type());
-    if (!ret) return NULL;
-
-    proc = G_ARCH_PROCESSOR(pygobject_get(self));
-    instr = G_ARCH_INSTRUCTION(pygobject_get(instr_obj));
-
-    found = g_arch_processor_get_next_instr(proc, instr);
-
-    if (found != NULL)
-        result = pygobject_new(G_OBJECT(found));
-
     else
     {
         result = Py_None;
@@ -309,16 +212,6 @@ PyTypeObject *get_python_arch_processor_type(void)
             METH_VARARGS,
             "find_instr_by_addr($self, addr, /)\n--\n\nLook for an instruction located at a given address."
         },
-        {
-            "get_prev_instr", py_arch_processor_get_prev_instr,
-            METH_VARARGS,
-            "get_prev_instr($self, instr, /)\n--\n\nProvide the instruction preceding a given instruction."
-        },
-        {
-            "get_next_instr", py_arch_processor_get_next_instr,
-            METH_VARARGS,
-            "get_next_instr($self, instr, /)\n--\n\nProvide the instruction following a given instruction."
-        },
         { NULL }
     };
 
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 45331b8..55893d1 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -638,6 +638,8 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
 
             }
 
+            g_object_unref(G_OBJECT(instr));
+
             g_object_unref(G_OBJECT(proc));
 
         }
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 15354e9..748c934 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -527,7 +527,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
     }
 
     result = G_IS_IMM_OPERAND(op);
-    if (!result) goto exit_instr;
+    if (!result) goto exit_operand;
 
     /* Traitement au niveau du rendu graphique */
 
@@ -559,6 +559,10 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
 
     /* TODO g_object_unref(G_OBJECT(buffer));*/
 
+ exit_operand:
+
+    g_object_unref(G_OBJECT(proc));
+
  exit_instr:
 
     g_object_unref(G_OBJECT(proc));
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 813701e..f210bd1 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -262,7 +262,11 @@ static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, co
 
     runs_count = g_get_num_processors();
 
-    ins_count = g_arch_processor_count_disassembled_instructions(proc);
+    g_arch_processor_lock(proc);
+
+    ins_count = g_arch_processor_count_instructions(proc);
+
+    g_arch_processor_unlock(proc);
 
     run_size = ins_count / runs_count;
 
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c
index 01e985d..cc1346c 100644
--- a/src/analysis/disass/dragon.c
+++ b/src/analysis/disass/dragon.c
@@ -49,7 +49,7 @@ struct _dragon_node
 
 
 /* Dénombre le nombre de noeuds présents dans une routine. */
-static dragon_node *create_dragon_nodes(const GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *, size_t *);
+static dragon_node *create_dragon_nodes(GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *, size_t *);
 
 /* Supprime de la mémoire tous les noeuds détectés. */
 static void delete_dragon_nodes(dragon_node *, size_t);
@@ -93,13 +93,14 @@ struct _dragon_knight
 *                                                                             *
 ******************************************************************************/
 
-static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start, size_t *count)
+static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start, size_t *count)
 {
     dragon_node *result;                    /* Liste à créer et renvoyer   */
     size_t allocated;                       /* Dimensionnement en mémoire  */
     bool need_alloc;                        /* Besoin d'une extension ?    */
     GArchInstruction *last;                 /* Mémorisation du passé       */
-    GArchInstruction *iter;                 /* Boucle de parcours          */
+    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   */
@@ -115,16 +116,22 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
     allocated = 0;
     need_alloc = true;
 
-    for (last = NULL, iter = g_arch_processor_find_covered_instr_by_address(proc, coverage, start);
-         iter != NULL;
-         last = iter, iter = g_arch_instruction_get_next_iter(iter /* FIXME : list*/, iter, ~0))
+    iter = g_arch_processor_get_covered_iter_from_address(proc, coverage, start);
+    if (iter == NULL) goto cdn_no_coverage;
+
+    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(iter);
+        irange = g_arch_instruction_get_range(instr);
 
         if (!mrange_contains_mrange(range, irange))
+        {
+            g_object_unref(G_OBJECT(instr));
             break;
+        }
 
         /* Découpage en blocs */
 
@@ -142,7 +149,7 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
 
             new = &result[*count - 1];
 
-            new->first = iter;
+            new->first = instr;
 
         }
 
@@ -165,8 +172,8 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
         {
             /* Analyse des sources */
 
-            g_arch_instruction_rlock_src(iter);
-            scount = g_arch_instruction_get_sources(iter, &sources);
+            g_arch_instruction_rlock_src(instr);
+            scount = g_arch_instruction_get_sources(instr, &sources);
 
             cut = false;
 
@@ -192,7 +199,7 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
 
                         new = &result[*count - 1];
 
-                        new->first = iter;
+                        new->first = instr;
 
                         cut = true;
 
@@ -203,14 +210,14 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
 
                 }
 
-            g_arch_instruction_runlock_src(iter);
+            g_arch_instruction_runlock_src(instr);
 
         }
 
         /* Analyse des destinations */
 
-        g_arch_instruction_rlock_dest(iter);
-        dcount = g_arch_instruction_get_destinations(iter, &dests);
+        g_arch_instruction_rlock_dest(instr);
+        dcount = g_arch_instruction_get_destinations(instr, &dests);
 
         cut = false;
 
@@ -219,7 +226,7 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
             {
                 case ILT_JUMP:
 
-                    result[*count - 1].last = iter;
+                    result[*count - 1].last = instr;
 
                     cut = true;
 
@@ -232,21 +239,27 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
 
             }
 
-        g_arch_instruction_runlock_dest(iter);
+        g_arch_instruction_runlock_dest(instr);
 
-        if (!need_alloc && g_arch_instruction_get_flags(iter) & AIF_RETURN_POINT)
+        if (!need_alloc && g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
         {
-            result[*count - 1].last = iter;
+            result[*count - 1].last = instr;
 
             need_alloc = true;
 
         }
 
+        g_object_unref(G_OBJECT(instr));
+
     }
 
     if (*count > 0)
         result[*count - 1].last = last;
 
+    delete_instruction_iterator(iter);
+
+ cdn_no_coverage:
+
     return result;
 
 }
@@ -623,7 +636,7 @@ const bitfield_t *get_domination_bits(const dragon_node *node)
 *                                                                             *
 ******************************************************************************/
 
-dragon_knight *begin_dragon_knight(const GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start)
+dragon_knight *begin_dragon_knight(GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start)
 {
     dragon_knight *result;                  /* Données à retourner         */
     dragon_node *nodes;                     /* Noeuds mis en place         */
diff --git a/src/analysis/disass/dragon.h b/src/analysis/disass/dragon.h
index 095281b..897e21b 100644
--- a/src/analysis/disass/dragon.h
+++ b/src/analysis/disass/dragon.h
@@ -72,7 +72,7 @@ typedef struct _dragon_knight dragon_knight;
 
 
 /* Attaque la complexité d'un code en créant des noeuds. */
-dragon_knight *begin_dragon_knight(const GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *);
+dragon_knight *begin_dragon_knight(GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *);
 
 /* Supprime de la mémoire les données d'une complexité de code. */
 void end_dragon_knight(dragon_knight *);
diff --git a/src/analysis/disass/instructions.c b/src/analysis/disass/instructions.c
index 799d196..d83536d 100644
--- a/src/analysis/disass/instructions.c
+++ b/src/analysis/disass/instructions.c
@@ -251,10 +251,16 @@ void g_instructions_study_do_link_operation(GInstructionsStudy *study, size_t in
 {
     GArchInstruction *instr;                /* Instruction en traitement   */
 
-    instr = g_arch_processor_get_disassembled_instruction(study->proc, index);
+    g_arch_processor_lock(study->proc);
+
+    instr = g_arch_processor_get_instruction(study->proc, index);
+
+    g_arch_processor_unlock(study->proc);
 
     g_arch_instruction_call_hook(instr, IPH_LINK, study->proc, study->ctx, study->format);
 
+    g_object_unref(G_OBJECT(instr));
+
 }
 
 
@@ -275,10 +281,16 @@ void g_instructions_study_do_post_operation(GInstructionsStudy *study, size_t in
 {
     GArchInstruction *instr;                /* Instruction en traitement   */
 
-    instr = g_arch_processor_get_disassembled_instruction(study->proc, index);
+    g_arch_processor_lock(study->proc);
+
+    instr = g_arch_processor_get_instruction(study->proc, index);
+
+    g_arch_processor_unlock(study->proc);
 
     g_arch_instruction_call_hook(instr, IPH_POST, study->proc, study->ctx, study->format);
 
+    g_object_unref(G_OBJECT(instr));
+
 }
 
 
@@ -300,16 +312,28 @@ void g_instructions_study_establish_links(GInstructionsStudy *study, size_t inde
     GArchInstruction *instr;                /* Instruction en traitement   */
     GArchInstruction *prev;                 /* Instruction précédente      */
 
-    instr = g_arch_processor_get_disassembled_instruction(study->proc, index);
+    g_arch_processor_lock(study->proc);
+
+    instr = g_arch_processor_get_instruction(study->proc, index);
+
+    g_arch_processor_unlock(study->proc);
 
     if (index > 0)
     {
-        prev = g_arch_processor_get_disassembled_instruction(study->proc, index - 1);
+        g_arch_processor_lock(study->proc);
+
+        prev = g_arch_processor_get_instruction(study->proc, index - 1);
+
+        g_arch_processor_unlock(study->proc);
 
         establish_natural_link(instr, prev);
 
+        g_object_unref(G_OBJECT(prev));
+
     }
 
     establish_links_for_instruction(instr, G_BIN_FORMAT(study->format), study->proc);
 
+    g_object_unref(G_OBJECT(instr));
+
 }
diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c
index c7a9524..28a8264 100644
--- a/src/analysis/disass/limit.c
+++ b/src/analysis/disass/limit.c
@@ -76,7 +76,7 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun
 *                                                                             *
 ******************************************************************************/
 
-void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count)
+void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count)
 {
     const mrange_t *range;                  /* Emplacement courant         */
     vmpa2t addr;                            /* Adresse à conserver         */
@@ -100,6 +100,8 @@ void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, const GArchP
 
     g_arch_instruction_set_flag(start, AIF_ROUTINE_START);
 
+    g_object_unref(G_OBJECT(start));
+
     /* Si on peut se raccrocher à la routine suivante... */
     if (prev != NULL)
     {
diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h
index 431c642..7aba8a6 100644
--- a/src/analysis/disass/limit.h
+++ b/src/analysis/disass/limit.h
@@ -32,7 +32,7 @@
 
 
 /* S'assure qu'une routine est bien bornée. */
-void compute_routine_limit(GBinRoutine *, GBinRoutine *, const GArchProcessor *, mrange_t *, size_t);
+void compute_routine_limit(GBinRoutine *, GBinRoutine *, GArchProcessor *, mrange_t *, size_t);
 
 
 
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 82da37d..18bbeb3 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -178,7 +178,7 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
 *                                                                             *
 ******************************************************************************/
 
-void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format, const GArchProcessor *proc)
+void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format, GArchProcessor *proc)
 {
     bool skip;                              /* Saut des conversions        */
     size_t count;                           /* Nombre d'opérandes présents */
@@ -209,7 +209,10 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
         target = g_arch_processor_find_instr_by_address(proc, &addr);
 
         if (target != NULL)
+        {
             g_arch_instruction_link_with(instr, target, ILT_REF);
+            g_object_unref(G_OBJECT(target));
+        }
 
     }
 
diff --git a/src/analysis/disass/links.h b/src/analysis/disass/links.h
index 8cdf663..bfa68db 100644
--- a/src/analysis/disass/links.h
+++ b/src/analysis/disass/links.h
@@ -35,7 +35,7 @@
 void establish_natural_link(GArchInstruction *, GArchInstruction *);
 
 /* Complète un désassemblage accompli pour une instruction. */
-void establish_links_for_instruction(GArchInstruction *, GBinFormat *, const GArchProcessor *);
+void establish_links_for_instruction(GArchInstruction *, GBinFormat *, GArchProcessor *);
 
 
 
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index f5decb7..0d85870 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -112,7 +112,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
     content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
-    count = g_arch_processor_count_disassembled_instructions(proc);
+    g_arch_processor_lock(proc);
+
+    count = g_arch_processor_count_instructions(proc);
 
     id = gtk_status_stack_add_activity(status, _("Printing all disassebled parts..."), count);
 
@@ -120,7 +122,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
     for (i = 0; i < count; i++)
     {
-        instr = g_arch_processor_get_disassembled_instruction(proc, i);
+        instr = g_arch_processor_get_instruction(proc, i);
 
         iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
 
@@ -322,12 +324,16 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
 
         g_code_buffer_append_new_line(buffer, line);
 
+        g_object_unref(G_OBJECT(instr));
+
         gtk_status_stack_update_activity_value(status, id, 1);
 
     }
 
     gtk_status_stack_remove_activity(status, id);
 
+    g_arch_processor_unlock(proc);
+
     g_object_unref(G_OBJECT(content));
 
     if (portions != NULL)
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index 04ef123..a9414fc 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -38,7 +38,7 @@ struct _GRoutinesStudy
 {
     GDelayedWork parent;                    /* A laisser en premier        */
 
-    const GArchProcessor *proc;             /* Processeurs avec ses instr. */
+    GArchProcessor *proc;                   /* Processeurs avec ses instr. */
 
     mrange_t *exe_ranges;                   /* Liste de zones exécutables  */
     size_t exe_count;                       /* Nombre de ces zones         */
@@ -189,7 +189,7 @@ static void g_routines_study_finalize(GRoutinesStudy *study)
 *                                                                             *
 ******************************************************************************/
 
-GRoutinesStudy *g_routines_study_new(const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)
+GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)
 {
     GRoutinesStudy *result;                /* Tâche à retourner           */
 
diff --git a/src/analysis/disass/routines.h b/src/analysis/disass/routines.h
index 4b4e530..72df309 100644
--- a/src/analysis/disass/routines.h
+++ b/src/analysis/disass/routines.h
@@ -52,7 +52,7 @@ typedef void (* rtn_fallback_cb) (GRoutinesStudy *, size_t);
 
 
 /* Crée une tâche d'étude de routines différée. */
-GRoutinesStudy *g_routines_study_new(const GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb);
+GRoutinesStudy *g_routines_study_new(GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb);
 
 /* Détermine si besoin est les bornes des routines. */
 void g_routines_study_compute_limits(GRoutinesStudy *, size_t);
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
index 311f672..694ec65 100644
--- a/src/arch/dalvik/link.c
+++ b/src/arch/dalvik/link.c
@@ -151,6 +151,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
 
                 g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP);
 
+                g_object_unref(G_OBJECT(target));
+
             }
 
             /* Autres cas */
@@ -223,6 +225,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
 
                     g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP);
 
+                    g_object_unref(G_OBJECT(target));
+
                 }
 
             }
@@ -298,6 +302,9 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
 
         }
 
+        if (switch_ins != NULL)
+            g_object_unref(G_OBJECT(switch_ins));
+
     }
 
 }
diff --git a/src/arch/instriter.c b/src/arch/instriter.c
index 0f33998..5a534d5 100644
--- a/src/arch/instriter.c
+++ b/src/arch/instriter.c
@@ -99,6 +99,83 @@ void delete_instruction_iterator(instr_iter_t *iter)
 *                                                                             *
 *  Paramètres  : iter = itérateur à manipuler.                                *
 *                                                                             *
+*  Description : Fournit l'instruction courante de l'itérateur.               *
+*                                                                             *
+*  Retour      : Instruction suivante trouvée, ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *get_instruction_iterator_current(instr_iter_t *iter)
+{
+    GArchInstruction *result;               /* Résultat à retourner        */
+
+    g_arch_processor_lock(iter->proc);
+
+    if (iter->stamp != g_arch_processor_get_stamp(iter->proc))
+        result = NULL;
+
+    else
+    {
+        if (iter->index < g_arch_processor_count_instructions(iter->proc))
+            result = g_arch_processor_get_instruction(iter->proc, iter->index);
+        else
+            result = NULL;
+
+    }
+
+    g_arch_processor_unlock(iter->proc);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter = itérateur à manipuler.                                *
+*                                                                             *
+*  Description : Fournit l'instruction qui en précède une autre.              *
+*                                                                             *
+*  Retour      : Instruction suivante trouvée, ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *get_instruction_iterator_prev(instr_iter_t *iter)
+{
+    GArchInstruction *result;               /* Résultat à retourner        */
+
+    g_arch_processor_lock(iter->proc);
+
+    if (iter->stamp != g_arch_processor_get_stamp(iter->proc))
+        result = NULL;
+
+    else
+    {
+        if (iter->index > 0)
+            result = g_arch_processor_get_instruction(iter->proc, iter->index);
+        else
+            result = NULL;
+
+        if (result != NULL)
+            iter->index--;
+
+    }
+
+    g_arch_processor_unlock(iter->proc);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter = itérateur à manipuler.                                *
+*                                                                             *
 *  Description : Fournit l'instruction qui en suit une autre.                 *
 *                                                                             *
 *  Retour      : Instruction suivante trouvée, ou NULL.                       *
@@ -118,8 +195,8 @@ GArchInstruction *get_instruction_iterator_next(instr_iter_t *iter)
 
     else
     {
-        if (iter->index < g_arch_processor_count_disassembled_instructions(iter->proc))
-            result = g_arch_processor_get_disassembled_instruction(iter->proc, iter->index);
+        if (iter->index < g_arch_processor_count_instructions(iter->proc))
+            result = g_arch_processor_get_instruction(iter->proc, iter->index);
         else
             result = NULL;
 
diff --git a/src/arch/instriter.h b/src/arch/instriter.h
index b9c7621..74e853d 100644
--- a/src/arch/instriter.h
+++ b/src/arch/instriter.h
@@ -42,6 +42,12 @@ instr_iter_t *create_instruction_iterator(GArchProcessor *, size_t);
 /* Détruit un itérateur mis en place. */
 void delete_instruction_iterator(instr_iter_t *);
 
+/* Fournit l'instruction courante de l'itérateur. */
+GArchInstruction *get_instruction_iterator_current(instr_iter_t *);
+
+/* Fournit l'instruction qui en précède une autre. */
+GArchInstruction *get_instruction_iterator_prev(instr_iter_t *);
+
 /* Fournit l'instruction qui en suit une autre. */
 GArchInstruction *get_instruction_iterator_next(instr_iter_t *);
 
diff --git a/src/arch/link.c b/src/arch/link.c
index 4519bc5..e5406da 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -66,7 +66,10 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
         target = g_arch_processor_find_instr_by_address(proc, &addr);
 
         if (target != NULL)
+        {
             g_arch_instruction_link_with(instr, target, ILT_JUMP);
+            g_object_unref(G_OBJECT(target));
+        }
 
     }
 
@@ -94,8 +97,8 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
     GArchOperand *op;                       /* Opérande numérique en place */
     virt_t virt;                            /* Adresse virtuelle           */
     vmpa2t addr;                            /* Adresse de destination      */
+    instr_iter_t *iter;                     /* Parcours d'instructions     */
     GArchInstruction *target;               /* Ligne visée par la référence*/
-    GArchInstruction *list;                 /* Ensemble des instructions   */
 
     assert(g_arch_instruction_count_operands(instr) > index);
 
@@ -114,24 +117,34 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
 
     if (virt != VMPA_NO_VIRTUAL)
     {
-        /* TODO : utiliser format pour contruire une adresse avec une position physique,
-         * ce qui accélèrerait les recherches.
-         */
         init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
 
-        target = g_arch_processor_find_instr_by_address(proc, &addr);
+        iter = g_arch_processor_get_iter_from_address(proc, &addr);
 
-        if (target != NULL)
+        if (iter != NULL)
         {
-            g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE);
+            target = get_instruction_iterator_current(iter);
+
+            if (target != NULL)
+            {
+                g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE);
 
-            list = g_arch_processor_get_disassembled_instructions(proc);
+                g_object_unref(G_OBJECT(target));
 
-            target = g_arch_instruction_get_next_iter(list, instr, ~0);
+            }
+
+            target = get_instruction_iterator_next(iter);
 
             if (target != NULL)
+            {
                 g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE);
 
+                g_object_unref(G_OBJECT(target));
+
+            }
+
+            delete_instruction_iterator(iter);
+
         }
 
     }
@@ -174,7 +187,10 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
         target = g_arch_processor_find_instr_by_address(proc, &addr);
 
         if (target != NULL)
+        {
             g_arch_instruction_link_with(instr, target, ILT_CALL);
+            g_object_unref(G_OBJECT(target));
+        }
 
     }
 
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 26c7170..24e2db6 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -78,6 +78,8 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction
 /* Termine la définition d'un nouveau groupe d'instructions. */
 static void g_arch_processor_finish_last_coverage(GArchProcessor *, GArchInstruction *, size_t);
 
+/* Recherche rapidement un indice d'instruction via une adresse. */
+static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool, size_t *);
 
 
 
@@ -375,89 +377,28 @@ void g_arch_processor_lock_unlock(GArchProcessor *proc, bool state)
 
 unsigned int g_arch_processor_get_stamp(const GArchProcessor *proc)
 {
-    //assert(g_atomic_int_get(&proc->locked) == 1);
-
     return proc->stamp;
 
 }
 
 
-
-/* ---------------------------------------------------------------------------------- */
-/*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : proc  = architecture à comléter par la procédure.            *
-*                first = première instruction d'un nouveau groupe.            *
-*                start = indice de cette instruction dans l'ensemble global.  *
-*                                                                             *
-*  Description : Démarre la définition d'un nouveau groupe d'instructions.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruction *first, size_t start)
-{
-    instr_coverage *coverage;               /* Couverture à définir        */
-    const mrange_t *irange;                 /* Couverture de l'instruction */
-
-    /* Mise à disposition de d'avantage d'espace */
-    if (proc->cov_allocated == proc->cov_count)
-    {
-        proc->cov_allocated += INSTR_ALLOC_BLOCK;
-
-        proc->coverages = (instr_coverage *)realloc(proc->coverages,
-                                                    proc->cov_allocated * sizeof(instr_coverage));
-
-    }
-
-    coverage = &proc->coverages[proc->cov_count++];
-
-    irange = g_arch_instruction_get_range(first);
-
-    init_mrange(&coverage->range, get_mrange_addr(irange), 0);
-
-    coverage->start = start;
-
-}
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc = architecture à comléter par la procédure.             *
-*                last = dernière instruction d'un nouveau groupe.             *
-*                end  = indice de cette instruction dans l'ensemble global.   *
+*  Paramètres  : proc = architecture visée par la procédure.                  *
 *                                                                             *
-*  Description : Termine la définition d'un nouveau groupe d'instructions.    *
+*  Description : Compte le nombre d'instructions représentées.                *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Nombre d'instructions présentes.                             *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end)
+size_t g_arch_processor_count_instructions(const GArchProcessor *proc)
 {
-    instr_coverage *coverage;               /* Couverture à définir        */
-    const mrange_t *irange;                 /* Couverture de l'instruction */
-    phys_t diff;                            /* Ecart entre les extrémités  */
-
-    coverage = &proc->coverages[proc->cov_count - 1];
-
-    irange = g_arch_instruction_get_range(last);
-
-    diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(irange));
-    diff += get_mrange_length(irange);
+    assert(g_atomic_int_get(&proc->locked) == 1);
 
-    set_mrange_length(&coverage->range, diff);
-
-    coverage->count = end - coverage->start + 1;
+    return proc->instr_count;
 
 }
 
@@ -523,70 +464,117 @@ void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchI
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : proc = architecture visée par la procédure.                  *
+*                index = indice de l'instruction visée.                       *
 *                                                                             *
-*  Description : Fournit les instructions désassemblées pour une architecture.*
+*  Description : Fournit une instruction désassemblée pour une architecture.  *
 *                                                                             *
-*  Retour      : Liste des instructions désassemblées ou NULL si aucune.      *
+*  Retour      : Instructions désassemblée trouvée ou NULL si aucune.         *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *proc)
+GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, size_t index)
 {
-    return (proc->instr_count > 0 ? proc->instructions[0] : NULL);
+    GArchInstruction *result;               /* Instruction à retourner     */
+
+    assert(g_atomic_int_get(&proc->locked) == 1);
+
+    if (proc->instr_count == 0)
+        result = NULL;
+
+    else
+    {
+        assert(index < proc->instr_count);
+
+        result = proc->instructions[index];
+
+        if (result != NULL)
+            g_object_ref(G_OBJECT(result));
+
+    }
+
+    return result;
 
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc = architecture visée par la procédure.                  *
-*                index = indice de l'instruction visée.                       *
+*  Paramètres  : proc  = architecture à comléter par la procédure.            *
+*                first = première instruction d'un nouveau groupe.            *
+*                start = indice de cette instruction dans l'ensemble global.  *
 *                                                                             *
-*  Description : Fournit une instruction désassemblée pour une architecture.  *
+*  Description : Démarre la définition d'un nouveau groupe d'instructions.    *
 *                                                                             *
-*  Retour      : Instructions désassemblée trouvée ou NULL si aucune.         *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *g_arch_processor_get_disassembled_instruction(const GArchProcessor *proc, size_t index)
+static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruction *first, size_t start)
 {
-    GArchInstruction *result;               /* Instruction à retourner     */
-
-    if (proc->instr_count == 0)
-        result = NULL;
+    instr_coverage *coverage;               /* Couverture à définir        */
+    const mrange_t *irange;                 /* Couverture de l'instruction */
 
-    else
+    /* Mise à disposition de d'avantage d'espace */
+    if (proc->cov_allocated == proc->cov_count)
     {
-        assert(index < proc->instr_count);
+        proc->cov_allocated += INSTR_ALLOC_BLOCK;
 
-        result = proc->instructions[index];
+        proc->coverages = (instr_coverage *)realloc(proc->coverages,
+                                                    proc->cov_allocated * sizeof(instr_coverage));
 
     }
 
-    return result;
+    coverage = &proc->coverages[proc->cov_count++];
+
+    irange = g_arch_instruction_get_range(first);
+
+    init_mrange(&coverage->range, get_mrange_addr(irange), 0);
+
+    coverage->start = start;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc = architecture visée par la procédure.                  *
+*  Paramètres  : proc = architecture à comléter par la procédure.             *
+*                last = dernière instruction d'un nouveau groupe.             *
+*                end  = indice de cette instruction dans l'ensemble global.   *
 *                                                                             *
-*  Description : Compte le nombre d'instructions représentées.                *
+*  Description : Termine la définition d'un nouveau groupe d'instructions.    *
 *                                                                             *
-*  Retour      : Nombre d'instructions présentes.                             *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *proc)
+static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end)
 {
-    return proc->instr_count;
+    instr_coverage *coverage;               /* Couverture à définir        */
+    const mrange_t *irange;                 /* Couverture de l'instruction */
+    phys_t diff;                            /* Ecart entre les extrémités  */
+
+    coverage = &proc->coverages[proc->cov_count - 1];
+
+    irange = g_arch_instruction_get_range(last);
+
+    diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(irange));
+    diff += get_mrange_length(irange);
+
+    set_mrange_length(&coverage->range, diff);
+
+    coverage->count = end - coverage->start + 1;
 
 }
 
@@ -609,6 +597,8 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce
     instr_coverage *result;                 /* Trouvaille à retourner      */
     void *ptr;                              /* Résultat des recherches     */
 
+    // TODO : assert locked !
+
     int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c)
     {
         int status;                         /* Bilan d'une comparaison     */
@@ -631,6 +621,72 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : proc     = processeur recensant diverses instructions.       *
+*                coverage = zone de couverture fine à fouiller.               *
+*                addr     = position en mémoire ou physique à chercher.       *
+*                nearby   = la recherche s'effectue-t-elle de façon stricte ? *
+*                index    = indice de l'instruction trouvée. [OUT]            *
+*                                                                             *
+*  Description : Recherche rapidement un indice d'instruction via une adresse.*
+*                                                                             *
+*  Retour      : Validité de l'indice fourni.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby, size_t *index)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    void *ptr;                              /* Résultat des recherches     */
+    __compar_fn_t fn;                       /* Fonction auxiliaire adaptée */
+
+    assert(g_atomic_int_get(&proc->locked) == 1);
+
+    int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b)
+    {
+        const mrange_t *range_b;            /* Emplacement pour l'instr. B */
+
+        range_b = g_arch_instruction_get_range(*b);
+
+        return cmp_vmpa(a, get_mrange_addr(range_b));
+
+    }
+
+    int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b)
+    {
+        const mrange_t *range_b;            /* Emplacement pour l'instr. B */
+
+        range_b = g_arch_instruction_get_range(*b);
+
+        return cmp_mrange_with_vmpa(range_b, a);
+
+    }
+
+    if (nearby)
+        fn = (__compar_fn_t)search_for_instr_by_nearby_addr;
+    else
+        fn = (__compar_fn_t)search_for_instr_by_addr;
+
+    ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count,
+                  sizeof(GArchInstruction *), fn);
+
+    if (ptr == NULL)
+        result = false;
+
+    else
+    {
+        result = true;
+        *index = ((GArchInstruction **)ptr) - proc->instructions;
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : proc   = processeur recensant diverses instructions.         *
 *                addr   = position en mémoire ou physique à chercher.         *
 *                nearby = la recherche s'effectue-t-elle de façon stricte ?   *
@@ -643,11 +699,13 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr, bool nearby)
+GArchInstruction *_g_arch_processor_find_instr_by_address(GArchProcessor *proc, const vmpa2t *addr, bool nearby)
 {
     GArchInstruction *result;               /* Trouvaille à retourner      */
     const instr_coverage *coverage;         /* Couverture fine à fouiller  */
 
+    g_arch_processor_lock(proc);
+
     coverage = g_arch_processor_find_coverage_by_address(proc, addr);
 
     if (coverage != NULL)
@@ -655,6 +713,8 @@ GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *
     else
         result = NULL;
 
+    g_arch_processor_unlock(proc);
+
     return result;
 
 }
@@ -678,92 +738,83 @@ GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *
 GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)
 {
     GArchInstruction *result;               /* Trouvaille à retourner      */
-    void *ptr;                              /* Résultat des recherches     */
-    __compar_fn_t fn;                       /* Fonction auxiliaire adaptée */
+    size_t index;                           /* Indice d'instruction visée  */
+    bool valid;                             /* Validité de l'indice        */
 
-    int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b)
-    {
-        const mrange_t *range_b;            /* Emplacement pour l'instr. B */
-
-        range_b = g_arch_instruction_get_range(*b);
-
-        return cmp_vmpa(a, get_mrange_addr(range_b));
-
-    }
-
-    int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b)
-    {
-        const mrange_t *range_b;            /* Emplacement pour l'instr. B */
-
-        range_b = g_arch_instruction_get_range(*b);
-
-        return cmp_mrange_with_vmpa(range_b, a);
+    valid = g_arch_processor_find_covered_index_by_address(proc, coverage, addr, nearby, &index);
 
-    }
-
-    if (nearby)
-        fn = (__compar_fn_t)search_for_instr_by_nearby_addr;
+    if (valid)
+        result = g_arch_processor_get_instruction(proc, index);
     else
-        fn = (__compar_fn_t)search_for_instr_by_addr;
-
-    ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count,
-                  sizeof(GArchInstruction *), fn);
-
-    result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
+        result = NULL;
 
     return result;
 
 }
 
-
+ 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc  = processeur recensant diverses instructions.          *
-*                instr = instruction de référence pour un parcours.           *
+*  Paramètres  : proc   = processeur recensant diverses instructions.         *
+*                addr   = position en mémoire ou physique à chercher.         *
+*                nearby = la recherche s'effectue-t-elle de façon stricte ?   *
 *                                                                             *
-*  Description : Fournit l'instruction qui en précède une autre.              *
+*  Description : Met en place un itérateur d'instruction selon une adresse.   *
 *                                                                             *
-*  Retour      : Instruction précédente trouvée, ou NULL.                     *
+*  Retour      : Itérateur mis en place, ou NULL si l'opération est un échec. *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *proc, const GArchInstruction *instr)
+instr_iter_t *_g_arch_processor_get_iter_from_address(GArchProcessor *proc, const vmpa2t *addr, bool nearby)
 {
-    GArchInstruction *result;               /* Instruction à retourner     */
-    GArchInstruction *list;                 /* Ensemble des instructions   */
+    instr_iter_t *result;                   /* Itérateur à retourner       */
+    const instr_coverage *coverage;         /* Couverture fine à fouiller  */
+
+    g_arch_processor_lock(proc);
+
+    coverage = g_arch_processor_find_coverage_by_address(proc, addr);
 
-    list = g_arch_processor_get_disassembled_instructions(proc);
+    if (coverage != NULL)
+        result = _g_arch_processor_get_covered_iter_from_address(proc, coverage, addr, nearby);
+    else
+        result = NULL;
 
-    result = g_arch_instruction_get_prev_iter(list, instr);
+    g_arch_processor_unlock(proc);
 
     return result;
 
 }
 
-
+ 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc  = processeur recensant diverses instructions.          *
-*                instr = instruction de référence pour un parcours.           *
+*  Paramètres  : proc     = processeur recensant diverses instructions.       *
+*                coverage = zone de couverture fine à fouiller.               *
+*                addr     = position en mémoire ou physique à chercher.       *
+*                nearby   = la recherche s'effectue-t-elle de façon stricte ? *
 *                                                                             *
-*  Description : Fournit l'instruction qui en suit une autre.                 *
+*  Description : Met en place un itérateur d'instruction selon une adresse.   *
 *                                                                             *
-*  Retour      : Instruction suivante trouvée, ou NULL.                       *
+*  Retour      : Itérateur mis en place, ou NULL si l'opération est un échec. *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *g_arch_processor_get_next_instr(const GArchProcessor *proc, const GArchInstruction *instr)
+instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)
 {
-    GArchInstruction *result;               /* Instruction à retourner     */
-    GArchInstruction *list;                 /* Ensemble des instructions   */
+    instr_iter_t *result;                   /* Itérateur à retourner       */
+    size_t index;                           /* Indice d'instruction visée  */
+    bool valid;                             /* Validité de l'indice        */
 
-    list = g_arch_processor_get_disassembled_instructions(proc);
+    valid = g_arch_processor_find_covered_index_by_address(proc, coverage, addr, nearby, &index);
 
-    result = g_arch_instruction_get_next_iter(list, instr, ~0);
+    if (valid)
+        result = create_instruction_iterator(proc, index);
+    else
+        result = NULL;
 
     return result;
 
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 02b3533..05ea77a 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -29,6 +29,7 @@
 
 
 #include "context.h"
+#include "instriter.h"
 #include "instruction.h"
 #include "../common/endianness.h"
 #include "../format/executable.h"
@@ -86,47 +87,62 @@ void g_arch_processor_lock_unlock(GArchProcessor *, bool);
 /* Fournit la marque de dernière modification des instructions. */
 unsigned int g_arch_processor_get_stamp(const GArchProcessor *);
 
+/* Compte le nombre d'instructions représentées. */
+size_t g_arch_processor_count_instructions(const GArchProcessor *);
 
+/* Note les instructions désassemblées avec une architecture. */
+void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
 
-/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
-
+/* Fournit une instruction désassemblée pour une architecture. */
+GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *, size_t);
 
-/* Couverture d'un groupe d'instructions */
-typedef struct _instr_coverage  instr_coverage;
 
 
-/* Note les instructions désassemblées avec une architecture. */
-void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
+/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
 
-/* Fournit les instructions désassemblées pour une architecture. */
-GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *);
 
-/* Fournit une instruction désassemblée pour une architecture. */
-GArchInstruction *g_arch_processor_get_disassembled_instruction(const GArchProcessor *, size_t);
+/* Couverture d'un groupe d'instructions */
+typedef struct _instr_coverage  instr_coverage;
 
-/* Compte le nombre d'instructions représentées. */
-size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *);
 
 /* Recherche un groupe d'instruction d'après son adresse. */
 const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *);
 
 /* Recherche une instruction d'après son adresse. */
-GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *, bool);
+GArchInstruction *_g_arch_processor_find_instr_by_address(GArchProcessor *, const vmpa2t *, bool);
 
 /* Recherche rapidement une instruction d'après son adresse. */
 GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool);
 
-#define g_arch_processor_find_instr_by_address(proc, addr)      \
+#define g_arch_processor_find_instr_by_address(proc, addr)                                          \
     _g_arch_processor_find_instr_by_address(proc, addr, false)
 
-#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr)    \
-    _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false)
-
-/* Fournit l'instruction qui en précède une autre. */
-GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *, const GArchInstruction *);
-
-/* Fournit l'instruction qui en suit une autre. */
-GArchInstruction *g_arch_processor_get_next_instr(const GArchProcessor *, const GArchInstruction *);
+#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr)                        \
+    ({                                                                                              \
+        GArchInstruction *__result;                                                                 \
+        g_arch_processor_lock(proc);                                                                \
+        __result = _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false);    \
+        g_arch_processor_unlock(proc);                                                              \
+        __result;                                                                                   \
+    })
+
+/* Met en place un itérateur d'instruction selon une adresse. */
+instr_iter_t *_g_arch_processor_get_iter_from_address(GArchProcessor *, const vmpa2t *, bool);
+
+/* Met en place un itérateur d'instruction selon une adresse. */
+instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *, const instr_coverage *, const vmpa2t *, bool);
+
+#define g_arch_processor_get_iter_from_address(proc, addr) \
+    _g_arch_processor_get_iter_from_address(proc, addr, false)
+
+#define g_arch_processor_get_covered_iter_from_address(proc, coverage, addr)                        \
+    ({                                                                                              \
+        instr_iter_t *__result;                                                                     \
+        g_arch_processor_lock(proc);                                                                \
+        __result = _g_arch_processor_get_covered_iter_from_address(proc, coverage, addr, false);    \
+        g_arch_processor_unlock(proc);                                                              \
+        __result;                                                                                   \
+    })
 
 
 
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index d205e47..57bbec0 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -1208,11 +1208,12 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
     vmpa2t last;                            /* Fin d'un groupe de lignes   */
     const mrange_t *range;                  /* Couverture courante         */
     GArchProcessor *proc;                   /* Processeur pour instructions*/
-    GArchInstruction *ref;                  /* Point de référence          */
+    vmpa2t iaddr;                           /* Adresse du prochain saut    */
+    instr_iter_t *iter;                     /* Boucle de parcours          */
+    GArchInstruction *instr;                /* Instruction à venir visiter */
 #ifndef NDEBUG
     bool is_return;                         /* Est-ce une instruc. finale ?*/
 #endif
-    vmpa2t iaddr;                           /* Position de l'instructin    */
     size_t i;                               /* Boucle de parcours          */
     bool updated;                           /* Besoin d'une mise à jour ?  */
 
@@ -1225,7 +1226,7 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
 
     proc = g_loaded_binary_get_processor(GTK_DISPLAY_PANEL(view)->binary);
 
-    ref = NULL;
+    init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
 
 #ifndef NDEBUG
     is_return = false;
@@ -1235,42 +1236,66 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
     {
         case GDK_SCROLL_LEFT:
         case GDK_SCROLL_UP:
+
             if (cmp_vmpa(get_mrange_addr(range), &first) != 0)
             {
-                ref = g_arch_processor_find_instr_by_address(proc, &first);
+                iter = g_arch_processor_get_iter_from_address(proc, &first);
+
+                if (iter != NULL)
+                {
+                    instr = get_instruction_iterator_prev(iter);
+
+                    if (instr != NULL)
+                    {
+                        /* TODO : boucler si !HAS_CODE */
+
+                        if (mrange_contains_addr(range, &iaddr))
+                            copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
 
-                if (ref != NULL)
-                    ref = g_arch_processor_get_prev_instr(proc, ref);
+                        g_object_unref(G_OBJECT(instr));
 
-                /* TODO : boucler si !HAS_CODE */
+                    }
 
-                if (ref != NULL)
-                    copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(ref)));
+                    delete_instruction_iterator(iter);
+
+                }
 
             }
+
             break;
 
         case GDK_SCROLL_RIGHT:
         case GDK_SCROLL_DOWN:
 
-            ref = g_arch_processor_find_instr_by_address(proc, &last);
+            iter = g_arch_processor_get_iter_from_address(proc, &last);
 
+            if (iter != NULL)
+            {
 #ifndef NDEBUG
-            if (ref != NULL)
-                is_return = (g_arch_instruction_get_flags(ref) & AIF_RETURN_POINT);
+                instr = get_instruction_iterator_current(iter);
+                if (instr != NULL)
+                {
+                    is_return = (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT);
+                    g_object_unref(G_OBJECT(instr));
+                }
 #endif
 
-            if (ref != NULL)
-                ref = g_arch_processor_get_next_instr(proc, ref);
+                instr = get_instruction_iterator_next(iter);
 
-            /* TODO : boucler si !HAS_CODE */
+                if (instr != NULL)
+                {
+                    /* TODO : boucler si !HAS_CODE */
 
-            if (ref != NULL)
-            {
-                copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(ref)));
+                    copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
+
+                    if (!mrange_contains_addr(range, &iaddr))
+                        init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+                    g_object_unref(G_OBJECT(instr));
+
+                }
 
-                if (!mrange_contains_addr(range, &iaddr))
-                    ref = NULL;
+                delete_instruction_iterator(iter);
 
             }
 
@@ -1286,7 +1311,8 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
 
     /* Recherche du bloc parent */
 
-    if (ref == NULL)
+    /* FIXME : valid ! */
+    if (iaddr.physical == VMPA_NO_PHYSICAL && iaddr.virtual == VMPA_NO_VIRTUAL)
         return;
 
     for (i = 0; i < view->children_count; i++)
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 95b4f50..da2c60f 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -384,6 +384,8 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar *
 
         switcher = g_db_switcher_new(instr, G_IMM_OPERAND(creator), display);
 
+        g_object_unref(G_OBJECT(instr));
+
         g_loaded_binary_add_to_collection(binary, G_DB_ITEM(switcher));
 
         g_object_unref(G_OBJECT(proc));
@@ -492,7 +494,6 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
     const mrange_t *range;                  /* Couverture en mémoire       */
     GLoadedBinary *binary;                  /* Représentation binaire      */
     GArchProcessor *proc;                   /* Processeur de l'architecture*/
-    GArchInstruction *list;                 /* Ensemble des instructions   */
     GArchInstruction *instr;                /* Point de croisements        */
     GObject *ref;                           /* Espace de référencements    */
     GtkWidget *dialog;                      /* Boîte de dialogue à montrer */
@@ -506,7 +507,6 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
 
         binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(bar));
         proc = g_loaded_binary_get_processor(binary);
-        list = g_arch_processor_get_disassembled_instructions(proc);
 
         /**
          * On ne peut pas se reposer sur l'espace couvert par une ligne, car il peut
@@ -518,9 +518,9 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
          *
          *    instr = g_arch_instruction_find_by_range(list, range);
          *
-         * Il faut ainsi être plus souple.
+         * Il faut ainsi être plus souple, et se baser sur l'adresse uniquement.
          */
-        instr = g_arch_instruction_find_by_address(list, get_mrange_addr(range), true);
+        instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
 
         ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));
 
@@ -538,6 +538,9 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
 
         gtk_widget_destroy(dialog);
 
+        if (instr != NULL)
+            g_object_unref(G_OBJECT(instr));
+
         g_object_unref(G_OBJECT(proc));
 
         g_object_unref(G_OBJECT(line));
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 4f919b1..b8631b6 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -1030,7 +1030,6 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
     const mrange_t *range;                  /* Couverture en mémoire       */
     GLoadedBinary *binary;                  /* Représentation binaire      */
     GArchProcessor *proc;                   /* Processeur de l'architecture*/
-    GArchInstruction *list;                 /* Ensemble des instructions   */
     GArchInstruction *instr;                /* Point de croisements        */
     GObject *ref;                           /* Espace de référencements    */
     GtkWidget *dialog;                      /* Boîte de dialogue à montrer */
@@ -1044,13 +1043,12 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
 
     binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(panel));
     proc = g_loaded_binary_get_processor(binary);
-    list = g_arch_processor_get_disassembled_instructions(proc);
 
     /**
      * Se rapporter aux commentaires de mcb_edition_list_xrefs() pour les questions
      * concernant l'usage d'une adresse d'instruction au lieu de son emplacement.
      */
-    instr = g_arch_instruction_find_by_address(list, get_mrange_addr(range), true);
+    instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
 
     ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(panel));
 
@@ -1069,6 +1067,9 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
 
     gtk_widget_destroy(dialog);
 
+    if (instr != NULL)
+        g_object_unref(G_OBJECT(instr));
+
     g_object_unref(G_OBJECT(proc));
 
     g_object_unref(G_OBJECT(symbol));
diff --git a/src/gui/status.c b/src/gui/status.c
index b6e8fe6..fc8eafd 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -269,6 +269,8 @@ static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binar
 
         gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr);
 
+        g_object_unref(G_OBJECT(instr));
+
         g_object_unref(G_OBJECT(proc));
 
     }
-- 
cgit v0.11.2-87-g4458