185fb9976SLang Hames //===------ MachOPlatform.cpp - Utilities for executing MachO in Orc ------===//
285fb9976SLang Hames //
385fb9976SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
485fb9976SLang Hames // See https://llvm.org/LICENSE.txt for license information.
585fb9976SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
685fb9976SLang Hames //
785fb9976SLang Hames //===----------------------------------------------------------------------===//
885fb9976SLang Hames
985fb9976SLang Hames #include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
1085fb9976SLang Hames
1185fb9976SLang Hames #include "llvm/BinaryFormat/MachO.h"
12bb5f97e3SLang Hames #include "llvm/ExecutionEngine/JITLink/x86_64.h"
1338a8760bSLang Hames #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
14bb5f97e3SLang Hames #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
1564288571SLang Hames #include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
1685fb9976SLang Hames #include "llvm/Support/BinaryByteStream.h"
178363ff04SLang Hames #include "llvm/Support/Debug.h"
188363ff04SLang Hames
198363ff04SLang Hames #define DEBUG_TYPE "orc"
2085fb9976SLang Hames
21bb5f97e3SLang Hames using namespace llvm;
22bb5f97e3SLang Hames using namespace llvm::orc;
23bb5f97e3SLang Hames using namespace llvm::orc::shared;
24bb5f97e3SLang Hames
25f9aef477SLang Hames namespace llvm {
26f9aef477SLang Hames namespace orc {
27f9aef477SLang Hames namespace shared {
28f9aef477SLang Hames
29f9aef477SLang Hames using SPSMachOJITDylibDepInfo = SPSTuple<bool, SPSSequence<SPSExecutorAddr>>;
30f9aef477SLang Hames using SPSMachOJITDylibDepInfoMap =
31f9aef477SLang Hames SPSSequence<SPSTuple<SPSExecutorAddr, SPSMachOJITDylibDepInfo>>;
32f9aef477SLang Hames
33f9aef477SLang Hames template <>
34f9aef477SLang Hames class SPSSerializationTraits<SPSMachOJITDylibDepInfo,
35f9aef477SLang Hames MachOPlatform::MachOJITDylibDepInfo> {
36f9aef477SLang Hames public:
size(const MachOPlatform::MachOJITDylibDepInfo & DDI)37f9aef477SLang Hames static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI) {
38f9aef477SLang Hames return SPSMachOJITDylibDepInfo::AsArgList::size(DDI.Sealed, DDI.DepHeaders);
39f9aef477SLang Hames }
40f9aef477SLang Hames
serialize(SPSOutputBuffer & OB,const MachOPlatform::MachOJITDylibDepInfo & DDI)41f9aef477SLang Hames static bool serialize(SPSOutputBuffer &OB,
42f9aef477SLang Hames const MachOPlatform::MachOJITDylibDepInfo &DDI) {
43f9aef477SLang Hames return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.Sealed,
44f9aef477SLang Hames DDI.DepHeaders);
45f9aef477SLang Hames }
46f9aef477SLang Hames
deserialize(SPSInputBuffer & IB,MachOPlatform::MachOJITDylibDepInfo & DDI)47f9aef477SLang Hames static bool deserialize(SPSInputBuffer &IB,
48f9aef477SLang Hames MachOPlatform::MachOJITDylibDepInfo &DDI) {
49f9aef477SLang Hames return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.Sealed,
50f9aef477SLang Hames DDI.DepHeaders);
51f9aef477SLang Hames }
52f9aef477SLang Hames };
53f9aef477SLang Hames
54f9aef477SLang Hames } // namespace shared
55f9aef477SLang Hames } // namespace orc
56f9aef477SLang Hames } // namespace llvm
57f9aef477SLang Hames
58bb5f97e3SLang Hames namespace {
59bb5f97e3SLang Hames
60bb5f97e3SLang Hames class MachOHeaderMaterializationUnit : public MaterializationUnit {
61bb5f97e3SLang Hames public:
MachOHeaderMaterializationUnit(MachOPlatform & MOP,const SymbolStringPtr & HeaderStartSymbol)62bb5f97e3SLang Hames MachOHeaderMaterializationUnit(MachOPlatform &MOP,
63bb5f97e3SLang Hames const SymbolStringPtr &HeaderStartSymbol)
64ae73f3fdSLang Hames : MaterializationUnit(createHeaderInterface(MOP, HeaderStartSymbol)),
65bb5f97e3SLang Hames MOP(MOP) {}
66bb5f97e3SLang Hames
getName() const67bb5f97e3SLang Hames StringRef getName() const override { return "MachOHeaderMU"; }
68bb5f97e3SLang Hames
materialize(std::unique_ptr<MaterializationResponsibility> R)69bb5f97e3SLang Hames void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
70bb5f97e3SLang Hames unsigned PointerSize;
71bb5f97e3SLang Hames support::endianness Endianness;
722487db1fSLang Hames const auto &TT =
732487db1fSLang Hames MOP.getExecutionSession().getExecutorProcessControl().getTargetTriple();
74bb5f97e3SLang Hames
752487db1fSLang Hames switch (TT.getArch()) {
76bb5f97e3SLang Hames case Triple::aarch64:
77bb5f97e3SLang Hames case Triple::x86_64:
78bb5f97e3SLang Hames PointerSize = 8;
79bb5f97e3SLang Hames Endianness = support::endianness::little;
80bb5f97e3SLang Hames break;
81bb5f97e3SLang Hames default:
82bb5f97e3SLang Hames llvm_unreachable("Unrecognized architecture");
83bb5f97e3SLang Hames }
84bb5f97e3SLang Hames
85bb5f97e3SLang Hames auto G = std::make_unique<jitlink::LinkGraph>(
862487db1fSLang Hames "<MachOHeaderMU>", TT, PointerSize, Endianness,
872487db1fSLang Hames jitlink::getGenericEdgeKindName);
88962a2479SLang Hames auto &HeaderSection = G->createSection("__header", jitlink::MemProt::Read);
89bb5f97e3SLang Hames auto &HeaderBlock = createHeaderBlock(*G, HeaderSection);
90bb5f97e3SLang Hames
91bb5f97e3SLang Hames // Init symbol is header-start symbol.
92bb5f97e3SLang Hames G->addDefinedSymbol(HeaderBlock, 0, *R->getInitializerSymbol(),
93bb5f97e3SLang Hames HeaderBlock.getSize(), jitlink::Linkage::Strong,
94bb5f97e3SLang Hames jitlink::Scope::Default, false, true);
95bb5f97e3SLang Hames for (auto &HS : AdditionalHeaderSymbols)
96bb5f97e3SLang Hames G->addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name,
97bb5f97e3SLang Hames HeaderBlock.getSize(), jitlink::Linkage::Strong,
98bb5f97e3SLang Hames jitlink::Scope::Default, false, true);
99bb5f97e3SLang Hames
100bb5f97e3SLang Hames MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));
101bb5f97e3SLang Hames }
102bb5f97e3SLang Hames
discard(const JITDylib & JD,const SymbolStringPtr & Sym)103bb5f97e3SLang Hames void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}
104bb5f97e3SLang Hames
105bb5f97e3SLang Hames private:
106bb5f97e3SLang Hames struct HeaderSymbol {
107bb5f97e3SLang Hames const char *Name;
108bb5f97e3SLang Hames uint64_t Offset;
109bb5f97e3SLang Hames };
110bb5f97e3SLang Hames
111bb5f97e3SLang Hames static constexpr HeaderSymbol AdditionalHeaderSymbols[] = {
112bb5f97e3SLang Hames {"___mh_executable_header", 0}};
113bb5f97e3SLang Hames
createHeaderBlock(jitlink::LinkGraph & G,jitlink::Section & HeaderSection)114bb5f97e3SLang Hames static jitlink::Block &createHeaderBlock(jitlink::LinkGraph &G,
115bb5f97e3SLang Hames jitlink::Section &HeaderSection) {
116bb5f97e3SLang Hames MachO::mach_header_64 Hdr;
117bb5f97e3SLang Hames Hdr.magic = MachO::MH_MAGIC_64;
118bb5f97e3SLang Hames switch (G.getTargetTriple().getArch()) {
119bb5f97e3SLang Hames case Triple::aarch64:
120bb5f97e3SLang Hames Hdr.cputype = MachO::CPU_TYPE_ARM64;
121bb5f97e3SLang Hames Hdr.cpusubtype = MachO::CPU_SUBTYPE_ARM64_ALL;
122bb5f97e3SLang Hames break;
123bb5f97e3SLang Hames case Triple::x86_64:
124bb5f97e3SLang Hames Hdr.cputype = MachO::CPU_TYPE_X86_64;
125bb5f97e3SLang Hames Hdr.cpusubtype = MachO::CPU_SUBTYPE_X86_64_ALL;
126bb5f97e3SLang Hames break;
127bb5f97e3SLang Hames default:
128bb5f97e3SLang Hames llvm_unreachable("Unrecognized architecture");
129bb5f97e3SLang Hames }
130bb5f97e3SLang Hames Hdr.filetype = MachO::MH_DYLIB; // Custom file type?
131bb5f97e3SLang Hames Hdr.ncmds = 0;
132bb5f97e3SLang Hames Hdr.sizeofcmds = 0;
133bb5f97e3SLang Hames Hdr.flags = 0;
134bb5f97e3SLang Hames Hdr.reserved = 0;
135bb5f97e3SLang Hames
136bb5f97e3SLang Hames if (G.getEndianness() != support::endian::system_endianness())
137bb5f97e3SLang Hames MachO::swapStruct(Hdr);
138bb5f97e3SLang Hames
139bb5f97e3SLang Hames auto HeaderContent = G.allocateString(
140bb5f97e3SLang Hames StringRef(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
141bb5f97e3SLang Hames
142089acf25SLang Hames return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
143089acf25SLang Hames 0);
144bb5f97e3SLang Hames }
145bb5f97e3SLang Hames
146ae73f3fdSLang Hames static MaterializationUnit::Interface
createHeaderInterface(MachOPlatform & MOP,const SymbolStringPtr & HeaderStartSymbol)147ae73f3fdSLang Hames createHeaderInterface(MachOPlatform &MOP,
148bb5f97e3SLang Hames const SymbolStringPtr &HeaderStartSymbol) {
149bb5f97e3SLang Hames SymbolFlagsMap HeaderSymbolFlags;
150bb5f97e3SLang Hames
151bb5f97e3SLang Hames HeaderSymbolFlags[HeaderStartSymbol] = JITSymbolFlags::Exported;
152bb5f97e3SLang Hames for (auto &HS : AdditionalHeaderSymbols)
153bb5f97e3SLang Hames HeaderSymbolFlags[MOP.getExecutionSession().intern(HS.Name)] =
154bb5f97e3SLang Hames JITSymbolFlags::Exported;
155bb5f97e3SLang Hames
156ae73f3fdSLang Hames return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),
157ae73f3fdSLang Hames HeaderStartSymbol);
158bb5f97e3SLang Hames }
159bb5f97e3SLang Hames
160bb5f97e3SLang Hames MachOPlatform &MOP;
161bb5f97e3SLang Hames };
162bb5f97e3SLang Hames
163bb5f97e3SLang Hames constexpr MachOHeaderMaterializationUnit::HeaderSymbol
164bb5f97e3SLang Hames MachOHeaderMaterializationUnit::AdditionalHeaderSymbols[];
165bb5f97e3SLang Hames
166bb5f97e3SLang Hames StringRef EHFrameSectionName = "__TEXT,__eh_frame";
167bb5f97e3SLang Hames StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
168cdcc3547SLang Hames StringRef ObjCClassListSectionName = "__DATA,__objc_classlist";
169cdcc3547SLang Hames StringRef ObjCImageInfoSectionName = "__DATA,__objc_image_info";
170cdcc3547SLang Hames StringRef ObjCSelRefsSectionName = "__DATA,__objc_selrefs";
171cdcc3547SLang Hames StringRef Swift5ProtoSectionName = "__TEXT,__swift5_proto";
172cdcc3547SLang Hames StringRef Swift5ProtosSectionName = "__TEXT,__swift5_protos";
1732a739f27SBen Langmuir StringRef Swift5TypesSectionName = "__TEXT,__swift5_types";
174eda6afdaSLang Hames StringRef ThreadBSSSectionName = "__DATA,__thread_bss";
175eda6afdaSLang Hames StringRef ThreadDataSectionName = "__DATA,__thread_data";
176eda6afdaSLang Hames StringRef ThreadVarsSectionName = "__DATA,__thread_vars";
177bb5f97e3SLang Hames
178cdcc3547SLang Hames StringRef InitSectionNames[] = {
179cdcc3547SLang Hames ModInitFuncSectionName, ObjCSelRefsSectionName, ObjCClassListSectionName,
1802a739f27SBen Langmuir Swift5ProtosSectionName, Swift5ProtoSectionName, Swift5TypesSectionName};
181bb5f97e3SLang Hames
182bb5f97e3SLang Hames } // end anonymous namespace
183bb5f97e3SLang Hames
18485fb9976SLang Hames namespace llvm {
18585fb9976SLang Hames namespace orc {
18685fb9976SLang Hames
187bb5f97e3SLang Hames Expected<std::unique_ptr<MachOPlatform>>
Create(ExecutionSession & ES,ObjectLinkingLayer & ObjLinkingLayer,JITDylib & PlatformJD,const char * OrcRuntimePath,Optional<SymbolAliasMap> RuntimeAliases)188bb5f97e3SLang Hames MachOPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
1892487db1fSLang Hames JITDylib &PlatformJD, const char *OrcRuntimePath,
190bb5f97e3SLang Hames Optional<SymbolAliasMap> RuntimeAliases) {
191bb5f97e3SLang Hames
1922487db1fSLang Hames auto &EPC = ES.getExecutorProcessControl();
1932487db1fSLang Hames
194bb5f97e3SLang Hames // If the target is not supported then bail out immediately.
195bb5f97e3SLang Hames if (!supportedTarget(EPC.getTargetTriple()))
196bb5f97e3SLang Hames return make_error<StringError>("Unsupported MachOPlatform triple: " +
197bb5f97e3SLang Hames EPC.getTargetTriple().str(),
198bb5f97e3SLang Hames inconvertibleErrorCode());
199bb5f97e3SLang Hames
200bb5f97e3SLang Hames // Create default aliases if the caller didn't supply any.
201bb5f97e3SLang Hames if (!RuntimeAliases)
202bb5f97e3SLang Hames RuntimeAliases = standardPlatformAliases(ES);
203bb5f97e3SLang Hames
204bb5f97e3SLang Hames // Define the aliases.
205bb5f97e3SLang Hames if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))
206bb5f97e3SLang Hames return std::move(Err);
207bb5f97e3SLang Hames
208bb5f97e3SLang Hames // Add JIT-dispatch function support symbols.
209bb5f97e3SLang Hames if (auto Err = PlatformJD.define(absoluteSymbols(
210bb5f97e3SLang Hames {{ES.intern("___orc_rt_jit_dispatch"),
211ef391df2SLang Hames {EPC.getJITDispatchInfo().JITDispatchFunction.getValue(),
212bb5f97e3SLang Hames JITSymbolFlags::Exported}},
213bb5f97e3SLang Hames {ES.intern("___orc_rt_jit_dispatch_ctx"),
214ef391df2SLang Hames {EPC.getJITDispatchInfo().JITDispatchContext.getValue(),
215bb5f97e3SLang Hames JITSymbolFlags::Exported}}})))
216bb5f97e3SLang Hames return std::move(Err);
217bb5f97e3SLang Hames
218bb5f97e3SLang Hames // Create a generator for the ORC runtime archive.
219bb5f97e3SLang Hames auto OrcRuntimeArchiveGenerator = StaticLibraryDefinitionGenerator::Load(
220bb5f97e3SLang Hames ObjLinkingLayer, OrcRuntimePath, EPC.getTargetTriple());
221bb5f97e3SLang Hames if (!OrcRuntimeArchiveGenerator)
222bb5f97e3SLang Hames return OrcRuntimeArchiveGenerator.takeError();
223bb5f97e3SLang Hames
224bb5f97e3SLang Hames // Create the instance.
225bb5f97e3SLang Hames Error Err = Error::success();
226bb5f97e3SLang Hames auto P = std::unique_ptr<MachOPlatform>(
2272487db1fSLang Hames new MachOPlatform(ES, ObjLinkingLayer, PlatformJD,
228bb5f97e3SLang Hames std::move(*OrcRuntimeArchiveGenerator), Err));
229bb5f97e3SLang Hames if (Err)
230bb5f97e3SLang Hames return std::move(Err);
231bb5f97e3SLang Hames return std::move(P);
23285fb9976SLang Hames }
23385fb9976SLang Hames
setupJITDylib(JITDylib & JD)23485fb9976SLang Hames Error MachOPlatform::setupJITDylib(JITDylib &JD) {
235f9aef477SLang Hames if (auto Err = JD.define(std::make_unique<MachOHeaderMaterializationUnit>(
236f9aef477SLang Hames *this, MachOHeaderStartSymbol)))
237f9aef477SLang Hames return Err;
238f9aef477SLang Hames
239f9aef477SLang Hames return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
24085fb9976SLang Hames }
24185fb9976SLang Hames
teardownJITDylib(JITDylib & JD)242f9aef477SLang Hames Error MachOPlatform::teardownJITDylib(JITDylib &JD) {
243f9aef477SLang Hames std::lock_guard<std::mutex> Lock(PlatformMutex);
244f9aef477SLang Hames auto I = JITDylibToHeaderAddr.find(&JD);
245f9aef477SLang Hames if (I != JITDylibToHeaderAddr.end()) {
246f9aef477SLang Hames assert(HeaderAddrToJITDylib.count(I->second) &&
247f9aef477SLang Hames "HeaderAddrToJITDylib missing entry");
248f9aef477SLang Hames HeaderAddrToJITDylib.erase(I->second);
249f9aef477SLang Hames JITDylibToHeaderAddr.erase(I);
250f9aef477SLang Hames }
251f9aef477SLang Hames JITDylibToPThreadKey.erase(&JD);
252f9aef477SLang Hames return Error::success();
253f9aef477SLang Hames }
254ade71641SLang Hames
notifyAdding(ResourceTracker & RT,const MaterializationUnit & MU)2550aec49c8SLang Hames Error MachOPlatform::notifyAdding(ResourceTracker &RT,
2560aec49c8SLang Hames const MaterializationUnit &MU) {
2570aec49c8SLang Hames auto &JD = RT.getJITDylib();
25885fb9976SLang Hames const auto &InitSym = MU.getInitializerSymbol();
25985fb9976SLang Hames if (!InitSym)
26085fb9976SLang Hames return Error::success();
26185fb9976SLang Hames
262cb84e482SLang Hames RegisteredInitSymbols[&JD].add(InitSym,
263cb84e482SLang Hames SymbolLookupFlags::WeaklyReferencedSymbol);
2648363ff04SLang Hames LLVM_DEBUG({
2658363ff04SLang Hames dbgs() << "MachOPlatform: Registered init symbol " << *InitSym << " for MU "
2668363ff04SLang Hames << MU.getName() << "\n";
2678363ff04SLang Hames });
26885fb9976SLang Hames return Error::success();
26985fb9976SLang Hames }
27085fb9976SLang Hames
notifyRemoving(ResourceTracker & RT)2710aec49c8SLang Hames Error MachOPlatform::notifyRemoving(ResourceTracker &RT) {
27285fb9976SLang Hames llvm_unreachable("Not supported yet");
27385fb9976SLang Hames }
27485fb9976SLang Hames
addAliases(ExecutionSession & ES,SymbolAliasMap & Aliases,ArrayRef<std::pair<const char *,const char * >> AL)275bb5f97e3SLang Hames static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
276bb5f97e3SLang Hames ArrayRef<std::pair<const char *, const char *>> AL) {
277bb5f97e3SLang Hames for (auto &KV : AL) {
278bb5f97e3SLang Hames auto AliasName = ES.intern(KV.first);
279bb5f97e3SLang Hames assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
280bb5f97e3SLang Hames Aliases[std::move(AliasName)] = {ES.intern(KV.second),
281bb5f97e3SLang Hames JITSymbolFlags::Exported};
282bb5f97e3SLang Hames }
283bb5f97e3SLang Hames }
28485fb9976SLang Hames
standardPlatformAliases(ExecutionSession & ES)285bb5f97e3SLang Hames SymbolAliasMap MachOPlatform::standardPlatformAliases(ExecutionSession &ES) {
286bb5f97e3SLang Hames SymbolAliasMap Aliases;
287bb5f97e3SLang Hames addAliases(ES, Aliases, requiredCXXAliases());
288bb5f97e3SLang Hames addAliases(ES, Aliases, standardRuntimeUtilityAliases());
289bb5f97e3SLang Hames return Aliases;
290bb5f97e3SLang Hames }
291bb5f97e3SLang Hames
292bb5f97e3SLang Hames ArrayRef<std::pair<const char *, const char *>>
requiredCXXAliases()293bb5f97e3SLang Hames MachOPlatform::requiredCXXAliases() {
294bb5f97e3SLang Hames static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
295bb5f97e3SLang Hames {"___cxa_atexit", "___orc_rt_macho_cxa_atexit"}};
296bb5f97e3SLang Hames
297df477706SLang Hames return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases);
298bb5f97e3SLang Hames }
299bb5f97e3SLang Hames
300bb5f97e3SLang Hames ArrayRef<std::pair<const char *, const char *>>
standardRuntimeUtilityAliases()301bb5f97e3SLang Hames MachOPlatform::standardRuntimeUtilityAliases() {
302bb5f97e3SLang Hames static const std::pair<const char *, const char *>
303bb5f97e3SLang Hames StandardRuntimeUtilityAliases[] = {
304bb5f97e3SLang Hames {"___orc_rt_run_program", "___orc_rt_macho_run_program"},
305*1aa71f86SPeter S. Housel {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
306*1aa71f86SPeter S. Housel {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
307*1aa71f86SPeter S. Housel {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
308*1aa71f86SPeter S. Housel {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
309bb5f97e3SLang Hames {"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
310bb5f97e3SLang Hames
311df477706SLang Hames return ArrayRef<std::pair<const char *, const char *>>(
312df477706SLang Hames StandardRuntimeUtilityAliases);
313bb5f97e3SLang Hames }
314bb5f97e3SLang Hames
isInitializerSection(StringRef SegName,StringRef SectName)315cdcc3547SLang Hames bool MachOPlatform::isInitializerSection(StringRef SegName,
316cdcc3547SLang Hames StringRef SectName) {
317cdcc3547SLang Hames for (auto &Name : InitSectionNames) {
318cdcc3547SLang Hames if (Name.startswith(SegName) && Name.substr(7) == SectName)
319cdcc3547SLang Hames return true;
320cdcc3547SLang Hames }
321cdcc3547SLang Hames return false;
322cdcc3547SLang Hames }
323cdcc3547SLang Hames
supportedTarget(const Triple & TT)324bb5f97e3SLang Hames bool MachOPlatform::supportedTarget(const Triple &TT) {
325bb5f97e3SLang Hames switch (TT.getArch()) {
3263d13ee28SBen Langmuir case Triple::aarch64:
327bb5f97e3SLang Hames case Triple::x86_64:
328bb5f97e3SLang Hames return true;
329bb5f97e3SLang Hames default:
330bb5f97e3SLang Hames return false;
331bb5f97e3SLang Hames }
332bb5f97e3SLang Hames }
333bb5f97e3SLang Hames
MachOPlatform(ExecutionSession & ES,ObjectLinkingLayer & ObjLinkingLayer,JITDylib & PlatformJD,std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,Error & Err)334bb5f97e3SLang Hames MachOPlatform::MachOPlatform(
335bb5f97e3SLang Hames ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
3362487db1fSLang Hames JITDylib &PlatformJD,
337bb5f97e3SLang Hames std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator, Error &Err)
3382487db1fSLang Hames : ES(ES), ObjLinkingLayer(ObjLinkingLayer),
339bb5f97e3SLang Hames MachOHeaderStartSymbol(ES.intern("___dso_handle")) {
340bb5f97e3SLang Hames ErrorAsOutParameter _(&Err);
341bb5f97e3SLang Hames
342bb5f97e3SLang Hames ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*this));
343bb5f97e3SLang Hames
344bb5f97e3SLang Hames PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
345bb5f97e3SLang Hames
346ff846fcbSLang Hames // Force linking of eh-frame registration functions.
347ff846fcbSLang Hames if (auto Err2 = lookupAndRecordAddrs(
348ff846fcbSLang Hames ES, LookupKind::Static, makeJITDylibSearchOrder(&PlatformJD),
349ff846fcbSLang Hames {{ES.intern("___orc_rt_macho_register_ehframe_section"),
350ff846fcbSLang Hames &orc_rt_macho_register_ehframe_section},
351ff846fcbSLang Hames {ES.intern("___orc_rt_macho_deregister_ehframe_section"),
352ff846fcbSLang Hames &orc_rt_macho_deregister_ehframe_section}})) {
353ff846fcbSLang Hames Err = std::move(Err2);
354ff846fcbSLang Hames return;
355ff846fcbSLang Hames }
356ff846fcbSLang Hames
357ff846fcbSLang Hames State = BootstrapPhase2;
358ff846fcbSLang Hames
359bb5f97e3SLang Hames // Associate wrapper function tags with JIT-side function implementations.
360bb5f97e3SLang Hames if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
361bb5f97e3SLang Hames Err = std::move(E2);
362bb5f97e3SLang Hames return;
363bb5f97e3SLang Hames }
364bb5f97e3SLang Hames
365bb5f97e3SLang Hames // Lookup addresses of runtime functions callable by the platform,
366bb5f97e3SLang Hames // call the platform bootstrap function to initialize the platform-state
367bb5f97e3SLang Hames // object in the executor.
368bb5f97e3SLang Hames if (auto E2 = bootstrapMachORuntime(PlatformJD)) {
369bb5f97e3SLang Hames Err = std::move(E2);
370bb5f97e3SLang Hames return;
371bb5f97e3SLang Hames }
372ff846fcbSLang Hames
373f9aef477SLang Hames // PlatformJD hasn't been set up by the platform yet (since we're creating
374f9aef477SLang Hames // the platform now), so set it up.
375f9aef477SLang Hames if (auto E2 = setupJITDylib(PlatformJD)) {
376f9aef477SLang Hames Err = std::move(E2);
377f9aef477SLang Hames return;
378f9aef477SLang Hames }
379f9aef477SLang Hames
380ff846fcbSLang Hames State = Initialized;
381bb5f97e3SLang Hames }
382bb5f97e3SLang Hames
associateRuntimeSupportFunctions(JITDylib & PlatformJD)383bb5f97e3SLang Hames Error MachOPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
3842487db1fSLang Hames ExecutionSession::JITDispatchHandlerAssociationMap WFs;
385bb5f97e3SLang Hames
386f9aef477SLang Hames using PushInitializersSPSSig =
387f9aef477SLang Hames SPSExpected<SPSMachOJITDylibDepInfoMap>(SPSExecutorAddr);
388f9aef477SLang Hames WFs[ES.intern("___orc_rt_macho_push_initializers_tag")] =
389f9aef477SLang Hames ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
390f9aef477SLang Hames this, &MachOPlatform::rt_pushInitializers);
391bb5f97e3SLang Hames
392bb5f97e3SLang Hames using LookupSymbolSPSSig =
393ef391df2SLang Hames SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSString);
394bb5f97e3SLang Hames WFs[ES.intern("___orc_rt_macho_symbol_lookup_tag")] =
3952487db1fSLang Hames ES.wrapAsyncWithSPS<LookupSymbolSPSSig>(this,
396bb5f97e3SLang Hames &MachOPlatform::rt_lookupSymbol);
397bb5f97e3SLang Hames
3982487db1fSLang Hames return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
399bb5f97e3SLang Hames }
400bb5f97e3SLang Hames
pushInitializersLoop(PushInitializersSendResultFn SendResult,JITDylibSP JD)401f9aef477SLang Hames void MachOPlatform::pushInitializersLoop(
402f9aef477SLang Hames PushInitializersSendResultFn SendResult, JITDylibSP JD) {
40385fb9976SLang Hames DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
404f9aef477SLang Hames DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap;
405f9aef477SLang Hames SmallVector<JITDylib *, 16> Worklist({JD.get()});
406f9aef477SLang Hames
407eb918d8dSLang Hames ES.runSessionLocked([&]() {
408f9aef477SLang Hames while (!Worklist.empty()) {
409f9aef477SLang Hames // FIXME: Check for defunct dylibs.
410f9aef477SLang Hames
411f9aef477SLang Hames auto DepJD = Worklist.back();
412f9aef477SLang Hames Worklist.pop_back();
413f9aef477SLang Hames
414f9aef477SLang Hames // If we've already visited this JITDylib on this iteration then continue.
415f9aef477SLang Hames if (JDDepMap.count(DepJD))
416f9aef477SLang Hames continue;
417f9aef477SLang Hames
418f9aef477SLang Hames // Add dep info.
419f9aef477SLang Hames auto &DM = JDDepMap[DepJD];
420f9aef477SLang Hames DepJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) {
421f9aef477SLang Hames for (auto &KV : O) {
422f9aef477SLang Hames if (KV.first == DepJD)
423f9aef477SLang Hames continue;
424f9aef477SLang Hames DM.push_back(KV.first);
425f9aef477SLang Hames Worklist.push_back(KV.first);
426f9aef477SLang Hames }
427f9aef477SLang Hames });
428f9aef477SLang Hames
429f9aef477SLang Hames // Add any registered init symbols.
430f9aef477SLang Hames auto RISItr = RegisteredInitSymbols.find(DepJD);
43185fb9976SLang Hames if (RISItr != RegisteredInitSymbols.end()) {
432f9aef477SLang Hames NewInitSymbols[DepJD] = std::move(RISItr->second);
43385fb9976SLang Hames RegisteredInitSymbols.erase(RISItr);
43485fb9976SLang Hames }
43585fb9976SLang Hames }
436eb918d8dSLang Hames });
43785fb9976SLang Hames
438f9aef477SLang Hames // If there are no further init symbols to look up then send the link order
439f9aef477SLang Hames // (as a list of header addresses) to the caller.
440bb5f97e3SLang Hames if (NewInitSymbols.empty()) {
441f9aef477SLang Hames
442f9aef477SLang Hames // To make the list intelligible to the runtime we need to convert all
443f9aef477SLang Hames // JITDylib pointers to their header addresses.
444f9aef477SLang Hames DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
445f9aef477SLang Hames HeaderAddrs.reserve(JDDepMap.size());
446f9aef477SLang Hames {
447f9aef477SLang Hames std::lock_guard<std::mutex> Lock(PlatformMutex);
448f9aef477SLang Hames for (auto &KV : JDDepMap) {
449f9aef477SLang Hames auto I = JITDylibToHeaderAddr.find(KV.first);
450f9aef477SLang Hames if (I == JITDylibToHeaderAddr.end()) {
451f9aef477SLang Hames // The header address should have been materialized by the previous
452f9aef477SLang Hames // round, but we need to handle the pathalogical case where someone
453f9aef477SLang Hames // removes the symbol on another thread while we're running.
454f9aef477SLang Hames SendResult(
455f9aef477SLang Hames make_error<StringError>("JITDylib " + KV.first->getName() +
456f9aef477SLang Hames " has no registered header address",
457f9aef477SLang Hames inconvertibleErrorCode()));
458f9aef477SLang Hames return;
459f9aef477SLang Hames }
460f9aef477SLang Hames HeaderAddrs[KV.first] = I->second;
461f9aef477SLang Hames }
462f9aef477SLang Hames }
463f9aef477SLang Hames
464f9aef477SLang Hames // Build the dep info map to return.
465f9aef477SLang Hames MachOJITDylibDepInfoMap DIM;
466f9aef477SLang Hames DIM.reserve(JDDepMap.size());
467f9aef477SLang Hames for (auto &KV : JDDepMap) {
468f9aef477SLang Hames assert(HeaderAddrs.count(KV.first) && "Missing header addr");
469f9aef477SLang Hames auto H = HeaderAddrs[KV.first];
470f9aef477SLang Hames MachOJITDylibDepInfo DepInfo;
471f9aef477SLang Hames for (auto &Dep : KV.second) {
472f9aef477SLang Hames assert(HeaderAddrs.count(Dep) && "Missing header addr");
473f9aef477SLang Hames DepInfo.DepHeaders.push_back(HeaderAddrs[Dep]);
474f9aef477SLang Hames }
475f9aef477SLang Hames DIM.push_back(std::make_pair(H, std::move(DepInfo)));
476f9aef477SLang Hames }
477f9aef477SLang Hames SendResult(DIM);
478c40ce0daSLang Hames return;
47985fb9976SLang Hames }
48085fb9976SLang Hames
481bb5f97e3SLang Hames // Otherwise issue a lookup and re-run this phase when it completes.
482bb5f97e3SLang Hames lookupInitSymbolsAsync(
483bb5f97e3SLang Hames [this, SendResult = std::move(SendResult), &JD](Error Err) mutable {
484bb5f97e3SLang Hames if (Err)
485bb5f97e3SLang Hames SendResult(std::move(Err));
486bb5f97e3SLang Hames else
487f9aef477SLang Hames pushInitializersLoop(std::move(SendResult), JD);
488bb5f97e3SLang Hames },
489bb5f97e3SLang Hames ES, std::move(NewInitSymbols));
490bb5f97e3SLang Hames }
491bb5f97e3SLang Hames
rt_pushInitializers(PushInitializersSendResultFn SendResult,ExecutorAddr JDHeaderAddr)492f9aef477SLang Hames void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
493f9aef477SLang Hames ExecutorAddr JDHeaderAddr) {
494f9aef477SLang Hames JITDylibSP JD;
495bb5f97e3SLang Hames {
496bb5f97e3SLang Hames std::lock_guard<std::mutex> Lock(PlatformMutex);
497f9aef477SLang Hames auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
498bb5f97e3SLang Hames if (I != HeaderAddrToJITDylib.end())
499bb5f97e3SLang Hames JD = I->second;
500bb5f97e3SLang Hames }
501bb5f97e3SLang Hames
502bb5f97e3SLang Hames LLVM_DEBUG({
503f9aef477SLang Hames dbgs() << "MachOPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";
504f9aef477SLang Hames if (JD)
505f9aef477SLang Hames dbgs() << "pushing initializers for " << JD->getName() << "\n";
506f9aef477SLang Hames else
507f9aef477SLang Hames dbgs() << "No JITDylib for header address.\n";
508bb5f97e3SLang Hames });
509f9aef477SLang Hames
510f9aef477SLang Hames if (!JD) {
511f9aef477SLang Hames SendResult(
512f9aef477SLang Hames make_error<StringError>("No JITDylib with header addr " +
513f9aef477SLang Hames formatv("{0:x}", JDHeaderAddr.getValue()),
514bb5f97e3SLang Hames inconvertibleErrorCode()));
515bb5f97e3SLang Hames return;
516bb5f97e3SLang Hames }
517bb5f97e3SLang Hames
518f9aef477SLang Hames pushInitializersLoop(std::move(SendResult), JD);
519bb5f97e3SLang Hames }
520bb5f97e3SLang Hames
rt_lookupSymbol(SendSymbolAddressFn SendResult,ExecutorAddr Handle,StringRef SymbolName)521bb5f97e3SLang Hames void MachOPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,
522ef391df2SLang Hames ExecutorAddr Handle, StringRef SymbolName) {
523bb5f97e3SLang Hames LLVM_DEBUG({
524bb5f97e3SLang Hames dbgs() << "MachOPlatform::rt_lookupSymbol(\""
525bb5f97e3SLang Hames << formatv("{0:x}", Handle.getValue()) << "\")\n";
526bb5f97e3SLang Hames });
527bb5f97e3SLang Hames
528bb5f97e3SLang Hames JITDylib *JD = nullptr;
529bb5f97e3SLang Hames
530bb5f97e3SLang Hames {
531bb5f97e3SLang Hames std::lock_guard<std::mutex> Lock(PlatformMutex);
532118e953bSLang Hames auto I = HeaderAddrToJITDylib.find(Handle);
533bb5f97e3SLang Hames if (I != HeaderAddrToJITDylib.end())
534bb5f97e3SLang Hames JD = I->second;
535bb5f97e3SLang Hames }
536bb5f97e3SLang Hames
537bb5f97e3SLang Hames if (!JD) {
538bb5f97e3SLang Hames LLVM_DEBUG({
539bb5f97e3SLang Hames dbgs() << " No JITDylib for handle "
540bb5f97e3SLang Hames << formatv("{0:x}", Handle.getValue()) << "\n";
541bb5f97e3SLang Hames });
542bb5f97e3SLang Hames SendResult(make_error<StringError>("No JITDylib associated with handle " +
543bb5f97e3SLang Hames formatv("{0:x}", Handle.getValue()),
544bb5f97e3SLang Hames inconvertibleErrorCode()));
545bb5f97e3SLang Hames return;
546bb5f97e3SLang Hames }
547bb5f97e3SLang Hames
548af5602d3SHubert Tong // Use functor class to work around XL build compiler issue on AIX.
549af5602d3SHubert Tong class RtLookupNotifyComplete {
550af5602d3SHubert Tong public:
551af5602d3SHubert Tong RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult)
552af5602d3SHubert Tong : SendResult(std::move(SendResult)) {}
553af5602d3SHubert Tong void operator()(Expected<SymbolMap> Result) {
554af5602d3SHubert Tong if (Result) {
555af5602d3SHubert Tong assert(Result->size() == 1 && "Unexpected result map count");
556ef391df2SLang Hames SendResult(ExecutorAddr(Result->begin()->second.getAddress()));
557af5602d3SHubert Tong } else {
558af5602d3SHubert Tong SendResult(Result.takeError());
559af5602d3SHubert Tong }
560af5602d3SHubert Tong }
561af5602d3SHubert Tong
562af5602d3SHubert Tong private:
563af5602d3SHubert Tong SendSymbolAddressFn SendResult;
564af5602d3SHubert Tong };
565af5602d3SHubert Tong
566bb5f97e3SLang Hames // FIXME: Proper mangling.
567bb5f97e3SLang Hames auto MangledName = ("_" + SymbolName).str();
568bb5f97e3SLang Hames ES.lookup(
569bb5f97e3SLang Hames LookupKind::DLSym, {{JD, JITDylibLookupFlags::MatchExportedSymbolsOnly}},
570bb5f97e3SLang Hames SymbolLookupSet(ES.intern(MangledName)), SymbolState::Ready,
571af5602d3SHubert Tong RtLookupNotifyComplete(std::move(SendResult)), NoDependenciesToRegister);
572bb5f97e3SLang Hames }
573bb5f97e3SLang Hames
bootstrapMachORuntime(JITDylib & PlatformJD)574bb5f97e3SLang Hames Error MachOPlatform::bootstrapMachORuntime(JITDylib &PlatformJD) {
57564288571SLang Hames if (auto Err = lookupAndRecordAddrs(
57664288571SLang Hames ES, LookupKind::Static, makeJITDylibSearchOrder(&PlatformJD),
57764288571SLang Hames {{ES.intern("___orc_rt_macho_platform_bootstrap"),
57864288571SLang Hames &orc_rt_macho_platform_bootstrap},
57964288571SLang Hames {ES.intern("___orc_rt_macho_platform_shutdown"),
58064288571SLang Hames &orc_rt_macho_platform_shutdown},
581f9aef477SLang Hames {ES.intern("___orc_rt_macho_register_jitdylib"),
582f9aef477SLang Hames &orc_rt_macho_register_jitdylib},
583f9aef477SLang Hames {ES.intern("___orc_rt_macho_deregister_jitdylib"),
584f9aef477SLang Hames &orc_rt_macho_deregister_jitdylib},
585f9aef477SLang Hames {ES.intern("___orc_rt_macho_register_object_platform_sections"),
586f9aef477SLang Hames &orc_rt_macho_register_object_platform_sections},
587f9aef477SLang Hames {ES.intern("___orc_rt_macho_deregister_object_platform_sections"),
588f9aef477SLang Hames &orc_rt_macho_deregister_object_platform_sections},
58964288571SLang Hames {ES.intern("___orc_rt_macho_create_pthread_key"),
59064288571SLang Hames &orc_rt_macho_create_pthread_key}}))
59164288571SLang Hames return Err;
592bb5f97e3SLang Hames
593ff846fcbSLang Hames return ES.callSPSWrapper<void()>(orc_rt_macho_platform_bootstrap);
59485fb9976SLang Hames }
59585fb9976SLang Hames
createPThreadKey()596eda6afdaSLang Hames Expected<uint64_t> MachOPlatform::createPThreadKey() {
597eda6afdaSLang Hames if (!orc_rt_macho_create_pthread_key)
598eda6afdaSLang Hames return make_error<StringError>(
599eda6afdaSLang Hames "Attempting to create pthread key in target, but runtime support has "
600eda6afdaSLang Hames "not been loaded yet",
601eda6afdaSLang Hames inconvertibleErrorCode());
602eda6afdaSLang Hames
603eda6afdaSLang Hames Expected<uint64_t> Result(0);
6042487db1fSLang Hames if (auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(void)>(
60521a06254SLang Hames orc_rt_macho_create_pthread_key, Result))
606eda6afdaSLang Hames return std::move(Err);
607eda6afdaSLang Hames return Result;
608eda6afdaSLang Hames }
609eda6afdaSLang Hames
modifyPassConfig(MaterializationResponsibility & MR,jitlink::LinkGraph & LG,jitlink::PassConfiguration & Config)610bb5f97e3SLang Hames void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
611bb5f97e3SLang Hames MaterializationResponsibility &MR, jitlink::LinkGraph &LG,
612bb5f97e3SLang Hames jitlink::PassConfiguration &Config) {
613bb5f97e3SLang Hames
614ff846fcbSLang Hames auto PS = MP.State.load();
615ff846fcbSLang Hames
616afeb1e4aSLang Hames // --- Handle Initializers ---
617afeb1e4aSLang Hames if (auto InitSymbol = MR.getInitializerSymbol()) {
618afeb1e4aSLang Hames
619afeb1e4aSLang Hames // If the initializer symbol is the MachOHeader start symbol then just
620afeb1e4aSLang Hames // register it and then bail out -- the header materialization unit
621afeb1e4aSLang Hames // definitely doesn't need any other passes.
622afeb1e4aSLang Hames if (InitSymbol == MP.MachOHeaderStartSymbol) {
623afeb1e4aSLang Hames Config.PostAllocationPasses.push_back([this, &MR](jitlink::LinkGraph &G) {
624afeb1e4aSLang Hames return associateJITDylibHeaderSymbol(G, MR);
625afeb1e4aSLang Hames });
626bb5f97e3SLang Hames return;
627bb5f97e3SLang Hames }
628bb5f97e3SLang Hames
629afeb1e4aSLang Hames // If the object contains an init symbol other than the header start symbol
630afeb1e4aSLang Hames // then add passes to preserve, process and register the init
631afeb1e4aSLang Hames // sections/symbols.
632afeb1e4aSLang Hames Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) {
633afeb1e4aSLang Hames if (auto Err = preserveInitSections(G, MR))
634afeb1e4aSLang Hames return Err;
635afeb1e4aSLang Hames return processObjCImageInfo(G, MR);
636afeb1e4aSLang Hames });
637afeb1e4aSLang Hames }
638afeb1e4aSLang Hames
639afeb1e4aSLang Hames // --- Add passes for eh-frame and TLV support ---
640ff846fcbSLang Hames if (PS == MachOPlatform::BootstrapPhase1) {
641ff846fcbSLang Hames Config.PostFixupPasses.push_back(
642ff846fcbSLang Hames [this](jitlink::LinkGraph &G) { return registerEHSectionsPhase1(G); });
643ff846fcbSLang Hames return;
644ff846fcbSLang Hames }
645afeb1e4aSLang Hames
646afeb1e4aSLang Hames // Insert TLV lowering at the start of the PostPrunePasses, since we want
647afeb1e4aSLang Hames // it to run before GOT/PLT lowering.
648afeb1e4aSLang Hames Config.PostPrunePasses.insert(
649afeb1e4aSLang Hames Config.PostPrunePasses.begin(),
650afeb1e4aSLang Hames [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
651afeb1e4aSLang Hames return fixTLVSectionsAndEdges(G, JD);
652afeb1e4aSLang Hames });
653afeb1e4aSLang Hames
654f9aef477SLang Hames // Add a pass to register the final addresses of any special sections in the
655f9aef477SLang Hames // object with the runtime.
656f9aef477SLang Hames Config.PostAllocationPasses.push_back(
657f9aef477SLang Hames [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
658f9aef477SLang Hames return registerObjectPlatformSections(G, JD);
659f9aef477SLang Hames });
66085fb9976SLang Hames }
66185fb9976SLang Hames
662963378bdSLang Hames ObjectLinkingLayer::Plugin::SyntheticSymbolDependenciesMap
getSyntheticSymbolDependencies(MaterializationResponsibility & MR)663bb5f97e3SLang Hames MachOPlatform::MachOPlatformPlugin::getSyntheticSymbolDependencies(
66485fb9976SLang Hames MaterializationResponsibility &MR) {
665bb5f97e3SLang Hames std::lock_guard<std::mutex> Lock(PluginMutex);
66685fb9976SLang Hames auto I = InitSymbolDeps.find(&MR);
66785fb9976SLang Hames if (I != InitSymbolDeps.end()) {
668963378bdSLang Hames SyntheticSymbolDependenciesMap Result;
66985fb9976SLang Hames Result[MR.getInitializerSymbol()] = std::move(I->second);
67085fb9976SLang Hames InitSymbolDeps.erase(&MR);
67185fb9976SLang Hames return Result;
67285fb9976SLang Hames }
673963378bdSLang Hames return SyntheticSymbolDependenciesMap();
67485fb9976SLang Hames }
67585fb9976SLang Hames
associateJITDylibHeaderSymbol(jitlink::LinkGraph & G,MaterializationResponsibility & MR)676afeb1e4aSLang Hames Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
677afeb1e4aSLang Hames jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
678bb5f97e3SLang Hames auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
679bb5f97e3SLang Hames return Sym->getName() == *MP.MachOHeaderStartSymbol;
680bb5f97e3SLang Hames });
681afeb1e4aSLang Hames assert(I != G.defined_symbols().end() && "Missing MachO header start symbol");
682afeb1e4aSLang Hames
683afeb1e4aSLang Hames auto &JD = MR.getTargetJITDylib();
684bb5f97e3SLang Hames std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
685118e953bSLang Hames auto HeaderAddr = (*I)->getAddress();
686f9aef477SLang Hames MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
687bb5f97e3SLang Hames MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
688f9aef477SLang Hames G.allocActions().push_back(
689f9aef477SLang Hames {cantFail(
690f9aef477SLang Hames WrapperFunctionCall::Create<SPSArgList<SPSString, SPSExecutorAddr>>(
691f9aef477SLang Hames MP.orc_rt_macho_register_jitdylib, JD.getName(), HeaderAddr)),
692f9aef477SLang Hames cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
693f9aef477SLang Hames MP.orc_rt_macho_deregister_jitdylib, HeaderAddr))});
694bb5f97e3SLang Hames return Error::success();
695bb5f97e3SLang Hames }
696bb5f97e3SLang Hames
preserveInitSections(jitlink::LinkGraph & G,MaterializationResponsibility & MR)697bb5f97e3SLang Hames Error MachOPlatform::MachOPlatformPlugin::preserveInitSections(
69885fb9976SLang Hames jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
69985fb9976SLang Hames
700bb5f97e3SLang Hames JITLinkSymbolSet InitSectionSymbols;
701bb5f97e3SLang Hames for (auto &InitSectionName : InitSectionNames) {
702bb5f97e3SLang Hames // Skip non-init sections.
703bb5f97e3SLang Hames auto *InitSection = G.findSectionByName(InitSectionName);
704bb5f97e3SLang Hames if (!InitSection)
705bb5f97e3SLang Hames continue;
70685fb9976SLang Hames
707bb5f97e3SLang Hames // Make a pass over live symbols in the section: those blocks are already
708bb5f97e3SLang Hames // preserved.
709bb5f97e3SLang Hames DenseSet<jitlink::Block *> AlreadyLiveBlocks;
710bb5f97e3SLang Hames for (auto &Sym : InitSection->symbols()) {
711bb5f97e3SLang Hames auto &B = Sym->getBlock();
712bb5f97e3SLang Hames if (Sym->isLive() && Sym->getOffset() == 0 &&
713bb5f97e3SLang Hames Sym->getSize() == B.getSize() && !AlreadyLiveBlocks.count(&B)) {
714bb5f97e3SLang Hames InitSectionSymbols.insert(Sym);
715bb5f97e3SLang Hames AlreadyLiveBlocks.insert(&B);
716bb5f97e3SLang Hames }
71785fb9976SLang Hames }
71885fb9976SLang Hames
719bb5f97e3SLang Hames // Add anonymous symbols to preserve any not-already-preserved blocks.
720bb5f97e3SLang Hames for (auto *B : InitSection->blocks())
721bb5f97e3SLang Hames if (!AlreadyLiveBlocks.count(B))
722bb5f97e3SLang Hames InitSectionSymbols.insert(
723bb5f97e3SLang Hames &G.addAnonymousSymbol(*B, 0, B->getSize(), false, true));
724bb5f97e3SLang Hames }
72585fb9976SLang Hames
726bb5f97e3SLang Hames if (!InitSectionSymbols.empty()) {
727bb5f97e3SLang Hames std::lock_guard<std::mutex> Lock(PluginMutex);
728bb5f97e3SLang Hames InitSymbolDeps[&MR] = std::move(InitSectionSymbols);
72985fb9976SLang Hames }
73085fb9976SLang Hames
73185fb9976SLang Hames return Error::success();
73285fb9976SLang Hames }
73385fb9976SLang Hames
processObjCImageInfo(jitlink::LinkGraph & G,MaterializationResponsibility & MR)734cdcc3547SLang Hames Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
735cdcc3547SLang Hames jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
736cdcc3547SLang Hames
737cdcc3547SLang Hames // If there's an ObjC imagine info then either
738cdcc3547SLang Hames // (1) It's the first __objc_imageinfo we've seen in this JITDylib. In
739cdcc3547SLang Hames // this case we name and record it.
740cdcc3547SLang Hames // OR
741cdcc3547SLang Hames // (2) We already have a recorded __objc_imageinfo for this JITDylib,
742cdcc3547SLang Hames // in which case we just verify it.
743cdcc3547SLang Hames auto *ObjCImageInfo = G.findSectionByName(ObjCImageInfoSectionName);
744cdcc3547SLang Hames if (!ObjCImageInfo)
745cdcc3547SLang Hames return Error::success();
746cdcc3547SLang Hames
747cdcc3547SLang Hames auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();
748cdcc3547SLang Hames
749cdcc3547SLang Hames // Check that the section is not empty if present.
750cdcc3547SLang Hames if (llvm::empty(ObjCImageInfoBlocks))
751cdcc3547SLang Hames return make_error<StringError>("Empty " + ObjCImageInfoSectionName +
752cdcc3547SLang Hames " section in " + G.getName(),
753cdcc3547SLang Hames inconvertibleErrorCode());
754cdcc3547SLang Hames
755cdcc3547SLang Hames // Check that there's only one block in the section.
756cdcc3547SLang Hames if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
757cdcc3547SLang Hames return make_error<StringError>("Multiple blocks in " +
758cdcc3547SLang Hames ObjCImageInfoSectionName +
759cdcc3547SLang Hames " section in " + G.getName(),
760cdcc3547SLang Hames inconvertibleErrorCode());
761cdcc3547SLang Hames
762cdcc3547SLang Hames // Check that the __objc_imageinfo section is unreferenced.
763cdcc3547SLang Hames // FIXME: We could optimize this check if Symbols had a ref-count.
764cdcc3547SLang Hames for (auto &Sec : G.sections()) {
765cdcc3547SLang Hames if (&Sec != ObjCImageInfo)
766cdcc3547SLang Hames for (auto *B : Sec.blocks())
767cdcc3547SLang Hames for (auto &E : B->edges())
768cdcc3547SLang Hames if (E.getTarget().isDefined() &&
769cdcc3547SLang Hames &E.getTarget().getBlock().getSection() == ObjCImageInfo)
770cdcc3547SLang Hames return make_error<StringError>(ObjCImageInfoSectionName +
771cdcc3547SLang Hames " is referenced within file " +
772cdcc3547SLang Hames G.getName(),
773cdcc3547SLang Hames inconvertibleErrorCode());
774cdcc3547SLang Hames }
775cdcc3547SLang Hames
776cdcc3547SLang Hames auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();
777cdcc3547SLang Hames auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();
778cdcc3547SLang Hames auto Version = support::endian::read32(ObjCImageInfoData, G.getEndianness());
779cdcc3547SLang Hames auto Flags =
780cdcc3547SLang Hames support::endian::read32(ObjCImageInfoData + 4, G.getEndianness());
781cdcc3547SLang Hames
782cdcc3547SLang Hames // Lock the mutex while we verify / update the ObjCImageInfos map.
783cdcc3547SLang Hames std::lock_guard<std::mutex> Lock(PluginMutex);
784cdcc3547SLang Hames
785cdcc3547SLang Hames auto ObjCImageInfoItr = ObjCImageInfos.find(&MR.getTargetJITDylib());
786cdcc3547SLang Hames if (ObjCImageInfoItr != ObjCImageInfos.end()) {
787cdcc3547SLang Hames // We've already registered an __objc_imageinfo section. Verify the
788cdcc3547SLang Hames // content of this new section matches, then delete it.
789cdcc3547SLang Hames if (ObjCImageInfoItr->second.first != Version)
790cdcc3547SLang Hames return make_error<StringError>(
791cdcc3547SLang Hames "ObjC version in " + G.getName() +
792cdcc3547SLang Hames " does not match first registered version",
793cdcc3547SLang Hames inconvertibleErrorCode());
794cdcc3547SLang Hames if (ObjCImageInfoItr->second.second != Flags)
795cdcc3547SLang Hames return make_error<StringError>("ObjC flags in " + G.getName() +
796cdcc3547SLang Hames " do not match first registered flags",
797cdcc3547SLang Hames inconvertibleErrorCode());
798cdcc3547SLang Hames
799cdcc3547SLang Hames // __objc_imageinfo is valid. Delete the block.
800cdcc3547SLang Hames for (auto *S : ObjCImageInfo->symbols())
801cdcc3547SLang Hames G.removeDefinedSymbol(*S);
802cdcc3547SLang Hames G.removeBlock(ObjCImageInfoBlock);
803cdcc3547SLang Hames } else {
804cdcc3547SLang Hames // We haven't registered an __objc_imageinfo section yet. Register and
805cdcc3547SLang Hames // move on. The section should already be marked no-dead-strip.
806cdcc3547SLang Hames ObjCImageInfos[&MR.getTargetJITDylib()] = std::make_pair(Version, Flags);
807cdcc3547SLang Hames }
808cdcc3547SLang Hames
809cdcc3547SLang Hames return Error::success();
810cdcc3547SLang Hames }
811cdcc3547SLang Hames
fixTLVSectionsAndEdges(jitlink::LinkGraph & G,JITDylib & JD)812eda6afdaSLang Hames Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
813eda6afdaSLang Hames jitlink::LinkGraph &G, JITDylib &JD) {
814eda6afdaSLang Hames
815eda6afdaSLang Hames // Rename external references to __tlv_bootstrap to ___orc_rt_tlv_get_addr.
816eda6afdaSLang Hames for (auto *Sym : G.external_symbols())
817eda6afdaSLang Hames if (Sym->getName() == "__tlv_bootstrap") {
818eda6afdaSLang Hames Sym->setName("___orc_rt_macho_tlv_get_addr");
819eda6afdaSLang Hames break;
820eda6afdaSLang Hames }
821eda6afdaSLang Hames
822eda6afdaSLang Hames // Store key in __thread_vars struct fields.
823eda6afdaSLang Hames if (auto *ThreadDataSec = G.findSectionByName(ThreadVarsSectionName)) {
824eda6afdaSLang Hames Optional<uint64_t> Key;
825eda6afdaSLang Hames {
826eda6afdaSLang Hames std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
827eda6afdaSLang Hames auto I = MP.JITDylibToPThreadKey.find(&JD);
828eda6afdaSLang Hames if (I != MP.JITDylibToPThreadKey.end())
829eda6afdaSLang Hames Key = I->second;
830eda6afdaSLang Hames }
831eda6afdaSLang Hames
832eda6afdaSLang Hames if (!Key) {
833eda6afdaSLang Hames if (auto KeyOrErr = MP.createPThreadKey())
834eda6afdaSLang Hames Key = *KeyOrErr;
835eda6afdaSLang Hames else
836eda6afdaSLang Hames return KeyOrErr.takeError();
837eda6afdaSLang Hames }
838eda6afdaSLang Hames
839eda6afdaSLang Hames uint64_t PlatformKeyBits =
840eda6afdaSLang Hames support::endian::byte_swap(*Key, G.getEndianness());
841eda6afdaSLang Hames
842eda6afdaSLang Hames for (auto *B : ThreadDataSec->blocks()) {
843eda6afdaSLang Hames if (B->getSize() != 3 * G.getPointerSize())
844eda6afdaSLang Hames return make_error<StringError>("__thread_vars block at " +
845eda6afdaSLang Hames formatv("{0:x}", B->getAddress()) +
846eda6afdaSLang Hames " has unexpected size",
847eda6afdaSLang Hames inconvertibleErrorCode());
848eda6afdaSLang Hames
849eda6afdaSLang Hames auto NewBlockContent = G.allocateBuffer(B->getSize());
850eda6afdaSLang Hames llvm::copy(B->getContent(), NewBlockContent.data());
851eda6afdaSLang Hames memcpy(NewBlockContent.data() + G.getPointerSize(), &PlatformKeyBits,
852eda6afdaSLang Hames G.getPointerSize());
853eda6afdaSLang Hames B->setContent(NewBlockContent);
854eda6afdaSLang Hames }
855eda6afdaSLang Hames }
856eda6afdaSLang Hames
857eda6afdaSLang Hames // Transform any TLV edges into GOT edges.
858eda6afdaSLang Hames for (auto *B : G.blocks())
859eda6afdaSLang Hames for (auto &E : B->edges())
860eda6afdaSLang Hames if (E.getKind() ==
86127ea3f16SLang Hames jitlink::x86_64::RequestTLVPAndTransformToPCRel32TLVPLoadREXRelaxable)
86227ea3f16SLang Hames E.setKind(jitlink::x86_64::
86327ea3f16SLang Hames RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable);
864eda6afdaSLang Hames
865eda6afdaSLang Hames return Error::success();
866eda6afdaSLang Hames }
867eda6afdaSLang Hames
registerObjectPlatformSections(jitlink::LinkGraph & G,JITDylib & JD)868f9aef477SLang Hames Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
869f9aef477SLang Hames jitlink::LinkGraph &G, JITDylib &JD) {
870afeb1e4aSLang Hames
871f9aef477SLang Hames // Add an action to register the eh-frame.
872afeb1e4aSLang Hames if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
873afeb1e4aSLang Hames jitlink::SectionRange R(*EHFrameSection);
874afeb1e4aSLang Hames if (!R.empty())
875089acf25SLang Hames G.allocActions().push_back(
876089acf25SLang Hames {cantFail(
877089acf25SLang Hames WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
878089acf25SLang Hames MP.orc_rt_macho_register_ehframe_section, R.getRange())),
879089acf25SLang Hames cantFail(
880089acf25SLang Hames WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
881089acf25SLang Hames MP.orc_rt_macho_deregister_ehframe_section, R.getRange()))});
882afeb1e4aSLang Hames }
883afeb1e4aSLang Hames
884afeb1e4aSLang Hames // Get a pointer to the thread data section if there is one. It will be used
885afeb1e4aSLang Hames // below.
886afeb1e4aSLang Hames jitlink::Section *ThreadDataSection =
887afeb1e4aSLang Hames G.findSectionByName(ThreadDataSectionName);
888afeb1e4aSLang Hames
889afeb1e4aSLang Hames // Handle thread BSS section if there is one.
890afeb1e4aSLang Hames if (auto *ThreadBSSSection = G.findSectionByName(ThreadBSSSectionName)) {
891afeb1e4aSLang Hames // If there's already a thread data section in this graph then merge the
892afeb1e4aSLang Hames // thread BSS section content into it, otherwise just treat the thread
893afeb1e4aSLang Hames // BSS section as the thread data section.
894afeb1e4aSLang Hames if (ThreadDataSection)
895afeb1e4aSLang Hames G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
896afeb1e4aSLang Hames else
897afeb1e4aSLang Hames ThreadDataSection = ThreadBSSSection;
898afeb1e4aSLang Hames }
899afeb1e4aSLang Hames
900f9aef477SLang Hames SmallVector<std::pair<StringRef, ExecutorAddrRange>, 8> MachOPlatformSecs;
901f9aef477SLang Hames
902afeb1e4aSLang Hames // Having merged thread BSS (if present) and thread data (if present),
903afeb1e4aSLang Hames // record the resulting section range.
904afeb1e4aSLang Hames if (ThreadDataSection) {
905afeb1e4aSLang Hames jitlink::SectionRange R(*ThreadDataSection);
906ff846fcbSLang Hames if (!R.empty()) {
907ff846fcbSLang Hames if (MP.State != MachOPlatform::Initialized)
908ff846fcbSLang Hames return make_error<StringError>("__thread_data section encountered, but "
909ff846fcbSLang Hames "MachOPlatform has not finished booting",
910ff846fcbSLang Hames inconvertibleErrorCode());
911ff846fcbSLang Hames
912f9aef477SLang Hames MachOPlatformSecs.push_back({ThreadDataSectionName, R.getRange()});
913f9aef477SLang Hames }
914f9aef477SLang Hames }
915f9aef477SLang Hames
916f9aef477SLang Hames // If any platform sections were found then add an allocation action to call
917f9aef477SLang Hames // the registration function.
918f9aef477SLang Hames StringRef PlatformSections[] = {
919f9aef477SLang Hames ModInitFuncSectionName, ObjCClassListSectionName,
920f9aef477SLang Hames ObjCImageInfoSectionName, ObjCSelRefsSectionName,
921f9aef477SLang Hames Swift5ProtoSectionName, Swift5ProtosSectionName,
922f9aef477SLang Hames Swift5TypesSectionName,
923f9aef477SLang Hames };
924f9aef477SLang Hames
925f9aef477SLang Hames for (auto &SecName : PlatformSections) {
926f9aef477SLang Hames auto *Sec = G.findSectionByName(SecName);
927f9aef477SLang Hames if (!Sec)
928f9aef477SLang Hames continue;
929f9aef477SLang Hames jitlink::SectionRange R(*Sec);
930f9aef477SLang Hames if (R.empty())
931f9aef477SLang Hames continue;
932f9aef477SLang Hames
933f9aef477SLang Hames MachOPlatformSecs.push_back({SecName, R.getRange()});
934f9aef477SLang Hames }
935f9aef477SLang Hames
936f9aef477SLang Hames if (!MachOPlatformSecs.empty()) {
937f9aef477SLang Hames Optional<ExecutorAddr> HeaderAddr;
938f9aef477SLang Hames {
939f9aef477SLang Hames std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
940f9aef477SLang Hames auto I = MP.JITDylibToHeaderAddr.find(&JD);
941f9aef477SLang Hames if (I != MP.JITDylibToHeaderAddr.end())
942f9aef477SLang Hames HeaderAddr = I->second;
943f9aef477SLang Hames }
944f9aef477SLang Hames
945f9aef477SLang Hames if (!HeaderAddr)
946f9aef477SLang Hames return make_error<StringError>("Missing header for " + JD.getName(),
947f9aef477SLang Hames inconvertibleErrorCode());
948f9aef477SLang Hames
949f9aef477SLang Hames // Dump the scraped inits.
950f9aef477SLang Hames LLVM_DEBUG({
951f9aef477SLang Hames dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
952f9aef477SLang Hames for (auto &KV : MachOPlatformSecs)
953f9aef477SLang Hames dbgs() << " " << KV.first << ": " << KV.second << "\n";
954f9aef477SLang Hames });
955f9aef477SLang Hames
956f9aef477SLang Hames using SPSRegisterObjectPlatformSectionsArgs =
957f9aef477SLang Hames SPSArgList<SPSExecutorAddr,
958f9aef477SLang Hames SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;
959ff846fcbSLang Hames G.allocActions().push_back(
960089acf25SLang Hames {cantFail(
961f9aef477SLang Hames WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
962f9aef477SLang Hames MP.orc_rt_macho_register_object_platform_sections, *HeaderAddr,
963f9aef477SLang Hames MachOPlatformSecs)),
964089acf25SLang Hames cantFail(
965f9aef477SLang Hames WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
966f9aef477SLang Hames MP.orc_rt_macho_deregister_object_platform_sections,
967f9aef477SLang Hames *HeaderAddr, MachOPlatformSecs))});
968afeb1e4aSLang Hames }
969f9aef477SLang Hames
970afeb1e4aSLang Hames return Error::success();
971afeb1e4aSLang Hames }
972afeb1e4aSLang Hames
registerEHSectionsPhase1(jitlink::LinkGraph & G)973ff846fcbSLang Hames Error MachOPlatform::MachOPlatformPlugin::registerEHSectionsPhase1(
974ff846fcbSLang Hames jitlink::LinkGraph &G) {
975ff846fcbSLang Hames
976ff846fcbSLang Hames // If there's no eh-frame there's nothing to do.
977ff846fcbSLang Hames auto *EHFrameSection = G.findSectionByName(EHFrameSectionName);
978ff846fcbSLang Hames if (!EHFrameSection)
979ff846fcbSLang Hames return Error::success();
980ff846fcbSLang Hames
981ff846fcbSLang Hames // If the eh-frame section is empty there's nothing to do.
982ff846fcbSLang Hames jitlink::SectionRange R(*EHFrameSection);
983ff846fcbSLang Hames if (R.empty())
984ff846fcbSLang Hames return Error::success();
985ff846fcbSLang Hames
986ff846fcbSLang Hames // Since we're linking the object containing the registration code now the
987ff846fcbSLang Hames // addresses won't be ready in the platform. We'll have to find them in this
988ff846fcbSLang Hames // graph instead.
989ff846fcbSLang Hames ExecutorAddr orc_rt_macho_register_ehframe_section;
990ff846fcbSLang Hames ExecutorAddr orc_rt_macho_deregister_ehframe_section;
991ff846fcbSLang Hames for (auto *Sym : G.defined_symbols()) {
992ff846fcbSLang Hames if (!Sym->hasName())
993ff846fcbSLang Hames continue;
994ff846fcbSLang Hames if (Sym->getName() == "___orc_rt_macho_register_ehframe_section")
995ff846fcbSLang Hames orc_rt_macho_register_ehframe_section = ExecutorAddr(Sym->getAddress());
996ff846fcbSLang Hames else if (Sym->getName() == "___orc_rt_macho_deregister_ehframe_section")
997ff846fcbSLang Hames orc_rt_macho_deregister_ehframe_section = ExecutorAddr(Sym->getAddress());
998ff846fcbSLang Hames
999ff846fcbSLang Hames if (orc_rt_macho_register_ehframe_section &&
1000ff846fcbSLang Hames orc_rt_macho_deregister_ehframe_section)
1001ff846fcbSLang Hames break;
1002afeb1e4aSLang Hames }
1003afeb1e4aSLang Hames
1004ff846fcbSLang Hames // If we failed to find the required functions then bail out.
1005ff846fcbSLang Hames if (!orc_rt_macho_register_ehframe_section ||
1006ff846fcbSLang Hames !orc_rt_macho_deregister_ehframe_section)
1007ff846fcbSLang Hames return make_error<StringError>("Could not find eh-frame registration "
1008ff846fcbSLang Hames "functions during platform bootstrap",
1009ff846fcbSLang Hames inconvertibleErrorCode());
1010ff846fcbSLang Hames
1011ff846fcbSLang Hames // Otherwise, add allocation actions to the graph to register eh-frames for
1012ff846fcbSLang Hames // this object.
1013ff846fcbSLang Hames G.allocActions().push_back(
1014089acf25SLang Hames {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1015089acf25SLang Hames orc_rt_macho_register_ehframe_section, R.getRange())),
1016089acf25SLang Hames cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1017089acf25SLang Hames orc_rt_macho_deregister_ehframe_section, R.getRange()))});
1018ff846fcbSLang Hames
1019afeb1e4aSLang Hames return Error::success();
1020afeb1e4aSLang Hames }
1021afeb1e4aSLang Hames
102285fb9976SLang Hames } // End namespace orc.
102385fb9976SLang Hames } // End namespace llvm.
1024