summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-01-15 14:47:04 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-01-15 14:47:04 (GMT)
commitaf2ac16182b6243f17e06ec75e441014159abe5e (patch)
treef0e82673bf5e63e3b06244c2139d8f10dca0203f /src/format
parent56e060d11c238ac7c7b3ecf0eb0527bbaebd5b4b (diff)
Improved symbol resolving using fully defined locations.
Diffstat (limited to 'src/format')
-rw-r--r--src/format/elf/symbols.c2
-rw-r--r--src/format/format.c50
2 files changed, 40 insertions, 12 deletions
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index b936a47..8451911 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -215,6 +215,8 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
_g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT);
+ g_object_unref(G_OBJECT(symbol));
+
}
else
{
diff --git a/src/format/format.c b/src/format/format.c
index 550e816..327b28e 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -297,21 +297,29 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
GBinRoutine *routine; /* Nouvelle routine à insérer */
/**
- * Lorsque les fonctions de recherche type g_binary_format_find_symbol_at()
- * sont appelées avec une localisation, cette dernière peut reposer soit sur
- * une position physique soit une adresse virtuelle uniquement.
+ * Pour que les fonctions de recherche basées sur _g_binary_format_find_symbol()
+ * fassent bien leur office, il faut que les symboles soient triés.
*
- * Pour que les comparaisons de positions puissent se réaliser, il faut donc
- * pouvoir satisfaire les deux aspects : physiques et virtuels.
+ * Cependant, les localisations à satisfaire lors d'une recherche recontrent
+ * un problème si les positions physiques ne sont pas renseignées. En effet
+ * les adresses virtuelles en sont potentiellement décorrélées (c'est le cas
+ * avec le format ELF par exemple, où les zones en mémoire ne suivent pas le
+ * même ordre que les segments du binaire).
*
- * On corrige donc le tir si besoin est ici.
+ * Comme les comparaisons entre localisations se réalisent sur les éléments
+ * renseignés communs, à commencer par la position physique si c'est possible,
+ * une localisation s'appuyant uniquement sur une adresse virtuelle va être
+ * analysée suivant une liste non triée d'adresses virtuelles.
+ *
+ * On corrige donc le tir si besoin est en forçant la comparaison via les
+ * positions physiques.
*/
#ifndef NDEBUG
range = g_binary_symbol_get_range(symbol);
addr = get_mrange_addr(range);
- assert(!is_invalid_vmpa(addr));
+ assert(has_phys_addr(addr));
#endif
g_rw_lock_writer_lock(&format->syms_lock);
@@ -684,9 +692,12 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
bool result; /* Bilan à retourner */
void *found; /* Résultat de recherches */
- result = false;
+ /**
+ * 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().
+ */
- *symbol = NULL; /* TODO : vérifier les doublons côtés appelants */
+ assert(has_phys_addr(addr));
found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn);
@@ -695,13 +706,22 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
if (index != NULL)
*index = (GBinSymbol **)found - format->symbols;
- *symbol = *(GBinSymbol **)found;
+ if (symbol != NULL)
+ {
+ *symbol = *(GBinSymbol **)found;
+ g_object_ref(G_OBJECT(*symbol));
+ }
- g_object_ref(G_OBJECT(*symbol));
result = true;
}
+ else
+ {
+ *symbol = NULL;
+ result = false;
+ }
+
return result;
}
@@ -816,7 +836,7 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
g_rw_lock_reader_lock(&format->syms_lock);
- result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, symbol);
+ result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, NULL);
if (result && (index + 1) < format->symbols_count)
{
@@ -826,7 +846,10 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
}
else
+ {
+ *symbol = NULL;
result = false;
+ }
g_rw_lock_reader_unlock(&format->syms_lock);
@@ -870,6 +893,9 @@ bool g_binary_format_resolve_symbol(GBinFormat *format, const vmpa2t *addr, bool
}
+ else
+ *diff = 0;
+
return result;
}