From 22457039c2c2f2db2ca75c38545ef127474dbe9b Mon Sep 17 00:00:00 2001 From: maximusron Date: Thu, 2 May 2024 19:01:15 +0200 Subject: [PATCH] Add llvm libunwind callback to suppress exceptions on apple silicon --- lib/Interpreter/Compatibility.h | 48 +++++++++++++++++++++++++++++++++ lib/Interpreter/CppInterOp.cpp | 7 ++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/Interpreter/Compatibility.h b/lib/Interpreter/Compatibility.h index ded7cbde..92778c68 100644 --- a/lib/Interpreter/Compatibility.h +++ b/lib/Interpreter/Compatibility.h @@ -13,11 +13,13 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/MachO.h" #include "llvm/Config/llvm-config.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Path.h" +#include "llvm/Object/MachO.h" #ifdef USE_CLING @@ -36,6 +38,43 @@ namespace compat { using Interpreter = cling::Interpreter; +#ifdef __APPLE__ + // Define a minimal mach header for JIT'd code. + static MachO::mach_header_64 fake_mach_header = { + .magic = MachO::MH_MAGIC_64, + .cputype = MachO::CPU_TYPE_ARM64, + .cpusubtype = MachO::CPU_SUBTYPE_ARM64_ALL, + .filetype = MachO::MH_DYLIB, + .ncmds = 0, + .sizeofcmds = 0, + .flags = 0, + .reserved = 0}; + + // Declare libunwind SPI types and functions. + struct unw_dynamic_unwind_sections { + uintptr_t dso_base; + uintptr_t dwarf_section; + size_t dwarf_section_length; + uintptr_t compact_unwind_section; + size_t compact_unwind_section_length; + }; + + int find_dynamic_unwind_sections(uintptr_t addr, + unw_dynamic_unwind_sections * info) { + info->dso_base = (uintptr_t)&fake_mach_header; + info->dwarf_section = 0; + info->dwarf_section_length = 0; + info->compact_unwind_section = 0; + info->compact_unwind_section_length = 0; + return 1; + } + + // Typedef for callback above. + typedef int (*unw_find_dynamic_unwind_sections)( + uintptr_t addr, struct unw_dynamic_unwind_sections * info); + +#endif + inline void maybeMangleDeclName(const clang::GlobalDecl& GD, std::string& mangledName) { cling::utils::Analyze::maybeMangleDeclName(GD, mangledName); @@ -151,6 +190,15 @@ createClangInterpreter(std::vector& args) { return std::move(*innerOrErr); } +#ifdef __APPLE__ +inline void removeFindDynamicUnwindSections() { + if (auto* unw_remove_find_dynamic_unwind_sections = (int (*)( + unw_find_dynamic_unwind_sections find_dynamic_unwind_sections)) + dlsym(RTLD_DEFAULT, "__unw_remove_find_dynamic_unwind_sections")) + unw_remove_find_dynamic_unwind_sections(find_dynamic_unwind_sections); +} +#endif + inline void maybeMangleDeclName(const clang::GlobalDecl& GD, std::string& mangledName) { // copied and adapted from CodeGen::CodeGenModule::getMangledName diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index eab23c81..9063bced 100644 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -62,7 +62,12 @@ namespace Cpp { // This might fix the issue https://reviews.llvm.org/D107087 // FIXME: For now we just leak the Interpreter. struct InterpDeleter { - ~InterpDeleter() { sInterpreter.release(); } + ~InterpDeleter() { +#ifdef __APPLE__ + compat::removeFindDynamicUnwindSections(); +#endif + sInterpreter.release(); + } } Deleter; static compat::Interpreter& getInterp() {