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.c121
1 files changed, 84 insertions, 37 deletions
diff --git a/src/format/format.c b/src/format/format.c
index c1877d2..3373af3 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -90,10 +90,19 @@ 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;
}
+
+/* FIXME : g_rw_lock_clear(&format->syms_lock);*/
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
@@ -181,6 +190,7 @@ 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. *
* *
@@ -190,15 +200,17 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
* *
******************************************************************************/
-void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
+void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool sort)
{
+
+ 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;
- qsort(format->symbols, format->symbols_count,
- sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp);
+ g_atomic_int_set(&format->unsorted_symbols, true);
switch (g_binary_symbol_get_target_type(symbol))
{
@@ -209,9 +221,8 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
++format->routines_count * sizeof(GBinRoutine *));
format->routines[format->routines_count - 1] = g_binary_symbol_get_routine(symbol);
-
- qsort(format->routines, format->routines_count,
- sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare);
+
+ format->unsorted_routines = true;
break;
@@ -220,6 +231,11 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
}
+ g_rw_lock_writer_unlock(&format->syms_lock);
+
+ if (sort)
+ g_binary_format_sort_symbols(format);
+
}
@@ -315,6 +331,43 @@ 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 à consulter. *
* count = taille du tableau créé. [OUT] *
* *
@@ -477,25 +530,32 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char *
bool g_binary_format_find_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 */
+ void *found; /* Résultat de recherches */
result = false;
*symbol = NULL; /* TODO : vérifier les doublons côtés appelants */
- for (i = 0; i < format->symbols_count && !result; i++)
+ int find_symbol(const vmpa2t *addr, const GBinSymbol **sym)
{
- range = g_binary_symbol_get_range(format->symbols[i]);
+ const mrange_t *range; /* Espace mémoire parcouru */
- if (cmp_vmpa(get_mrange_addr(range), addr) == 0)
- {
- *symbol = format->symbols[i];
- g_object_ref(G_OBJECT(*symbol));
+ range = g_binary_symbol_get_range(*sym);
- result = true;
+ return cmp_vmpa_by_virt(addr, get_mrange_addr(range));
- }
+ }
+
+ found = bsearch(addr, format->symbols,
+ format->symbols_count, sizeof(GBinSymbol *),
+ (__compar_fn_t)find_symbol);
+
+ if (found != NULL)
+ {
+ *symbol = *(GBinSymbol **)found;
+
+ g_object_ref(G_OBJECT(*symbol));
+ result = true;
}
@@ -565,29 +625,16 @@ bool g_binary_format_find_next_symbol_at(const GBinFormat *format, const vmpa2t
bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff)
{
- bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
- const mrange_t *range; /* Espace mémoire parcouru */
+ bool result; /* Bilan à retourner */
+ const mrange_t *range; /* Espace mémoire parcouru */
- result = false;
-
- //for (i = 0; i < format->symbols_count && !result; i++)
- for (i = format->symbols_count; i > 0 && !result; i--)
- {
- range = g_binary_symbol_get_range(format->symbols[i - 1]);
+ result = g_binary_format_find_symbol_at(format, addr, symbol);
- if (mrange_contains_addr(range, addr))
- {
- *symbol = format->symbols[i - 1];
- g_object_ref(G_OBJECT(*symbol));
-
- *diff = compute_vmpa_diff(get_mrange_addr(range), addr);
-
- result = true;
-
- }
-
- }
+ if (result)
+ {
+ range = g_binary_symbol_get_range(*symbol);
+ *diff = compute_vmpa_diff(get_mrange_addr(range), addr);
+ }
return result;