[libunwind] b3fdf33 - Enable `-funwind-tables` flag when building libunwind

Sergej Jaskiewicz via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 3 13:52:52 PST 2019


Author: Sergej Jaskiewicz
Date: 2019-12-04T00:52:19+03:00
New Revision: b3fdf33ba6aa7ef80621696f74aaf2f6f8e1d1de

URL: https://github.com/llvm/llvm-project/commit/b3fdf33ba6aa7ef80621696f74aaf2f6f8e1d1de
DIFF: https://github.com/llvm/llvm-project/commit/b3fdf33ba6aa7ef80621696f74aaf2f6f8e1d1de.diff

LOG: Enable `-funwind-tables` flag when building libunwind

Summary:
Or, rather, don't accidentally forget to pass it.

This is aimed to solve the problem discussed in [this thread](http://lists.llvm.org/pipermail/llvm-dev/2019-November/136890.html), and to fix [a year-old bug](https://bugs.llvm.org/show_bug.cgi?id=38468).

TL;DR: when building libunwind for ARM Linux, we **need** libunwind to be built with the `-funwind-tables` flag, because, well ARM EHABI needs unwind info produced by this flag. Without the flag all the procedures in libunwind are marked `.cantunwind`, which causes all sorts of bad things. From `_Unwind_Backtrace` not working, to C++ exceptions not being caught (which is the aforementioned bug is about).

Previously, this flag was not added because the CMake check `add_compile_flags_if_supported(-funwind-tables)` produced a false negative. Why? With this flag, the compiler generates calls to the `__aeabi_unwind_cpp_pr0` symbol, which is defined in libunwind itself and obviously is not available at configure time, before libunwind is built. This led to failure at link time during the CMake check. We handle this by disabling the linker for CMake checks in linbunwind.

Also, this patch introduces a lit feature `libunwind-arm-ehabi`, which is used to mark the `signal_frame.pass.cpp` test as unsupported (as was advised by @miyuki in D70397).

Reviewers: peter.smith, phosek, EricWF, compnerd, jroelofs, saugustine, miyuki, jfb

Subscribers: mgorny, kristof.beyls, christof, libcxx-commits, miyuki

Tags: #libc

Differential Revision: https://reviews.llvm.org/D70815

Added: 
    

Modified: 
    libunwind/CMakeLists.txt
    libunwind/cmake/config-ix.cmake
    libunwind/test/CMakeLists.txt
    libunwind/test/libunwind/test/config.py
    libunwind/test/lit.site.cfg.in
    libunwind/test/signal_frame.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
index 08095d1333a5..7aa1c782ac74 100644
--- a/libunwind/CMakeLists.txt
+++ b/libunwind/CMakeLists.txt
@@ -220,6 +220,21 @@ include(HandleLibunwindFlags)
 # Setup Compiler Flags
 #===============================================================================
 
+# Don't run the linker in CMake checks.
+#
+# The reason why this was added is that when building libunwind for
+# ARM Linux, we need to pass the -funwind-tables flag in order for it to
+# work properly with ARM EHABI.
+#
+# However, when performing CMake checks, adding this flag causes the check
+# to produce a false negative, because the compiler generates calls
+# to __aeabi_unwind_cpp_pr0, which is defined in libunwind itself,
+# which isn't built yet, so the linker complains about undefined symbols.
+#
+# This leads to libunwind not being built with this flag, which makes
+# libunwind quite useless in this setup.
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
 # Get required flags.
 add_target_flags_if(LIBUNWIND_BUILD_32_BITS "-m32")
 
@@ -292,6 +307,12 @@ add_cxx_compile_flags_if_supported(-fstrict-aliasing)
 add_cxx_compile_flags_if_supported(-EHsc)
 
 add_compile_flags_if_supported(-funwind-tables)
+
+if (LIBUNWIND_USES_ARM_EHABI AND NOT LIBUNWIND_SUPPORTS_FUNWIND_TABLES_FLAG)
+  message(SEND_ERROR "The -funwind-tables flag must be supported "
+                     "because this target uses ARM Exception Handling ABI")
+endif()
+
 add_cxx_compile_flags_if_supported(-fno-exceptions)
 add_cxx_compile_flags_if_supported(-fno-rtti)
 

diff  --git a/libunwind/cmake/config-ix.cmake b/libunwind/cmake/config-ix.cmake
index 02d2f13f2e28..0d833e996ca1 100644
--- a/libunwind/cmake/config-ix.cmake
+++ b/libunwind/cmake/config-ix.cmake
@@ -2,6 +2,7 @@ include(CMakePushCheckState)
 include(CheckCCompilerFlag)
 include(CheckCXXCompilerFlag)
 include(CheckLibraryExists)
+include(CheckSymbolExists)
 include(CheckCSourceCompiles)
 
 check_library_exists(c fopen "" LIBUNWIND_HAS_C_LIB)
@@ -73,3 +74,13 @@ check_cxx_compiler_flag(-nostdinc++ LIBUNWIND_HAS_NOSTDINCXX_FLAG)
 # Check libraries
 check_library_exists(dl dladdr "" LIBUNWIND_HAS_DL_LIB)
 check_library_exists(pthread pthread_once "" LIBUNWIND_HAS_PTHREAD_LIB)
+
+# Check symbols
+check_symbol_exists(__arm__ "" LIBUNWIND_TARGET_ARM)
+check_symbol_exists(__USING_SJLJ_EXCEPTIONS__ "" LIBUNWIND_USES_SJLJ_EXCEPTIONS)
+check_symbol_exists(__ARM_DWARF_EH__ "" LIBUNWIND_USES_DWARF_EH)
+
+if(LIBUNWIND_TARGET_ARM AND NOT LIBUNWIND_USES_SJLJ_EXCEPTIONS AND NOT LIBUNWIND_USES_DWARF_EH)
+  # This condition is copied from __libunwind_config.h
+  set(LIBUNWIND_USES_ARM_EHABI ON)
+endif()

diff  --git a/libunwind/test/CMakeLists.txt b/libunwind/test/CMakeLists.txt
index d902e3e82941..40d4acd4e8c2 100644
--- a/libunwind/test/CMakeLists.txt
+++ b/libunwind/test/CMakeLists.txt
@@ -16,6 +16,7 @@ pythonize_bool(LIBCXX_ENABLE_SHARED)
 pythonize_bool(LIBUNWIND_ENABLE_SHARED)
 pythonize_bool(LIBUNWIND_ENABLE_THREADS)
 pythonize_bool(LIBUNWIND_ENABLE_EXCEPTIONS)
+pythonize_bool(LIBUNWIND_USES_ARM_EHABI)
 pythonize_bool(LIBUNWIND_USE_COMPILER_RT)
 pythonize_bool(LIBUNWIND_BUILD_EXTERNAL_THREAD_LIBRARY)
 set(LIBUNWIND_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING

diff  --git a/libunwind/test/libunwind/test/config.py b/libunwind/test/libunwind/test/config.py
index 05e3f3cc21f3..41ca3f9b4a44 100644
--- a/libunwind/test/libunwind/test/config.py
+++ b/libunwind/test/libunwind/test/config.py
@@ -37,6 +37,8 @@ def configure_features(self):
         super(Configuration, self).configure_features()
         if not self.get_lit_bool('enable_exceptions', True):
             self.config.available_features.add('libcxxabi-no-exceptions')
+        if self.get_lit_bool('arm_ehabi', False):
+            self.config.available_features.add('libunwind-arm-ehabi')
 
     def configure_compile_flags(self):
         self.cxx.compile_flags += ['-DLIBUNWIND_NO_TIMER']
@@ -66,3 +68,11 @@ def configure_compile_flags_exceptions(self):
 
     def configure_compile_flags_rtti(self):
         pass
+
+    def configure_link_flags_cxx_library(self):
+        # libunwind tests should not link with libc++
+        pass
+
+    def configure_link_flags_abi_library(self):
+        # libunwind tests should not link with libc++abi
+        pass

diff  --git a/libunwind/test/lit.site.cfg.in b/libunwind/test/lit.site.cfg.in
index 34da72ac1068..37f90a90efdb 100644
--- a/libunwind/test/lit.site.cfg.in
+++ b/libunwind/test/lit.site.cfg.in
@@ -19,6 +19,7 @@ config.executor                 = "@LIBUNWIND_EXECUTOR@"
 config.libunwind_shared         = @LIBUNWIND_ENABLE_SHARED@
 config.enable_shared            = @LIBCXX_ENABLE_SHARED@
 config.enable_exceptions        = @LIBUNWIND_ENABLE_EXCEPTIONS@
+config.arm_ehabi                = @LIBUNWIND_USES_ARM_EHABI@
 config.host_triple              = "@LLVM_HOST_TRIPLE@"
 config.target_triple            = "@TARGET_TRIPLE@"
 config.use_target               = bool("@LIBUNWIND_TARGET_TRIPLE@")

diff  --git a/libunwind/test/signal_frame.pass.cpp b/libunwind/test/signal_frame.pass.cpp
index a6f3f483bea5..a899461fafb4 100644
--- a/libunwind/test/signal_frame.pass.cpp
+++ b/libunwind/test/signal_frame.pass.cpp
@@ -9,6 +9,8 @@
 
 // Ensure that functions marked as signal frames are reported as such.
 
+// UNSUPPORTED: libunwind-arm-ehabi
+
 #include <assert.h>
 #include <stdlib.h>
 #include <libunwind.h>
@@ -20,9 +22,7 @@ void test() {
   unw_getcontext(&uc);
   unw_init_local(&cursor, &uc);
   assert(unw_step(&cursor) > 0);
-#if !defined(_LIBUNWIND_ARM_EHABI)
   assert(unw_is_signal_frame(&cursor));
-#endif
 }
 
 int main() {


        


More information about the cfe-commits mailing list