summaryrefslogtreecommitdiff
path: root/src
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
parenta6975c1d754a1ba5bfb9e23f0b26692c746e6f9c (diff)
Created a real iterator for symbols.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/disassembler.c19
-rw-r--r--src/analysis/disass/output.c48
-rw-r--r--src/analysis/disass/routines.c42
-rw-r--r--src/analysis/disass/routines.h4
-rw-r--r--src/arch/processor.c4
-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
-rw-r--r--src/gui/dialogs/gotox.c26
-rw-r--r--src/gui/panels/strings.c31
-rw-r--r--src/gui/panels/symbols.c65
14 files changed, 726 insertions, 136 deletions
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));
}