diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-05-13 19:59:41 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-05-13 19:59:41 (GMT) |
commit | ed5541867f94b36e701708757a0489298fe77135 (patch) | |
tree | 56cc80141354d1d955a6ad9599e3bc2ab7366ad7 /src/format/format.c | |
parent | 3d28b198f12671e4933890a4b79933d064593ce3 (diff) |
Inserted symbols and routines using an optimized 100 times faster method.
Diffstat (limited to 'src/format/format.c')
-rw-r--r-- | src/format/format.c | 123 |
1 files changed, 39 insertions, 84 deletions
diff --git a/src/format/format.c b/src/format/format.c index 88f59b8..0ae6107 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -37,6 +37,7 @@ #include "java/java.h" #include "pe/pe.h" #include "../arch/processor.h" +#include "../common/sort.h" #include "../decomp/expr/block.h" #include "../gui/panels/log.h" #include "../plugins/pglist.h" @@ -56,7 +57,7 @@ static void _g_binary_format_remove_symbol(GBinFormat *, size_t); static void g_binary_format_delete_duplicated_symbols(GBinFormat *); /* Recherche le symbole associé à une adresse. */ -static bool _g_binary_format_find_symbol(const GBinFormat *, const vmpa2t *, __compar_fn_t, GBinSymbol **); +static bool _g_binary_format_find_symbol(const GBinFormat *, const vmpa2t *, __compar_fn_t, size_t *, GBinSymbol **); @@ -97,9 +98,6 @@ static void g_binary_format_class_init(GBinFormatClass *klass) static void g_binary_format_init(GBinFormat *format) { g_rw_lock_init(&format->syms_lock); - g_atomic_int_set(&format->unsorted_symbols, false); - - format->unsorted_routines = false; } @@ -270,7 +268,6 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc * * * Paramètres : format = informations chargées à compléter. * * symbol = symbole à ajouter à la liste. * -* sort = fait état d'un obligation de tri final. * * * * Description : Ajoute un symbole à la collection du format binaire. * * * @@ -280,7 +277,7 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc * * ******************************************************************************/ -void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool sort) +void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol) { #ifndef NDEBUG const mrange_t *range; /* Couverture du symbole */ @@ -307,25 +304,17 @@ void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool so g_rw_lock_writer_lock(&format->syms_lock); - format->symbols = (GBinSymbol **)realloc(format->symbols, - ++format->symbols_count * sizeof(GBinSymbol *)); - - format->symbols[format->symbols_count - 1] = symbol; - - g_atomic_int_set(&format->unsorted_symbols, true); + format->symbols = qinsert(format->symbols, &format->symbols_count, + sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp, symbol); switch (g_binary_symbol_get_target_type(symbol)) { case STP_ROUTINE: case STP_ENTRY_POINT: - format->routines = (GBinRoutine **)realloc(format->routines, - ++format->routines_count * sizeof(GBinRoutine *)); - - format->routines[format->routines_count - 1] = g_binary_symbol_get_routine(symbol); - - format->unsorted_routines = true; - + format->routines = qinsert(format->routines, &format->routines_count, + sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare, + g_binary_symbol_get_routine(symbol)); break; default: @@ -335,9 +324,6 @@ void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool so g_rw_lock_writer_unlock(&format->syms_lock); - if (sort) - g_binary_format_sort_symbols(format); - } @@ -434,43 +420,6 @@ void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol) /****************************************************************************** * * -* Paramètres : format = informations chargées à arranger. * -* * -* Description : Réorganise si besoin est les symboles collectés. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_format_sort_symbols(GBinFormat *format) -{ - if (g_atomic_int_compare_and_exchange(&format->unsorted_symbols, true, false)) - { - g_rw_lock_writer_lock(&format->syms_lock); - - qsort(format->symbols, format->symbols_count, - sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp); - - if (format->unsorted_routines) - { - qsort(format->routines, format->routines_count, - sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare); - - format->unsorted_routines = false; - - } - - g_rw_lock_writer_unlock(&format->syms_lock); - - } - -} - - -/****************************************************************************** -* * * Paramètres : format = informations chargées à corriger si besoin est. * * * * Description : Supprime les éventuels doublons au sein des symboles. * @@ -488,8 +437,6 @@ static void g_binary_format_delete_duplicated_symbols(GBinFormat *format) mrange_t last; /* Dernière localisation vue */ size_t index; /* Indice de suppression */ - g_binary_format_sort_symbols(G_BIN_FORMAT(format)); - g_rw_lock_writer_lock(&format->syms_lock); if (format->symbols_count > 1) @@ -684,6 +631,7 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char * * Paramètres : format = informations chargées à consulter. * * addr = adresse à cibler lors des recherches. * * fn = méthode de comparaison des symboles. * +* index = indice de l'éventuel symbole trouvé ou NULL. [OUT] * * symbol = éventuel symbole trouvé à déréfenrencer. [OUT] * * * * Description : Recherche le symbole associé à une adresse. * @@ -694,7 +642,7 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char * * * ******************************************************************************/ -static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t *addr, __compar_fn_t fn, GBinSymbol **symbol) +static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t *addr, __compar_fn_t fn, size_t *index, GBinSymbol **symbol) { bool result; /* Bilan à retourner */ void *found; /* Résultat de recherches */ @@ -703,14 +651,13 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t *symbol = NULL; /* TODO : vérifier les doublons côtés appelants */ - g_rw_lock_reader_lock(&format->syms_lock); - found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn); - g_rw_lock_reader_unlock(&format->syms_lock); - if (found != NULL) { + if (index != NULL) + *index = (GBinSymbol **)found - format->symbols; + *symbol = *(GBinSymbol **)found; g_object_ref(G_OBJECT(*symbol)); @@ -751,7 +698,11 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr } - result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, symbol); + g_rw_lock_reader_lock(&format->syms_lock); + + result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, NULL, symbol); + + g_rw_lock_reader_unlock(&format->syms_lock); return result; @@ -786,7 +737,11 @@ bool g_binary_format_find_symbol_for(const GBinFormat *format, const vmpa2t *add } - result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, symbol); + g_rw_lock_reader_lock(&format->syms_lock); + + result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, NULL, symbol); + + g_rw_lock_reader_unlock(&format->syms_lock); return result; @@ -810,32 +765,32 @@ bool g_binary_format_find_symbol_for(const GBinFormat *format, const vmpa2t *add bool g_binary_format_find_next_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol) { bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - const mrange_t *range; /* Espace mémoire parcouru */ + size_t index; /* Indice à considérer */ - result = false; - - *symbol = NULL; + int find_symbol(const vmpa2t *addr, const GBinSymbol **sym) + { + const mrange_t *range; /* Espace mémoire parcouru */ - g_rw_lock_reader_lock(&format->syms_lock); + range = g_binary_symbol_get_range(*sym); - /* TODO : ajouter un peu de dichotomie ici ! */ + return cmp_mrange_with_vmpa(range, addr); - for (i = 0; i < format->symbols_count && !result; i++) - { - range = g_binary_symbol_get_range(format->symbols[i]); + } - if (cmp_vmpa(get_mrange_addr(range), addr) == 0 && (i + 1) < format->symbols_count) - { - *symbol = format->symbols[i + 1]; - g_object_ref(G_OBJECT(*symbol)); + g_rw_lock_reader_lock(&format->syms_lock); - result = true; + result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, symbol); - } + if (result && (index + 1) < format->symbols_count) + { + *symbol = format->symbols[index + 1]; + g_object_ref(G_OBJECT(*symbol)); } + else + result = false; + g_rw_lock_reader_unlock(&format->syms_lock); return result; |