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
This commit is contained in:
Sergej Jaskiewicz 2019-11-05 14:47:24 +03:00
parent 195eb9034a
commit b3fdf33ba6
6 changed files with 46 additions and 2 deletions

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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@")

View File

@ -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() {