aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2018-03-27 22:10:55 -0700
committerRyan Prichard <rprichard@google.com>2018-04-04 15:56:02 -0700
commit9dac3e9efdf6b00766b992940c831ca3881b48d5 (patch)
tree843f5110c21d06bd5f7f09a36c2872f330f3776b
parent075f77d6d6b7874577788ed5b2c800ee11e67135 (diff)
downloadbionic-9dac3e9efdf6b00766b992940c831ca3881b48d5.tar.gz
Break libdl.so and ld-android.so's dependency on libc.so.
* Specify "nocrt: true" to avoid calling __cxa_finalize. * Define a dummy __aeabi_unwind_cpp_pr0 for arm32. Bug: b/62815515 Bug: b/73873002 Test: boot AOSP hikey960-userdebug Test: run ndk_cxa_example in special /system/bin/debug namespace Test: run Bionic unit tests Change-Id: I59bcb100a2753286b59c51a47d7a183507219a07 (cherry picked from commit 470b66644b912ac3025ea30141f2f327bb879445)
-rw-r--r--libdl/Android.bp7
-rw-r--r--libdl/libdl.cpp12
-rw-r--r--linker/Android.bp7
-rw-r--r--linker/ld_android.cpp14
-rw-r--r--tests/dlfcn_test.cpp13
5 files changed, 35 insertions, 18 deletions
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 082cdead1..5998f9bbc 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -84,12 +84,7 @@ cc_library {
],
stl: "none",
- // 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,
+ nocrt: true,
system_shared_libs: [],
// This is placeholder library the actual implementation is (currently)
diff --git a/libdl/libdl.cpp b/libdl/libdl.cpp
index c8340888e..402804ec5 100644
--- a/libdl/libdl.cpp
+++ b/libdl/libdl.cpp
@@ -214,4 +214,16 @@ struct android_namespace_t* android_get_exported_namespace(const char* name) {
return __loader_android_get_exported_namespace(name);
}
+#if defined(__arm__)
+// An arm32 unwinding table has an R_ARM_NONE relocation to
+// __aeabi_unwind_cpp_pr0. This shared library will never invoke the unwinder,
+// so it doesn't actually need the routine. Define a dummy version here,
+// because the real version calls libc functions (e.g. memcpy, abort), which
+// would create a dependency cycle with libc.so.
+__attribute__((visibility("hidden")))
+void __aeabi_unwind_cpp_pr0() {
+ __builtin_trap();
+}
+#endif
+
} // extern "C"
diff --git a/linker/Android.bp b/linker/Android.bp
index 2fcf369ef..7877a372d 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -271,12 +271,7 @@ cc_library {
name: "ld-android",
defaults: ["linux_bionic_supported"],
- // NOTE: ld-android.so 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
- // allow_undefined_symbols to remove --no-undefined from the linker flags.
- allow_undefined_symbols: true,
+ nocrt: true,
system_shared_libs: [],
sanitize: {
diff --git a/linker/ld_android.cpp b/linker/ld_android.cpp
index e2499b300..0528cd889 100644
--- a/linker/ld_android.cpp
+++ b/linker/ld_android.cpp
@@ -26,11 +26,10 @@
* SUCH DAMAGE.
*/
-#include <stdlib.h>
#include <sys/cdefs.h>
extern "C" void __internal_linker_error() {
- abort();
+ __builtin_trap();
}
__strong_alias(__loader_android_create_namespace, __internal_linker_error);
@@ -59,3 +58,14 @@ __strong_alias(__loader_dl_unwind_find_exidx, __internal_linker_error);
#endif
__strong_alias(rtld_db_dlactivity, __internal_linker_error);
+#if defined(__arm__)
+// An arm32 unwinding table has an R_ARM_NONE relocation to
+// __aeabi_unwind_cpp_pr0. This shared library will never invoke the unwinder,
+// so it doesn't actually need the routine. Define a dummy version here,
+// because the real version calls libc functions (e.g. memcpy, abort), which
+// would create a dependency cycle with libc.so.
+__attribute__((visibility("hidden")))
+extern "C" void __aeabi_unwind_cpp_pr0() {
+ __builtin_trap();
+}
+#endif
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 84f525dee..7d9abf926 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1438,7 +1438,8 @@ const llvm::ELF::Elf32_Dyn* to_dynamic_table(const char* p) {
#define DT_ANDROID_RELA (llvm::ELF::DT_LOOS + 4)
template<typename ELFT>
-void validate_compatibility_of_native_library(const std::string& path, ELFT* elf) {
+void validate_compatibility_of_native_library(const std::string& soname,
+ const std::string& path, ELFT* elf) {
bool has_elf_hash = false;
bool has_android_rel = false;
bool has_rel = false;
@@ -1464,10 +1465,14 @@ void validate_compatibility_of_native_library(const std::string& path, ELFT* elf
ASSERT_TRUE(has_elf_hash) << path.c_str() << ": missing elf hash (DT_HASH)";
ASSERT_TRUE(!has_android_rel) << path.c_str() << ": has packed relocations";
- ASSERT_TRUE(has_rel) << path.c_str() << ": missing DT_REL/DT_RELA";
+ // libdl.so is simple enough that it might not have any relocations, so
+ // exempt it from the DT_REL/DT_RELA check.
+ if (soname != "libdl.so") {
+ ASSERT_TRUE(has_rel) << path.c_str() << ": missing DT_REL/DT_RELA";
+ }
}
-void validate_compatibility_of_native_library(const char* soname) {
+void validate_compatibility_of_native_library(const std::string& soname) {
// On the systems with emulation system libraries would be of different
// architecture. Try to use alternate paths first.
std::string path = std::string(ALTERNATE_PATH_TO_SYSTEM_LIB) + soname;
@@ -1487,7 +1492,7 @@ void validate_compatibility_of_native_library(const char* soname) {
ASSERT_TRUE(elf != nullptr);
- validate_compatibility_of_native_library(path, elf);
+ validate_compatibility_of_native_library(soname, path, elf);
}
// This is a test for app compatibility workaround for arm apps