diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2015-05-30 13:04:39 -0700 |
---|---|---|
committer | Dmitriy Ivanov <dimitry@google.com> | 2015-06-01 14:33:43 -0700 |
commit | f439b5a3186ca0fef1092f45770abc716da9d87a (patch) | |
tree | d85508ffcefb14495e90d6e0669440558f753367 /linker/linker.cpp | |
parent | d70891687d742414d457e41a998726e5eb0a09bd (diff) |
Fix dlsym(handle_of_main_executable, ...)
According to man dlopen(3) and posix docs in the case when si is handle
of the main executable we need to search not only in the executable and its
dependencies but also in all libraries loaded with RTLD_GLOBAL.
see also: http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlopen.html
Bug: http://b/21528224
Bug: http://b/17512583
Bug: https://code.google.com/p/android/issues/detail?id=173822
Change-Id: Ib2801367ba48b6f3704da89a6d9f5e6911430013
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index 531cd1908..1382a9cdc 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -948,6 +948,17 @@ static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until, // This is used by dlsym(3). It performs symbol lookup only within the // specified soinfo object and its dependencies in breadth first order. const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) { + // According to man dlopen(3) and posix docs in the case when si is handle + // of the main executable we need to search not only in the executable and its + // dependencies but also in all libraries loaded with RTLD_GLOBAL. + // + // Since RTLD_GLOBAL is always set for the main executable and all dt_needed shared + // libraries and they are loaded in breath-first (correct) order we can just execute + // dlsym(RTLD_DEFAULT, ...); instead of doing two stage lookup. + if (si == somain) { + return dlsym_linear_lookup(name, found, nullptr, RTLD_DEFAULT); + } + SymbolName symbol_name(name); return dlsym_handle_lookup(si, nullptr, found, symbol_name); } |