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
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 082cdea..5998f9b 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -84,12 +84,7 @@
     ],
     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 c834088..402804e 100644
--- a/libdl/libdl.cpp
+++ b/libdl/libdl.cpp
@@ -214,4 +214,16 @@
   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"