aboutsummaryrefslogtreecommitdiffstats
path: root/linker/linker.cpp
diff options
context:
space:
mode:
authorDmitriy Ivanov <dimitry@google.com>2015-05-30 13:04:39 -0700
committerDmitriy Ivanov <dimitry@google.com>2015-06-01 16:57:33 -0700
commitc4ebe60e1a2fc165ff11442765325628e27f2a05 (patch)
tree01a510b550aed2f303ca0c9dbf1cf081a55a5d5c /linker/linker.cpp
parentc5e02eeb353c3cdd357413f563701d5018fc76a5 (diff)
downloadandroid_bionic-c4ebe60e1a2fc165ff11442765325628e27f2a05.tar.gz
android_bionic-c4ebe60e1a2fc165ff11442765325628e27f2a05.tar.bz2
android_bionic-c4ebe60e1a2fc165ff11442765325628e27f2a05.zip
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 (cherry picked from commit f439b5a3186ca0fef1092f45770abc716da9d87a)
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r--linker/linker.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 764b5cc5f..02ee9c703 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -963,6 +963,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);
}