From 58dac77607c52fcc29e263bd87a367f29d1514b3 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Wed, 4 May 2022 19:19:00 +0200 Subject: [PATCH] More patches --- ...-libunwind-freebsd-libgcc-api-compat.patch | 107 ++++++++++++ ...ibunwind-revert-monorepo-requirement.patch | 156 ++++++++++++++++++ deps/unwind.mk | 10 +- 3 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 deps/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch create mode 100644 deps/patches/llvm-libunwind-revert-monorepo-requirement.patch 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 00000000000000..afb4b941d5b92f --- /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-revert-monorepo-requirement.patch b/deps/patches/llvm-libunwind-revert-monorepo-requirement.patch new file mode 100644 index 00000000000000..4e3897dfb98013 --- /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 ad7a91f4dff4a1..1559611c3f0d48 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-force-dwarf.patch-applied $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-revert-monorepo-requirement.patch-applied $(SRCCACHE)/llvmunwind-$(LLVMUNWIND_VER)/llvm-libunwind-freebsd-libgcc-api-compat.patch-applied mkdir -p $(dir $@) cd $(dir $@) && \ $(CMAKE) $(dir $<) $(LLVMUNWIND_OPTS)