Merge "Fix dlsym(handle_of_main_executable, ...)"
This commit is contained in:
commit
ef55f96723
@ -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);
|
||||
}
|
||||
|
@ -145,13 +145,28 @@ TEST(dlfcn, dlsym_from_sofile_with_preload) {
|
||||
dlclose(preload);
|
||||
}
|
||||
|
||||
TEST(dlfcn, dlsym_handle_global_sym) {
|
||||
// check that we do not look into global group
|
||||
// when looking up symbol by handle
|
||||
void* handle = dlopen("libtest_empty.so", RTLD_NOW);
|
||||
dlopen("libtest_with_dependency.so", RTLD_NOW | RTLD_GLOBAL);
|
||||
void* sym = dlsym(handle, "getRandomNumber");
|
||||
ASSERT_TRUE(sym == nullptr);
|
||||
ASSERT_SUBSTR("undefined symbol: getRandomNumber", dlerror());
|
||||
|
||||
sym = dlsym(handle, "DlSymTestFunction");
|
||||
ASSERT_TRUE(sym == nullptr);
|
||||
ASSERT_SUBSTR("undefined symbol: DlSymTestFunction", dlerror());
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
TEST(dlfcn, dlsym_with_dependencies) {
|
||||
void* handle = dlopen("libtest_with_dependency.so", RTLD_NOW);
|
||||
ASSERT_TRUE(handle != NULL);
|
||||
ASSERT_TRUE(handle != nullptr);
|
||||
dlerror();
|
||||
// This symbol is in DT_NEEDED library.
|
||||
void* sym = dlsym(handle, "getRandomNumber");
|
||||
ASSERT_TRUE(sym != NULL);
|
||||
ASSERT_TRUE(sym != nullptr) << dlerror();
|
||||
int (*fn)(void);
|
||||
fn = reinterpret_cast<int (*)(void)>(sym);
|
||||
EXPECT_EQ(4, fn());
|
||||
@ -583,6 +598,15 @@ TEST(dlfcn, dlopen_check_rtld_global) {
|
||||
// RTLD_GLOBAL implies RTLD_NODELETE, let's check that
|
||||
void* sym_after_dlclose = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
|
||||
ASSERT_EQ(sym, sym_after_dlclose);
|
||||
|
||||
// Check if dlsym() for main program's handle searches RTLD_GLOBAL
|
||||
// shared libraries after symbol was not found in the main executable
|
||||
// and dependent libraries.
|
||||
void* handle_for_main_executable = dlopen(nullptr, RTLD_NOW);
|
||||
sym = dlsym(handle_for_main_executable, "dlopen_testlib_simple_func");
|
||||
ASSERT_TRUE(sym != nullptr) << dlerror();
|
||||
|
||||
dlclose(handle_for_main_executable);
|
||||
}
|
||||
|
||||
// libtest_with_dependency_loop.so -> libtest_with_dependency_loop_a.so ->
|
||||
|
@ -404,6 +404,14 @@ libtest_dlsym_from_this_grandchild_src_files := dlsym_from_this_symbol2.cpp
|
||||
module := libtest_dlsym_from_this_grandchild
|
||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Empty library
|
||||
# -----------------------------------------------------------------------------
|
||||
libtest_empty_src_files := empty.cpp
|
||||
|
||||
module := libtest_empty
|
||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Library with weak undefined function
|
||||
# -----------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user