diff options
author | Timur Sultanov <SultanovTS@yandex.ru> | 2022-02-16 21:23:29 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-04-03 23:25:39 +0100 |
commit | 33d19a562fc06cbd85feb12ad589e5c0bf143d64 (patch) | |
tree | 164e963b26ca3f5d5098fa7bb1979880cb6700f5 | |
parent | fbbea77fa40be48eb7abf2987e357c11e9828c8a (diff) | |
download | serenity-33d19a562fc06cbd85feb12ad589e5c0bf143d64.zip |
LibELF: Look up symbols in all global modules
dlsym() called with RTLD_DEFAULT (nullptr) should look up
symbol in all global modules instead of only looking into the
executable file
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLinker.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index b4d5033997..499632578b 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -458,17 +458,21 @@ static Result<void*, DlErrorMessage> __dlsym(void* handle, char const* symbol_na __pthread_mutex_lock(&s_loader_lock); ScopeGuard unlock_guard = [] { __pthread_mutex_unlock(&s_loader_lock); }; - auto object = static_cast<DynamicObject*>(handle); - if (!handle) { - auto library_name = get_library_name(s_main_program_name); - auto global_object = s_global_objects.get(library_name); - object = *global_object; - } - auto symbol = object->lookup_symbol(symbol_name); - if (!symbol.has_value()) { - return DlErrorMessage { String::formatted("Symbol {} not found", symbol_name) }; + Optional<DynamicObject::SymbolLookupResult> symbol; + + if (handle) { + auto object = static_cast<DynamicObject*>(handle); + symbol = object->lookup_symbol(symbol_name); + } else { + // When handle is 0 (RTLD_DEFAULT) we should look up the symbol in all global modules + // https://pubs.opengroup.org/onlinepubs/009604499/functions/dlsym.html + symbol = DynamicLinker::lookup_global_symbol(symbol_name); } - return symbol.value().address.as_ptr(); + + if (symbol.has_value()) + return symbol.value().address.as_ptr(); + + return DlErrorMessage { String::formatted("Symbol {} not found", symbol_name) }; } static Result<void, DlErrorMessage> __dladdr(void* addr, Dl_info* info) |