Skip to content

Commit

Permalink
More patches
Browse files Browse the repository at this point in the history
  • Loading branch information
fxcoudert committed May 4, 2022
1 parent 3a6a2d1 commit 58dac77
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 1 deletion.
107 changes: 107 additions & 0 deletions deps/patches/llvm-libunwind-freebsd-libgcc-api-compat.patch
Original file line number Diff line number Diff line change
@@ -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 <dim@FreeBSD.org>
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
156 changes: 156 additions & 0 deletions deps/patches/llvm-libunwind-revert-monorepo-requirement.patch
Original file line number Diff line number Diff line change
@@ -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++)
10 changes: 9 additions & 1 deletion deps/unwind.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 58dac77

Please sign in to comment.