Skip to content

Commit bf2828f

Browse files
lhamesllvmbot
authored andcommitted
[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 eae6d6d, 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 e2eaf8d)
1 parent c7e085c commit bf2828f

File tree

9 files changed

+110
-19
lines changed

9 files changed

+110
-19
lines changed

llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class MachOPlatform : public Platform {
368368
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
369369

370370
std::mutex PlatformMutex;
371+
bool ForceEHFrames = false;
371372
BootstrapInfo *Bootstrap = nullptr;
372373
DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
373374
DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===- DefaultHostBootstrapValues.h - Defaults for host process -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Set sensible default bootstrap values for JIT execution in the host process.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H
14+
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H
15+
16+
#include "llvm/ADT/StringMap.h"
17+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
18+
#include <vector>
19+
20+
namespace llvm::orc {
21+
22+
void addDefaultBootstrapValuesForHostProcess(
23+
StringMap<std::vector<char>> &BootstrapMap,
24+
StringMap<ExecutorAddr> &BootstrapSymbols);
25+
26+
} // namespace llvm::orc
27+
28+
#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H

llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
1010

1111
#include "llvm/ExecutionEngine/Orc/Core.h"
12-
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
13-
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
12+
#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h"
1413
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
1514
#include "llvm/Support/Process.h"
1615
#include "llvm/TargetParser/Host.h"
@@ -49,10 +48,7 @@ SelfExecutorProcessControl::SelfExecutorProcessControl(
4948
if (this->TargetTriple.isOSBinFormatMachO())
5049
GlobalManglingPrefix = '_';
5150

52-
this->BootstrapSymbols[rt::RegisterEHFrameSectionWrapperName] =
53-
ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper);
54-
this->BootstrapSymbols[rt::DeregisterEHFrameSectionWrapperName] =
55-
ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper);
51+
addDefaultBootstrapValuesForHostProcess(BootstrapMap, BootstrapSymbols);
5652

5753
#ifdef __APPLE__
5854
// FIXME: Don't add an UnwindInfoManager by default -- it's redundant when

llvm/lib/ExecutionEngine/Orc/LLJIT.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,22 +1221,37 @@ Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J) {
12211221

12221222
if (auto *OLL = dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer())) {
12231223

1224-
bool CompactUnwindInfoSupported = false;
1224+
bool UseEHFrames = true;
12251225

12261226
// Enable compact-unwind support if possible.
12271227
if (J.getTargetTriple().isOSDarwin() ||
12281228
J.getTargetTriple().isOSBinFormatMachO()) {
1229-
if (auto UIRP = UnwindInfoRegistrationPlugin::Create(
1230-
J.getIRCompileLayer(), PlatformJD)) {
1231-
CompactUnwindInfoSupported = true;
1232-
OLL->addPlugin(std::move(*UIRP));
1233-
LLVM_DEBUG(dbgs() << "Enabled compact-unwind support.\n");
1234-
} else
1235-
consumeError(UIRP.takeError());
1229+
1230+
// Check if the bootstrap map says that we should force eh-frames:
1231+
// Older libunwinds require this as they don't have a dynamic
1232+
// registration API for compact-unwind.
1233+
std::optional<bool> ForceEHFrames;
1234+
if (auto Err = J.getExecutionSession().getBootstrapMapValue<bool, bool>(
1235+
"darwin-use-ehframes-only", ForceEHFrames))
1236+
return Err;
1237+
if (ForceEHFrames.has_value())
1238+
UseEHFrames = *ForceEHFrames;
1239+
else
1240+
UseEHFrames = false;
1241+
1242+
// If UseEHFrames hasn't been set then we're good to use compact-unwind.
1243+
if (!UseEHFrames) {
1244+
if (auto UIRP = UnwindInfoRegistrationPlugin::Create(
1245+
J.getIRCompileLayer(), PlatformJD)) {
1246+
OLL->addPlugin(std::move(*UIRP));
1247+
LLVM_DEBUG(dbgs() << "Enabled compact-unwind support.\n");
1248+
} else
1249+
return UIRP.takeError();
1250+
}
12361251
}
12371252

12381253
// Otherwise fall back to standard unwind registration.
1239-
if (!CompactUnwindInfoSupported) {
1254+
if (UseEHFrames) {
12401255
auto &ES = J.getExecutionSession();
12411256
if (auto EHFrameRegistrar = EPCEHFrameRegistrar::Create(ES)) {
12421257
OLL->addPlugin(std::make_unique<EHFrameRegistrationPlugin>(

llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,15 @@ MachOPlatform::MachOPlatform(
481481
ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*this));
482482
PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
483483

484+
{
485+
// Check for force-eh-frame
486+
std::optional<bool> ForceEHFrames;
487+
if ((Err = ES.getBootstrapMapValue<bool, bool>("darwin-use-ehframes-only",
488+
ForceEHFrames)))
489+
return;
490+
this->ForceEHFrames = ForceEHFrames.has_value() ? *ForceEHFrames : false;
491+
}
492+
484493
BootstrapInfo BI;
485494
Bootstrap = &BI;
486495

@@ -811,6 +820,12 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
811820
HeaderAddr = I->second;
812821
}
813822

823+
// If we're forcing eh-frame use then discard the compact-unwind section
824+
// immediately to prevent FDEs from being stripped.
825+
if (MP.ForceEHFrames)
826+
if (auto *CUSec = LG.findSectionByName(MachOCompactUnwindSectionName))
827+
LG.removeSection(*CUSec);
828+
814829
// Point the libunwind dso-base absolute symbol at the header for the
815830
// JITDylib. This will prevent us from synthesizing a new header for
816831
// every object.

llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ endif()
1111

1212
add_llvm_component_library(LLVMOrcTargetProcess
1313
ExecutorSharedMemoryMapperService.cpp
14+
DefaultHostBootstrapValues.cpp
1415
JITLoaderGDB.cpp
1516
JITLoaderPerf.cpp
1617
JITLoaderVTune.cpp
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===----- DefaultHostBootstrapValues.cpp - Defaults for host process -----===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h"
10+
11+
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12+
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
13+
14+
#ifdef __APPLE__
15+
#include <dlfcn.h>
16+
#endif // __APPLE__
17+
18+
namespace llvm::orc {
19+
20+
void addDefaultBootstrapValuesForHostProcess(
21+
StringMap<std::vector<char>> &BootstrapMap,
22+
StringMap<ExecutorAddr> &BootstrapSymbols) {
23+
24+
// FIXME: We probably shouldn't set these on Windows?
25+
BootstrapSymbols[rt::RegisterEHFrameSectionWrapperName] =
26+
ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper);
27+
BootstrapSymbols[rt::DeregisterEHFrameSectionWrapperName] =
28+
ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper);
29+
30+
#ifdef __APPLE__
31+
if (!dlsym(RTLD_DEFAULT, "__unw_add_find_dynamic_unwind_sections"))
32+
BootstrapMap["darwin-use-ehframes-only"].push_back(1);
33+
#endif // __APPLE__
34+
}
35+
36+
} // namespace llvm::orc

llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,6 @@ void addTo(StringMap<ExecutorAddr> &M) {
106106
ExecutorAddr::fromPtr(&writeBuffersWrapper);
107107
M[rt::MemoryWritePointersWrapperName] =
108108
ExecutorAddr::fromPtr(&writePointersWrapper);
109-
M[rt::RegisterEHFrameSectionWrapperName] =
110-
ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper);
111-
M[rt::DeregisterEHFrameSectionWrapperName] =
112-
ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper);
113109
M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper);
114110
M[rt::RunAsVoidFunctionWrapperName] =
115111
ExecutorAddr::fromPtr(&runAsVoidFunctionWrapper);

llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "llvm/ADT/StringRef.h"
1414
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX, LLVM_ENABLE_THREADS
15+
#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h"
1516
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"
1617
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
1718
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
@@ -187,6 +188,8 @@ int main(int argc, char *argv[]) {
187188
std::make_unique<SimpleRemoteEPCServer::ThreadDispatcher>());
188189
S.bootstrapSymbols() =
189190
SimpleRemoteEPCServer::defaultBootstrapSymbols();
191+
addDefaultBootstrapValuesForHostProcess(S.bootstrapMap(),
192+
S.bootstrapSymbols());
190193
S.services().push_back(
191194
std::make_unique<rt_bootstrap::SimpleExecutorMemoryManager>());
192195
S.services().push_back(

0 commit comments

Comments
 (0)