From 23b9c6e68bbe5f0531f9a9408c2deb9f897701dc Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 13 Jan 2018 23:37:31 +0100
Subject: Created a real iterator for symbols.

---
 ChangeLog                           |  40 +++++
 plugins/pychrysa/format/Makefile.am |   3 +-
 plugins/pychrysa/format/format.c    | 228 +---------------------------
 plugins/pychrysa/format/module.c    |   3 +-
 plugins/pychrysa/format/symiter.c   | 276 ++++++++++++++++++++++++++++++++++
 plugins/pychrysa/format/symiter.h   |  42 ++++++
 src/analysis/disass/disassembler.c  |  19 ++-
 src/analysis/disass/output.c        |  48 +++---
 src/analysis/disass/routines.c      |  42 ++++--
 src/analysis/disass/routines.h      |   4 +-
 src/arch/processor.c                |   4 +
 src/format/Makefile.am              |   1 +
 src/format/format-int.h             |   6 +-
 src/format/format.c                 | 239 +++++++++++++++++++++++------
 src/format/format.h                 |  32 +++-
 src/format/symiter.c                | 289 ++++++++++++++++++++++++++++++++++++
 src/format/symiter.h                |  56 +++++++
 src/gui/dialogs/gotox.c             |  26 ++--
 src/gui/panels/strings.c            |  31 ++--
 src/gui/panels/symbols.c            |  65 ++++----
 20 files changed, 1095 insertions(+), 359 deletions(-)
 create mode 100644 plugins/pychrysa/format/symiter.c
 create mode 100644 plugins/pychrysa/format/symiter.h
 create mode 100644 src/format/symiter.c
 create mode 100644 src/format/symiter.h

diff --git a/ChangeLog b/ChangeLog
index 2cfb140..416027c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,45 @@
 18-01-13  Cyrille Bagard <nocbos@gmail.com>
 
+	* plugins/pychrysa/format/Makefile.am:
+	Add the 'symiter.[ch]' files to libpychrysaformat_la_SOURCES.
+
+	* plugins/pychrysa/format/format.c:
+	Delete the previous version of symbol iterators and update code.
+
+	* plugins/pychrysa/format/module.c:
+	Update code.
+
+	* plugins/pychrysa/format/symiter.c:
+	* plugins/pychrysa/format/symiter.h:
+	New entries: provide Python bindings for the new symbol iterator.
+
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/output.c:
+	* src/analysis/disass/routines.c:
+	* src/analysis/disass/routines.h:
+
+	* src/arch/processor.c:
+	Fix a compilation bug when NDEBUG is defined.
+
+	* src/format/Makefile.am:
+	Add the 'symiter.[ch]' files to libformat_la_SOURCES.
+
+	* src/format/format-int.h:
+	* src/format/format.c:
+	* src/format/format.h:
+	Rewrite all accesses to symbols.
+
+	* src/format/symiter.c:
+	* src/format/symiter.h:
+	New entries: create a real iterator for symbols.
+
+	* src/gui/dialogs/gotox.c:
+	* src/gui/panels/strings.c:
+	* src/gui/panels/symbols.c:
+	Update code.
+
+18-01-13  Cyrille Bagard <nocbos@gmail.com>
+
 	* plugins/dex/loading.c:
 	* plugins/elf/format.c:
 	* plugins/elf/loading.c:
diff --git a/plugins/pychrysa/format/Makefile.am b/plugins/pychrysa/format/Makefile.am
index e59cf8a..325206c 100644
--- a/plugins/pychrysa/format/Makefile.am
+++ b/plugins/pychrysa/format/Makefile.am
@@ -5,7 +5,8 @@ libpychrysaformat_la_SOURCES =			\
 	executable.h executable.c			\
 	format.h format.c					\
 	module.h module.c					\
-	symbol.h symbol.c
+	symbol.h symbol.c					\
+	symiter.h symiter.c
 
 libpychrysaformat_la_LIBADD = 
 
diff --git a/plugins/pychrysa/format/format.c b/plugins/pychrysa/format/format.c
index aed9664..5920b27 100644
--- a/plugins/pychrysa/format/format.c
+++ b/plugins/pychrysa/format/format.c
@@ -31,36 +31,12 @@
 #include <format/format.h>
 
 
+#include "symiter.h"
 #include "../helpers.h"
 #include "../arch/vmpa.h"
 
 
 
-/* ------------------------ PARCOURS DE SYMBOLES DE BINAIRES ------------------------ */
-
-
-/* Parcours des symboles présents dans un binaire */
-typedef struct _pyBinSymbolIterator
-{
-    PyObject_HEAD                           /* A laisser en premier        */
-
-    GBinFormat *format;                     /* Format binaire à consulter  */
-    size_t next;                            /* Symbole binaire à présenter */
-
-} pyBinSymbolIterator;
-
-
-/* Prend acte d'un compteur de référence à 0. */
-static void py_binary_symbol_iterator_dealloc(PyObject *);
-
-/* Fournit un itérateur pour symboles de format binaire. */
-static PyObject *py_binary_symbol_iterator_next(PyObject *);
-
-/* Initialise un objet Python de type 'BinSymbolIterator'. */
-static int py_binary_symbol_iterator_init(PyObject *, PyObject *, PyObject *);
-
-
-
 /* ---------------------------- FORMAT BINAIRE GENERIQUE ---------------------------- */
 
 
@@ -104,195 +80,6 @@ static bool define_python_binary_format_constants(PyTypeObject *);
 
 
 /* ---------------------------------------------------------------------------------- */
-/*                          PARCOURS DE SYMBOLES DE BINAIRES                          */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = instance Python à libérer de la mémoire.              *
-*                                                                             *
-*  Description : Prend acte d'un compteur de référence à 0.                   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void py_binary_symbol_iterator_dealloc(PyObject *self)
-{
-    pyBinSymbolIterator *iterator;          /* Références pour le parcours */
-
-    /**
-     * Il aurait été sans doute mieux de reposer ici sur .tp_finalize,
-     * mais cela semble impliquer de mettre en place tous les mécanismes de GC...
-     *
-     * cf. https://docs.python.org/3/extending/newtypes.html#finalization-and-de-allocation
-     */
-
-    iterator = (pyBinSymbolIterator *)self;
-
-    g_object_unref(G_OBJECT(iterator->format));
-
-    Py_TYPE(self)->tp_free((PyObject *)self);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = itérateur à manipuler.                                *
-*                                                                             *
-*  Description : Fournit un itérateur pour symboles de format binaire.        *
-*                                                                             *
-*  Retour      : Instance Python prête à emploi.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_binary_symbol_iterator_next(PyObject *self)
-{
-    PyObject *result;                       /* Instance à retourner        */
-    pyBinSymbolIterator *iterator;          /* Références pour le parcours */
-    size_t count;                           /* Nombre de symboles présents */
-    GBinSymbol **symbols;                   /* Liste de ces mêmes symboles */
-
-    iterator = (pyBinSymbolIterator *)self;
-
-    symbols = g_binary_format_get_symbols(iterator->format, &count);
-
-    if (iterator->next < count)
-    {
-        result = pygobject_new(G_OBJECT(symbols[iterator->next]));
-        iterator->next++;
-    }
-    else
-    {
-        PyErr_SetNone(PyExc_StopIteration);
-        result = NULL;
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = objet instancié à initialiser.                        *
-*                args = arguments fournis à l'appel.                          *
-*                kwds = arguments de type key=val fournis.                    *
-*                                                                             *
-*  Description : Initialise un objet Python de type 'BinSymbolIterator'.      *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static int py_binary_symbol_iterator_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    pyBinSymbolIterator *iterator;          /* Références pour le parcours */
-    PyObject *format;                       /* Format binaire en Python    */
-    int ret;                                /* Bilan de lecture des args.  */
-
-    ret = PyArg_ParseTuple(args, "O", &format);
-    if (!ret) return -1;
-
-    ret = PyObject_IsInstance(format, (PyObject *)get_python_binary_format_type());
-    if (!ret) return -1;
-
-    iterator = (pyBinSymbolIterator *)self;
-
-    iterator->format = G_BIN_FORMAT(pygobject_get(format));
-    g_object_ref(G_OBJECT(iterator->format));
-
-    iterator->next = 0;
-
-    return 0;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Fournit un accès à une définition de type à diffuser.        *
-*                                                                             *
-*  Retour      : Définition d'objet pour Python.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyTypeObject *get_python_binary_symbol_iterator_type(void)
-{
-    static PyTypeObject py_binary_symbol_iterator_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.format.BinSymbolIterator",
-        .tp_basicsize   = sizeof(pyBinSymbolIterator),
-
-        .tp_dealloc     = py_binary_symbol_iterator_dealloc,
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = "Iterator for binary symbols",
-
-        .tp_iter        = PyObject_SelfIter,
-        .tp_iternext    = py_binary_symbol_iterator_next,
-
-        .tp_init        = py_binary_symbol_iterator_init,
-
-        .tp_new         = PyType_GenericNew,
-
-    };
-
-    return &py_binary_symbol_iterator_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide...BinSymbolIterator'.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool register_python_binary_symbol_iterator(PyObject *module)
-{
-    PyTypeObject *py_binary_symbol_iterator_type; /* Type Python 'BinSymbolIterator' */
-    int ret;                                /* Bilan d'un appel            */
-
-    py_binary_symbol_iterator_type = get_python_binary_symbol_iterator_type();
-
-    py_binary_symbol_iterator_type->tp_base = &PyBaseObject_Type;
-
-    if (PyType_Ready(py_binary_symbol_iterator_type) != 0)
-        return false;
-
-    Py_INCREF(py_binary_symbol_iterator_type);
-    ret = PyModule_AddObject(module, "BinSymbolIterator", (PyObject *)py_binary_symbol_iterator_type);
-    if (ret != 0) return false;
-
-    return true;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
 /*                              FORMAT BINAIRE GENERIQUE                              */
 /* ---------------------------------------------------------------------------------- */
 
@@ -539,18 +326,17 @@ static PyObject *py_binary_format_get_content(PyObject *self, void *closure)
 
 static PyObject *py_binary_format_get_symbols(PyObject *self, void *closure)
 {
-    PyObject *result;                       /* Instance à retourner        */
+    PyObject *result;                       /* Instance Python à retourner */
     PyTypeObject *iterator_type;            /* Type Python de l'itérateur  */
-    PyObject *args_list;                    /* Arguments de mise en place  */
+    PyObject *args;                         /* Liste des arguments d'appel */
 
-    iterator_type = get_python_binary_symbol_iterator_type();
+    iterator_type = get_python_sym_iterator_type();
 
-    Py_INCREF(self);
+    args = Py_BuildValue("On", self, 0);
 
-    args_list = Py_BuildValue("(O)", self);
-    result = PyObject_CallObject((PyObject *)iterator_type, args_list);
+    result = PyObject_CallObject((PyObject *)iterator_type, args);
 
-    Py_DECREF(args_list);
+    Py_DECREF(args);
 
     return result;
 
diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c
index 642b1dc..1daeb3f 100644
--- a/plugins/pychrysa/format/module.c
+++ b/plugins/pychrysa/format/module.c
@@ -31,6 +31,7 @@
 #include "executable.h"
 #include "format.h"
 #include "symbol.h"
+#include "symiter.h"
 #include "../access.h"
 
 
@@ -81,10 +82,10 @@ bool add_format_module_to_python_module(PyObject *super)
 
     result = true;
 
-    result &= register_python_binary_symbol_iterator(module);
     result &= register_python_binary_format(module);
     result &= register_python_executable_format(module);
     result &= register_python_binary_symbol(module);
+    result &= register_python_sym_iterator(module);
 
     if (result)
         register_access_to_python_module("pychrysalide.format", module);
diff --git a/plugins/pychrysa/format/symiter.c b/plugins/pychrysa/format/symiter.c
new file mode 100644
index 0000000..db0b744
--- /dev/null
+++ b/plugins/pychrysa/format/symiter.c
@@ -0,0 +1,276 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * symiter.c - équivalent Python du fichier "format/symiter.c"
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "symiter.h"
+
+
+#include <pygobject.h>
+
+
+#include <format/symiter.h>
+
+
+#include "format.h"
+
+
+
+/* Transcription d'un itérateur en Python */
+typedef struct _PySymIterator
+{
+    PyObject_HEAD;                          /* A laisser en premier        */
+
+    sym_iter_t *native;                     /* Version native de l'objet   */
+    bool first_time;                        /* Premier élément retourné ?  */
+
+} PySymIterator;
+
+
+/* Libère de la mémoire un itérateur sur des symboles. */
+static void py_sym_iterator_dealloc(PySymIterator *);
+
+/* Fournit le symbole qui en suit un autr. */
+static PyObject *py_sym_iterator_next(PySymIterator *);
+
+/* Initialise un nouvel itérateur. */
+static int py_sym_iterator_init(PySymIterator *, PyObject *, PyObject *);
+
+/* Construit un nouvel itérateur. */
+static PyObject *py_sym_iterator_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = itérateur à supprimer.                                *
+*                                                                             *
+*  Description : Libère de la mémoire un itérateur sur des symboles.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_sym_iterator_dealloc(PySymIterator *self)
+{
+    delete_symbol_iterator(self->native);
+
+    Py_TYPE(self)->tp_free((PyObject *)self);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = itérateur à manipuler.                                *
+*                                                                             *
+*  Description : Fournit le symbole qui en suit un autre.                     *
+*                                                                             *
+*  Retour      : Symbole suivant trouvé, ou NULL.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_sym_iterator_next(PySymIterator *self)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GBinSymbol *next;                       /* Symbole suivant             */
+
+    if (self->first_time)
+    {
+        next = get_symbol_iterator_current(self->native);
+        self->first_time = false;
+    }
+
+    else
+        next = get_symbol_iterator_next(self->native);
+
+    if (next != NULL)
+    {
+        result = pygobject_new(G_OBJECT(next));
+        g_object_unref(G_OBJECT(next));
+    }
+
+    else
+    {
+        PyErr_SetNone(PyExc_StopIteration);
+        result = NULL;
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = instance d'objet à initialiser.                       *
+*                args = arguments passés pour l'appel.                        *
+*                kwds = mots clefs éventuellement fournis en complément.      *
+*                                                                             *
+*  Description : Initialise un nouvel itérateur.                              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_sym_iterator_init(PySymIterator *self, PyObject *args, PyObject *kwds)
+{
+    int result;                             /* Bilan à retourner           */
+    PyObject *fmt_obj;                      /* Format version Python       */
+    unsigned long index;                    /* Indice de premier symbole   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBinFormat *format;                     /* Version native du format    */
+
+    result = -1;
+
+    ret = PyArg_ParseTuple(args, "Ok", &fmt_obj, &index);
+    if (ret == 0) goto psii_exit;
+
+    ret = PyObject_IsInstance(fmt_obj, (PyObject *)get_python_binary_format_type());
+    if (!ret) goto psii_exit;
+
+    format = G_BIN_FORMAT(pygobject_get(fmt_obj));
+
+    self->native = create_symbol_iterator(format, index);
+    self->first_time = true;
+
+    result = 0;
+
+ psii_exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type d'objet à mettre en place.                       *
+*                args = arguments passés pour l'appel.                        *
+*                kwds = mots clefs éventuellement fournis en complément.      *
+*                                                                             *
+*  Description : Construit un nouvel itérateur.                               *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_sym_iterator_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PySymIterator *result;                  /* Nouvelle instance à renvoyer*/
+    int ret;                                /* Bilan de l'initialisation   */
+
+    result = (PySymIterator *)type->tp_alloc(type, 0);
+
+    if (result != NULL)
+    {
+        ret = py_sym_iterator_init(result, args, kwds);
+
+        if (ret != 0)
+        {
+            Py_DECREF(result);
+            result = NULL;
+        }
+
+    }
+
+    return (PyObject *)result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_sym_iterator_type(void)
+{
+    static PyTypeObject py_sym_iterator_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.format.SymIterator",
+        .tp_basicsize   = sizeof(PySymIterator),
+
+        .tp_dealloc     = (destructor)py_sym_iterator_dealloc,
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "Iterator for Chrysalide symbols registered in a given format.",
+
+        .tp_iter        = PyObject_SelfIter,
+        .tp_iternext    = (iternextfunc)py_sym_iterator_next,
+
+        .tp_init        = (initproc)py_sym_iterator_init,
+        .tp_new         = py_sym_iterator_new,
+
+    };
+
+    return &py_sym_iterator_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.format.SymIterator'.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_sym_iterator(PyObject *module)
+{
+    PyTypeObject *py_sym_iterator_type;     /* Type Python 'BinContent'    */
+    int ret;                                /* Bilan d'un appel            */
+
+    py_sym_iterator_type = get_python_sym_iterator_type();
+
+    if (PyType_Ready(py_sym_iterator_type) < 0)
+        return false;
+
+    Py_INCREF(py_sym_iterator_type);
+    ret = PyModule_AddObject(module, "SymIterator", (PyObject *)py_sym_iterator_type);
+
+    return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/format/symiter.h b/plugins/pychrysa/format/symiter.h
new file mode 100644
index 0000000..6cc1d29
--- /dev/null
+++ b/plugins/pychrysa/format/symiter.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * symiter.h - prototypes pour l'équivalent Python du fichier "format/symiter.h"
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_FORMAT_SYMITER_H
+#define _PLUGINS_PYCHRYSALIDE_FORMAT_SYMITER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_sym_iterator_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.format.SymIterator'. */
+bool register_python_sym_iterator(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_FORMAT_SYMITER_H */
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index bb69c0e..ae60602 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -92,7 +92,7 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GBufferCa
 static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *);
 
 /* Opère sur toutes les routines. */
-static void process_all_routines(wgroup_id_t, GtkStatusStack *, const char *, rtn_fallback_cb, GArchProcessor *, GExeFormat *);
+static void process_all_routines(wgroup_id_t, GtkStatusStack *, const char *, rtn_fallback_cb, GArchProcessor *, GBinFormat *);
 
 /* Assure le désassemblage en différé. */
 static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkStatusStack *);
@@ -318,10 +318,9 @@ static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, co
 *                                                                             *
 ******************************************************************************/
 
-static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const char *msg, rtn_fallback_cb fallback, GArchProcessor *proc, GExeFormat *format)
+static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const char *msg, rtn_fallback_cb fallback, GArchProcessor *proc, GBinFormat *format)
 {
     GBinPortion *portions;                  /* Couche première de portions */
-    GBinSymbol **symbols;                   /* Liste des symboles trouvés  */
     size_t sym_count;                       /* Nombre de ces symboles      */
     guint runs_count;                       /* Qté d'exécutions parallèles */
     size_t run_size;                        /* Volume réparti par exécution*/
@@ -332,9 +331,11 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const
     size_t end;                             /* Fin d'un bloc de traitement */
     GRoutinesStudy *study;                  /* Tâche d'étude à programmer  */
 
-    portions = g_exe_format_get_portions(format);
+    portions = g_exe_format_get_portions(G_EXE_FORMAT(format));
 
-    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
+    g_binary_format_lock_symbols_rd(format);
+
+    sym_count = g_binary_format_count_symbols(format);
 
     runs_count = g_get_num_processors();
 
@@ -353,7 +354,7 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const
         else
             end = begin + run_size;
 
-        study = g_routines_study_new(proc, portions, symbols, sym_count,
+        study = g_routines_study_new(proc, format, portions,
                                      begin, end, id, fallback);
 
         g_work_queue_schedule_work(queue, G_DELAYED_WORK(study), gid);
@@ -364,6 +365,8 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const
 
     gtk_status_stack_remove_activity(status, id);
 
+    g_binary_format_unlock_symbols_rd(format);
+
     g_object_unref(G_OBJECT(portions));
 
 }
@@ -471,7 +474,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 
     process_all_routines(gid, status,
                          _("Finding remaining limits..."),
-                         g_routines_study_compute_limits, proc, disass->format);
+                         g_routines_study_compute_limits, proc, G_BIN_FORMAT(disass->format));
 
 
 
@@ -525,7 +528,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
 #if 1
     process_all_routines(gid, status,
                          _("Control-flow analysis for routines..."),
-                         g_routines_study_handle_blocks, proc, disass->format);
+                         g_routines_study_handle_blocks, proc, G_BIN_FORMAT(disass->format));
 #endif
 
 
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 3cc282a..19c7de9 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -32,6 +32,7 @@
 
 #include "../../core/logs.h"
 #include "../../format/format.h"
+#include "../../format/symiter.h"
 #include "../../glibext/generators/rborder.h"
 
 
@@ -60,9 +61,8 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
     GBinPortion **portions;                 /* Morceaux d'encadrement      */
     size_t portions_count;                  /* Taille de cette liste       */
     size_t portion_index;                   /* Prochaine portion à traiter */
-    GBinSymbol **symbols;                   /* Symboles à représenter      */
-    size_t sym_count;                       /* Qté de symboles présents    */
-    size_t sym_index;                       /* Prochain symbole non traité */
+    sym_iter_t *siter;                      /* Parcours des symboles       */
+    GBinSymbol *symbol;                     /* Symbole manipulé            */
     MemoryDataSize msize;                   /* Taille du bus d'adresses    */
     const GBinContent *content;             /* Contenu binaire global      */
     size_t count;                           /* Nombre total d'instructions */
@@ -127,8 +127,9 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
     g_object_unref(G_OBJECT(root));
 
-    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
-    sym_index = 0;
+    siter = create_symbol_iterator(G_BIN_FORMAT(format), 0);
+
+    symbol = get_symbol_iterator_current(siter);
 
     msize = g_arch_processor_get_memory_size(proc);
 
@@ -205,21 +206,24 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
         /* Début d'un nouveau symbole ? */
 
-        if (sym_index == sym_count)
+        if (symbol == NULL)
             compared = -1;
 
         else
         {
             iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
 
-            for ( ; sym_index < sym_count; sym_index++)
+            for ( ; symbol != NULL; symbol = get_symbol_iterator_next(siter))
             {
-                sym_status = g_binary_symbol_get_status(symbols[sym_index]);
+                sym_status = g_binary_symbol_get_status(symbol);
 
                 if (sym_status == SSS_IMPORTED)
+                {
+                    g_object_unref(G_OBJECT(symbol));
                     continue;
+                }
 
-                saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
+                saddr = get_mrange_addr(g_binary_symbol_get_range(symbol));
 
                 compared = cmp_vmpa(iaddr, saddr);
 
@@ -228,10 +232,10 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
                 log_variadic_message(LMT_BAD_BINARY,
                                      _("Unable to find a proper location for symbol '%s' @ 0x%08x"),
-                                     g_binary_symbol_get_label(symbols[sym_index]), get_phy_addr(saddr));
+                                     g_binary_symbol_get_label(symbol), get_phy_addr(saddr));
 
                 asprintf(&errmsg, _("Unable to find a proper location for symbol '%s'"),
-                         g_binary_symbol_get_label(symbols[sym_index]));
+                         g_binary_symbol_get_label(symbol));
 
                 g_arch_processor_add_error(proc, APE_LABEL, saddr, errmsg);
 
@@ -239,22 +243,24 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
                 _missing++;
 
+                g_object_unref(G_OBJECT(symbol));
+
             }
 
-            if (sym_index == sym_count)
+            if (symbol == NULL)
                 goto no_more_symbol_finally;
 
             if (compared == 0)
             {
                 /* Coupure pour une nouvelle routine */
 
-                stype = g_binary_symbol_get_target_type(symbols[sym_index]);
+                stype = g_binary_symbol_get_target_type(symbol);
 
                 if (stype == STP_ROUTINE || stype == STP_ENTRY_POINT)
                 {
                     /* Impression de la marque de début */
 
-                    copy_vmpa(&intro_addr, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])));
+                    copy_vmpa(&intro_addr, get_mrange_addr(g_binary_symbol_get_range(symbol)));
 
                     border = g_border_generator_new(lang, &intro_addr, true, msize);
                     g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE);
@@ -273,7 +279,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
                      * est nécessaire pour imprimer cette marque de clôture.
                      */
 
-                    compute_mrange_end_addr(g_binary_symbol_get_range(symbols[sym_index]), &outro_addr);
+                    compute_mrange_end_addr(g_binary_symbol_get_range(symbol), &outro_addr);
 
                     expect_outro = true;
 
@@ -281,7 +287,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
                 /* Etiquette ? */
 
-                generator = g_binary_symbol_produce_label(symbols[sym_index]);
+                generator = g_binary_symbol_produce_label(symbol);
 
                 if (generator != NULL)
                     g_buffer_cache_append(cache, generator, BLF_NONE);
@@ -298,7 +304,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
         {
             /* Point d'entrée ? */
 
-            if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT)
+            if (g_binary_symbol_get_target_type(symbol) == STP_ENTRY_POINT)
                 flags |= BLF_ENTRYPOINT;
 
             /**
@@ -311,7 +317,8 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
             flags |= BLF_WIDTH_MANAGER;
 
-            sym_index++;
+            g_object_unref(G_OBJECT(symbol));
+            symbol = get_symbol_iterator_next(siter);
 
         }
 
@@ -369,6 +376,11 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
     g_object_unref(G_OBJECT(content));
 
+    if (symbol != NULL)
+        g_object_unref(G_OBJECT(symbol));
+
+    delete_symbol_iterator(siter);
+
     if (portions != NULL)
         free(portions);
 
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index bc4247c..661e136 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -38,12 +38,11 @@ struct _GRoutinesStudy
 {
     GDelayedWork parent;                    /* A laisser en premier        */
 
-    GArchProcessor *proc;                   /* Processeurs avec ses instr. */
-
+    GArchProcessor *proc;                   /* Processeur avec ses instr.  */
+    GBinFormat *format;                     /* Format de fichier manipulé  */
     GBinPortion *portions;                  /* Couches de binaire bornées  */
 
-    GBinSymbol **symbols;                   /* Liste de symboles à traiter */
-    size_t count;                           /* Taille de cette liste       */
+    size_t count;                           /* Nombre de symboles à traiter*/
 
     rtn_fallback_cb fallback;               /* Routine de traitement finale*/
     size_t begin;                           /* Point de départ du parcours */
@@ -148,6 +147,11 @@ static void g_routines_study_dispose(GRoutinesStudy *study)
 {
     g_object_unref(G_OBJECT(study->portions));
 
+    g_binary_format_unlock_symbols_rd(study->format);
+
+    g_object_unref(G_OBJECT(study->format));
+    g_object_unref(G_OBJECT(study->proc));
+
     G_OBJECT_CLASS(g_routines_study_parent_class)->dispose(G_OBJECT(study));
 
 }
@@ -175,9 +179,8 @@ static void g_routines_study_finalize(GRoutinesStudy *study)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : proc     = ensemble d'instructions désassemblées.            *
+*                format   = format de fichier à manipuler.                    *
 *                portions = ensemble de couches binaires bornées.             *
-*                symbols  = liste de symboles à parcourir.                    *
-*                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.   *
@@ -191,19 +194,24 @@ static void g_routines_study_finalize(GRoutinesStudy *study)
 *                                                                             *
 ******************************************************************************/
 
-GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, GBinPortion *portions, GBinSymbol **symbols, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)
+GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, GBinFormat *format, GBinPortion *portions, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)
 {
     GRoutinesStudy *result;                /* Tâche à retourner           */
 
     result = g_object_new(G_TYPE_ROUTINES_STUDY, NULL);
 
     result->proc = proc;
+    g_object_ref(G_OBJECT(proc));
+
+    result->format = format;
+    g_object_ref(G_OBJECT(format));
 
     result->portions = portions;
     g_object_ref(G_OBJECT(portions));
 
-    result->symbols = symbols;
-    result->count = count;
+    g_binary_format_lock_symbols_rd(format);
+
+    result->count = g_binary_format_count_symbols(format);
 
     result->fallback = fallback;
     result->begin = begin;
@@ -238,12 +246,12 @@ static void g_routines_study_process(GRoutinesStudy *study, GtkStatusStack *stat
 
     for (i = study->begin; i < study->end; i++)
     {
-        symbol = study->symbols[i];
+        symbol = g_binary_format_get_symbol(study->format, i);
 
         sym_status = g_binary_symbol_get_status(symbol);
 
         if (sym_status == SSS_IMPORTED)
-            continue;
+            goto grsp_next;
 
         type = g_binary_symbol_get_target_type(symbol);
 
@@ -252,6 +260,10 @@ static void g_routines_study_process(GRoutinesStudy *study, GtkStatusStack *stat
 
         gtk_status_stack_update_activity_value(status, study->id, 1);
 
+ grsp_next:
+
+        g_object_unref(G_OBJECT(symbol));
+
     }
 
 }
@@ -274,6 +286,7 @@ static void g_routines_study_process(GRoutinesStudy *study, GtkStatusStack *stat
 void g_routines_study_compute_limits(GRoutinesStudy *study, GBinRoutine *routine, size_t index)
 {
     GBinSymbol *symbol;                     /* Version alternative         */
+    GBinSymbol *next_symbol;                /* Eventuel symbole suivant    */
     const mrange_t *range;                  /* Zone du symbole suivant     */
     const vmpa2t *next;                     /* Début de la zone suivante   */
 
@@ -281,8 +294,13 @@ void g_routines_study_compute_limits(GRoutinesStudy *study, GBinRoutine *routine
 
     if ((index + 1) < study->count)
     {
-        range = g_binary_symbol_get_range(study->symbols[index + 1]);
+        next_symbol = g_binary_format_get_symbol(study->format, index + 1);
+
+        range = g_binary_symbol_get_range(next_symbol);
         next = get_mrange_addr(range);
+
+        g_object_unref(G_OBJECT(next_symbol));
+
     }
 
     else
diff --git a/src/analysis/disass/routines.h b/src/analysis/disass/routines.h
index 4b3efa9..db8144d 100644
--- a/src/analysis/disass/routines.h
+++ b/src/analysis/disass/routines.h
@@ -28,7 +28,7 @@
 #include "../routine.h"
 #include "../../arch/processor.h"
 #include "../../format/executable.h"
-#include "../../format/symbol.h"
+#include "../../format/format.h"
 #include "../../gtkext/gtkstatusstack.h"
 
 
@@ -53,7 +53,7 @@ typedef void (* rtn_fallback_cb) (GRoutinesStudy *, GBinRoutine *, size_t);
 
 
 /* Crée une tâche d'étude de routines différée. */
-GRoutinesStudy *g_routines_study_new(GArchProcessor *, GBinPortion *, GBinSymbol **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb);
+GRoutinesStudy *g_routines_study_new(GArchProcessor *, GBinFormat *, GBinPortion *, 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 *, GBinRoutine *, size_t);
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 21b6c49..78ded34 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -374,11 +374,15 @@ void g_arch_processor_lock_unlock(GArchProcessor *proc, bool state)
     if (state)
     {
         g_mutex_lock(&proc->mutex);
+#ifndef NDEBUG
         g_atomic_int_set(&proc->locked, 1);
+#endif
     }
     else
     {
+#ifndef NDEBUG
         g_atomic_int_set(&proc->locked, 0);
+#endif
         g_mutex_unlock(&proc->mutex);
     }
 
diff --git a/src/format/Makefile.am b/src/format/Makefile.am
index dfb9624..9b42ab0 100644
--- a/src/format/Makefile.am
+++ b/src/format/Makefile.am
@@ -10,6 +10,7 @@ libformat_la_SOURCES =					\
 	format.h format.c					\
 	preload-int.h						\
 	preload.h preload.c					\
+	symiter.h symiter.c					\
 	symbol-int.h						\
 	symbol.h symbol.c
 
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 0ab0e85..f377ca3 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -77,8 +77,12 @@ struct _GBinFormat
     GPreloadInfo *info;                     /* Préchargements du format    */
 
     GBinSymbol **symbols;                   /* Liste des symboles trouvés  */
-    size_t symbols_count;                   /* Quantité de ces symboles    */
+    size_t sym_count;                       /* Quantité de ces symboles    */
+    unsigned int sym_stamp;                 /* Marque de suivi des modifs  */
     GRWLock syms_lock;                      /* Accès à la liste de symboles*/
+#ifndef NDEBUG
+    gint sym_locked;                        /* Statut d'accès à la liste   */
+#endif
 
     const char **src_files;                 /* Nom des fichiers source     */
     size_t src_count;                       /* Taille de la liste          */
diff --git a/src/format/format.c b/src/format/format.c
index 1ab7efa..a188204 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -50,6 +50,11 @@ static void g_binary_format_dispose(GBinFormat *);
 /* Procède à la libération totale de la mémoire. */
 static void g_binary_format_finalize(GBinFormat *);
 
+
+
+/* ---------------------- RASSEMBLEMENT ET GESTION DE SYMBOLES ---------------------- */
+
+
 /* Retire un symbole de la collection du format binaire. */
 static void _g_binary_format_remove_symbol(GBinFormat *, size_t);
 
@@ -108,6 +113,9 @@ static void g_binary_format_init(GBinFormat *format)
     format->info = g_preload_info_new();
 
     g_rw_lock_init(&format->syms_lock);
+#ifndef DEBUG
+    g_atomic_int_set(&format->sym_locked, 0);
+#endif
 
     format->errors = NULL;
     format->error_count = 0;
@@ -361,6 +369,161 @@ void g_binary_format_activate_disassembling_context(GBinFormat *format, GProcCon
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                        RASSEMBLEMENT ET GESTION DE SYMBOLES                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = architecture à manipuler.                           *
+*                state  = nouvel état de l'accès aux symboles.                *
+*                                                                             *
+*  Description : Protège ou lève la protection de l'accès aux symboles.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_format_lock_unlock_symbols_rd(GBinFormat *format, bool state)
+{
+#ifndef NDEBUG
+    gint test;                              /* Test de valeur courante     */
+#endif
+
+    if (state)
+    {
+        g_rw_lock_reader_lock(&format->syms_lock);
+#ifndef NDEBUG
+        g_atomic_int_inc(&format->sym_locked);
+#endif
+    }
+    else
+    {
+#ifndef NDEBUG
+        test = g_atomic_int_add(&format->sym_locked, -1);
+        assert(test > 0);
+#endif
+        g_rw_lock_reader_unlock(&format->syms_lock);
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = architecture à manipuler.                           *
+*                state  = nouvel état de l'accès aux symboles.                *
+*                                                                             *
+*  Description : Protège ou lève la protection de l'accès aux symboles.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_format_lock_unlock_symbols_wr(GBinFormat *format, bool state)
+{
+    if (state)
+    {
+        g_rw_lock_writer_lock(&format->syms_lock);
+#ifndef NDEBUG
+        g_atomic_int_set(&format->sym_locked, 1);
+#endif
+    }
+    else
+    {
+#ifndef NDEBUG
+        g_atomic_int_set(&format->sym_locked, 0);
+#endif
+        g_rw_lock_writer_unlock(&format->syms_lock);
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = architecture à consulter via la procédure.          *
+*                                                                             *
+*  Description : Fournit la marque de dernière modification des symboles.     *
+*                                                                             *
+*  Retour      : Marque de la dernière modification de la liste de symboles.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_binary_format_get_symbols_stamp(const GBinFormat *format)
+{
+    return format->sym_stamp;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = format visé par la procédure.                       *
+*                                                                             *
+*  Description : Compte le nombre de symboles représentés.                    *
+*                                                                             *
+*  Retour      : Nombre de symboles présents.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_binary_format_count_symbols(const GBinFormat *format)
+{
+    assert(g_atomic_int_get(&format->sym_locked) > 0);
+
+    return format->sym_count;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = format visé par la procédure.                       *
+*                index  = indice du symbole visé.                             *
+*                                                                             *
+*  Description : Fournit un symbole lié à un format.                          *
+*                                                                             *
+*  Retour      : Symbole conservé trouvé ou NULL si aucun.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinSymbol *g_binary_format_get_symbol(const GBinFormat *format, size_t index)
+{
+    GBinSymbol *result;                     /* Symbole à retourner         */
+
+    assert(g_atomic_int_get(&format->sym_locked) > 0);
+
+    if (format->sym_count == 0)
+        result = NULL;
+
+    else
+    {
+        assert(index < format->sym_count);
+
+        result = format->symbols[index];
+        assert(result != NULL);
+
+        g_object_ref(G_OBJECT(result));
+
+    }
+
+    return result;
+
+}
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format = informations chargées à compléter.                  *
@@ -409,7 +572,7 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
     assert(has_phys_addr(addr) || g_binary_symbol_get_status(symbol) == SSS_IMPORTED);
 #endif
 
-    g_rw_lock_writer_lock(&format->syms_lock);
+    g_binary_format_lock_unlock_symbols_wr(format, true);
 
     /**
      * Avec tous les traitements parallèles, il est possible que plusieurs chemins d'exécution
@@ -421,21 +584,22 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
      * construction du symbole dans les cas peu fréquents où le symbole était déjà en place.
      */
 
-    result = bsearch_index(&symbol, format->symbols, format->symbols_count,
+    result = bsearch_index(&symbol, format->symbols, format->sym_count,
                            sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp, &index);
 
     if (!result)
     {
-        format->symbols = _qinsert(format->symbols, &format->symbols_count,
+        format->symbols = _qinsert(format->symbols, &format->sym_count,
                                    sizeof(GBinSymbol *), &symbol, index);
 
+        format->sym_stamp++;
         result = true;
 
     }
     else
         g_object_unref(G_OBJECT(symbol));
 
-    g_rw_lock_writer_unlock(&format->syms_lock);
+    g_binary_format_lock_unlock_symbols_wr(format, false);
 
     return result;
 
@@ -459,17 +623,18 @@ static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index)
 {
     /**
      * TODO : envoyer un signal pour avertir les opérandes concernées.
-     * TODO : vérifier les conditions d'accès (verrou).
      */
 
-    assert(index < format->symbols_count);
+    assert(g_atomic_int_get(&format->sym_locked) == 1);
+
+    assert(index < format->sym_count);
 
-    if ((index + 1) < format->symbols_count)
+    if ((index + 1) < format->sym_count)
         memmove(&format->symbols[index], &format->symbols[index + 1],
-                (format->symbols_count - index - 1) * sizeof(GBinSymbol *));
+                (format->sym_count - index - 1) * sizeof(GBinSymbol *));
 
     format->symbols = (GBinSymbol **)realloc(format->symbols,
-                                             --format->symbols_count * sizeof(GBinSymbol *));
+                                             --format->sym_count * sizeof(GBinSymbol *));
 
 }
 
@@ -493,7 +658,7 @@ void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol)
 
     // FIXME : dicho
 
-    for (i = 0; i < format->symbols_count; i++)
+    for (i = 0; i < format->sym_count; i++)
         if (format->symbols[i] == symbol)
             break;
 
@@ -521,15 +686,15 @@ static void g_binary_format_delete_duplicated_symbols(GBinFormat *format)
     mrange_t last;                          /* Dernière localisation vue   */
     size_t index;                           /* Indice de suppression       */
 
-    g_rw_lock_writer_lock(&format->syms_lock);
+    g_binary_format_lock_unlock_symbols_wr(format, true);
 
-    if (format->symbols_count > 1)
+    if (format->sym_count > 1)
     {
         range = g_binary_symbol_get_range(format->symbols[0]);
         copy_mrange(&last, range);
     }
 
-    for (i = 1; i < format->symbols_count; i++)
+    for (i = 1; i < format->sym_count; i++)
     {
         range = g_binary_symbol_get_range(format->symbols[i]);
 
@@ -554,29 +719,7 @@ static void g_binary_format_delete_duplicated_symbols(GBinFormat *format)
 
     }
 
-    g_rw_lock_writer_unlock(&format->syms_lock);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : format = informations chargées à consulter.                  *
-*                count  = taille du tableau créé. [OUT]                       *
-*                                                                             *
-*  Description : Fournit la liste de tous les symboles détectés.              *
-*                                                                             *
-*  Retour      : Tableau créé ou NULL si aucun symbole trouvé.                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count)
-{
-    *count = format->symbols_count;
-
-    return format->symbols;
+    g_binary_format_lock_unlock_symbols_wr(format, false);
 
 }
 
@@ -693,9 +836,9 @@ bool g_binary_format_find_symbol_by_label(GBinFormat *format, const char *label,
 
     result = false;
 
-    g_rw_lock_reader_lock(&format->syms_lock);
+    g_binary_format_lock_symbols_rd(format);
 
-    for (i = 0; i < format->symbols_count && !result; i++)
+    for (i = 0; i < format->sym_count && !result; i++)
     {
         cur_lbl = g_binary_symbol_get_label(format->symbols[i]);
         if (cur_lbl == NULL) continue;
@@ -711,7 +854,7 @@ bool g_binary_format_find_symbol_by_label(GBinFormat *format, const char *label,
 
     }
 
-    g_rw_lock_reader_unlock(&format->syms_lock);
+    g_binary_format_unlock_symbols_rd(format);
 
     return result;
 
@@ -739,6 +882,8 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
     bool result;                            /* Bilan à retourner           */
     void *found;                            /* Résultat de recherches      */
 
+    assert(g_atomic_int_get(&format->sym_locked) > 0);
+
     /**
      * Pour ce qui est des justifications quant à la vérification suivante,
      * se référer aux commentaires placés dans g_binary_format_add_symbol().
@@ -746,7 +891,7 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
 
     assert(has_phys_addr(addr));
 
-    found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn);
+    found = bsearch(addr, format->symbols, format->sym_count, sizeof(GBinSymbol *), fn);
 
     if (found != NULL)
     {
@@ -802,11 +947,11 @@ bool g_binary_format_find_symbol_at(GBinFormat *format, const vmpa2t *addr, GBin
 
     }
 
-    g_rw_lock_reader_lock(&format->syms_lock);
+    g_binary_format_lock_symbols_rd(format);
 
     result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, NULL, symbol);
 
-    g_rw_lock_reader_unlock(&format->syms_lock);
+    g_binary_format_unlock_symbols_rd(format);
 
     return result;
 
@@ -841,11 +986,11 @@ bool g_binary_format_find_symbol_for(GBinFormat *format, const vmpa2t *addr, GBi
 
     }
 
-    g_rw_lock_reader_lock(&format->syms_lock);
+    g_binary_format_lock_symbols_rd(format);
 
     result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, NULL, symbol);
 
-    g_rw_lock_reader_unlock(&format->syms_lock);
+    g_binary_format_unlock_symbols_rd(format);
 
     return result;
 
@@ -881,11 +1026,11 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
 
     }
 
-    g_rw_lock_reader_lock(&format->syms_lock);
+    g_binary_format_lock_symbols_rd(format);
 
     result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, NULL);
 
-    if (result && (index + 1) < format->symbols_count)
+    if (result && (index + 1) < format->sym_count)
     {
         *symbol = format->symbols[index + 1];
         g_object_ref(G_OBJECT(*symbol));
@@ -898,7 +1043,7 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
         result = false;
     }
 
-    g_rw_lock_reader_unlock(&format->syms_lock);
+    g_binary_format_unlock_symbols_rd(format);
 
     return result;
 
diff --git a/src/format/format.h b/src/format/format.h
index 8247478..9a3a6e3 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -70,15 +70,38 @@ void g_binary_format_preload_disassembling_context(GBinFormat *, GProcContext *,
 /* Définit les points de départ d'un contexte de désassemblage. */
 void g_binary_format_activate_disassembling_context(GBinFormat *, GProcContext *, GtkStatusStack *);
 
+
+
+/* ---------------------- RASSEMBLEMENT ET GESTION DE SYMBOLES ---------------------- */
+
+
+/* Protège ou lève la protection de l'accès aux symboles. */
+void g_binary_format_lock_unlock_symbols_rd(GBinFormat *, bool);
+
+#define g_binary_format_lock_symbols_rd(f) g_binary_format_lock_unlock_symbols_rd(f, true)
+#define g_binary_format_unlock_symbols_rd(f) g_binary_format_lock_unlock_symbols_rd(f, false)
+
+/* Protège ou lève la protection de l'accès aux symboles. */
+void g_binary_format_lock_unlock_symbols_wr(GBinFormat *, bool);
+
+#define g_binary_format_lock_symbols_wr(f) g_binary_format_lock_unlock_symbols_wr(f, true)
+#define g_binary_format_unlock_symbols_wr(f) g_binary_format_lock_unlock_symbols_wr(f, false)
+
+/* Fournit la marque de dernière modification des symboles. */
+unsigned int g_binary_format_get_symbols_stamp(const GBinFormat *);
+
+/* Compte le nombre de symboles représentés. */
+size_t g_binary_format_count_symbols(const GBinFormat *);
+
+/* Fournit un symbole lié à un format. */
+GBinSymbol *g_binary_format_get_symbol(const GBinFormat *, size_t);
+
 /* Ajoute un symbole à la collection du format binaire. */
 bool g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
 
 /* Retire un symbole de la collection du format binaire. */
 void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *);
 
-/* Fournit la liste de tous les symboles détectés. */
-GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
-
 /* Construit une désignation pour chaîne de caractères. */
 char *create_string_label(GBinFormat *, const vmpa2t *, size_t);
 
@@ -97,6 +120,9 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *, const vmpa2t *, GBinSymbo
 /* Recherche le symbole correspondant à une adresse. */
 bool g_binary_format_resolve_symbol(GBinFormat *, const vmpa2t *, bool, GBinSymbol **, phys_t *);
 
+
+
+
 /* Fournit la liste des fichiers source détectés. */
 const char * const *g_binary_format_get_source_files(const GBinFormat *, size_t *, size_t *);
 
diff --git a/src/format/symiter.c b/src/format/symiter.c
new file mode 100644
index 0000000..74b4abb
--- /dev/null
+++ b/src/format/symiter.c
@@ -0,0 +1,289 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * symiter.c - prototypes pour le parcours simplifié d'un ensemble de symboles
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "symiter.h"
+
+
+#include <malloc.h>
+
+
+#include "format.h"
+
+
+
+/* Suivi d'un parcours de symboles */
+typedef struct _sym_iter_t
+{
+    GBinFormat *format;                     /* Conteneur associé           */
+    unsigned int stamp;                     /* Suivi d'évolutions externes */
+
+    size_t index;                           /* Symbole courant             */
+
+    mrange_t restriction;                   /* Enventuelle limite de zone  */
+    bool is_restricted;                     /* Validité de l'étendue       */
+
+} sym_iter_t;
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = processeur recensant divers symboles.               *
+*                index  = indice du premier symbole à fournir.                *
+*                                                                             *
+*  Description : Construit un itérateur pour parcourir des symboles.          *
+*                                                                             *
+*  Retour      : Itérateur prêt à emploi.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+sym_iter_t *create_symbol_iterator(GBinFormat *format, size_t index)
+{
+    sym_iter_t *result;                     /* Structure à retourner       */
+
+    result = (sym_iter_t *)malloc(sizeof(sym_iter_t));
+
+    g_object_ref(G_OBJECT(format));
+
+    result->format = format;
+    result->stamp = g_binary_format_get_symbols_stamp(format);
+
+    result->index = index;
+
+    result->is_restricted = false;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter = itérateur à traiter.                                  *
+*                                                                             *
+*  Description : Détruit un itérateur mis en place.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_symbol_iterator(sym_iter_t *iter)
+{
+    g_object_unref(G_OBJECT(iter->format));
+
+    free(iter);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter  = itérateur à traiter.                                 *
+*                range = bornes de l'espace de parcours.                      *
+*                                                                             *
+*  Description : Limite le parcours des symboles à une zone donnée.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void restrict_symbol_iterator(sym_iter_t *iter, const mrange_t *range)
+{
+    copy_mrange(&iter->restriction, range);
+
+    iter->is_restricted = true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter = itérateur à manipuler.                                *
+*                                                                             *
+*  Description : Fournit le symbole courant de l'itérateur.                   *
+*                                                                             *
+*  Retour      : Symbole suivant trouvé, ou NULL.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinSymbol *get_symbol_iterator_current(sym_iter_t *iter)
+{
+    GBinSymbol *result;                     /* Résultat à retourner        */
+    const mrange_t *irange;                 /* Emplacement de symbole      */
+
+    g_binary_format_lock_symbols_rd(iter->format);
+
+    if (iter->stamp != g_binary_format_get_symbols_stamp(iter->format))
+        result = NULL;
+
+    else
+    {
+        if (iter->index < g_binary_format_count_symbols(iter->format))
+        {
+            result = g_binary_format_get_symbol(iter->format, iter->index);
+
+            /* Le symbole sort-il des clous ? */
+            if (iter->is_restricted)
+            {
+                irange = g_binary_symbol_get_range(result);
+
+                if (!mrange_contains_mrange(&iter->restriction, irange))
+                {
+                    g_object_unref(G_OBJECT(result));
+                    result = NULL;
+                }
+
+            }
+
+        }
+
+        else
+            result = NULL;
+
+    }
+
+    g_binary_format_unlock_symbols_rd(iter->format);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter = itérateur à manipuler.                                *
+*                                                                             *
+*  Description : Fournit le symbole qui en précède un autre.                  *
+*                                                                             *
+*  Retour      : Symbole suivant trouvé, ou NULL.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinSymbol *get_symbol_iterator_prev(sym_iter_t *iter)
+{
+    GBinSymbol *result;                     /* Résultat à retourner        */
+    const mrange_t *irange;                 /* Emplacement de symbole      */
+
+    g_binary_format_lock_symbols_rd(iter->format);
+
+    if (iter->stamp != g_binary_format_get_symbols_stamp(iter->format))
+        result = NULL;
+
+    else
+    {
+        if (iter->index > 1)
+        {
+            iter->index--;
+            result = g_binary_format_get_symbol(iter->format, iter->index);
+
+            /* Le symbole sort-il des clous ? */
+            if (iter->is_restricted)
+            {
+                irange = g_binary_symbol_get_range(result);
+
+                if (!mrange_contains_mrange(&iter->restriction, irange))
+                {
+                    g_object_unref(G_OBJECT(result));
+                    result = NULL;
+                }
+
+            }
+
+        }
+
+        else
+            result = NULL;
+
+    }
+
+    g_binary_format_unlock_symbols_rd(iter->format);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iter = itérateur à manipuler.                                *
+*                                                                             *
+*  Description : Fournit le symbole qui en suit un autre.                     *
+*                                                                             *
+*  Retour      : Symbole suivant trouvé, ou NULL.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinSymbol *get_symbol_iterator_next(sym_iter_t *iter)
+{
+    GBinSymbol *result;                     /* Résultat à retourner        */
+    const mrange_t *irange;                 /* Emplacement de symbole      */
+
+    g_binary_format_lock_symbols_rd(iter->format);
+
+    if (iter->stamp != g_binary_format_get_symbols_stamp(iter->format))
+        result = NULL;
+
+    else
+    {
+        if ((iter->index + 1) < g_binary_format_count_symbols(iter->format))
+        {
+            iter->index++;
+            result = g_binary_format_get_symbol(iter->format, iter->index);
+
+            /* Le symbole sort-il des clous ? */
+            if (iter->is_restricted)
+            {
+                irange = g_binary_symbol_get_range(result);
+
+                if (!mrange_contains_mrange(&iter->restriction, irange))
+                {
+                    g_object_unref(G_OBJECT(result));
+                    result = NULL;
+                }
+
+            }
+
+        }
+
+        else
+            result = NULL;
+
+    }
+
+    g_binary_format_unlock_symbols_rd(iter->format);
+
+    return result;
+
+}
diff --git a/src/format/symiter.h b/src/format/symiter.h
new file mode 100644
index 0000000..32f4af7
--- /dev/null
+++ b/src/format/symiter.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * symiter.h - prototypes pour le parcours simplifié d'un ensemble de symboles
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _FORMAT_SYMITER_H
+#define _FORMAT_SYMITER_H
+
+
+#include "format.h"
+
+
+
+/* Suivi d'un parcours de symboles */
+typedef struct _sym_iter_t sym_iter_t;
+
+
+/* Construit un itérateur pour parcourir des symboles. */
+sym_iter_t *create_symbol_iterator(GBinFormat *, size_t);
+
+/* Détruit un itérateur mis en place. */
+void delete_symbol_iterator(sym_iter_t *);
+
+/* Limite le parcours des symboles à une zone donnée. */
+void restrict_symbol_iterator(sym_iter_t *, const mrange_t *);
+
+/* Fournit le symbole courant de l'itérateur. */
+GBinSymbol *get_symbol_iterator_current(sym_iter_t *);
+
+/* Fournit le symbole qui en précède un autre. */
+GBinSymbol *get_symbol_iterator_prev(sym_iter_t *);
+
+/* Fournit le symbole qui en suit un autre. */
+GBinSymbol *get_symbol_iterator_next(sym_iter_t *);
+
+
+
+#endif  /* _FORMAT_SYMITER_H */
diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c
index 00ad356..31123ff 100644
--- a/src/gui/dialogs/gotox.c
+++ b/src/gui/dialogs/gotox.c
@@ -32,6 +32,7 @@
 
 
 #include "../../format/format.h"
+#include "../../format/symiter.h"
 #include "../../gtkext/easygtk.h"
 #include "../../gtkext/support.h"
 
@@ -213,10 +214,9 @@ GtkWidget *create_gotox_dialog_for_entry_points(GtkWindow *parent, GLoadedBinary
     GtkWidget *result;                      /* Fenêtre à renvoyer          */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GBinFormat *format;                     /* Format associé au binaire   */
-    GBinSymbol **symbols;                   /* Symboles à représenter      */
-    size_t sym_count;                       /* Qté de symboles présents    */
+    sym_iter_t *siter;                      /* Parcours des symboles       */
+    GBinSymbol *symbol;                     /* Symbole manipulé            */
     bool has_entry_points;                  /* Présences d'insertions ?    */
-    size_t i;                               /* Boucle de parcours          */
     vmpa2t addr;                            /* Localisation de symbole     */
 
     /* Mise en place de la boîte de dialogue */
@@ -229,23 +229,31 @@ GtkWidget *create_gotox_dialog_for_entry_points(GtkWindow *parent, GLoadedBinary
 
     format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
 
-    symbols = g_binary_format_get_symbols(format, &sym_count);
+    siter = create_symbol_iterator(format, 0);
 
     has_entry_points = false;
 
-    for (i = 0; i < sym_count; i++)
+    for (symbol = get_symbol_iterator_current(siter);
+         symbol != NULL;
+         symbol = get_symbol_iterator_next(siter))
     {
-        if (g_binary_symbol_get_target_type(symbols[i]) != STP_ENTRY_POINT)
-            continue;
+        if (g_binary_symbol_get_target_type(symbol) != STP_ENTRY_POINT)
+            goto cgdfep_next;
 
-        copy_vmpa(&addr, get_mrange_addr(g_binary_symbol_get_range(symbols[i])));
+        copy_vmpa(&addr, get_mrange_addr(g_binary_symbol_get_range(symbol)));
 
-        add_new_location_to_list(store, binary, &addr, symbols[i]);
+        add_new_location_to_list(store, binary, &addr, symbol);
 
         has_entry_points = true;
 
+ cgdfep_next:
+
+        g_object_unref(G_OBJECT(symbol));
+
     }
 
+    delete_symbol_iterator(siter);
+
     g_object_unref(G_OBJECT(format));
 
     g_object_unref(G_OBJECT(store));
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 23383a1..5942d03 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -35,6 +35,7 @@
 #include "../../common/extstr.h"
 #include "../../core/params.h"
 #include "../../format/format.h"
+#include "../../format/symiter.h"
 #include "../../gtkext/easygtk.h"
 #include "../../gtkext/gtkdockable-int.h"
 
@@ -468,9 +469,8 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
     GExeFormat *format;                     /* Format de travail           */
     GBinPortion *portions;                  /* Couche première de portions */
     GBinContent *content;                   /* Contenu binaire en mémoire  */
-    size_t count;                           /* Nombre des chaînes          */
-    GBinSymbol **symbols;                   /* Liste des chaînes trouvées  */
-    size_t i;                               /* Boucle de parcours          */
+    sym_iter_t *siter;                      /* Parcours des symboles       */
+    GBinSymbol *symbol;                     /* Symbole manipulé            */
     const mrange_t *range;                  /* Couverture mémoire          */
     const vmpa2t *addr;                     /* Adressse liée à la chaîne   */
     VMPA_BUFFER(phys);                      /* Position physique           */
@@ -509,13 +509,16 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
     portions = g_exe_format_get_portions(format);
     content = g_binary_format_get_content(G_BIN_FORMAT(format));
 
-    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &count);
+    siter = create_symbol_iterator(G_BIN_FORMAT(format), 0);
 
-    for (i = 0; i < count; i++)
+    for (symbol = get_symbol_iterator_current(siter);
+         symbol != NULL;
+         symbol = get_symbol_iterator_next(siter))
     {
-        if (g_binary_symbol_get_target_type(symbols[i]) != STP_RO_STRING) continue;
+        if (g_binary_symbol_get_target_type(symbol) != STP_RO_STRING)
+            goto cspcb_next;
 
-        range = g_binary_symbol_get_range(symbols[i]);
+        range = g_binary_symbol_get_range(symbol);
         addr = get_mrange_addr(range);
 
         vmpa2_phys_to_string(addr, msize, phys, NULL);
@@ -525,7 +528,7 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
         area = g_binary_portion_get_desc(portion);
         g_object_unref(G_OBJECT(portion));
 
-        label = g_binary_symbol_get_label(symbols[i]);
+        label = g_binary_symbol_get_label(symbol);
 
         text = (char *)calloc(get_mrange_length(range) + 1, sizeof(char));
 
@@ -534,13 +537,13 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
         if (!g_binary_content_read_raw(content, &pos, get_mrange_length(range), (uint8_t *)text))
         {
             free(text);
-            continue;
+            goto cspcb_next;
         }
 
         if (is_string_filtered(panel, label, text))
         {
             free(text);
-            continue;
+            goto cspcb_next;
         }
 
         text = strrpl(text, "&", "&amp;");
@@ -551,7 +554,7 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
 
         gtk_tree_store_append(store, &iter, NULL);
         gtk_tree_store_set(store, &iter,
-                           STC_STRING, symbols[i],
+                           STC_STRING, symbol,
                            STC_PHYSICAL, phys,
                            STC_VIRTUAL, virt,
                            STC_AREA, area,
@@ -561,8 +564,14 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
 
         free(text);
 
+ cspcb_next:
+
+        g_object_unref(G_OBJECT(symbol));
+
     }
 
+    delete_symbol_iterator(siter);
+
     g_object_unref(G_OBJECT(content));
     g_object_unref(G_OBJECT(portions));
     g_object_unref(G_OBJECT(format));
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index f64f087..dee03b5 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -39,6 +39,7 @@
 #include "panel-int.h"
 #include "../core/global.h"
 #include "../../format/format.h"
+#include "../../format/symiter.h"
 #include "../../gtkext/easygtk.h"
 #include "../../gtkext/support.h"
 #include "../../gtkext/tmgt.h"
@@ -649,11 +650,10 @@ static void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBin
 static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
 {
     GExeFormat *format;                     /* Format associé au binaire   */
-    GBinSymbol **symbols;                   /* Symboles à représenter      */
-    size_t sym_count;                       /* Qté de symboles présents    */
     GArchProcessor *proc;                   /* Architecture utilisée       */
     MemoryDataSize size;                    /* Taille des localisations    */
-    size_t i;                               /* Boucle de parcours          */
+    sym_iter_t *siter;                      /* Parcours des symboles       */
+    GBinSymbol *symbol;                     /* Symbole manipulé            */
     regmatch_t match;                       /* Récupération des trouvailles*/
     cairo_surface_t *icon;                  /* Image associée au symbole   */
     const char *original;                   /* Etiquette brute d'origine   */
@@ -664,18 +664,20 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
 
     format = g_loaded_binary_get_format(panel->binary);
 
-    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
-
     proc = g_loaded_binary_get_processor(panel->binary);
     size = g_arch_processor_get_memory_size(proc);
     g_object_unref(G_OBJECT(proc));
 
-    for (i = 0; i < sym_count; i++)
+    siter = create_symbol_iterator(G_BIN_FORMAT(format), 0);
+
+    for (symbol = get_symbol_iterator_current(siter);
+         symbol != NULL;
+         symbol = get_symbol_iterator_next(siter))
     {
-        if (!is_symbol_matching(panel, symbols[i], &match))
-            continue;
+        if (!is_symbol_matching(panel, symbol, &match))
+            goto rsfnlv_next;
 
-        switch (g_binary_symbol_get_target_type(symbols[i]))
+        switch (g_binary_symbol_get_target_type(symbol))
         {
             case STP_ROUTINE:
             case STP_ENTRY_POINT:
@@ -689,15 +691,15 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
                 break;
         }
 
-        original = g_binary_symbol_get_label(symbols[i]);
+        original = g_binary_symbol_get_label(symbol);
         name = build_highlighted_name(original, &match, 0);
 
-        addr = get_mrange_addr(g_binary_symbol_get_range(symbols[i]));
+        addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
         vmpa2_virt_to_string(addr, size, virt, NULL);
 
         gtk_tree_store_append(panel->store, &iter, NULL);
         gtk_tree_store_set(panel->store, &iter,
-                           SBC_SYMBOL, symbols[i],
+                           SBC_SYMBOL, symbol,
                            SBC_PICTURE, icon,
                            SBC_NAME, name,
                            SBC_ORIGINAL, original,
@@ -706,8 +708,14 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
 
         free(name);
 
+ rsfnlv_next:
+
+        g_object_unref(G_OBJECT(symbol));
+
     }
 
+    delete_symbol_iterator(siter);
+
     g_object_unref(G_OBJECT(format));
 
 }
@@ -849,11 +857,10 @@ static bool find_parent_for_symbol(GSymbolsPanel *panel, const GBinSymbol *symbo
 static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
 {
     GExeFormat *format;                     /* Format associé au binaire   */
-    GBinSymbol **symbols;                   /* Symboles à représenter      */
-    size_t sym_count;                       /* Qté de symboles présents    */
     GArchProcessor *proc;                   /* Architecture utilisée       */
     MemoryDataSize size;                    /* Taille des localisations    */
-    size_t i;                               /* Boucle de parcours          */
+    sym_iter_t *siter;                      /* Parcours des symboles       */
+    GBinSymbol *symbol;                     /* Symbole manipulé            */
     regmatch_t match;                       /* Récupération des trouvailles*/
     GtkTreeIter parent;                     /* Point d'insertion parent    */
     size_t last;                            /* Position du dernier élément */
@@ -866,18 +873,20 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
 
     format = g_loaded_binary_get_format(panel->binary);
 
-    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
-
     proc = g_loaded_binary_get_processor(panel->binary);
     size = g_arch_processor_get_memory_size(proc);
     g_object_unref(G_OBJECT(proc));
 
-    for (i = 0; i < sym_count; i++)
+    siter = create_symbol_iterator(G_BIN_FORMAT(format), 0);
+
+    for (symbol = get_symbol_iterator_current(siter);
+         symbol != NULL;
+         symbol = get_symbol_iterator_next(siter))
     {
-        if (!is_symbol_matching(panel, symbols[i], &match))
-            continue;
+        if (!is_symbol_matching(panel, symbol, &match))
+            goto rsfntv_next;
 
-        if (find_parent_for_symbol(panel, symbols[i], &parent, &match, &last))
+        if (find_parent_for_symbol(panel, symbol, &parent, &match, &last))
         {
             gtk_tree_store_set(panel->store, &parent,
                                SBC_PICTURE, G_SYMBOLS_PANEL_GET_CLASS(panel)->class_img,
@@ -890,7 +899,7 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
         else
             gtk_tree_store_append(panel->store, &iter, NULL);
 
-        switch (g_binary_symbol_get_target_type(symbols[i]))
+        switch (g_binary_symbol_get_target_type(symbol))
         {
             case STP_ROUTINE:
             case STP_ENTRY_POINT:
@@ -904,14 +913,14 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
                 break;
         }
 
-        original = g_binary_symbol_get_label(symbols[i]);
+        original = g_binary_symbol_get_label(symbol);
         name = build_highlighted_name(original + last, &match, last);
 
-        addr = get_mrange_addr(g_binary_symbol_get_range(symbols[i]));
+        addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
         vmpa2_virt_to_string(addr, size, virt, NULL);
 
         gtk_tree_store_set(panel->store, &iter,
-                           SBC_SYMBOL, symbols[i],
+                           SBC_SYMBOL, symbol,
                            SBC_PICTURE, icon,
                            SBC_NAME, name,
                            SBC_ORIGINAL, original + last,
@@ -920,8 +929,14 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
 
         free(name);
 
+ rsfntv_next:
+
+        g_object_unref(G_OBJECT(symbol));
+
     }
 
+    delete_symbol_iterator(siter);
+
     g_object_unref(G_OBJECT(format));
 
 }
-- 
cgit v0.11.2-87-g4458