Skip to content

Commit

Permalink
Add llvm libunwind callback to suppress exceptions on apple silicon
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronj0 committed May 2, 2024
1 parent 244d1ab commit 2245703
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
48 changes: 48 additions & 0 deletions lib/Interpreter/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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);
Expand Down Expand Up @@ -151,6 +190,15 @@ createClangInterpreter(std::vector<const char*>& 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
Expand Down
7 changes: 6 additions & 1 deletion lib/Interpreter/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit 2245703

Please sign in to comment.