Skip to content

Commit d6524c8

Browse files
committed
Reapply "[ORC] Enable JIT support for the compact-unwind frame..." with fixes.
This reapplies 4f03258 (and follow up patches 26fc07d, a001cc0, c9bc242, and fd174f0), which were reverted in 212cdc9 to investigate bot failures (e.g. https://lab.llvm.org/buildbot/#/builders/108/builds/8502) The fix to address the bot failures was landed in d0052eb. This patch also restricts construction of the UnwindInfoManager object to Apple platforms (as it won't be used on other platforms).
1 parent 1fcba94 commit d6524c8

File tree

17 files changed

+191
-164
lines changed

17 files changed

+191
-164
lines changed

clang/test/Interpreter/simple-exception.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// clang-format off
22
// UNSUPPORTED: system-aix
3-
// XFAIL for arm and arm64, or running on Windows.
4-
// XFAIL: target=arm{{.*}}, system-windows
3+
// XFAIL for arm, or running on Windows.
4+
// XFAIL: target=arm-{{.*}}, target=armv{{.*}}, system-windows
55
// RUN: cat %s | clang-repl | FileCheck %s
66

77
// Incompatible with msan. It passes with -O3 but fail -Oz. Interpreter

compiler-rt/lib/orc/macho_platform.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@ Error MachOPlatformRuntimeState::registerObjectPlatformSections(
557557
return make_error<StringError>(ErrStream.str());
558558
}
559559

560+
ORC_RT_DEBUG({
561+
printdbg(" UnwindInfo: %s, UseCallbackStyleUnwindInfo: %s\n",
562+
UnwindInfo ? "true" : "false",
563+
UseCallbackStyleUnwindInfo ? "true" : "false");
564+
});
565+
560566
if (UnwindInfo && UseCallbackStyleUnwindInfo) {
561567
ORC_RT_DEBUG({
562568
printdbg(" Registering new-style unwind info for:\n"

llvm/include/llvm/ExecutionEngine/Orc/Core.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,8 +1204,13 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
12041204

12051205
JITDylib(ExecutionSession &ES, std::string Name);
12061206

1207-
std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
1208-
IL_removeTracker(ResourceTracker &RT);
1207+
struct RemoveTrackerResult {
1208+
AsynchronousSymbolQuerySet QueriesToFail;
1209+
std::shared_ptr<SymbolDependenceMap> FailedSymbols;
1210+
std::vector<std::unique_ptr<MaterializationUnit>> DefunctMUs;
1211+
};
1212+
1213+
RemoveTrackerResult IL_removeTracker(ResourceTracker &RT);
12091214

12101215
void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
12111216

llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
2121
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
2222
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
23+
#include "llvm/ExecutionEngine/Orc/TargetProcess/UnwindInfoManager.h"
2324
#include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
2425
#include "llvm/Support/DynamicLibrary.h"
2526
#include "llvm/Support/MSVCErrorWorkarounds.h"
@@ -507,6 +508,9 @@ class SelfExecutorProcessControl : public ExecutorProcessControl,
507508
SymbolLookupCompleteFn F) override;
508509

509510
std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
511+
#ifdef __APPLE__
512+
std::unique_ptr<UnwindInfoManager> UnwindInfoMgr;
513+
#endif // __APPLE__
510514
char GlobalManglingPrefix = 0;
511515
};
512516

llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ using SPSRunAsMainSignature = int64_t(shared::SPSExecutorAddr,
8888
using SPSRunAsVoidFunctionSignature = int32_t(shared::SPSExecutorAddr);
8989
using SPSRunAsIntFunctionSignature = int32_t(shared::SPSExecutorAddr, int32_t);
9090
} // end namespace rt
91+
92+
namespace rt_alt {
93+
extern const char *UnwindInfoManagerInstanceName;
94+
extern const char *UnwindInfoManagerFindSectionsHelperName;
95+
extern const char *UnwindInfoManagerEnableWrapperName;
96+
extern const char *UnwindInfoManagerDisableWrapperName;
97+
extern const char *UnwindInfoManagerRegisterActionName;
98+
extern const char *UnwindInfoManagerDeregisterActionName;
99+
} // end namespace rt_alt
91100
} // end namespace orc
92101
} // end namespace llvm
93102

llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ tablegen(LLVM COFFOptions.inc -gen-opt-parser-defs)
33
add_public_tablegen_target(JITLinkTableGen)
44

55
add_llvm_component_library(LLVMJITLink
6+
CompactUnwindSupport.cpp
67
DWARFRecordSectionSplitter.cpp
78
EHFrameSupport.cpp
89
JITLink.cpp

llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp

Lines changed: 0 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -733,121 +733,5 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
733733
return Error::success();
734734
}
735735

736-
Error CompactUnwindSplitter::operator()(LinkGraph &G) {
737-
auto *CUSec = G.findSectionByName(CompactUnwindSectionName);
738-
if (!CUSec)
739-
return Error::success();
740-
741-
if (!G.getTargetTriple().isOSBinFormatMachO())
742-
return make_error<JITLinkError>(
743-
"Error linking " + G.getName() +
744-
": compact unwind splitting not supported on non-macho target " +
745-
G.getTargetTriple().str());
746-
747-
unsigned CURecordSize = 0;
748-
unsigned PersonalityEdgeOffset = 0;
749-
unsigned LSDAEdgeOffset = 0;
750-
switch (G.getTargetTriple().getArch()) {
751-
case Triple::aarch64:
752-
case Triple::x86_64:
753-
// 64-bit compact-unwind record format:
754-
// Range start: 8 bytes.
755-
// Range size: 4 bytes.
756-
// CU encoding: 4 bytes.
757-
// Personality: 8 bytes.
758-
// LSDA: 8 bytes.
759-
CURecordSize = 32;
760-
PersonalityEdgeOffset = 16;
761-
LSDAEdgeOffset = 24;
762-
break;
763-
default:
764-
return make_error<JITLinkError>(
765-
"Error linking " + G.getName() +
766-
": compact unwind splitting not supported on " +
767-
G.getTargetTriple().getArchName());
768-
}
769-
770-
std::vector<Block *> OriginalBlocks(CUSec->blocks().begin(),
771-
CUSec->blocks().end());
772-
LLVM_DEBUG({
773-
dbgs() << "In " << G.getName() << " splitting compact unwind section "
774-
<< CompactUnwindSectionName << " containing "
775-
<< OriginalBlocks.size() << " initial blocks...\n";
776-
});
777-
778-
while (!OriginalBlocks.empty()) {
779-
auto *B = OriginalBlocks.back();
780-
OriginalBlocks.pop_back();
781-
782-
if (B->getSize() == 0) {
783-
LLVM_DEBUG({
784-
dbgs() << " Skipping empty block at "
785-
<< formatv("{0:x16}", B->getAddress()) << "\n";
786-
});
787-
continue;
788-
}
789-
790-
unsigned NumBlocks = B->getSize() / CURecordSize;
791-
792-
LLVM_DEBUG({
793-
dbgs() << " Splitting block at " << formatv("{0:x16}", B->getAddress())
794-
<< " into " << NumBlocks << " compact unwind record(s)\n";
795-
});
796-
797-
if (B->getSize() % CURecordSize)
798-
return make_error<JITLinkError>(
799-
"Error splitting compact unwind record in " + G.getName() +
800-
": block at " + formatv("{0:x}", B->getAddress()) + " has size " +
801-
formatv("{0:x}", B->getSize()) +
802-
" (not a multiple of CU record size of " +
803-
formatv("{0:x}", CURecordSize) + ")");
804-
805-
auto Blocks =
806-
G.splitBlock(*B, map_range(seq(1U, NumBlocks), [=](Edge::OffsetT Idx) {
807-
return Idx * CURecordSize;
808-
}));
809-
810-
for (auto *CURec : Blocks) {
811-
bool AddedKeepAlive = false;
812-
813-
for (auto &E : CURec->edges()) {
814-
if (E.getOffset() == 0) {
815-
LLVM_DEBUG({
816-
dbgs() << " Updating compact unwind record at "
817-
<< CURec->getAddress() << " to point to "
818-
<< (E.getTarget().hasName() ? *E.getTarget().getName()
819-
: StringRef())
820-
<< " (at " << E.getTarget().getAddress() << ")\n";
821-
});
822-
823-
if (E.getTarget().isExternal())
824-
return make_error<JITLinkError>(
825-
"Error adding keep-alive edge for compact unwind record at " +
826-
formatv("{0:x}", CURec->getAddress()) + ": target " +
827-
*E.getTarget().getName() + " is an external symbol");
828-
auto &TgtBlock = E.getTarget().getBlock();
829-
auto &CURecSym =
830-
G.addAnonymousSymbol(*CURec, 0, CURecordSize, false, false);
831-
TgtBlock.addEdge(Edge::KeepAlive, 0, CURecSym, 0);
832-
AddedKeepAlive = true;
833-
} else if (E.getOffset() != PersonalityEdgeOffset &&
834-
E.getOffset() != LSDAEdgeOffset)
835-
return make_error<JITLinkError>(
836-
"Unexpected edge at offset " + formatv("{0:x}", E.getOffset()) +
837-
" in compact unwind record at " +
838-
formatv("{0:x}", CURec->getAddress()));
839-
}
840-
841-
if (!AddedKeepAlive)
842-
return make_error<JITLinkError>(
843-
"Error adding keep-alive edge for compact unwind record at " +
844-
formatv("{0:x}", CURec->getAddress()) +
845-
": no outgoing target edge at offset 0");
846-
}
847-
}
848-
849-
return Error::success();
850-
}
851-
852736
} // end namespace jitlink
853737
} // end namespace llvm

llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,6 @@ class MachOLinkGraphBuilder {
236236
StringMap<SectionParserFunction> CustomSectionParserFunctions;
237237
};
238238

239-
/// A pass to split up __LD,__compact_unwind sections.
240-
class CompactUnwindSplitter {
241-
public:
242-
CompactUnwindSplitter(StringRef CompactUnwindSectionName)
243-
: CompactUnwindSectionName(CompactUnwindSectionName) {}
244-
Error operator()(LinkGraph &G);
245-
246-
private:
247-
StringRef CompactUnwindSectionName;
248-
};
249-
250239
} // end namespace jitlink
251240
} // end namespace llvm
252241

llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
1515
#include "llvm/ExecutionEngine/JITLink/aarch64.h"
1616

17+
#include "CompactUnwindSupport.h"
1718
#include "DefineExternalSectionStartAndEndSymbols.h"
1819
#include "MachOLinkGraphBuilder.h"
1920

@@ -625,6 +626,27 @@ static Error applyPACSigningToModInitPointers(LinkGraph &G) {
625626
return Error::success();
626627
}
627628

629+
struct CompactUnwindTraits_MachO_arm64
630+
: public CompactUnwindTraits<CompactUnwindTraits_MachO_arm64,
631+
/* PointerSize = */ 8> {
632+
// FIXME: Reinstate once we no longer need the MSVC workaround. See
633+
// FIXME for CompactUnwindTraits in CompactUnwindSupport.h.
634+
// constexpr static size_t PointerSize = 8;
635+
636+
constexpr static endianness Endianness = endianness::little;
637+
638+
constexpr static uint32_t EncodingModeMask = 0x0f000000;
639+
640+
using GOTManager = aarch64::GOTTableManager;
641+
642+
static bool encodingSpecifiesDWARF(uint32_t Encoding) {
643+
constexpr uint32_t DWARFMode = 0x03000000;
644+
return (Encoding & EncodingModeMask) == DWARFMode;
645+
}
646+
647+
static bool encodingCannotBeMerged(uint32_t Encoding) { return false; }
648+
};
649+
628650
void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
629651
std::unique_ptr<JITLinkContext> Ctx) {
630652

@@ -637,16 +659,21 @@ void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
637659
else
638660
Config.PrePrunePasses.push_back(markAllSymbolsLive);
639661

640-
// Add compact unwind splitter pass.
641-
Config.PrePrunePasses.push_back(
642-
CompactUnwindSplitter("__LD,__compact_unwind"));
643-
644662
// Add eh-frame passes.
645-
// FIXME: Prune eh-frames for which compact-unwind is available once
646-
// we support compact-unwind registration with libunwind.
647663
Config.PrePrunePasses.push_back(createEHFrameSplitterPass_MachO_arm64());
648664
Config.PrePrunePasses.push_back(createEHFrameEdgeFixerPass_MachO_arm64());
649665

666+
// Create a compact-unwind manager for use in passes below.
667+
auto CompactUnwindMgr =
668+
std::make_shared<CompactUnwindManager<CompactUnwindTraits_MachO_arm64>>(
669+
"__LD,__compact_unwind", "__TEXT,__unwind_info",
670+
"__TEXT,__eh_frame");
671+
672+
// Add compact unwind prepare pass.
673+
Config.PrePrunePasses.push_back([CompactUnwindMgr](LinkGraph &G) {
674+
return CompactUnwindMgr->prepareForPrune(G);
675+
});
676+
650677
// Resolve any external section start / end symbols.
651678
Config.PostAllocationPasses.push_back(
652679
createDefineExternalSectionStartAndEndSymbolsPass(
@@ -663,6 +690,16 @@ void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
663690
Config.PreFixupPasses.push_back(
664691
aarch64::lowerPointer64AuthEdgesToSigningFunction);
665692
}
693+
694+
// Reserve unwind-info space.
695+
Config.PostPrunePasses.push_back([CompactUnwindMgr](LinkGraph &G) {
696+
return CompactUnwindMgr->processAndReserveUnwindInfo(G);
697+
});
698+
699+
// Translate compact-unwind to unwind-info.
700+
Config.PreFixupPasses.push_back([CompactUnwindMgr](LinkGraph &G) {
701+
return CompactUnwindMgr->writeUnwindInfo(G);
702+
});
666703
}
667704

668705
if (auto Err = Ctx->modifyPassConfig(*G, Config))

llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
1515
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
1616

17+
#include "CompactUnwindSupport.h"
1718
#include "DefineExternalSectionStartAndEndSymbols.h"
1819
#include "MachOLinkGraphBuilder.h"
1920

@@ -500,26 +501,56 @@ Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_x86_64(
500501
.buildGraph();
501502
}
502503

504+
struct CompactUnwindTraits_MachO_x86_64
505+
: public CompactUnwindTraits<CompactUnwindTraits_MachO_x86_64,
506+
/* PointerSize = */ 8> {
507+
// FIXME: Reinstate once we no longer need the MSVC workaround. See
508+
// FIXME for CompactUnwindTraits in CompactUnwindSupport.h.
509+
// constexpr static size_t PointerSize = 8;
510+
511+
constexpr static endianness Endianness = endianness::little;
512+
513+
constexpr static uint32_t EncodingModeMask = 0x0f000000;
514+
515+
using GOTManager = x86_64::GOTTableManager;
516+
517+
static bool encodingSpecifiesDWARF(uint32_t Encoding) {
518+
constexpr uint32_t DWARFMode = 0x04000000;
519+
return (Encoding & EncodingModeMask) == DWARFMode;
520+
}
521+
522+
static bool encodingCannotBeMerged(uint32_t Encoding) {
523+
constexpr uint32_t StackIndirectMode = 0x03000000;
524+
return (Encoding & EncodingModeMask) == StackIndirectMode;
525+
}
526+
};
527+
503528
void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
504529
std::unique_ptr<JITLinkContext> Ctx) {
505530

506531
PassConfiguration Config;
507532

508533
if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {
509-
// Add eh-frame passes.
510-
Config.PrePrunePasses.push_back(createEHFrameSplitterPass_MachO_x86_64());
511-
Config.PrePrunePasses.push_back(createEHFrameEdgeFixerPass_MachO_x86_64());
512-
513-
// Add compact unwind splitter pass.
514-
Config.PrePrunePasses.push_back(
515-
CompactUnwindSplitter("__LD,__compact_unwind"));
516-
517534
// Add a mark-live pass.
518535
if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))
519536
Config.PrePrunePasses.push_back(std::move(MarkLive));
520537
else
521538
Config.PrePrunePasses.push_back(markAllSymbolsLive);
522539

540+
// Add eh-frame passes.
541+
Config.PrePrunePasses.push_back(createEHFrameSplitterPass_MachO_x86_64());
542+
Config.PrePrunePasses.push_back(createEHFrameEdgeFixerPass_MachO_x86_64());
543+
544+
// Create a compact-unwind manager for use in passes below.
545+
auto CompactUnwindMgr = std::make_shared<
546+
CompactUnwindManager<CompactUnwindTraits_MachO_x86_64>>(
547+
"__LD,__compact_unwind", "__TEXT,__unwind_info", "__TEXT,__eh_frame");
548+
549+
// Add compact unwind prepare pass.
550+
Config.PrePrunePasses.push_back([CompactUnwindMgr](LinkGraph &G) {
551+
return CompactUnwindMgr->prepareForPrune(G);
552+
});
553+
523554
// Resolve any external section start / end symbols.
524555
Config.PostAllocationPasses.push_back(
525556
createDefineExternalSectionStartAndEndSymbolsPass(
@@ -528,6 +559,16 @@ void link_MachO_x86_64(std::unique_ptr<LinkGraph> G,
528559
// Add an in-place GOT/Stubs pass.
529560
Config.PostPrunePasses.push_back(buildGOTAndStubs_MachO_x86_64);
530561

562+
// Reserve space for unwind-info.
563+
Config.PostPrunePasses.push_back([CompactUnwindMgr](LinkGraph &G) {
564+
return CompactUnwindMgr->processAndReserveUnwindInfo(G);
565+
});
566+
567+
// Translate compact-unwind to unwind-info.
568+
Config.PreFixupPasses.push_back([CompactUnwindMgr](LinkGraph &G) {
569+
return CompactUnwindMgr->writeUnwindInfo(G);
570+
});
571+
531572
// Add GOT/Stubs optimizer pass.
532573
Config.PreFixupPasses.push_back(x86_64::optimizeGOTAndStubAccesses);
533574
}

llvm/lib/ExecutionEngine/Orc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_llvm_component_library(LLVMOrcJIT
5757
ExecutorProcessControl.cpp
5858
TaskDispatch.cpp
5959
ThreadSafeModule.cpp
60+
UnwindInfoRegistrationPlugin.cpp
6061
RedirectionManager.cpp
6162
JITLinkRedirectableSymbolManager.cpp
6263
ReOptimizeLayer.cpp

0 commit comments

Comments
 (0)