summaryrefslogtreecommitdiff
path: root/src/format/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/format.c')
-rw-r--r--src/format/format.c123
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;