Skip to content

Commit

Permalink
[ORC][MachO] Prepare MachOPlatform for compact-unwind support.
Browse files Browse the repository at this point in the history
The MachOPlatform::MachOPlatformPlugin class will now inject a
"__jitlink$libunwind_dso_base" symbol into each LinkGraph pointing to the Mach
header for the containing JITDylib. The compact-unwind support plugin will use
this symbol as the dso-base for the __unwind_info sections. (Failure to inject
this symbol would result in the compact-unwind support plugin creating a new
header for every graph).
  • Loading branch information
lhames committed Jan 22, 2025
1 parent 7256c91 commit 382bafc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ class MachOPlatform : public Platform {

std::optional<UnwindSections> findUnwindSectionInfo(jitlink::LinkGraph &G);
Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD,
ExecutorAddr HeaderAddr,
bool InBootstrapPhase);

Error createObjCRuntimeObject(jitlink::LinkGraph &G);
Expand Down
48 changes: 28 additions & 20 deletions llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,14 +794,29 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(

bool InBootstrapPhase = false;

if (LLVM_UNLIKELY(&MR.getTargetJITDylib() == &MP.PlatformJD)) {
ExecutorAddr HeaderAddr;
{
std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
if (MP.Bootstrap) {
InBootstrapPhase = true;
++MP.Bootstrap->ActiveGraphs;
if (LLVM_UNLIKELY(&MR.getTargetJITDylib() == &MP.PlatformJD)) {
if (MP.Bootstrap) {
InBootstrapPhase = true;
++MP.Bootstrap->ActiveGraphs;
}
}

// Get the dso-base address if available.
auto I = MP.JITDylibToHeaderAddr.find(&MR.getTargetJITDylib());
if (I != MP.JITDylibToHeaderAddr.end())
HeaderAddr = I->second;
}

// 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.
if (HeaderAddr)
LG.addAbsoluteSymbol("__jitlink$libunwind_dso_base", HeaderAddr, 0,
Linkage::Strong, Scope::Local, true);

// If we're in the bootstrap phase then increment the active graphs.
if (LLVM_UNLIKELY(InBootstrapPhase))
Config.PostAllocationPasses.push_back([this](LinkGraph &G) {
Expand Down Expand Up @@ -857,10 +872,11 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(

// Add a pass to register the final addresses of any special sections in the
// object with the runtime.
Config.PostAllocationPasses.push_back(
[this, &JD = MR.getTargetJITDylib(), InBootstrapPhase](LinkGraph &G) {
return registerObjectPlatformSections(G, JD, InBootstrapPhase);
});
Config.PostAllocationPasses.push_back([this, &JD = MR.getTargetJITDylib(),
HeaderAddr,
InBootstrapPhase](LinkGraph &G) {
return registerObjectPlatformSections(G, JD, HeaderAddr, InBootstrapPhase);
});

// If we're in the bootstrap phase then steal allocation actions and then
// decrement the active graphs.
Expand Down Expand Up @@ -1249,7 +1265,7 @@ MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
SecRange.Start = std::min(SecRange.Start, R.Start);
SecRange.End = std::max(SecRange.End, R.End);
for (auto &E : B->edges()) {
if (!E.getTarget().isDefined())
if (E.getKind() != Edge::KeepAlive || !E.getTarget().isDefined())
continue;
auto &TargetBlock = E.getTarget().getBlock();
auto &TargetSection = TargetBlock.getSection();
Expand Down Expand Up @@ -1307,7 +1323,8 @@ MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
}

Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
jitlink::LinkGraph &G, JITDylib &JD, bool InBootstrapPhase) {
jitlink::LinkGraph &G, JITDylib &JD, ExecutorAddr HeaderAddr,
bool InBootstrapPhase) {

// Get a pointer to the thread data section if there is one. It will be used
// below.
Expand Down Expand Up @@ -1378,22 +1395,13 @@ Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
dbgs() << " " << KV.first << ": " << KV.second << "\n";
});

assert(HeaderAddr && "Null header registered for JD");
using SPSRegisterObjectPlatformSectionsArgs = SPSArgList<
SPSExecutorAddr,
SPSOptional<SPSTuple<SPSSequence<SPSExecutorAddrRange>,
SPSExecutorAddrRange, SPSExecutorAddrRange>>,
SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;

ExecutorAddr HeaderAddr;
{
std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
auto I = MP.JITDylibToHeaderAddr.find(&JD);
assert(I != MP.JITDylibToHeaderAddr.end() &&
"No header registered for JD");
assert(I->second && "Null header registered for JD");
HeaderAddr = I->second;
}

AllocActionCallPair AllocActions = {
cantFail(
WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
Expand Down

0 comments on commit 382bafc

Please sign in to comment.