diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-01-13 22:37:31 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-01-13 22:37:31 (GMT) |
commit | 23b9c6e68bbe5f0531f9a9408c2deb9f897701dc (patch) | |
tree | 3804d6c21c9cd5e291cb8c7853607cdda992d125 /src/format | |
parent | a6975c1d754a1ba5bfb9e23f0b26692c746e6f9c (diff) |
Created a real iterator for symbols.
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/Makefile.am | 1 | ||||
-rw-r--r-- | src/format/format-int.h | 6 | ||||
-rw-r--r-- | src/format/format.c | 239 | ||||
-rw-r--r-- | src/format/format.h | 32 | ||||
-rw-r--r-- | src/format/symiter.c | 289 | ||||
-rw-r--r-- | src/format/symiter.h | 56 |
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 */ |