From 25f7919f27faba941292b90aeb4062088ec50c02 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Wed, 4 May 2022 19:01:07 +0200 Subject: [PATCH] Add missing libunwind patches Fixes #44499 --- deps/patches/llvm-libunwind-force-dwarf.patch | 179 +++++++++++++++++ ...-libunwind-freebsd-libgcc-api-compat.patch | 107 ++++++++++ .../llvm-libunwind-prologue-epilogue.patch | 183 ++++++++++++++++++ ...ibunwind-revert-monorepo-requirement.patch | 156 +++++++++++++++ deps/unwind.mk | 10 +- 5 files changed, 634 insertions(+), 1 deletion(-) create mode 100644 deps/patches/llvm-libunwind-force-dwarf.patch create mode 100644 deps/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch create mode 100644 deps/patches/llvm-libunwind-prologue-epilogue.patch create mode 100644 deps/patches/llvm-libunwind-revert-monorepo-requirement.patch diff --git a/deps/patches/llvm-libunwind-force-dwarf.patch b/deps/patches/llvm-libunwind-force-dwarf.patch new file mode 100644 index 0000000000000..2f4d31acb8a4a --- /dev/null +++ b/deps/patches/llvm-libunwind-force-dwarf.patch @@ -0,0 +1,179 @@ +An updated version of this libosxunwind commit: + +Author: Keno Fischer +Date: Tue Aug 27 15:01:22 2013 -0400 + + Add option to step with DWARF + +--- +diff -pur a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h +--- a/libunwind/include/libunwind.h 2021-06-28 18:23:38.000000000 +0200 ++++ b/libunwind/include/libunwind.h 2022-05-04 18:44:24.000000000 +0200 +@@ -108,6 +108,7 @@ extern "C" { + + extern int unw_getcontext(unw_context_t *) LIBUNWIND_AVAIL; + extern int unw_init_local(unw_cursor_t *, unw_context_t *) LIBUNWIND_AVAIL; ++extern int unw_init_local_dwarf(unw_cursor_t *, unw_context_t *) LIBUNWIND_AVAIL; + extern int unw_step(unw_cursor_t *) LIBUNWIND_AVAIL; + extern int unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *) LIBUNWIND_AVAIL; + extern int unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *) LIBUNWIND_AVAIL; +Only in b/libunwind/include: libunwind.h.orig +diff -pur a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp +--- a/libunwind/src/UnwindCursor.hpp 2021-06-28 18:23:38.000000000 +0200 ++++ b/libunwind/src/UnwindCursor.hpp 2022-05-04 18:45:11.000000000 +0200 +@@ -437,6 +437,9 @@ public: + virtual bool isSignalFrame() { + _LIBUNWIND_ABORT("isSignalFrame not implemented"); + } ++ virtual void setForceDWARF(bool) { ++ _LIBUNWIND_ABORT("setForceDWARF not implemented"); ++ } + virtual bool getFunctionName(char *, size_t, unw_word_t *) { + _LIBUNWIND_ABORT("getFunctionName not implemented"); + } +@@ -894,6 +897,7 @@ public: + virtual void getInfo(unw_proc_info_t *); + virtual void jumpto(); + virtual bool isSignalFrame(); ++ virtual void setForceDWARF(bool force); + virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off); + virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false); + virtual const char *getRegisterName(int num); +@@ -963,7 +967,7 @@ private: + const UnwindInfoSections §s); + int stepWithCompactEncoding() { + #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +- if ( compactSaysUseDwarf() ) ++ if ( _forceDwarf || compactSaysUseDwarf() ) + return stepWithDwarfFDE(); + #endif + R dummy; +@@ -1198,6 +1202,7 @@ private: + unw_proc_info_t _info; + bool _unwindInfoMissing; + bool _isSignalFrame; ++ bool _forceDwarf; + #if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64) + bool _isSigReturn = false; + #endif +@@ -1207,7 +1212,7 @@ private: + template + UnwindCursor::UnwindCursor(unw_context_t *context, A &as) + : _addressSpace(as), _registers(context), _unwindInfoMissing(false), +- _isSignalFrame(false) { ++ _isSignalFrame(false), _forceDwarf(false) { + static_assert((check_fit, unw_cursor_t>::does_fit), + "UnwindCursor<> does not fit in unw_cursor_t"); + static_assert((alignof(UnwindCursor) <= alignof(unw_cursor_t)), +@@ -1217,7 +1222,8 @@ UnwindCursor::UnwindCursor(unw_con + + template + UnwindCursor::UnwindCursor(A &as, void *) +- : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { ++ : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false), ++ _forceDwarf(false) { + memset(&_info, 0, sizeof(_info)); + // FIXME + // fill in _registers from thread arg +@@ -1273,6 +1279,10 @@ template bool U + return _isSignalFrame; + } + ++template void UnwindCursor::setForceDWARF(bool force) { ++ _forceDwarf = force; ++} ++ + #endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) + + #if defined(_LIBUNWIND_ARM_EHABI) +@@ -1941,7 +1951,13 @@ void UnwindCursor::setInfoBasedOnI + // record that we have no unwind info. + if (_info.format == 0) + _unwindInfoMissing = true; ++ #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) ++ if (!(_forceDwarf || compactSaysUseDwarf(&dwarfOffset))) ++ return; ++ #else + return; ++ #endif ++ + } + } + #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) +diff -pur a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp +--- a/libunwind/src/libunwind.cpp 2021-06-28 18:23:38.000000000 +0200 ++++ b/libunwind/src/libunwind.cpp 2022-05-04 18:44:24.000000000 +0200 +@@ -71,6 +71,7 @@ _LIBUNWIND_HIDDEN int __unw_init_local(u + new (reinterpret_cast *>(cursor)) + UnwindCursor( + context, LocalAddressSpace::sThisAddressSpace); ++ static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); + #undef REGISTER_KIND + AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + co->setInfoBasedOnIPRegister(); +@@ -79,6 +80,54 @@ _LIBUNWIND_HIDDEN int __unw_init_local(u + } + _LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local) + ++_LIBUNWIND_HIDDEN int __unw_init_local_dwarf(unw_cursor_t *cursor, ++ unw_context_t *context) { ++ _LIBUNWIND_TRACE_API("__unw_init_local_dwarf(cursor=%p, context=%p)", ++ static_cast(cursor), ++ static_cast(context)); ++#if defined(__i386__) ++# define REGISTER_KIND Registers_x86 ++#elif defined(__x86_64__) ++# define REGISTER_KIND Registers_x86_64 ++#elif defined(__powerpc64__) ++# define REGISTER_KIND Registers_ppc64 ++#elif defined(__ppc__) ++# define REGISTER_KIND Registers_ppc ++#elif defined(__aarch64__) ++# define REGISTER_KIND Registers_arm64 ++#elif defined(__arm__) ++# define REGISTER_KIND Registers_arm ++#elif defined(__or1k__) ++# define REGISTER_KIND Registers_or1k ++#elif defined(__hexagon__) ++# define REGISTER_KIND Registers_hexagon ++#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 ++# define REGISTER_KIND Registers_mips_o32 ++#elif defined(__mips64) ++# define REGISTER_KIND Registers_mips_newabi ++#elif defined(__mips__) ++# warning The MIPS architecture is not supported with this ABI and environment! ++#elif defined(__sparc__) ++# define REGISTER_KIND Registers_sparc ++#elif defined(__riscv) && __riscv_xlen == 64 ++# define REGISTER_KIND Registers_riscv ++#else ++# error Architecture not supported ++#endif ++ // Use "placement new" to allocate UnwindCursor in the cursor buffer. ++ new (reinterpret_cast *>(cursor)) ++ UnwindCursor( ++ context, LocalAddressSpace::sThisAddressSpace); ++ static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); ++#undef REGISTER_KIND ++ AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; ++ co->setForceDWARF(true); ++ co->setInfoBasedOnIPRegister(); ++ ++ return UNW_ESUCCESS; ++} ++_LIBUNWIND_WEAK_ALIAS(__unw_init_local_dwarf, unw_init_local_dwarf) ++ + /// Get value of specified register at cursor position in stack frame. + _LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, + unw_word_t *value) { +diff -pur a/libunwind/src/libunwind_ext.h b/libunwind/src/libunwind_ext.h +--- a/libunwind/src/libunwind_ext.h 2021-06-28 18:23:38.000000000 +0200 ++++ b/libunwind/src/libunwind_ext.h 2022-05-04 18:44:24.000000000 +0200 +@@ -25,6 +25,7 @@ extern "C" { + + extern int __unw_getcontext(unw_context_t *); + extern int __unw_init_local(unw_cursor_t *, unw_context_t *); ++extern int __unw_init_local_dwarf(unw_cursor_t *, unw_context_t *); + extern int __unw_step(unw_cursor_t *); + extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); + extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); diff --git a/deps/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch b/deps/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch new file mode 100644 index 0000000000000..afb4b941d5b92 --- /dev/null +++ b/deps/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch @@ -0,0 +1,107 @@ +Modification of the following patch in the FreeBSD source tree, which +includes LLVM libunwind in contrib/llvm-project/libunwind. + +From 9f287522cec9feac040d7cb845a440a8f6b7b90e Mon Sep 17 00:00:00 2001 +From: Dimitry Andric +Date: Sun, 2 Aug 2020 18:12:14 +0000 +Subject: [PATCH] Reapply r310365 (by emaste): + +libunwind: make __{de,}register_frame compatible with libgcc API + +The libgcc __register_frame and __deregister_frame functions take a +pointer to a set of FDE/CIEs, terminated by an entry where length is 0. + +In Apple's libunwind implementation the pointer is taken to be to a +single FDE. I suspect this was just an Apple bug, compensated by Apple- +specific code in LLVM. + +See lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp and +http://lists.llvm.org/pipermail/llvm-dev/2013-April/061737.html +for more detail. + +This change is based on the LLVM RTDyldMemoryManager.cpp. It should +later be changed to be alignment-safe. + +Reported by: dim +Reviewed by: dim +Sponsored by: The FreeBSD Foundation +Differential Revision: https://reviews.freebsd.org/D8869 + +Reapply r351610: + +Update libunwind custom frame register and deregister functions for +FreeBSD: use the new doubly underscored names for unw_add_dynamic_fde +and unw_remove_dynamic_fde. + +NOTE: this should be upstreamed... +--- + .../libunwind/src/UnwindLevel1-gcc-ext.c | 42 ++++++++++++++++++- + 1 file changed, 41 insertions(+), 1 deletion(-) + +diff --git a/libunwind/src/UnwindLevel1-gcc-ext.c b/libunwind/src/UnwindLevel1-gcc-ext.c +index 310b836d129e5..30f9cabf241f2 100644 +--- a/libunwind/src/UnwindLevel1-gcc-ext.c ++++ b/libunwind/src/UnwindLevel1-gcc-ext.c +@@ -234,6 +234,46 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, + + #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + ++#if defined(__FreeBSD__) ++ ++// Based on LLVM's lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp ++// and XXX should be fixed to be alignment-safe. ++static void processFDE(const char *addr, bool isDeregister) { ++ uint64_t length; ++ while ((length = *((const uint32_t *)addr)) != 0) { ++ const char *p = addr + 4; ++ if (length == 0xffffffff) { ++ length = *((const uint64_t *)p); ++ p += 8; ++ } ++ uint32_t offset = *((const uint32_t *)p); ++ if (offset != 0) { ++ if (isDeregister) ++ __unw_remove_dynamic_fde((unw_word_t)(uintptr_t)addr); ++ else ++ __unw_add_dynamic_fde((unw_word_t)(uintptr_t)addr); ++ } ++ addr = p + length; ++ } ++} ++ ++/// Called by programs with dynamic code generators that want to register ++/// dynamically generated FDEs, with a libgcc-compatible API. ++ ++_LIBUNWIND_EXPORT void __register_frame(const void *addr) { ++ _LIBUNWIND_TRACE_API("__register_frame(%p)", addr); ++ processFDE(addr, false); ++} ++ ++/// Called by programs with dynamic code generators that want to unregister ++/// dynamically generated FDEs, with a libgcc-compatible API. ++_LIBUNWIND_EXPORT void __deregister_frame(const void *addr) { ++ _LIBUNWIND_TRACE_API("__deregister_frame(%p)", addr); ++ processFDE(addr, true); ++} ++ ++#else // defined(__FreeBSD__) ++ + /// Called by programs with dynamic code generators that want + /// to register a dynamically generated FDE. + /// This function has existed on Mac OS X since 10.4, but +@@ -243,7 +283,6 @@ _LIBUNWIND_EXPORT void __register_frame(const void *fde) { + __unw_add_dynamic_fde((unw_word_t)(uintptr_t)fde); + } + +- + /// Called by programs with dynamic code generators that want + /// to unregister a dynamically generated FDE. + /// This function has existed on Mac OS X since 10.4, but +@@ -253,6 +292,7 @@ _LIBUNWIND_EXPORT void __deregister_frame(const void *fde) { + __unw_remove_dynamic_fde((unw_word_t)(uintptr_t)fde); + } + ++#endif // defined(__FreeBSD__) + + // The following register/deregister functions are gcc extensions. + // They have existed on Mac OS X, but have never worked because Mac OS X diff --git a/deps/patches/llvm-libunwind-prologue-epilogue.patch b/deps/patches/llvm-libunwind-prologue-epilogue.patch new file mode 100644 index 0000000000000..7dadca728f9cf --- /dev/null +++ b/deps/patches/llvm-libunwind-prologue-epilogue.patch @@ -0,0 +1,183 @@ +An updated version of this libosxunwind commit: + +commit ca57a5b60de4cd1daa42ed2e5d1d4aa3e96a09d1 +Author: Keno Fischer +Date: Mon Aug 26 15:28:08 2013 -0400 + + Add support for unwinding during prologue/epilogue + +--- +diff --git a/libunwind/src/CompactUnwinder.hpp b/libunwind/src/CompactUnwinder.hpp +index 1c3175dff50a..78a658ccbc27 100644 +--- a/libunwind/src/CompactUnwinder.hpp ++++ b/libunwind/src/CompactUnwinder.hpp +@@ -310,6 +310,50 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( + uint32_t savedRegistersLocations = + EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_REGISTERS); + ++ // If we have not stored EBP yet ++ if (functionStart == registers.getIP()) { ++ uint64_t rsp = registers.getSP(); ++ // old esp is ebp less return address ++ registers.setSP(rsp+8); ++ // pop return address into eip ++ registers.setIP(addressSpace.get64(rsp)); ++ ++ return UNW_STEP_SUCCESS; ++ } else if (functionStart + 1 == registers.getIP()) { ++ uint64_t rsp = registers.getSP(); ++ // old esp is ebp less return address ++ registers.setSP(rsp + 16); ++ // pop return address into eip ++ registers.setIP(addressSpace.get64(rsp + 8)); ++ ++ return UNW_STEP_SUCCESS; ++ } ++ ++ // If we're about to return, we've already popped the base pointer ++ uint8_t b = addressSpace.get8(registers.getIP()); ++ ++ // This is a hack to detect VZEROUPPER but in between popq rbp and ret ++ // It's not pretty but it works ++ if (b == 0xC5) { ++ if ((b = addressSpace.get8(registers.getIP() + 1)) == 0xF8 && ++ (b = addressSpace.get8(registers.getIP() + 2)) == 0x77) ++ b = addressSpace.get8(registers.getIP() + 3); ++ else ++ goto skip_ret; ++ } ++ ++ if (b == 0xC3 || b == 0xCB || b == 0xC2 || b == 0xCA) { ++ uint64_t rbp = registers.getSP(); ++ // old esp is ebp less return address ++ registers.setSP(rbp + 16); ++ // pop return address into eip ++ registers.setIP(addressSpace.get64(rbp + 8)); ++ ++ return UNW_STEP_SUCCESS; ++ } ++ ++ skip_ret: ++ + uint64_t savedRegisters = registers.getRBP() - 8 * savedRegistersOffset; + for (int i = 0; i < 5; ++i) { + switch (savedRegistersLocations & 0x7) { +@@ -430,6 +474,118 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( + } + } + } ++ ++ // Note that the order of these registers is so that ++ // registersSaved[0] is the one that will be pushed onto the stack last. ++ // Thus, if we want to walk this from the top, we need to go in reverse. ++ assert(regCount <= 6); ++ ++ // check whether we are still in the prologue ++ uint64_t curAddr = functionStart; ++ if (regCount > 0) { ++ for (int8_t i = (int8_t)(regCount) - 1; i >= 0; --i) { ++ if (registers.getIP() == curAddr) { ++ // None of the registers have been modified yet, so we don't need to reload them ++ framelessUnwind(addressSpace, registers.getSP() + 8 * (regCount - (uint64_t)(i + 1)), registers); ++ return UNW_STEP_SUCCESS; ++ } else { ++ assert(curAddr < registers.getIP()); ++ } ++ ++ ++ // pushq %rbp and pushq %rbx is 1 byte. Everything else 2 ++ if ((UNWIND_X86_64_REG_RBP == registersSaved[i]) || ++ (UNWIND_X86_64_REG_RBX == registersSaved[i])) ++ curAddr += 1; ++ else ++ curAddr += 2; ++ } ++ } ++ if (registers.getIP() == curAddr) { ++ // None of the registers have been modified yet, so we don't need to reload them ++ framelessUnwind(addressSpace, registers.getSP() + 8*regCount, registers); ++ return UNW_STEP_SUCCESS; ++ } else { ++ assert(curAddr < registers.getIP()); ++ } ++ ++ ++ // And now for the epilogue ++ { ++ uint8_t i = 0; ++ uint64_t p = registers.getIP(); ++ uint8_t b = 0; ++ ++ while (true) { ++ b = addressSpace.get8(p++); ++ // This is a hack to detect VZEROUPPER but in between the popq's and ret ++ // It's not pretty but it works ++ if (b == 0xC5) { ++ if ((b = addressSpace.get8(p++)) == 0xF8 && (b = addressSpace.get8(p++)) == 0x77) ++ b = addressSpace.get8(p++); ++ else ++ break; ++ } ++ // popq %rbx popq %rbp ++ if (b == 0x5B || b == 0x5D) { ++ i++; ++ } else if (b == 0x41) { ++ b = addressSpace.get8(p++); ++ if (b == 0x5C || b == 0x5D || b == 0x5E || b == 0x5F) ++ i++; ++ else ++ break; ++ } else if (b == 0xC3 || b == 0xCB || b == 0xC2 || b == 0xCA) { ++ // i pop's haven't happened yet ++ uint64_t savedRegisters = registers.getSP() + 8 * i; ++ if (regCount > 0) { ++ for (int8_t j = (int8_t)(regCount) - 1; j >= (int8_t)(regCount) - i; --j) { ++ uint64_t addr = savedRegisters - 8 * (regCount - (uint64_t)(j)); ++ switch (registersSaved[j]) { ++ case UNWIND_X86_64_REG_RBX: ++ registers.setRBX(addressSpace.get64(addr)); ++ break; ++ case UNWIND_X86_64_REG_R12: ++ registers.setR12(addressSpace.get64(addr)); ++ break; ++ case UNWIND_X86_64_REG_R13: ++ registers.setR13(addressSpace.get64(addr)); ++ break; ++ case UNWIND_X86_64_REG_R14: ++ registers.setR14(addressSpace.get64(addr)); ++ break; ++ case UNWIND_X86_64_REG_R15: ++ registers.setR15(addressSpace.get64(addr)); ++ break; ++ case UNWIND_X86_64_REG_RBP: ++ registers.setRBP(addressSpace.get64(addr)); ++ break; ++ default: ++ _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " ++ "function starting at 0x%llX", ++ encoding, functionStart); ++ _LIBUNWIND_ABORT("invalid compact unwind encoding"); ++ } ++ } ++ } ++ framelessUnwind(addressSpace, savedRegisters, registers); ++ return UNW_STEP_SUCCESS; ++ } else { ++ break; ++ } ++ } ++ } ++ ++ /* ++ 0x10fe2733a: 5b popq %rbx ++ 0x10fe2733b: 41 5c popq %r12 ++ 0x10fe2733d: 41 5d popq %r13 ++ 0x10fe2733f: 41 5e popq %r14 ++ 0x10fe27341: 41 5f popq %r15 ++ 0x10fe27343: 5d popq %rbp ++ */ ++ ++ + uint64_t savedRegisters = registers.getSP() + stackSize - 8 - 8 * regCount; + for (uint32_t i = 0; i < regCount; ++i) { + switch (registersSaved[i]) { diff --git a/deps/patches/llvm-libunwind-revert-monorepo-requirement.patch b/deps/patches/llvm-libunwind-revert-monorepo-requirement.patch new file mode 100644 index 0000000000000..4e3897dfb9801 --- /dev/null +++ b/deps/patches/llvm-libunwind-revert-monorepo-requirement.patch @@ -0,0 +1,156 @@ +Upstream commit 8c03fdf34a659925a3f09c8f54016e47ea1c7519 changed the build such +that it requires living inside the monorepo with libcxx available, only so that +it can reuse a CMake file to simplify some build steps. This patch is a revert +of that commit applied only to libunwind. + +--- +diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt +index 570b8db90653..a383d7d77d6f 100644 +--- a/libunwind/CMakeLists.txt ++++ b/libunwind/CMakeLists.txt +@@ -1,7 +1,3 @@ +-if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libcxx") +- message(FATAL_ERROR "libunwind requires being built in a monorepo layout with libcxx available") +-endif() +- + #=============================================================================== + # Setup Project + #=============================================================================== +@@ -15,31 +11,103 @@ set(CMAKE_MODULE_PATH + ${CMAKE_MODULE_PATH} + ) + +-set(LIBUNWIND_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +-set(LIBUNWIND_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +-set(LIBUNWIND_LIBCXX_PATH "${CMAKE_CURRENT_LIST_DIR}/../libcxx" CACHE PATH +- "Specify path to libc++ source.") +- + if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBUNWIND_STANDALONE_BUILD) + project(libunwind LANGUAGES C CXX ASM) + ++ # Rely on llvm-config. ++ set(CONFIG_OUTPUT) ++ if(NOT LLVM_CONFIG_PATH) ++ find_program(LLVM_CONFIG_PATH "llvm-config") ++ endif() ++ if (DEFINED LLVM_PATH) ++ set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include") ++ set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree") ++ set(LLVM_MAIN_SRC_DIR ${LLVM_PATH}) ++ set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules") ++ elseif(LLVM_CONFIG_PATH) ++ message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}") ++ set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} "--includedir" "--prefix" "--src-root") ++ execute_process(COMMAND ${CONFIG_COMMAND} ++ RESULT_VARIABLE HAD_ERROR ++ OUTPUT_VARIABLE CONFIG_OUTPUT) ++ if (NOT HAD_ERROR) ++ string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" ++ CONFIG_OUTPUT ${CONFIG_OUTPUT}) ++ else() ++ string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") ++ message(STATUS "${CONFIG_COMMAND_STR}") ++ message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") ++ endif() ++ ++ list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) ++ list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) ++ list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) ++ ++ set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") ++ set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") ++ set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") ++ set(LLVM_LIT_PATH "${LLVM_PATH}/utils/lit/lit.py") ++ ++ # --cmakedir is supported since llvm r291218 (4.0 release) ++ execute_process( ++ COMMAND ${LLVM_CONFIG_PATH} --cmakedir ++ RESULT_VARIABLE HAD_ERROR ++ OUTPUT_VARIABLE CONFIG_OUTPUT ++ ERROR_QUIET) ++ if(NOT HAD_ERROR) ++ string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH_FROM_LLVM_CONFIG) ++ file(TO_CMAKE_PATH "${LLVM_CMAKE_PATH_FROM_LLVM_CONFIG}" LLVM_CMAKE_PATH) ++ else() ++ file(TO_CMAKE_PATH "${LLVM_BINARY_DIR}" LLVM_BINARY_DIR_CMAKE_STYLE) ++ set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") ++ endif() ++ else() ++ message(WARNING "UNSUPPORTED LIBUNWIND CONFIGURATION DETECTED: " ++ "llvm-config not found and LLVM_MAIN_SRC_DIR not defined. " ++ "Reconfigure with -DLLVM_CONFIG=path/to/llvm-config " ++ "or -DLLVM_PATH=path/to/llvm-source-root.") ++ endif() ++ ++ if (EXISTS ${LLVM_CMAKE_PATH}) ++ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") ++ include("${LLVM_CMAKE_PATH}/AddLLVM.cmake") ++ include("${LLVM_CMAKE_PATH}/HandleLLVMOptions.cmake") ++ else() ++ message(WARNING "Not found: ${LLVM_CMAKE_PATH}") ++ endif() ++ + set(PACKAGE_NAME libunwind) + set(PACKAGE_VERSION 12.0.1) + set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") + set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") + +- # Add the CMake module path of libcxx so we can reuse HandleOutOfTreeLLVM.cmake +- set(LIBUNWIND_LIBCXX_CMAKE_PATH "${LIBUNWIND_LIBCXX_PATH}/cmake/Modules") +- list(APPEND CMAKE_MODULE_PATH "${LIBUNWIND_LIBCXX_CMAKE_PATH}") ++ if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) ++ set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) ++ else() ++ # Seek installed Lit. ++ find_program(LLVM_LIT "lit.py" ${LLVM_MAIN_SRC_DIR}/utils/lit ++ DOC "Path to lit.py") ++ endif() + +- # In a standalone build, we don't have llvm to automatically generate the +- # llvm-lit script for us. So we need to provide an explicit directory that +- # the configurator should write the script into. +- set(LIBUNWIND_STANDALONE_BUILD 1) +- set(LLVM_LIT_OUTPUT_DIR "${LIBUNWIND_BINARY_DIR}/bin") ++ if (LLVM_LIT) ++ # Define the default arguments to use with 'lit', and an option for the user ++ # to override. ++ set(LIT_ARGS_DEFAULT "-sv") ++ if (MSVC OR XCODE) ++ set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") ++ endif() ++ set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") ++ ++ # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. ++ if (WIN32 AND NOT CYGWIN) ++ set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") ++ endif() ++ else() ++ set(LLVM_INCLUDE_TESTS OFF) ++ endif() + +- # Find the LLVM sources and simulate LLVM CMake options. +- include(HandleOutOfTreeLLVM) ++ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}) ++ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}) + else() + set(LLVM_LIT "${CMAKE_SOURCE_DIR}/utils/lit/lit.py") + endif() +@@ -85,8 +153,6 @@ set(LIBUNWIND_TEST_COMPILER_FLAGS "" CACHE STRING + "Additional compiler flags for test programs.") + set(LIBUNWIND_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/lit.site.cfg.in" CACHE STRING + "The Lit testing configuration to use when running the tests.") +-set(LIBUNWIND_TEST_PARAMS "" CACHE STRING +- "A list of parameters to run the Lit test suite with.") + + if (NOT LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_STATIC) + message(FATAL_ERROR "libunwind must be built as either a shared or static library.") +@@ -113,6 +179,9 @@ set(CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/cmake" + ${CMAKE_MODULE_PATH}) + ++set(LIBUNWIND_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) ++set(LIBUNWIND_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) ++ + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) diff --git a/deps/unwind.mk b/deps/unwind.mk index ad7a91f4dff4a..1aa50211cc969 100644 --- a/deps/unwind.mk +++ b/deps/unwind.mk @@ -95,10 +95,18 @@ $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-force-dwarf.patch-applie cd $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER) && patch -p2 -f < $(SRCDIR)/patches/llvm-libunwind-force-dwarf.patch echo 1 > $@ +$(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-revert-monorepo-requirement.patch-applied: $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-force-dwarf.patch-applied + cd $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER) && patch -p2 -f < $(SRCDIR)/patches/llvm-libunwind-revert-monorepo-requirement.patch + echo 1 > $@ + +$(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-freebsd-libgcc-api-compat.patch-applied: $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-revert-monorepo-requirement.patch-applied + cd $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER) && patch -p2 -f < $(SRCDIR)/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch + echo 1 > $@ + checksum-llvmunwind: $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER).tar.xz $(JLCHECKSUM) $< -$(BUILDDIR)/llvmunwind-$(LLVMUNWIND_VER)/build-configured: $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/source-extracted $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-force-dwarf.patch-applied +$(BUILDDIR)/llvmunwind-$(LLVMUNWIND_VER)/build-configured: $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/source-extracted $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-freebsd-libgcc-api-compat.patch-applied mkdir -p $(dir $@) cd $(dir $@) && \ $(CMAKE) $(dir $<) $(LLVMUNWIND_OPTS)