Commit b3fdf33b authored by Sergej Jaskiewicz's avatar Sergej Jaskiewicz
Browse files

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
parent 195eb903
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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)

+11 −0
Original line number Diff line number Diff line
@@ -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()
+1 −0
Original line number Diff line number Diff line
@@ -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
+10 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ class Configuration(LibcxxConfiguration):
        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 @@ class Configuration(LibcxxConfiguration):

    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
+1 −0
Original line number Diff line number Diff line
@@ -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@")
Loading