diff options
Diffstat (limited to 'src/format/format.c')
-rw-r--r-- | src/format/format.c | 239 |
1 files changed, 192 insertions, 47 deletions
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; |