Merge "Fix dlsym(handle_of_main_executable, ...)"

This commit is contained in:
Dmitriy Ivanov 2015-06-01 23:48:08 +00:00 committed by Gerrit Code Review
commit ef55f96723
3 changed files with 45 additions and 2 deletions

View File

@ -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);
}

View File

@ -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 ->

View File

@ -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
# -----------------------------------------------------------------------------