Move dl_unwind_find_exidx from libdl.a to libc.a
arm32 has two special APIs to find exidx exception handling info,
dl_unwind_find_exidx and __gnu_Unwind_Find_exdix. The two functions have
identical behavior and function prototypes. libgcc's arm32 unwinder calls
__gnu_Unwind_Find_exdix, whereas LLVM's libunwind previously called
__gnu_Unwind_Find_exdix, but switched to dl_unwind_find_exidx as a result
of three patches (D30306, D30681, D39468).
In Bionic, for dynamic linking, __gnu_Unwind_Find_exdix in libc.so calls
dl_unwind_find_exidx in libdl.so.
For static executables, though, __gnu_Unwind_Find_exdix in libc.a used the
__exidx_* symbols, while dl_unwind_find_exidx in libdl.a(libdl_static.o)
was a return-0 no-op.
To fix the LLVM unwinder, replace the no-op dl_unwind_find_exidx in
libdl.a with a real function in libc.a(exidx_static.o), and have the GNU
function call the dl function for more consistency with dynamic linking.
dl_iterate_phdr follows a similar pattern, where the function exists in
libc.a and libdl.so (not libc.so or libdl.a).
This change makes unwinding work with an updated libunwind_llvm on arm32,
and it helps to allow unwinding in static executables without libdl.a.
Bug: https://github.com/android/ndk/issues/1094
Bug: http://b/141485154
Test: NDK tests, bionic unit tests
Change-Id: Ieeeb9b39a0e28544e21f9afe6fe51ef10d7c828c
diff --git a/libc/Android.bp b/libc/Android.bp
index 37e0f09..3e2ee1d 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1525,6 +1525,22 @@
],
}
+// Versions of dl_iterate_phdr and similar APIs used to lookup unwinding information in a static
+// executable.
+cc_library_static {
+ name: "libc_unwind_static",
+ defaults: ["libc_defaults"],
+ cflags: ["-DLIBC_STATIC"],
+
+ srcs: ["bionic/dl_iterate_phdr_static.cpp"],
+ arch: {
+ // arm32-specific dl_unwind_find_exidx and __gnu_Unwind_Find_exidx APIs
+ arm: {
+ srcs: ["arch-arm/bionic/exidx_static.c"],
+ },
+ },
+}
+
// ========================================================
// libc_nomalloc.a
// ========================================================
@@ -1537,20 +1553,13 @@
cc_library_static {
name: "libc_nomalloc",
-
defaults: ["libc_defaults"],
-
- arch: {
- arm: {
- srcs: ["arch-arm/bionic/exidx_static.c"],
- },
- },
-
cflags: ["-DLIBC_STATIC"],
whole_static_libs: [
"libc_common_static",
"libc_init_static",
+ "libc_unwind_static",
],
}
@@ -1572,7 +1581,6 @@
filegroup {
name: "libc_sources_static",
srcs: [
- "bionic/dl_iterate_phdr_static.cpp",
"bionic/malloc_common.cpp",
"bionic/malloc_limit.cpp",
],
@@ -1586,11 +1594,6 @@
],
}
-filegroup {
- name: "libc_sources_static_arm",
- srcs: [ "arch-arm/bionic/exidx_static.c" ],
-}
-
// ========================================================
// libc.a + libc.so
// ========================================================
@@ -1613,6 +1616,7 @@
whole_static_libs: [
"libc_init_static",
"libc_common_static",
+ "libc_unwind_static",
],
},
shared: {
@@ -1662,9 +1666,6 @@
// special for arm
cflags: ["-DCRT_LEGACY_WORKAROUND"],
},
- static: {
- srcs: [":libc_sources_static_arm"],
- },
// Arm 32 bit does not produce complete exidx unwind information
// so keep the .debug_frame which is relatively small and does