LLVM  15.0.0git
MachOPlatform.cpp
Go to the documentation of this file.
1 //===------ MachOPlatform.cpp - Utilities for executing MachO in Orc ------===//
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 
10 
17 #include "llvm/Support/Debug.h"
18 
19 #define DEBUG_TYPE "orc"
20 
21 using namespace llvm;
22 using namespace llvm::orc;
23 using namespace llvm::orc::shared;
24 
25 namespace llvm {
26 namespace orc {
27 namespace shared {
28 
32 
33 template <>
35  MachOPlatform::MachOJITDylibDepInfo> {
36 public:
37  static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI) {
39  }
40 
43  return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.Sealed,
44  DDI.DepHeaders);
45  }
46 
47  static bool deserialize(SPSInputBuffer &IB,
49  return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.Sealed,
50  DDI.DepHeaders);
51  }
52 };
53 
54 } // namespace shared
55 } // namespace orc
56 } // namespace llvm
57 
58 namespace {
59 
60 class MachOHeaderMaterializationUnit : public MaterializationUnit {
61 public:
62  MachOHeaderMaterializationUnit(MachOPlatform &MOP,
63  const SymbolStringPtr &HeaderStartSymbol)
64  : MaterializationUnit(createHeaderInterface(MOP, HeaderStartSymbol)),
65  MOP(MOP) {}
66 
67  StringRef getName() const override { return "MachOHeaderMU"; }
68 
69  void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
70  unsigned PointerSize;
72  const auto &TT =
73  MOP.getExecutionSession().getExecutorProcessControl().getTargetTriple();
74 
75  switch (TT.getArch()) {
76  case Triple::aarch64:
77  case Triple::x86_64:
78  PointerSize = 8;
80  break;
81  default:
82  llvm_unreachable("Unrecognized architecture");
83  }
84 
85  auto G = std::make_unique<jitlink::LinkGraph>(
86  "<MachOHeaderMU>", TT, PointerSize, Endianness,
88  auto &HeaderSection = G->createSection("__header", jitlink::MemProt::Read);
89  auto &HeaderBlock = createHeaderBlock(*G, HeaderSection);
90 
91  // Init symbol is header-start symbol.
92  G->addDefinedSymbol(HeaderBlock, 0, *R->getInitializerSymbol(),
93  HeaderBlock.getSize(), jitlink::Linkage::Strong,
94  jitlink::Scope::Default, false, true);
95  for (auto &HS : AdditionalHeaderSymbols)
96  G->addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name,
97  HeaderBlock.getSize(), jitlink::Linkage::Strong,
98  jitlink::Scope::Default, false, true);
99 
100  MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));
101  }
102 
103  void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}
104 
105 private:
106  struct HeaderSymbol {
107  const char *Name;
109  };
110 
111  static constexpr HeaderSymbol AdditionalHeaderSymbols[] = {
112  {"___mh_executable_header", 0}};
113 
114  static jitlink::Block &createHeaderBlock(jitlink::LinkGraph &G,
115  jitlink::Section &HeaderSection) {
118  switch (G.getTargetTriple().getArch()) {
119  case Triple::aarch64:
122  break;
123  case Triple::x86_64:
126  break;
127  default:
128  llvm_unreachable("Unrecognized architecture");
129  }
130  Hdr.filetype = MachO::MH_DYLIB; // Custom file type?
131  Hdr.ncmds = 0;
132  Hdr.sizeofcmds = 0;
133  Hdr.flags = 0;
134  Hdr.reserved = 0;
135 
136  if (G.getEndianness() != support::endian::system_endianness())
137  MachO::swapStruct(Hdr);
138 
139  auto HeaderContent = G.allocateString(
140  StringRef(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
141 
142  return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
143  0);
144  }
145 
147  createHeaderInterface(MachOPlatform &MOP,
148  const SymbolStringPtr &HeaderStartSymbol) {
149  SymbolFlagsMap HeaderSymbolFlags;
150 
151  HeaderSymbolFlags[HeaderStartSymbol] = JITSymbolFlags::Exported;
152  for (auto &HS : AdditionalHeaderSymbols)
153  HeaderSymbolFlags[MOP.getExecutionSession().intern(HS.Name)] =
155 
156  return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),
157  HeaderStartSymbol);
158  }
159 
160  MachOPlatform &MOP;
161 };
162 
163 constexpr MachOHeaderMaterializationUnit::HeaderSymbol
164  MachOHeaderMaterializationUnit::AdditionalHeaderSymbols[];
165 
166 StringRef EHFrameSectionName = "__TEXT,__eh_frame";
167 StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
168 StringRef ObjCClassListSectionName = "__DATA,__objc_classlist";
169 StringRef ObjCImageInfoSectionName = "__DATA,__objc_image_info";
170 StringRef ObjCSelRefsSectionName = "__DATA,__objc_selrefs";
171 StringRef Swift5ProtoSectionName = "__TEXT,__swift5_proto";
172 StringRef Swift5ProtosSectionName = "__TEXT,__swift5_protos";
173 StringRef Swift5TypesSectionName = "__TEXT,__swift5_types";
174 StringRef ThreadBSSSectionName = "__DATA,__thread_bss";
175 StringRef ThreadDataSectionName = "__DATA,__thread_data";
176 StringRef ThreadVarsSectionName = "__DATA,__thread_vars";
177 
178 StringRef InitSectionNames[] = {
179  ModInitFuncSectionName, ObjCSelRefsSectionName, ObjCClassListSectionName,
180  Swift5ProtosSectionName, Swift5ProtoSectionName, Swift5TypesSectionName};
181 
182 } // end anonymous namespace
183 
184 namespace llvm {
185 namespace orc {
186 
189  JITDylib &PlatformJD, const char *OrcRuntimePath,
190  Optional<SymbolAliasMap> RuntimeAliases) {
191 
192  auto &EPC = ES.getExecutorProcessControl();
193 
194  // If the target is not supported then bail out immediately.
195  if (!supportedTarget(EPC.getTargetTriple()))
196  return make_error<StringError>("Unsupported MachOPlatform triple: " +
197  EPC.getTargetTriple().str(),
199 
200  // Create default aliases if the caller didn't supply any.
201  if (!RuntimeAliases)
202  RuntimeAliases = standardPlatformAliases(ES);
203 
204  // Define the aliases.
205  if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))
206  return std::move(Err);
207 
208  // Add JIT-dispatch function support symbols.
209  if (auto Err = PlatformJD.define(absoluteSymbols(
210  {{ES.intern("___orc_rt_jit_dispatch"),
211  {EPC.getJITDispatchInfo().JITDispatchFunction.getValue(),
213  {ES.intern("___orc_rt_jit_dispatch_ctx"),
214  {EPC.getJITDispatchInfo().JITDispatchContext.getValue(),
216  return std::move(Err);
217 
218  // Create a generator for the ORC runtime archive.
219  auto OrcRuntimeArchiveGenerator = StaticLibraryDefinitionGenerator::Load(
220  ObjLinkingLayer, OrcRuntimePath, EPC.getTargetTriple());
221  if (!OrcRuntimeArchiveGenerator)
222  return OrcRuntimeArchiveGenerator.takeError();
223 
224  // Create the instance.
225  Error Err = Error::success();
226  auto P = std::unique_ptr<MachOPlatform>(
227  new MachOPlatform(ES, ObjLinkingLayer, PlatformJD,
228  std::move(*OrcRuntimeArchiveGenerator), Err));
229  if (Err)
230  return std::move(Err);
231  return std::move(P);
232 }
233 
235  if (auto Err = JD.define(std::make_unique<MachOHeaderMaterializationUnit>(
236  *this, MachOHeaderStartSymbol)))
237  return Err;
238 
239  return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
240 }
241 
243  std::lock_guard<std::mutex> Lock(PlatformMutex);
244  auto I = JITDylibToHeaderAddr.find(&JD);
245  if (I != JITDylibToHeaderAddr.end()) {
246  assert(HeaderAddrToJITDylib.count(I->second) &&
247  "HeaderAddrToJITDylib missing entry");
248  HeaderAddrToJITDylib.erase(I->second);
249  JITDylibToHeaderAddr.erase(I);
250  }
251  JITDylibToPThreadKey.erase(&JD);
252  return Error::success();
253 }
254 
256  const MaterializationUnit &MU) {
257  auto &JD = RT.getJITDylib();
258  const auto &InitSym = MU.getInitializerSymbol();
259  if (!InitSym)
260  return Error::success();
261 
262  RegisteredInitSymbols[&JD].add(InitSym,
264  LLVM_DEBUG({
265  dbgs() << "MachOPlatform: Registered init symbol " << *InitSym << " for MU "
266  << MU.getName() << "\n";
267  });
268  return Error::success();
269 }
270 
272  llvm_unreachable("Not supported yet");
273 }
274 
275 static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
276  ArrayRef<std::pair<const char *, const char *>> AL) {
277  for (auto &KV : AL) {
278  auto AliasName = ES.intern(KV.first);
279  assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
280  Aliases[std::move(AliasName)] = {ES.intern(KV.second),
282  }
283 }
284 
286  SymbolAliasMap Aliases;
287  addAliases(ES, Aliases, requiredCXXAliases());
288  addAliases(ES, Aliases, standardRuntimeUtilityAliases());
289  return Aliases;
290 }
291 
294  static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
295  {"___cxa_atexit", "___orc_rt_macho_cxa_atexit"}};
296 
297  return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases);
298 }
299 
302  static const std::pair<const char *, const char *>
303  StandardRuntimeUtilityAliases[] = {
304  {"___orc_rt_run_program", "___orc_rt_macho_run_program"},
305  {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
306  {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
307  {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
308  {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
309  {"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
310 
312  StandardRuntimeUtilityAliases);
313 }
314 
316  StringRef SectName) {
317  for (auto &Name : InitSectionNames) {
318  if (Name.startswith(SegName) && Name.substr(7) == SectName)
319  return true;
320  }
321  return false;
322 }
323 
324 bool MachOPlatform::supportedTarget(const Triple &TT) {
325  switch (TT.getArch()) {
326  case Triple::aarch64:
327  case Triple::x86_64:
328  return true;
329  default:
330  return false;
331  }
332 }
333 
334 MachOPlatform::MachOPlatform(
335  ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
336  JITDylib &PlatformJD,
337  std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator, Error &Err)
338  : ES(ES), ObjLinkingLayer(ObjLinkingLayer),
339  MachOHeaderStartSymbol(ES.intern("___dso_handle")) {
340  ErrorAsOutParameter _(&Err);
341 
342  ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*this));
343 
344  PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
345 
346  // Force linking of eh-frame registration functions.
347  if (auto Err2 = lookupAndRecordAddrs(
349  {{ES.intern("___orc_rt_macho_register_ehframe_section"),
350  &orc_rt_macho_register_ehframe_section},
351  {ES.intern("___orc_rt_macho_deregister_ehframe_section"),
352  &orc_rt_macho_deregister_ehframe_section}})) {
353  Err = std::move(Err2);
354  return;
355  }
356 
357  State = BootstrapPhase2;
358 
359  // Associate wrapper function tags with JIT-side function implementations.
360  if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
361  Err = std::move(E2);
362  return;
363  }
364 
365  // Lookup addresses of runtime functions callable by the platform,
366  // call the platform bootstrap function to initialize the platform-state
367  // object in the executor.
368  if (auto E2 = bootstrapMachORuntime(PlatformJD)) {
369  Err = std::move(E2);
370  return;
371  }
372 
373  // PlatformJD hasn't been set up by the platform yet (since we're creating
374  // the platform now), so set it up.
375  if (auto E2 = setupJITDylib(PlatformJD)) {
376  Err = std::move(E2);
377  return;
378  }
379 
380  State = Initialized;
381 }
382 
383 Error MachOPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
385 
386  using PushInitializersSPSSig =
388  WFs[ES.intern("___orc_rt_macho_push_initializers_tag")] =
389  ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
390  this, &MachOPlatform::rt_pushInitializers);
391 
392  using LookupSymbolSPSSig =
394  WFs[ES.intern("___orc_rt_macho_symbol_lookup_tag")] =
395  ES.wrapAsyncWithSPS<LookupSymbolSPSSig>(this,
396  &MachOPlatform::rt_lookupSymbol);
397 
398  return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
399 }
400 
401 void MachOPlatform::pushInitializersLoop(
402  PushInitializersSendResultFn SendResult, JITDylibSP JD) {
405  SmallVector<JITDylib *, 16> Worklist({JD.get()});
406 
407  ES.runSessionLocked([&]() {
408  while (!Worklist.empty()) {
409  // FIXME: Check for defunct dylibs.
410 
411  auto DepJD = Worklist.back();
412  Worklist.pop_back();
413 
414  // If we've already visited this JITDylib on this iteration then continue.
415  if (JDDepMap.count(DepJD))
416  continue;
417 
418  // Add dep info.
419  auto &DM = JDDepMap[DepJD];
420  DepJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) {
421  for (auto &KV : O) {
422  if (KV.first == DepJD)
423  continue;
424  DM.push_back(KV.first);
425  Worklist.push_back(KV.first);
426  }
427  });
428 
429  // Add any registered init symbols.
430  auto RISItr = RegisteredInitSymbols.find(DepJD);
431  if (RISItr != RegisteredInitSymbols.end()) {
432  NewInitSymbols[DepJD] = std::move(RISItr->second);
433  RegisteredInitSymbols.erase(RISItr);
434  }
435  }
436  });
437 
438  // If there are no further init symbols to look up then send the link order
439  // (as a list of header addresses) to the caller.
440  if (NewInitSymbols.empty()) {
441 
442  // To make the list intelligible to the runtime we need to convert all
443  // JITDylib pointers to their header addresses.
445  HeaderAddrs.reserve(JDDepMap.size());
446  {
447  std::lock_guard<std::mutex> Lock(PlatformMutex);
448  for (auto &KV : JDDepMap) {
449  auto I = JITDylibToHeaderAddr.find(KV.first);
450  if (I == JITDylibToHeaderAddr.end()) {
451  // The header address should have been materialized by the previous
452  // round, but we need to handle the pathalogical case where someone
453  // removes the symbol on another thread while we're running.
454  SendResult(
455  make_error<StringError>("JITDylib " + KV.first->getName() +
456  " has no registered header address",
458  return;
459  }
460  HeaderAddrs[KV.first] = I->second;
461  }
462  }
463 
464  // Build the dep info map to return.
465  MachOJITDylibDepInfoMap DIM;
466  DIM.reserve(JDDepMap.size());
467  for (auto &KV : JDDepMap) {
468  assert(HeaderAddrs.count(KV.first) && "Missing header addr");
469  auto H = HeaderAddrs[KV.first];
470  MachOJITDylibDepInfo DepInfo;
471  for (auto &Dep : KV.second) {
472  assert(HeaderAddrs.count(Dep) && "Missing header addr");
473  DepInfo.DepHeaders.push_back(HeaderAddrs[Dep]);
474  }
475  DIM.push_back(std::make_pair(H, std::move(DepInfo)));
476  }
477  SendResult(DIM);
478  return;
479  }
480 
481  // Otherwise issue a lookup and re-run this phase when it completes.
482  lookupInitSymbolsAsync(
483  [this, SendResult = std::move(SendResult), &JD](Error Err) mutable {
484  if (Err)
485  SendResult(std::move(Err));
486  else
487  pushInitializersLoop(std::move(SendResult), JD);
488  },
489  ES, std::move(NewInitSymbols));
490 }
491 
492 void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
493  ExecutorAddr JDHeaderAddr) {
494  JITDylibSP JD;
495  {
496  std::lock_guard<std::mutex> Lock(PlatformMutex);
497  auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
498  if (I != HeaderAddrToJITDylib.end())
499  JD = I->second;
500  }
501 
502  LLVM_DEBUG({
503  dbgs() << "MachOPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";
504  if (JD)
505  dbgs() << "pushing initializers for " << JD->getName() << "\n";
506  else
507  dbgs() << "No JITDylib for header address.\n";
508  });
509 
510  if (!JD) {
511  SendResult(
512  make_error<StringError>("No JITDylib with header addr " +
513  formatv("{0:x}", JDHeaderAddr.getValue()),
515  return;
516  }
517 
518  pushInitializersLoop(std::move(SendResult), JD);
519 }
520 
521 void MachOPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,
523  LLVM_DEBUG({
524  dbgs() << "MachOPlatform::rt_lookupSymbol(\""
525  << formatv("{0:x}", Handle.getValue()) << "\")\n";
526  });
527 
528  JITDylib *JD = nullptr;
529 
530  {
531  std::lock_guard<std::mutex> Lock(PlatformMutex);
532  auto I = HeaderAddrToJITDylib.find(Handle);
533  if (I != HeaderAddrToJITDylib.end())
534  JD = I->second;
535  }
536 
537  if (!JD) {
538  LLVM_DEBUG({
539  dbgs() << " No JITDylib for handle "
540  << formatv("{0:x}", Handle.getValue()) << "\n";
541  });
542  SendResult(make_error<StringError>("No JITDylib associated with handle " +
543  formatv("{0:x}", Handle.getValue()),
545  return;
546  }
547 
548  // Use functor class to work around XL build compiler issue on AIX.
549  class RtLookupNotifyComplete {
550  public:
551  RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult)
552  : SendResult(std::move(SendResult)) {}
553  void operator()(Expected<SymbolMap> Result) {
554  if (Result) {
555  assert(Result->size() == 1 && "Unexpected result map count");
556  SendResult(ExecutorAddr(Result->begin()->second.getAddress()));
557  } else {
558  SendResult(Result.takeError());
559  }
560  }
561 
562  private:
563  SendSymbolAddressFn SendResult;
564  };
565 
566  // FIXME: Proper mangling.
567  auto MangledName = ("_" + SymbolName).str();
568  ES.lookup(
569  LookupKind::DLSym, {{JD, JITDylibLookupFlags::MatchExportedSymbolsOnly}},
570  SymbolLookupSet(ES.intern(MangledName)), SymbolState::Ready,
571  RtLookupNotifyComplete(std::move(SendResult)), NoDependenciesToRegister);
572 }
573 
574 Error MachOPlatform::bootstrapMachORuntime(JITDylib &PlatformJD) {
575  if (auto Err = lookupAndRecordAddrs(
577  {{ES.intern("___orc_rt_macho_platform_bootstrap"),
578  &orc_rt_macho_platform_bootstrap},
579  {ES.intern("___orc_rt_macho_platform_shutdown"),
580  &orc_rt_macho_platform_shutdown},
581  {ES.intern("___orc_rt_macho_register_jitdylib"),
582  &orc_rt_macho_register_jitdylib},
583  {ES.intern("___orc_rt_macho_deregister_jitdylib"),
584  &orc_rt_macho_deregister_jitdylib},
585  {ES.intern("___orc_rt_macho_register_object_platform_sections"),
586  &orc_rt_macho_register_object_platform_sections},
587  {ES.intern("___orc_rt_macho_deregister_object_platform_sections"),
588  &orc_rt_macho_deregister_object_platform_sections},
589  {ES.intern("___orc_rt_macho_create_pthread_key"),
590  &orc_rt_macho_create_pthread_key}}))
591  return Err;
592 
593  return ES.callSPSWrapper<void()>(orc_rt_macho_platform_bootstrap);
594 }
595 
596 Expected<uint64_t> MachOPlatform::createPThreadKey() {
597  if (!orc_rt_macho_create_pthread_key)
598  return make_error<StringError>(
599  "Attempting to create pthread key in target, but runtime support has "
600  "not been loaded yet",
602 
604  if (auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(void)>(
605  orc_rt_macho_create_pthread_key, Result))
606  return std::move(Err);
607  return Result;
608 }
609 
610 void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
612  jitlink::PassConfiguration &Config) {
613 
614  auto PS = MP.State.load();
615 
616  // --- Handle Initializers ---
617  if (auto InitSymbol = MR.getInitializerSymbol()) {
618 
619  // If the initializer symbol is the MachOHeader start symbol then just
620  // register it and then bail out -- the header materialization unit
621  // definitely doesn't need any other passes.
622  if (InitSymbol == MP.MachOHeaderStartSymbol) {
623  Config.PostAllocationPasses.push_back([this, &MR](jitlink::LinkGraph &G) {
624  return associateJITDylibHeaderSymbol(G, MR);
625  });
626  return;
627  }
628 
629  // If the object contains an init symbol other than the header start symbol
630  // then add passes to preserve, process and register the init
631  // sections/symbols.
632  Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) {
633  if (auto Err = preserveInitSections(G, MR))
634  return Err;
635  return processObjCImageInfo(G, MR);
636  });
637  }
638 
639  // --- Add passes for eh-frame and TLV support ---
640  if (PS == MachOPlatform::BootstrapPhase1) {
641  Config.PostFixupPasses.push_back(
642  [this](jitlink::LinkGraph &G) { return registerEHSectionsPhase1(G); });
643  return;
644  }
645 
646  // Insert TLV lowering at the start of the PostPrunePasses, since we want
647  // it to run before GOT/PLT lowering.
648  Config.PostPrunePasses.insert(
649  Config.PostPrunePasses.begin(),
650  [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
651  return fixTLVSectionsAndEdges(G, JD);
652  });
653 
654  // Add a pass to register the final addresses of any special sections in the
655  // object with the runtime.
656  Config.PostAllocationPasses.push_back(
657  [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
658  return registerObjectPlatformSections(G, JD);
659  });
660 }
661 
663 MachOPlatform::MachOPlatformPlugin::getSyntheticSymbolDependencies(
665  std::lock_guard<std::mutex> Lock(PluginMutex);
666  auto I = InitSymbolDeps.find(&MR);
667  if (I != InitSymbolDeps.end()) {
668  SyntheticSymbolDependenciesMap Result;
669  Result[MR.getInitializerSymbol()] = std::move(I->second);
670  InitSymbolDeps.erase(&MR);
671  return Result;
672  }
673  return SyntheticSymbolDependenciesMap();
674 }
675 
676 Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
678  auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
679  return Sym->getName() == *MP.MachOHeaderStartSymbol;
680  });
681  assert(I != G.defined_symbols().end() && "Missing MachO header start symbol");
682 
683  auto &JD = MR.getTargetJITDylib();
684  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
685  auto HeaderAddr = (*I)->getAddress();
686  MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
687  MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
688  G.allocActions().push_back(
689  {cantFail(
690  WrapperFunctionCall::Create<SPSArgList<SPSString, SPSExecutorAddr>>(
691  MP.orc_rt_macho_register_jitdylib, JD.getName(), HeaderAddr)),
692  cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
693  MP.orc_rt_macho_deregister_jitdylib, HeaderAddr))});
694  return Error::success();
695 }
696 
697 Error MachOPlatform::MachOPlatformPlugin::preserveInitSections(
699 
700  JITLinkSymbolSet InitSectionSymbols;
701  for (auto &InitSectionName : InitSectionNames) {
702  // Skip non-init sections.
703  auto *InitSection = G.findSectionByName(InitSectionName);
704  if (!InitSection)
705  continue;
706 
707  // Make a pass over live symbols in the section: those blocks are already
708  // preserved.
709  DenseSet<jitlink::Block *> AlreadyLiveBlocks;
710  for (auto &Sym : InitSection->symbols()) {
711  auto &B = Sym->getBlock();
712  if (Sym->isLive() && Sym->getOffset() == 0 &&
713  Sym->getSize() == B.getSize() && !AlreadyLiveBlocks.count(&B)) {
714  InitSectionSymbols.insert(Sym);
715  AlreadyLiveBlocks.insert(&B);
716  }
717  }
718 
719  // Add anonymous symbols to preserve any not-already-preserved blocks.
720  for (auto *B : InitSection->blocks())
721  if (!AlreadyLiveBlocks.count(B))
722  InitSectionSymbols.insert(
723  &G.addAnonymousSymbol(*B, 0, B->getSize(), false, true));
724  }
725 
726  if (!InitSectionSymbols.empty()) {
727  std::lock_guard<std::mutex> Lock(PluginMutex);
728  InitSymbolDeps[&MR] = std::move(InitSectionSymbols);
729  }
730 
731  return Error::success();
732 }
733 
734 Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
736 
737  // If there's an ObjC imagine info then either
738  // (1) It's the first __objc_imageinfo we've seen in this JITDylib. In
739  // this case we name and record it.
740  // OR
741  // (2) We already have a recorded __objc_imageinfo for this JITDylib,
742  // in which case we just verify it.
743  auto *ObjCImageInfo = G.findSectionByName(ObjCImageInfoSectionName);
744  if (!ObjCImageInfo)
745  return Error::success();
746 
747  auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();
748 
749  // Check that the section is not empty if present.
750  if (llvm::empty(ObjCImageInfoBlocks))
751  return make_error<StringError>("Empty " + ObjCImageInfoSectionName +
752  " section in " + G.getName(),
754 
755  // Check that there's only one block in the section.
756  if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
757  return make_error<StringError>("Multiple blocks in " +
758  ObjCImageInfoSectionName +
759  " section in " + G.getName(),
761 
762  // Check that the __objc_imageinfo section is unreferenced.
763  // FIXME: We could optimize this check if Symbols had a ref-count.
764  for (auto &Sec : G.sections()) {
765  if (&Sec != ObjCImageInfo)
766  for (auto *B : Sec.blocks())
767  for (auto &E : B->edges())
768  if (E.getTarget().isDefined() &&
769  &E.getTarget().getBlock().getSection() == ObjCImageInfo)
770  return make_error<StringError>(ObjCImageInfoSectionName +
771  " is referenced within file " +
772  G.getName(),
774  }
775 
776  auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();
777  auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();
778  auto Version = support::endian::read32(ObjCImageInfoData, G.getEndianness());
779  auto Flags =
780  support::endian::read32(ObjCImageInfoData + 4, G.getEndianness());
781 
782  // Lock the mutex while we verify / update the ObjCImageInfos map.
783  std::lock_guard<std::mutex> Lock(PluginMutex);
784 
785  auto ObjCImageInfoItr = ObjCImageInfos.find(&MR.getTargetJITDylib());
786  if (ObjCImageInfoItr != ObjCImageInfos.end()) {
787  // We've already registered an __objc_imageinfo section. Verify the
788  // content of this new section matches, then delete it.
789  if (ObjCImageInfoItr->second.first != Version)
790  return make_error<StringError>(
791  "ObjC version in " + G.getName() +
792  " does not match first registered version",
794  if (ObjCImageInfoItr->second.second != Flags)
795  return make_error<StringError>("ObjC flags in " + G.getName() +
796  " do not match first registered flags",
798 
799  // __objc_imageinfo is valid. Delete the block.
800  for (auto *S : ObjCImageInfo->symbols())
801  G.removeDefinedSymbol(*S);
802  G.removeBlock(ObjCImageInfoBlock);
803  } else {
804  // We haven't registered an __objc_imageinfo section yet. Register and
805  // move on. The section should already be marked no-dead-strip.
806  ObjCImageInfos[&MR.getTargetJITDylib()] = std::make_pair(Version, Flags);
807  }
808 
809  return Error::success();
810 }
811 
812 Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
813  jitlink::LinkGraph &G, JITDylib &JD) {
814 
815  // Rename external references to __tlv_bootstrap to ___orc_rt_tlv_get_addr.
816  for (auto *Sym : G.external_symbols())
817  if (Sym->getName() == "__tlv_bootstrap") {
818  Sym->setName("___orc_rt_macho_tlv_get_addr");
819  break;
820  }
821 
822  // Store key in __thread_vars struct fields.
823  if (auto *ThreadDataSec = G.findSectionByName(ThreadVarsSectionName)) {
825  {
826  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
827  auto I = MP.JITDylibToPThreadKey.find(&JD);
828  if (I != MP.JITDylibToPThreadKey.end())
829  Key = I->second;
830  }
831 
832  if (!Key) {
833  if (auto KeyOrErr = MP.createPThreadKey())
834  Key = *KeyOrErr;
835  else
836  return KeyOrErr.takeError();
837  }
838 
839  uint64_t PlatformKeyBits =
840  support::endian::byte_swap(*Key, G.getEndianness());
841 
842  for (auto *B : ThreadDataSec->blocks()) {
843  if (B->getSize() != 3 * G.getPointerSize())
844  return make_error<StringError>("__thread_vars block at " +
845  formatv("{0:x}", B->getAddress()) +
846  " has unexpected size",
848 
849  auto NewBlockContent = G.allocateBuffer(B->getSize());
850  llvm::copy(B->getContent(), NewBlockContent.data());
851  memcpy(NewBlockContent.data() + G.getPointerSize(), &PlatformKeyBits,
852  G.getPointerSize());
853  B->setContent(NewBlockContent);
854  }
855  }
856 
857  // Transform any TLV edges into GOT edges.
858  for (auto *B : G.blocks())
859  for (auto &E : B->edges())
860  if (E.getKind() ==
862  E.setKind(jitlink::x86_64::
864 
865  return Error::success();
866 }
867 
868 Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
869  jitlink::LinkGraph &G, JITDylib &JD) {
870 
871  // Add an action to register the eh-frame.
872  if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
873  jitlink::SectionRange R(*EHFrameSection);
874  if (!R.empty())
875  G.allocActions().push_back(
876  {cantFail(
877  WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
878  MP.orc_rt_macho_register_ehframe_section, R.getRange())),
879  cantFail(
880  WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
881  MP.orc_rt_macho_deregister_ehframe_section, R.getRange()))});
882  }
883 
884  // Get a pointer to the thread data section if there is one. It will be used
885  // below.
886  jitlink::Section *ThreadDataSection =
887  G.findSectionByName(ThreadDataSectionName);
888 
889  // Handle thread BSS section if there is one.
890  if (auto *ThreadBSSSection = G.findSectionByName(ThreadBSSSectionName)) {
891  // If there's already a thread data section in this graph then merge the
892  // thread BSS section content into it, otherwise just treat the thread
893  // BSS section as the thread data section.
894  if (ThreadDataSection)
895  G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
896  else
897  ThreadDataSection = ThreadBSSSection;
898  }
899 
901 
902  // Having merged thread BSS (if present) and thread data (if present),
903  // record the resulting section range.
904  if (ThreadDataSection) {
905  jitlink::SectionRange R(*ThreadDataSection);
906  if (!R.empty()) {
907  if (MP.State != MachOPlatform::Initialized)
908  return make_error<StringError>("__thread_data section encountered, but "
909  "MachOPlatform has not finished booting",
911 
912  MachOPlatformSecs.push_back({ThreadDataSectionName, R.getRange()});
913  }
914  }
915 
916  // If any platform sections were found then add an allocation action to call
917  // the registration function.
918  StringRef PlatformSections[] = {
919  ModInitFuncSectionName, ObjCClassListSectionName,
920  ObjCImageInfoSectionName, ObjCSelRefsSectionName,
921  Swift5ProtoSectionName, Swift5ProtosSectionName,
922  Swift5TypesSectionName,
923  };
924 
925  for (auto &SecName : PlatformSections) {
926  auto *Sec = G.findSectionByName(SecName);
927  if (!Sec)
928  continue;
929  jitlink::SectionRange R(*Sec);
930  if (R.empty())
931  continue;
932 
933  MachOPlatformSecs.push_back({SecName, R.getRange()});
934  }
935 
936  if (!MachOPlatformSecs.empty()) {
937  Optional<ExecutorAddr> HeaderAddr;
938  {
939  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
940  auto I = MP.JITDylibToHeaderAddr.find(&JD);
941  if (I != MP.JITDylibToHeaderAddr.end())
942  HeaderAddr = I->second;
943  }
944 
945  if (!HeaderAddr)
946  return make_error<StringError>("Missing header for " + JD.getName(),
948 
949  // Dump the scraped inits.
950  LLVM_DEBUG({
951  dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
952  for (auto &KV : MachOPlatformSecs)
953  dbgs() << " " << KV.first << ": " << KV.second << "\n";
954  });
955 
956  using SPSRegisterObjectPlatformSectionsArgs =
959  G.allocActions().push_back(
960  {cantFail(
961  WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
962  MP.orc_rt_macho_register_object_platform_sections, *HeaderAddr,
963  MachOPlatformSecs)),
964  cantFail(
965  WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
966  MP.orc_rt_macho_deregister_object_platform_sections,
967  *HeaderAddr, MachOPlatformSecs))});
968  }
969 
970  return Error::success();
971 }
972 
973 Error MachOPlatform::MachOPlatformPlugin::registerEHSectionsPhase1(
975 
976  // If there's no eh-frame there's nothing to do.
977  auto *EHFrameSection = G.findSectionByName(EHFrameSectionName);
978  if (!EHFrameSection)
979  return Error::success();
980 
981  // If the eh-frame section is empty there's nothing to do.
982  jitlink::SectionRange R(*EHFrameSection);
983  if (R.empty())
984  return Error::success();
985 
986  // Since we're linking the object containing the registration code now the
987  // addresses won't be ready in the platform. We'll have to find them in this
988  // graph instead.
989  ExecutorAddr orc_rt_macho_register_ehframe_section;
990  ExecutorAddr orc_rt_macho_deregister_ehframe_section;
991  for (auto *Sym : G.defined_symbols()) {
992  if (!Sym->hasName())
993  continue;
994  if (Sym->getName() == "___orc_rt_macho_register_ehframe_section")
995  orc_rt_macho_register_ehframe_section = ExecutorAddr(Sym->getAddress());
996  else if (Sym->getName() == "___orc_rt_macho_deregister_ehframe_section")
997  orc_rt_macho_deregister_ehframe_section = ExecutorAddr(Sym->getAddress());
998 
999  if (orc_rt_macho_register_ehframe_section &&
1000  orc_rt_macho_deregister_ehframe_section)
1001  break;
1002  }
1003 
1004  // If we failed to find the required functions then bail out.
1005  if (!orc_rt_macho_register_ehframe_section ||
1006  !orc_rt_macho_deregister_ehframe_section)
1007  return make_error<StringError>("Could not find eh-frame registration "
1008  "functions during platform bootstrap",
1010 
1011  // Otherwise, add allocation actions to the graph to register eh-frames for
1012  // this object.
1013  G.allocActions().push_back(
1014  {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1015  orc_rt_macho_register_ehframe_section, R.getRange())),
1016  cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1017  orc_rt_macho_deregister_ehframe_section, R.getRange()))});
1018 
1019  return Error::success();
1020 }
1021 
1022 } // End namespace orc.
1023 } // End namespace llvm.
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:30
llvm::IntrusiveRefCntPtr::get
T * get() const
Definition: IntrusiveRefCntPtr.h:200
llvm::orc::MachOPlatform::notifyRemoving
Error notifyRemoving(ResourceTracker &RT) override
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
Definition: MachOPlatform.cpp:271
llvm::orc::MaterializationResponsibility
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:519
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::orc::JITDylib
Represents a JIT'd dynamic library.
Definition: Core.h:946
llvm::msgpack::Endianness
constexpr support::endianness Endianness
The endianness of all multi-byte encoded values in MessagePack.
Definition: MsgPack.h:24
llvm::AArch64CC::AL
@ AL
Definition: AArch64BaseInfo.h:269
llvm::orc::shared::SPSSequence
SPS tag type for sequences.
Definition: SimplePackedSerialization.h:205
llvm::ARM::PredBlockMask::TT
@ TT
llvm::MachO::mach_header_64::flags
uint32_t flags
Definition: MachO.h:528
llvm::support::endian::read32
uint32_t read32(const void *P, endianness E)
Definition: Endian.h:363
llvm::orc::shared::SPSSerializationTraits
Specialize to describe how to serialize/deserialize to/from the given concrete type.
Definition: SimplePackedSerialization.h:105
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
BinaryByteStream.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::orc::SymbolLookupSet
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:175
llvm::orc::shared::SPSOutputBuffer
Output char buffer with overflow check.
Definition: SimplePackedSerialization.h:54
llvm::orc::LookupKind::Static
@ Static
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:57
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::orc::MachOPlatform::teardownJITDylib
Error teardownJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...
Definition: MachOPlatform.cpp:242
llvm::orc::ExecutorAddr::getValue
uint64_t getValue() const
Definition: ExecutorAddress.h:62
llvm::orc::shared
Definition: ELFNixPlatform.h:245
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:86
llvm::orc::ResourceTracker
API to remove / transfer ownership of JIT resources.
Definition: Core.h:53
llvm::copy
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1668
llvm::Optional
Definition: APInt.h:33
llvm::DenseMapBase::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:147
llvm::orc::shared::SPSInputBuffer
Input char buffer with underflow check.
Definition: SimplePackedSerialization.h:74
llvm::MachO::mach_header_64::ncmds
uint32_t ncmds
Definition: MachO.h:526
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::orc::shared::SPSTuple
SPS tag type for tuples.
Definition: SimplePackedSerialization.h:195
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::count
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:665
llvm::MachO::CPU_TYPE_X86_64
@ CPU_TYPE_X86_64
Definition: MachO.h:1445
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
ExecutionUtils.h
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:241
DebugUtils.h
llvm::orc::MaterializationUnit::getName
virtual StringRef getName() const =0
Return the name of this materialization unit.
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::orc::MachOPlatform::Create
static Expected< std::unique_ptr< MachOPlatform > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, Optional< SymbolAliasMap > RuntimeAliases=None)
Try to create a MachOPlatform instance, adding the ORC runtime to the given JITDylib.
Definition: MachOPlatform.cpp:188
llvm::orc::ResourceTracker::getJITDylib
JITDylib & getJITDylib() const
Return the JITDylib targeted by this tracker.
Definition: Core.h:68
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
llvm::orc::ExecutionSession::registerJITDispatchHandlers
Error registerJITDispatchHandlers(JITDylib &JD, JITDispatchHandlerAssociationMap WFs)
For each tag symbol name, associate the corresponding AsyncHandlerWrapperFunction with the address of...
Definition: Core.cpp:2185
llvm::orc::MachOPlatform::requiredCXXAliases
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Definition: MachOPlatform.cpp:293
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::support::little
@ little
Definition: Endian.h:27
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDepInfo, MachOPlatform::MachOJITDylibDepInfo >::serialize
static bool serialize(SPSOutputBuffer &OB, const MachOPlatform::MachOJITDylibDepInfo &DDI)
Definition: MachOPlatform.cpp:41
llvm::orc
Definition: CompileOnDemandLayer.h:54
llvm::orc::NoDependenciesToRegister
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:34
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:486
llvm::AArch64CC::HS
@ HS
Definition: AArch64BaseInfo.h:257
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachO::mach_header_64::reserved
uint32_t reserved
Definition: MachO.h:529
llvm::orc::ExecutionSession::intern
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1409
llvm::orc::JITDylib::addGenerator
GeneratorT & addGenerator(std::unique_ptr< GeneratorT > DefGenerator)
Adds a definition generator to this JITDylib and returns a referenece to it.
Definition: Core.h:1782
llvm::orc::shared::SPSExecutorAddr
Definition: ExecutorAddress.h:185
llvm::orc::ExecutionSession::runSessionLocked
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1419
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1097
llvm::orc::MaterializationUnit::Interface
Definition: Core.h:672
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1027
llvm::orc::MachOPlatform
Mediates between MachO initialization and ExecutionSession state.
Definition: MachOPlatform.h:30
llvm::MachO::mach_header_64::magic
uint32_t magic
Definition: MachO.h:522
llvm::orc::SymbolLookupFlags::WeaklyReferencedSymbol
@ WeaklyReferencedSymbol
llvm::orc::MachOPlatform::isInitializerSection
static bool isInitializerSection(StringRef SegName, StringRef SectName)
Returns true if the given section name is an initializer section.
Definition: MachOPlatform.cpp:315
llvm::orc::MaterializationResponsibility::getInitializerSymbol
const SymbolStringPtr & getInitializerSymbol() const
Returns the initialization pseudo-symbol, if any.
Definition: Core.h:552
llvm::orc::MachOPlatform::notifyAdding
Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override
This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...
Definition: MachOPlatform.cpp:255
llvm::MachO::mach_header_64
Definition: MachO.h:521
llvm::orc::MachOPlatform::MachOJITDylibDepInfo
Definition: MachOPlatform.h:33
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
llvm::orc::MaterializationResponsibility::getTargetJITDylib
JITDylib & getTargetJITDylib() const
Returns the target JITDylib that these symbols are being materialized into.
Definition: Core.h:538
uint64_t
llvm::MachO::MH_MAGIC_64
@ MH_MAGIC_64
Definition: MachO.h:32
llvm::orc::MaterializationUnit::getInitializerSymbol
const SymbolStringPtr & getInitializerSymbol() const
Returns the initialization symbol for this MaterializationUnit (if any).
Definition: Core.h:698
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDepInfo, MachOPlatform::MachOJITDylibDepInfo >::deserialize
static bool deserialize(SPSInputBuffer &IB, MachOPlatform::MachOJITDylibDepInfo &DDI)
Definition: MachOPlatform.cpp:47
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::orc::shared::SPSExpected
SPS tag type for expecteds, which are either a T or a string representing an error.
Definition: SimplePackedSerialization.h:548
llvm::DenseMap< SymbolStringPtr, JITSymbolFlags >
LookupAndRecordAddrs.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
size
i< reg-> size
Definition: README.txt:166
llvm::MachO::CPU_TYPE_ARM64
@ CPU_TYPE_ARM64
Definition: MachO.h:1449
llvm::MachO::CPU_SUBTYPE_ARM64_ALL
@ CPU_SUBTYPE_ARM64_ALL
Definition: MachO.h:1520
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1675
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::orc::ExecutionSession::callSPSWrapper
Error callSPSWrapper(ExecutorAddr WrapperFnAddr, WrapperCallArgTs &&...WrapperCallArgs)
Run a wrapper function using SPS to serialize the arguments and deserialize the results.
Definition: Core.h:1603
llvm::orc::ExecutionSession::getExecutorProcessControl
ExecutorProcessControl & getExecutorProcessControl()
Get the ExecutorProcessControl object associated with this ExecutionSession.
Definition: Core.h:1401
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Reloc::Static
@ Static
Definition: CodeGen.h:22
MachOPlatform.h
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::orc::StaticLibraryDefinitionGenerator::Load
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Load(ObjectLayer &L, const char *FileName, GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())
Try to create a StaticLibraryDefinitionGenerator from the given path.
Definition: ExecutionUtils.cpp:273
x86_64.h
llvm::orc::ObjectLinkingLayer
An ObjectLayer implementation built on JITLink.
Definition: ObjectLinkingLayer.h:50
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1644
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::empty
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:98
llvm::orc::MachOPlatform::setupJITDylib
Error setupJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is created (unless it is cre...
Definition: MachOPlatform.cpp:234
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::MachO::MH_DYLIB
@ MH_DYLIB
Definition: MachO.h:48
llvm::empty
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Definition: STLExtras.h:268
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
H
#define H(x, y, z)
Definition: MD5.cpp:57
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
llvm::orc::ObjectLinkingLayer::addPlugin
ObjectLinkingLayer & addPlugin(std::unique_ptr< Plugin > P)
Add a pass-config modifier.
Definition: ObjectLinkingLayer.h:126
llvm::orc::addAliases
static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, ArrayRef< std::pair< const char *, const char * >> AL)
Definition: ELFNixPlatform.cpp:190
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::orc::MachOPlatform::MachOJITDylibDepInfo::Sealed
bool Sealed
Definition: MachOPlatform.h:34
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1358
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDepInfo, MachOPlatform::MachOJITDylibDepInfo >::size
static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI)
Definition: MachOPlatform.cpp:37
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:801
llvm::support::endian::byte_swap
value_type byte_swap(value_type value, endianness endian)
Definition: Endian.h:49
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::size
unsigned size() const
Definition: DenseMap.h:101
llvm::orc::symbolAliases
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
Definition: Core.h:802
llvm::orc::MachOPlatform::standardRuntimeUtilityAliases
static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()
Returns the array of standard runtime utility aliases for MachO.
Definition: MachOPlatform.cpp:301
llvm::orc::absoluteSymbols
std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols)
Create an AbsoluteSymbolsMaterializationUnit with the given symbols.
Definition: Core.h:756
llvm::support::endian::system_endianness
constexpr endianness system_endianness()
Definition: Endian.h:44
llvm::MachO::CPU_SUBTYPE_X86_64_ALL
@ CPU_SUBTYPE_X86_64_ALL
Definition: MachO.h:1490
llvm::MachO::mach_header_64::sizeofcmds
uint32_t sizeofcmds
Definition: MachO.h:527
llvm::orc::JITDylib::define
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition: Core.h:1799
llvm::MachO::mach_header_64::cpusubtype
uint32_t cpusubtype
Definition: MachO.h:524
llvm::orc::MachOPlatform::MachOJITDylibDepInfo::DepHeaders
std::vector< ExecutorAddr > DepHeaders
Definition: MachOPlatform.h:35
llvm::orc::ExecutionSession::lookup
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Definition: Core.cpp:2076
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::reserve
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition: DenseMap.h:105
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::orc::MachOPlatform::standardPlatformAliases
static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)
Returns an AliasMap containing the default aliases for the MachOPlatform.
Definition: MachOPlatform.cpp:285
llvm::orc::ExecutionSession::wrapAsyncWithSPS
static JITDispatchHandlerFunction wrapAsyncWithSPS(HandlerT &&H)
Wrap a handler that takes concrete argument types (and a sender for a concrete return type) to produc...
Definition: Core.h:1617
MachO.h
llvm::MachO::swapStruct
void swapStruct(fat_header &mh)
Definition: MachO.h:1028
llvm::MachO::mach_header_64::cputype
uint32_t cputype
Definition: MachO.h:523
Debug.h
llvm::orc::shared::SPSArgList
A utility class for serializing to a blob from a variadic list.
Definition: SimplePackedSerialization.h:108
llvm::IntrusiveRefCntPtr
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
Definition: IntrusiveRefCntPtr.h:168
llvm::orc::makeJITDylibSearchOrder
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition: Core.h:158
llvm::MachO::mach_header_64::filetype
uint32_t filetype
Definition: MachO.h:525
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:51
llvm::orc::lookupAndRecordAddrs
void lookupAndRecordAddrs(unique_function< void(Error)> OnRecorded, ExecutionSession &ES, LookupKind K, const JITDylibSearchOrder &SearchOrder, std::vector< std::pair< SymbolStringPtr, ExecutorAddr * >> Pairs, SymbolLookupFlags LookupFlags=SymbolLookupFlags::RequiredSymbol)
Record addresses of the given symbols in the given ExecutorAddrs.
Definition: LookupAndRecordAddrs.cpp:16
llvm::JITSymbolFlags::Exported
@ Exported
Definition: JITSymbol.h:85
llvm::orc::MachOPlatform::getExecutionSession
ExecutionSession & getExecutionSession() const
Definition: MachOPlatform.h:85