summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-01-13 22:37:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-01-13 22:37:31 (GMT)
commit23b9c6e68bbe5f0531f9a9408c2deb9f897701dc (patch)
tree3804d6c21c9cd5e291cb8c7853607cdda992d125 /src/format
parenta6975c1d754a1ba5bfb9e23f0b26692c746e6f9c (diff)
Created a real iterator for symbols.
Diffstat (limited to 'src/format')
-rw-r--r--src/format/Makefile.am1
-rw-r--r--src/format/format-int.h6
-rw-r--r--src/format/format.c239
-rw-r--r--src/format/format.h32
-rw-r--r--src/format/symiter.c289
-rw-r--r--src/format/symiter.h56
6 files changed, 572 insertions, 51 deletions
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 */