Introduce anonymous namespace
The anonymous namespace is introduced to
handle cases when linker can not find the
caller. This usually happens when caller
code was not loaded by dynamic linker;
for example mono-generated code.
Bug: http://b/25844435
Bug: http://b/22548808
Change-Id: I9e5b1d23c1c75bc78548d68e79216a6a943a33cf
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 7957921..d07ec86 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -89,9 +89,12 @@
return dlopen_ext(filename, flags, nullptr, caller_addr);
}
+extern android_namespace_t* g_anonymous_namespace;
+
void* dlsym(void* handle, const char* symbol) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ // TODO(dimitry): move (most of) the code below to linker.cpp
#if !defined(__LP64__)
if (handle == nullptr) {
__bionic_format_dlerror("dlsym library handle is null", nullptr);
@@ -108,16 +111,10 @@
const ElfW(Sym)* sym = nullptr;
void* caller_addr = __builtin_return_address(0);
soinfo* caller = find_containing_library(caller_addr);
- if (caller == nullptr) {
- char buf[256];
- __libc_format_buffer(buf, sizeof(buf), "dlsym couldn't locate its caller address=%p; "
- "the caller was code not loaded by the dynamic linker", caller_addr);
- __bionic_format_dlerror(buf, nullptr);
- return nullptr;
- }
+ android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace;
if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
- sym = dlsym_linear_lookup(caller->get_namespace(), symbol, &found, caller, handle);
+ sym = dlsym_linear_lookup(ns, symbol, &found, caller, handle);
} else {
sym = dlsym_handle_lookup(reinterpret_cast<soinfo*>(handle), &found, symbol);
}
@@ -184,11 +181,12 @@
return get_application_target_sdk_version();
}
-bool android_init_public_namespace(const char* path) {
+bool android_init_namespaces(const char* public_ns_sonames,
+ const char* anon_ns_library_path) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
- bool success = init_public_namespace(path);
+ bool success = init_namespaces(public_ns_sonames, anon_ns_library_path);
if (!success) {
- __bionic_format_dlerror("android_init_public_namespace failed", linker_get_error_buffer());
+ __bionic_format_dlerror("android_init_namespaces failed", linker_get_error_buffer());
}
return success;
@@ -234,11 +232,11 @@
// 00000000001 1111111112222222222 3333333333444444444455555555556666666666777 777777788888888889999999999
// 01234567890 1234567890123456789 0123456789012345678901234567890123456789012 345678901234567890123456789
"erate_phdr\0android_dlopen_ext\0android_set_application_target_sdk_version\0android_get_application_tar"
- // 0000000000111111 111122222222223333333333444444 4444555555555566666666667
- // 0123456789012345 678901234567890123456789012345 6789012345678901234567890
- "get_sdk_version\0android_init_public_namespace\0android_create_namespace\0"
+ // 0000000000111111 111122222222223333333333 4444444444555555555566666
+ // 0123456789012345 678901234567890123456789 0123456789012345678901234
+ "get_sdk_version\0android_init_namespaces\0android_create_namespace\0"
#if defined(__arm__)
- // 271
+ // 265
"dl_unwind_find_exidx\0"
#endif
;
@@ -260,10 +258,10 @@
ELFW(SYM_INITIALIZER)(111, &android_dlopen_ext, 1),
ELFW(SYM_INITIALIZER)(130, &android_set_application_target_sdk_version, 1),
ELFW(SYM_INITIALIZER)(173, &android_get_application_target_sdk_version, 1),
- ELFW(SYM_INITIALIZER)(216, &android_init_public_namespace, 1),
- ELFW(SYM_INITIALIZER)(246, &android_create_namespace, 1),
+ ELFW(SYM_INITIALIZER)(216, &android_init_namespaces, 1),
+ ELFW(SYM_INITIALIZER)(240, &android_create_namespace, 1),
#if defined(__arm__)
- ELFW(SYM_INITIALIZER)(271, &dl_unwind_find_exidx, 1),
+ ELFW(SYM_INITIALIZER)(265, &dl_unwind_find_exidx, 1),
#endif
};