7373
7474#include < stack>
7575
76+ #ifdef __APPLE__
77+ // Define a minimal mach header for JIT'd code, to support exceptions on osx 14
78+ // and later. See llvm/llvm-project#49036
79+ static llvm::MachO::mach_header_64 fake_mach_header = {
80+ .magic = llvm::MachO::MH_MAGIC_64,
81+ .cputype = llvm::MachO::CPU_TYPE_ARM64,
82+ .cpusubtype = llvm::MachO::CPU_SUBTYPE_ARM64_ALL,
83+ .filetype = llvm::MachO::MH_DYLIB,
84+ .ncmds = 0 ,
85+ .sizeofcmds = 0 ,
86+ .flags = 0 ,
87+ .reserved = 0 };
88+
89+ // Declare libunwind SPI types and functions.
90+ struct unw_dynamic_unwind_sections {
91+ uintptr_t dso_base;
92+ uintptr_t dwarf_section;
93+ size_t dwarf_section_length;
94+ uintptr_t compact_unwind_section;
95+ size_t compact_unwind_section_length;
96+ };
97+
98+ int find_dynamic_unwind_sections (uintptr_t addr,
99+ unw_dynamic_unwind_sections* info) {
100+ info->dso_base = (uintptr_t )&fake_mach_header;
101+ info->dwarf_section = 0 ;
102+ info->dwarf_section_length = 0 ;
103+ info->compact_unwind_section = 0 ;
104+ info->compact_unwind_section_length = 0 ;
105+ return 1 ;
106+ }
107+
108+ // Typedef for callback above.
109+ typedef int (*unw_find_dynamic_unwind_sections)(
110+ uintptr_t addr, struct unw_dynamic_unwind_sections * info);
111+
112+ #endif // __APPLE__
113+
76114namespace Cpp {
77115
78116using namespace clang ;
@@ -88,7 +126,15 @@ static compat::Interpreter* sInterpreter = nullptr;
88126// This might fix the issue https://reviews.llvm.org/D107087
89127// FIXME: For now we just leak the Interpreter.
90128struct InterpDeleter {
91- ~InterpDeleter () = default ;
129+ ~InterpDeleter () {
130+ #ifdef __APPLE__
131+ if (auto * unw_remove_find_dynamic_unwind_sections = (int (*)(
132+ unw_find_dynamic_unwind_sections find_dynamic_unwind_sections))
133+ dlsym (RTLD_DEFAULT, " __unw_remove_find_dynamic_unwind_sections" ))
134+ unw_remove_find_dynamic_unwind_sections (find_dynamic_unwind_sections);
135+ #endif
136+ // sInterpreter.release();
137+ }
92138} Deleter;
93139
94140static compat::Interpreter& getInterp () {
@@ -2865,6 +2911,8 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
28652911#ifdef _WIN32
28662912 // FIXME : Workaround Sema::PushDeclContext assert on windows
28672913 ClingArgv.push_back (" -fno-delayed-template-parsing" );
2914+ #elif __APPLE__
2915+ ClingArgv.push_back (" -fforce-dwarf-frame" );
28682916#endif
28692917 ClingArgv.insert (ClingArgv.end (), Args.begin (), Args.end ());
28702918 // To keep the Interpreter creation interface between cling and clang-repl
@@ -2923,6 +2971,14 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
29232971 // FIXME: Enable this assert once we figure out how to fix the multiple
29242972 // calls to CreateInterpreter.
29252973 // assert(!sInterpreter && "Interpreter already set.");
2974+ #ifdef __APPLE__
2975+ // Add a handler to support exceptions from interpreted code.
2976+ // See llvm/llvm-project#49036
2977+ if (auto * unw_add_find_dynamic_unwind_sections = (int (*)(
2978+ unw_find_dynamic_unwind_sections find_dynamic_unwind_sections))
2979+ dlsym (RTLD_DEFAULT, " __unw_add_find_dynamic_unwind_sections" ))
2980+ unw_add_find_dynamic_unwind_sections (find_dynamic_unwind_sections);
2981+ #endif // __APPLE__
29262982 sInterpreter = I;
29272983 return I;
29282984}
0 commit comments