aboutsummaryrefslogtreecommitdiff
path: root/libdl
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-11-22 16:55:25 -0800
committerDimitry Ivanov <dimitry@google.com>2016-12-09 14:53:59 -0800
commitd9e427cf41893377dcdd0650ba20ff7cf7d72209 (patch)
tree6515aceab94a11861876b6e145adb6922183ebff /libdl
parent227894a754eb11cb1203c359192d59654b01b93e (diff)
downloadbionic-d9e427cf41893377dcdd0650ba20ff7cf7d72209.tar.gz
Bionic loader is no longer hijacking libdl.so
Do not hijack libdl.so methods but make libdl proxy calls to loader instead. This will be replaces by calls to libc.so once loader functionality is migrated. Also add a lock to dl_unwind_find_exidx function call. Test: bionic-unit-tests --gtest_filter=dl*:Dl* Bug: http://b/27106625 Change-Id: Ic33a7109a86f4262798d63a35f4c61d15b0068bb
Diffstat (limited to 'libdl')
-rw-r--r--libdl/Android.bp49
-rw-r--r--libdl/ld_android.c1
-rw-r--r--libdl/libdl.c152
3 files changed, 173 insertions, 29 deletions
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 9db3a9426..e9b79d79c 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -57,6 +57,55 @@ cc_library {
allow_undefined_symbols: true,
system_shared_libs: [],
+ // This is placeholder library the actual implementation is (currently)
+ // provided by the linker.
+ shared_libs: [ "ld-android" ],
+
+ sanitize: {
+ never: true,
+ },
+}
+
+cc_library {
+ // NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
+ // libgcc.a are made static to ld-android.so. This in turn ensures that libraries that
+ // a) pull symbols from libgcc.a and b) depend on ld-android.so will not rely on ld-android.so
+ // to provide those symbols, but will instead pull them from libgcc.a. Specifically,
+ // we use this property to make sure libc.so has its own copy of the code from
+ // libgcc.a it uses.
+ //
+ // DO NOT REMOVE --exclude-libs!
+
+ ldflags: ["-Wl,--exclude-libs=libgcc.a"],
+
+ // for x86, exclude libgcc_eh.a for the same reasons as above
+ arch: {
+ x86: {
+ ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+ },
+ x86_64: {
+ ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+ },
+ },
+ srcs: ["ld_android.c"],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wunused",
+ "-Werror",
+ ],
+ stl: "none",
+
+ name: "ld-android",
+
+ // NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a needs a
+ // few symbols from libc. Using --no-undefined here results in having to link
+ // against libc creating a circular dependency which is removed and we end up
+ // with missing symbols. Since this library is just a bunch of stubs, we set
+ // LOCAL_ALLOW_UNDEFINED_SYMBOLS to remove --no-undefined from the linker flags.
+ allow_undefined_symbols: true,
+ system_shared_libs: [],
+
sanitize: {
never: true,
},
diff --git a/libdl/ld_android.c b/libdl/ld_android.c
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/libdl/ld_android.c
@@ -0,0 +1 @@
+
diff --git a/libdl/libdl.c b/libdl/libdl.c
index 4cc4deac8..832946841 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.c
@@ -20,54 +20,148 @@
#include <stdbool.h>
#include <android/dlext.h>
-// These are stubs for functions that are actually defined
-// in the dynamic linker and hijacked at runtime.
+// These functions are exported by the loader
+// TODO(dimitry): replace these with reference to libc.so
-void* dlopen(const char* filename __unused, int flag __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlopen(const char* filename, int flags, const void* caller_addr);
-char* dlerror(void) { return 0; }
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlerror();
-void* dlsym(void* handle __unused, const char* symbol __unused) { return 0; }
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr);
-void* dlvsym(void* handle __unused, const char* symbol __unused, const char* version __unused) {
- return 0;
+__attribute__((__weak__, visibility("default")))
+void* __loader_dlvsym(void* handle,
+ const char* symbol,
+ const char* version,
+ const void* caller_addr);
+
+__attribute__((__weak__, visibility("default")))
+int __loader_dladdr(const void* addr, Dl_info* info);
+
+__attribute__((__weak__, visibility("default")))
+int __loader_dlclose(void* handle);
+
+#if defined(__arm__)
+__attribute__((__weak__, visibility("default")))
+_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount);
+#endif
+
+__attribute__((__weak__, visibility("default")))
+int __loader_dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data),
+ void* data);
+
+__attribute__((__weak__, visibility("default")))
+void __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size);
+
+__attribute__((__weak__, visibility("default")))
+void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
+
+__attribute__((__weak__, visibility("default")))
+void* __loader_android_dlopen_ext(const char* filename,
+ int flag,
+ const android_dlextinfo* extinfo,
+ const void* caller_addr);
+
+__attribute__((__weak__, visibility("default")))
+void __loader_android_set_application_target_sdk_version(uint32_t target);
+
+__attribute__((__weak__, visibility("default")))
+uint32_t __loader_android_get_application_target_sdk_version();
+
+__attribute__((__weak__, visibility("default")))
+bool __loader_android_init_namespaces(const char* public_ns_sonames,
+ const char* anon_ns_library_path);
+
+__attribute__((__weak__, visibility("default")))
+struct android_namespace_t* __loader_android_create_namespace(
+ const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ struct android_namespace_t* parent,
+ const void* caller_addr);
+
+// Proxy calls to bionic loader
+void* dlopen(const char* filename, int flag) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __loader_dlopen(filename, flag, caller_addr);
+}
+
+char* dlerror() {
+ return __loader_dlerror();
+}
+
+void* dlsym(void* handle, const char* symbol) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __loader_dlsym(handle, symbol, caller_addr);
}
-int dladdr(const void* addr __unused, Dl_info* info __unused) { return 0; }
+void* dlvsym(void* handle, const char* symbol, const char* version) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __loader_dlvsym(handle, symbol, version, caller_addr);
+}
-int dlclose(void* handle __unused) { return 0; }
+int dladdr(const void* addr, Dl_info* info) {
+ return __loader_dladdr(addr, info);
+}
+
+int dlclose(void* handle) {
+ return __loader_dlclose(handle);
+}
#if defined(__arm__)
-_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc __unused, int* pcount __unused) { return 0; }
+_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
+ return __loader_dl_unwind_find_exidx(pc, pcount);
+}
#endif
-int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data) __unused,
- void* data __unused) {
- return 0;
+int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data), void* data) {
+ return __loader_dl_iterate_phdr(cb, data);
}
-void android_get_LD_LIBRARY_PATH(char* buffer __unused, size_t buffer_size __unused) { }
-void android_update_LD_LIBRARY_PATH(const char* ld_library_path __unused) { }
+void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
+ __loader_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
+}
+
+void android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
+ __loader_android_update_LD_LIBRARY_PATH(ld_library_path);
+}
-void* android_dlopen_ext(const char* filename __unused, int flag __unused,
- const android_dlextinfo* extinfo __unused) {
- return 0;
+void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __loader_android_dlopen_ext(filename, flag, extinfo, caller_addr);
}
-void android_set_application_target_sdk_version(uint32_t target __unused) { }
-uint32_t android_get_application_target_sdk_version() { return 0; }
+void android_set_application_target_sdk_version(uint32_t target) {
+ __loader_android_set_application_target_sdk_version(target);
+}
+uint32_t android_get_application_target_sdk_version() {
+ return __loader_android_get_application_target_sdk_version();
+}
-bool android_init_namespaces(const char* public_ns_sonames __unused,
- const char* anon_ns_library_path __unused) {
- return false;
+bool android_init_namespaces(const char* public_ns_sonames,
+ const char* anon_ns_library_path) {
+ return __loader_android_init_namespaces(public_ns_sonames, anon_ns_library_path);
}
-struct android_namespace_t* android_create_namespace(const char* name __unused,
- const char* ld_library_path __unused,
- const char* default_library_path __unused,
- uint64_t type __unused,
- const char* permitted_when_isolated_path __unused) {
- return 0;
+struct android_namespace_t* android_create_namespace(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ struct android_namespace_t* parent) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __loader_android_create_namespace(name,
+ ld_library_path,
+ default_library_path,
+ type,
+ permitted_when_isolated_path,
+ parent,
+ caller_addr);
}
void android_dlwarning(void* obj, void (*f)(void*, const char*)) { f(obj, 0); }