am ef55f967: Merge "Fix dlsym(handle_of_main_executable, ...)"
* commit 'ef55f967234f160a4e00a51ca53377fadd17715d': Fix dlsym(handle_of_main_executable, ...)
This commit is contained in:
commit
4af36c8d99
@ -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
|
// This is used by dlsym(3). It performs symbol lookup only within the
|
||||||
// specified soinfo object and its dependencies in breadth first order.
|
// specified soinfo object and its dependencies in breadth first order.
|
||||||
const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name) {
|
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);
|
SymbolName symbol_name(name);
|
||||||
return dlsym_handle_lookup(si, nullptr, found, symbol_name);
|
return dlsym_handle_lookup(si, nullptr, found, symbol_name);
|
||||||
}
|
}
|
||||||
|
@ -145,13 +145,28 @@ TEST(dlfcn, dlsym_from_sofile_with_preload) {
|
|||||||
dlclose(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) {
|
TEST(dlfcn, dlsym_with_dependencies) {
|
||||||
void* handle = dlopen("libtest_with_dependency.so", RTLD_NOW);
|
void* handle = dlopen("libtest_with_dependency.so", RTLD_NOW);
|
||||||
ASSERT_TRUE(handle != NULL);
|
ASSERT_TRUE(handle != nullptr);
|
||||||
dlerror();
|
dlerror();
|
||||||
// This symbol is in DT_NEEDED library.
|
// This symbol is in DT_NEEDED library.
|
||||||
void* sym = dlsym(handle, "getRandomNumber");
|
void* sym = dlsym(handle, "getRandomNumber");
|
||||||
ASSERT_TRUE(sym != NULL);
|
ASSERT_TRUE(sym != nullptr) << dlerror();
|
||||||
int (*fn)(void);
|
int (*fn)(void);
|
||||||
fn = reinterpret_cast<int (*)(void)>(sym);
|
fn = reinterpret_cast<int (*)(void)>(sym);
|
||||||
EXPECT_EQ(4, fn());
|
EXPECT_EQ(4, fn());
|
||||||
@ -583,6 +598,15 @@ TEST(dlfcn, dlopen_check_rtld_global) {
|
|||||||
// RTLD_GLOBAL implies RTLD_NODELETE, let's check that
|
// RTLD_GLOBAL implies RTLD_NODELETE, let's check that
|
||||||
void* sym_after_dlclose = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
|
void* sym_after_dlclose = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
|
||||||
ASSERT_EQ(sym, sym_after_dlclose);
|
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 ->
|
// 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
|
module := libtest_dlsym_from_this_grandchild
|
||||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
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
|
# Library with weak undefined function
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user