Author: Lang Hames Date: 2025-02-08T16:19:55Z New Revision: bf2828f65823264f46e9cca60f0f4e9988ce2f57
URL: https://github.com/llvm/llvm-project/commit/bf2828f65823264f46e9cca60f0f4e9988ce2f57 DIFF: https://github.com/llvm/llvm-project/commit/bf2828f65823264f46e9cca60f0f4e9988ce2f57.diff LOG: [ORC] Force eh-frame use for older Darwins on x86-64 in MachOPlatform, LLJIT. The system libunwind on older Darwins does not support JIT registration of compact-unwind. Since the CompactUnwindManager utility discards redundant eh-frame FDEs by default we need to remove the compact-unwind section first when targeting older libunwinds in order to preserve eh-frames. While LLJIT was already doing this as of eae6d6d18bd, MachOPlatform was not. This was causing buildbot failures in the ORC runtime (e.g. in https://green.lab.llvm.org/job/llvm.org/job/clang-stage1-RA/3479/). This patch updates both LLJIT and MachOPlatform to check a bootstrap value, "darwin-use-ehframes-only", to determine whether to forcibly preserve eh-frame sections. If this value is present and set to true then compact-unwind sections will be discarded, causing eh-frames to be preserved. If the value is absent or set to false then compact-unwind will be used and redundant FDEs in eh-frames discarded (FDEs that are needed by the compact-unwind section are always preserved). rdar://143895614 (cherry picked from commit e2eaf8ded78507100513a17e8193e2c4b094f8da) Added: llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h llvm/lib/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.cpp Modified: llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp llvm/lib/ExecutionEngine/Orc/LLJIT.cpp llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h index 6e99f6c03a7c676..91842714f6c4c38 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h @@ -368,6 +368,7 @@ class MachOPlatform : public Platform { DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols; std::mutex PlatformMutex; + bool ForceEHFrames = false; BootstrapInfo *Bootstrap = nullptr; DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr; DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h new file mode 100644 index 000000000000000..d3277e61eeb7b12 --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h @@ -0,0 +1,28 @@ +//===- DefaultHostBootstrapValues.h - Defaults for host process -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Set sensible default bootstrap values for JIT execution in the host process. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H +#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" +#include <vector> + +namespace llvm::orc { + +void addDefaultBootstrapValuesForHostProcess( + StringMap<std::vector<char>> &BootstrapMap, + StringMap<ExecutorAddr> &BootstrapSymbols); + +} // namespace llvm::orc + +#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp index a9dbcd166117b0c..7b38150ab4b650b 100644 --- a/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp @@ -9,8 +9,7 @@ #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/Core.h" -#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" -#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h" +#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h" #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h" #include "llvm/Support/Process.h" #include "llvm/TargetParser/Host.h" @@ -49,10 +48,7 @@ SelfExecutorProcessControl::SelfExecutorProcessControl( if (this->TargetTriple.isOSBinFormatMachO()) GlobalManglingPrefix = '_'; - this->BootstrapSymbols[rt::RegisterEHFrameSectionWrapperName] = - ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper); - this->BootstrapSymbols[rt::DeregisterEHFrameSectionWrapperName] = - ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper); + addDefaultBootstrapValuesForHostProcess(BootstrapMap, BootstrapSymbols); #ifdef __APPLE__ // FIXME: Don't add an UnwindInfoManager by default -- it's redundant when diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 938fe58ef85cfeb..dd844ae3a42bc88 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -1221,22 +1221,37 @@ Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) { if (auto *OLL = dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer())) { - bool CompactUnwindInfoSupported = false; + bool UseEHFrames = true; // Enable compact-unwind support if possible. if (J.getTargetTriple().isOSDarwin() || J.getTargetTriple().isOSBinFormatMachO()) { - if (auto UIRP = UnwindInfoRegistrationPlugin::Create( - J.getIRCompileLayer(), PlatformJD)) { - CompactUnwindInfoSupported = true; - OLL->addPlugin(std::move(*UIRP)); - LLVM_DEBUG(dbgs() << "Enabled compact-unwind support.\n"); - } else - consumeError(UIRP.takeError()); + + // Check if the bootstrap map says that we should force eh-frames: + // Older libunwinds require this as they don't have a dynamic + // registration API for compact-unwind. + std::optional<bool> ForceEHFrames; + if (auto Err = J.getExecutionSession().getBootstrapMapValue<bool, bool>( + "darwin-use-ehframes-only", ForceEHFrames)) + return Err; + if (ForceEHFrames.has_value()) + UseEHFrames = *ForceEHFrames; + else + UseEHFrames = false; + + // If UseEHFrames hasn't been set then we're good to use compact-unwind. + if (!UseEHFrames) { + if (auto UIRP = UnwindInfoRegistrationPlugin::Create( + J.getIRCompileLayer(), PlatformJD)) { + OLL->addPlugin(std::move(*UIRP)); + LLVM_DEBUG(dbgs() << "Enabled compact-unwind support.\n"); + } else + return UIRP.takeError(); + } } // Otherwise fall back to standard unwind registration. - if (!CompactUnwindInfoSupported) { + if (UseEHFrames) { auto &ES = J.getExecutionSession(); if (auto EHFrameRegistrar = EPCEHFrameRegistrar::Create(ES)) { OLL->addPlugin(std::make_unique<EHFrameRegistrationPlugin>( diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp index 845990d965b16d3..d4e341a96f5b1f8 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp @@ -481,6 +481,15 @@ MachOPlatform::MachOPlatform( ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*this)); PlatformJD.addGenerator(std::move(OrcRuntimeGenerator)); + { + // Check for force-eh-frame + std::optional<bool> ForceEHFrames; + if ((Err = ES.getBootstrapMapValue<bool, bool>("darwin-use-ehframes-only", + ForceEHFrames))) + return; + this->ForceEHFrames = ForceEHFrames.has_value() ? *ForceEHFrames : false; + } + BootstrapInfo BI; Bootstrap = &BI; @@ -811,6 +820,12 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig( HeaderAddr = I->second; } + // If we're forcing eh-frame use then discard the compact-unwind section + // immediately to prevent FDEs from being stripped. + if (MP.ForceEHFrames) + if (auto *CUSec = LG.findSectionByName(MachOCompactUnwindSectionName)) + LG.removeSection(*CUSec); + // Point the libunwind dso-base absolute symbol at the header for the // JITDylib. This will prevent us from synthesizing a new header for // every object. diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt index ffc1bbfa121b393..282d4cfc2ddade4 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt @@ -11,6 +11,7 @@ endif() add_llvm_component_library(LLVMOrcTargetProcess ExecutorSharedMemoryMapperService.cpp + DefaultHostBootstrapValues.cpp JITLoaderGDB.cpp JITLoaderPerf.cpp JITLoaderVTune.cpp diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.cpp new file mode 100644 index 000000000000000..c95b7ac5159fe65 --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.cpp @@ -0,0 +1,36 @@ +//===----- DefaultHostBootstrapValues.cpp - Defaults for host process -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h" + +#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" +#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h" + +#ifdef __APPLE__ +#include <dlfcn.h> +#endif // __APPLE__ + +namespace llvm::orc { + +void addDefaultBootstrapValuesForHostProcess( + StringMap<std::vector<char>> &BootstrapMap, + StringMap<ExecutorAddr> &BootstrapSymbols) { + + // FIXME: We probably shouldn't set these on Windows? + BootstrapSymbols[rt::RegisterEHFrameSectionWrapperName] = + ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper); + BootstrapSymbols[rt::DeregisterEHFrameSectionWrapperName] = + ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper); + +#ifdef __APPLE__ + if (!dlsym(RTLD_DEFAULT, "__unw_add_find_dynamic_unwind_sections")) + BootstrapMap["darwin-use-ehframes-only"].push_back(1); +#endif // __APPLE__ +} + +} // namespace llvm::orc diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp index d88fbbfc863850b..c4f201b353d2791 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp @@ -106,10 +106,6 @@ void addTo(StringMap<ExecutorAddr> &M) { ExecutorAddr::fromPtr(&writeBuffersWrapper); M[rt::MemoryWritePointersWrapperName] = ExecutorAddr::fromPtr(&writePointersWrapper); - M[rt::RegisterEHFrameSectionWrapperName] = - ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper); - M[rt::DeregisterEHFrameSectionWrapperName] = - ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper); M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper); M[rt::RunAsVoidFunctionWrapperName] = ExecutorAddr::fromPtr(&runAsVoidFunctionWrapper); diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp index 86b89a38c176010..dbdec7732777448 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX, LLVM_ENABLE_THREADS +#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h" #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h" #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h" #include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h" @@ -187,6 +188,8 @@ int main(int argc, char *argv[]) { std::make_unique<SimpleRemoteEPCServer::ThreadDispatcher>()); S.bootstrapSymbols() = SimpleRemoteEPCServer::defaultBootstrapSymbols(); + addDefaultBootstrapValuesForHostProcess(S.bootstrapMap(), + S.bootstrapSymbols()); S.services().push_back( std::make_unique<rt_bootstrap::SimpleExecutorMemoryManager>()); S.services().push_back( _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits