From 94aea8b17d03ff695ec59197eed83f97acfb322b Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 26 Oct 2025 10:28:41 -0400 Subject: [PATCH] Fix custom EHFrame registration on llvm21 --- src/jitlayers.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 90091cc1f38db..fcc367fa53c51 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1217,6 +1217,8 @@ class JLMemoryUsagePlugin : public ObjectLinkingLayer::Plugin { #endif } +#if defined(JL_USE_JITLINK) && defined(LLVM_SHLIB) +# if JL_LLVM_VERSION < 210000 class JLEHFrameRegistrar final : public jitlink::EHFrameRegistrar { public: Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) override { @@ -1229,6 +1231,72 @@ class JLEHFrameRegistrar final : public jitlink::EHFrameRegistrar { return Error::success(); } }; +# else +class JLEHFrameRegistrationPlugin final : public LinkGraphLinkingLayer::Plugin { + static Error registerEHFrameWrapper(orc::ExecutorAddrRange EHFrame) { + register_eh_frames(EHFrame.Start.toPtr(), static_cast(EHFrame.size())); + return Error::success(); + } + + static Error deregisterEHFrameWrapper(orc::ExecutorAddrRange EHFrame) { + deregister_eh_frames(EHFrame.Start.toPtr(), static_cast(EHFrame.size())); + return Error::success(); + } + + static orc::shared::CWrapperFunctionResult + registerEHFrameSectionAllocAction(const char *ArgData, size_t ArgSize) { + using namespace llvm::orc::shared; + return WrapperFunction::handle( + ArgData, ArgSize, registerEHFrameWrapper) + .release(); + } + + static orc::shared::CWrapperFunctionResult + deregisterEHFrameSectionAllocAction(const char *ArgData, size_t ArgSize) { + using namespace llvm::orc::shared; + return WrapperFunction::handle( + ArgData, ArgSize, deregisterEHFrameWrapper) + .release(); + } + + static Error postFixup(jitlink::LinkGraph &G) + { + using namespace llvm::orc::shared; + auto registerFrame = ExecutorAddr::fromPtr(registerEHFrameSectionAllocAction); + auto deregisterFrame = ExecutorAddr::fromPtr(deregisterEHFrameSectionAllocAction); + if (auto *EHFrame = jitlink::getEHFrameSection(G)) { + auto R = jitlink::SectionRange(*EHFrame).getRange(); + G.allocActions().push_back( + {cantFail( + WrapperFunctionCall::Create>( + registerFrame, R)), + cantFail( + WrapperFunctionCall::Create>( + deregisterFrame, R))}); + } + return Error::success(); + } + +public: + JLEHFrameRegistrationPlugin() {} + + void modifyPassConfig(MaterializationResponsibility&, + jitlink::LinkGraph&, + jitlink::PassConfiguration &PassConfig) override + { + PassConfig.PostFixupPasses.push_back(postFixup); + } + Error notifyFailed(MaterializationResponsibility&) override { + return Error::success(); + } + Error notifyRemovingResources(JITDylib&, ResourceKey) override { + return Error::success(); + } + void notifyTransferringResources(JITDylib&, ResourceKey, + ResourceKey) override {} +}; +# endif +#endif RTDyldMemoryManager *createRTDyldMemoryManager(void) JL_NOTSAFEPOINT; std::unique_ptr createJITLinkMemoryManager() JL_NOTSAFEPOINT; @@ -1941,15 +2009,26 @@ JuliaOJIT::JuliaOJIT() OptSelLayer(ES, OptimizeLayer, static_cast(selectOptLevel)) { #ifdef JL_USE_JITLINK -# if defined(LLVM_SHLIB) +# if JL_LLVM_VERSION < 210000 +# if defined(LLVM_SHLIB) // When dynamically linking against LLVM, use our custom EH frame registration code // also used with RTDyld to inform both our and the libc copy of libunwind. auto ehRegistrar = std::make_unique(); -# else +# else auto ehRegistrar = std::make_unique(); -# endif +# endif ObjectLayer.addPlugin(std::make_unique( ES, std::move(ehRegistrar))); +#else + // llvm's EHFrameRegistrationPlugin does not seem to have any customization + // hooks in 21+. Do our own registration with a separate plugin instead. +# if defined(LLVM_SHLIB) + // When dynamically linking against LLVM, use our custom EH frame registration code + // also used with RTDyld to inform both our and the libc copy of libunwind. + ObjectLayer.addPlugin(std::make_unique()); +# endif + ObjectLayer.addPlugin(std::move(EHFrameRegistrationPlugin::Create(ES).get())); +#endif ObjectLayer.addPlugin(std::make_unique()); ObjectLayer.addPlugin(std::make_unique(&jit_bytes_size));