diff options
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/elf/symbols.c | 2 | ||||
-rw-r--r-- | src/format/format.c | 50 |
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; } |