LLVM  16.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 #include <optional>
19 
20 #define DEBUG_TYPE "orc"
21 
22 using namespace llvm;
23 using namespace llvm::orc;
24 using namespace llvm::orc::shared;
25 
26 namespace llvm {
27 namespace orc {
28 namespace shared {
29 
33 
34 template <>
36  MachOPlatform::MachOJITDylibDepInfo> {
37 public:
38  static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI) {
40  }
41 
44  return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.Sealed,
45  DDI.DepHeaders);
46  }
47 
50  return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.Sealed,
51  DDI.DepHeaders);
52  }
53 };
54 
55 } // namespace shared
56 } // namespace orc
57 } // namespace llvm
58 
59 namespace {
60 
61 class MachOHeaderMaterializationUnit : public MaterializationUnit {
62 public:
63  MachOHeaderMaterializationUnit(MachOPlatform &MOP,
64  const SymbolStringPtr &HeaderStartSymbol)
65  : MaterializationUnit(createHeaderInterface(MOP, HeaderStartSymbol)),
66  MOP(MOP) {}
67 
68  StringRef getName() const override { return "MachOHeaderMU"; }
69 
70  void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
71  unsigned PointerSize;
73  const auto &TT =
74  MOP.getExecutionSession().getExecutorProcessControl().getTargetTriple();
75 
76  switch (TT.getArch()) {
77  case Triple::aarch64:
78  case Triple::x86_64:
79  PointerSize = 8;
81  break;
82  default:
83  llvm_unreachable("Unrecognized architecture");
84  }
85 
86  auto G = std::make_unique<jitlink::LinkGraph>(
87  "<MachOHeaderMU>", TT, PointerSize, Endianness,
89  auto &HeaderSection = G->createSection("__header", MemProt::Read);
90  auto &HeaderBlock = createHeaderBlock(*G, HeaderSection);
91 
92  // Init symbol is header-start symbol.
93  G->addDefinedSymbol(HeaderBlock, 0, *R->getInitializerSymbol(),
94  HeaderBlock.getSize(), jitlink::Linkage::Strong,
95  jitlink::Scope::Default, false, true);
96  for (auto &HS : AdditionalHeaderSymbols)
97  G->addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name,
98  HeaderBlock.getSize(), jitlink::Linkage::Strong,
99  jitlink::Scope::Default, false, true);
100 
101  MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));
102  }
103 
104  void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}
105 
106 private:
107  struct HeaderSymbol {
108  const char *Name;
110  };
111 
112  static constexpr HeaderSymbol AdditionalHeaderSymbols[] = {
113  {"___mh_executable_header", 0}};
114 
115  static jitlink::Block &createHeaderBlock(jitlink::LinkGraph &G,
116  jitlink::Section &HeaderSection) {
119  switch (G.getTargetTriple().getArch()) {
120  case Triple::aarch64:
123  break;
124  case Triple::x86_64:
127  break;
128  default:
129  llvm_unreachable("Unrecognized architecture");
130  }
131  Hdr.filetype = MachO::MH_DYLIB; // Custom file type?
132  Hdr.ncmds = 0;
133  Hdr.sizeofcmds = 0;
134  Hdr.flags = 0;
135  Hdr.reserved = 0;
136 
137  if (G.getEndianness() != support::endian::system_endianness())
138  MachO::swapStruct(Hdr);
139 
140  auto HeaderContent = G.allocateString(
141  StringRef(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
142 
143  return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
144  0);
145  }
146 
148  createHeaderInterface(MachOPlatform &MOP,
149  const SymbolStringPtr &HeaderStartSymbol) {
150  SymbolFlagsMap HeaderSymbolFlags;
151 
152  HeaderSymbolFlags[HeaderStartSymbol] = JITSymbolFlags::Exported;
153  for (auto &HS : AdditionalHeaderSymbols)
154  HeaderSymbolFlags[MOP.getExecutionSession().intern(HS.Name)] =
156 
157  return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),
158  HeaderStartSymbol);
159  }
160 
161  MachOPlatform &MOP;
162 };
163 
164 constexpr MachOHeaderMaterializationUnit::HeaderSymbol
165  MachOHeaderMaterializationUnit::AdditionalHeaderSymbols[];
166 
167 StringRef DataCommonSectionName = "__DATA,__common";
168 StringRef DataDataSectionName = "__DATA,__data";
169 StringRef EHFrameSectionName = "__TEXT,__eh_frame";
170 StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
171 StringRef ObjCClassListSectionName = "__DATA,__objc_classlist";
172 StringRef ObjCImageInfoSectionName = "__DATA,__objc_image_info";
173 StringRef ObjCSelRefsSectionName = "__DATA,__objc_selrefs";
174 StringRef Swift5ProtoSectionName = "__TEXT,__swift5_proto";
175 StringRef Swift5ProtosSectionName = "__TEXT,__swift5_protos";
176 StringRef Swift5TypesSectionName = "__TEXT,__swift5_types";
177 StringRef ThreadBSSSectionName = "__DATA,__thread_bss";
178 StringRef ThreadDataSectionName = "__DATA,__thread_data";
179 StringRef ThreadVarsSectionName = "__DATA,__thread_vars";
180 
181 StringRef InitSectionNames[] = {
182  ModInitFuncSectionName, ObjCSelRefsSectionName, ObjCClassListSectionName,
183  Swift5ProtosSectionName, Swift5ProtoSectionName, Swift5TypesSectionName};
184 
185 } // end anonymous namespace
186 
187 namespace llvm {
188 namespace orc {
189 
192  JITDylib &PlatformJD, const char *OrcRuntimePath,
193  Optional<SymbolAliasMap> RuntimeAliases) {
194 
195  auto &EPC = ES.getExecutorProcessControl();
196 
197  // If the target is not supported then bail out immediately.
198  if (!supportedTarget(EPC.getTargetTriple()))
199  return make_error<StringError>("Unsupported MachOPlatform triple: " +
200  EPC.getTargetTriple().str(),
202 
203  // Create default aliases if the caller didn't supply any.
204  if (!RuntimeAliases)
205  RuntimeAliases = standardPlatformAliases(ES);
206 
207  // Define the aliases.
208  if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))
209  return std::move(Err);
210 
211  // Add JIT-dispatch function support symbols.
212  if (auto Err = PlatformJD.define(absoluteSymbols(
213  {{ES.intern("___orc_rt_jit_dispatch"),
214  {EPC.getJITDispatchInfo().JITDispatchFunction.getValue(),
216  {ES.intern("___orc_rt_jit_dispatch_ctx"),
217  {EPC.getJITDispatchInfo().JITDispatchContext.getValue(),
219  return std::move(Err);
220 
221  // Create a generator for the ORC runtime archive.
222  auto OrcRuntimeArchiveGenerator = StaticLibraryDefinitionGenerator::Load(
223  ObjLinkingLayer, OrcRuntimePath, EPC.getTargetTriple());
224  if (!OrcRuntimeArchiveGenerator)
225  return OrcRuntimeArchiveGenerator.takeError();
226 
227  // Create the instance.
228  Error Err = Error::success();
229  auto P = std::unique_ptr<MachOPlatform>(
230  new MachOPlatform(ES, ObjLinkingLayer, PlatformJD,
231  std::move(*OrcRuntimeArchiveGenerator), Err));
232  if (Err)
233  return std::move(Err);
234  return std::move(P);
235 }
236 
238  if (auto Err = JD.define(std::make_unique<MachOHeaderMaterializationUnit>(
239  *this, MachOHeaderStartSymbol)))
240  return Err;
241 
242  return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
243 }
244 
246  std::lock_guard<std::mutex> Lock(PlatformMutex);
247  auto I = JITDylibToHeaderAddr.find(&JD);
248  if (I != JITDylibToHeaderAddr.end()) {
249  assert(HeaderAddrToJITDylib.count(I->second) &&
250  "HeaderAddrToJITDylib missing entry");
251  HeaderAddrToJITDylib.erase(I->second);
252  JITDylibToHeaderAddr.erase(I);
253  }
254  JITDylibToPThreadKey.erase(&JD);
255  return Error::success();
256 }
257 
259  const MaterializationUnit &MU) {
260  auto &JD = RT.getJITDylib();
261  const auto &InitSym = MU.getInitializerSymbol();
262  if (!InitSym)
263  return Error::success();
264 
265  RegisteredInitSymbols[&JD].add(InitSym,
267  LLVM_DEBUG({
268  dbgs() << "MachOPlatform: Registered init symbol " << *InitSym << " for MU "
269  << MU.getName() << "\n";
270  });
271  return Error::success();
272 }
273 
275  llvm_unreachable("Not supported yet");
276 }
277 
278 static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
279  ArrayRef<std::pair<const char *, const char *>> AL) {
280  for (auto &KV : AL) {
281  auto AliasName = ES.intern(KV.first);
282  assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
283  Aliases[std::move(AliasName)] = {ES.intern(KV.second),
285  }
286 }
287 
289  SymbolAliasMap Aliases;
290  addAliases(ES, Aliases, requiredCXXAliases());
291  addAliases(ES, Aliases, standardRuntimeUtilityAliases());
292  return Aliases;
293 }
294 
297  static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
298  {"___cxa_atexit", "___orc_rt_macho_cxa_atexit"}};
299 
300  return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases);
301 }
302 
305  static const std::pair<const char *, const char *>
306  StandardRuntimeUtilityAliases[] = {
307  {"___orc_rt_run_program", "___orc_rt_macho_run_program"},
308  {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
309  {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
310  {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
311  {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
312  {"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
313 
315  StandardRuntimeUtilityAliases);
316 }
317 
319  StringRef SectName) {
320  for (auto &Name : InitSectionNames) {
321  if (Name.startswith(SegName) && Name.substr(7) == SectName)
322  return true;
323  }
324  return false;
325 }
326 
327 bool MachOPlatform::supportedTarget(const Triple &TT) {
328  switch (TT.getArch()) {
329  case Triple::aarch64:
330  case Triple::x86_64:
331  return true;
332  default:
333  return false;
334  }
335 }
336 
337 MachOPlatform::MachOPlatform(
338  ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
339  JITDylib &PlatformJD,
340  std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator, Error &Err)
341  : ES(ES), ObjLinkingLayer(ObjLinkingLayer),
342  MachOHeaderStartSymbol(ES.intern("___dso_handle")) {
343  ErrorAsOutParameter _(&Err);
344 
345  ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*this));
346 
347  PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
348 
349  // Force linking of eh-frame registration functions.
350  if (auto Err2 = lookupAndRecordAddrs(
352  {{ES.intern("___orc_rt_macho_register_ehframe_section"),
353  &orc_rt_macho_register_ehframe_section},
354  {ES.intern("___orc_rt_macho_deregister_ehframe_section"),
355  &orc_rt_macho_deregister_ehframe_section}})) {
356  Err = std::move(Err2);
357  return;
358  }
359 
360  State = BootstrapPhase2;
361 
362  // Associate wrapper function tags with JIT-side function implementations.
363  if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
364  Err = std::move(E2);
365  return;
366  }
367 
368  // Lookup addresses of runtime functions callable by the platform,
369  // call the platform bootstrap function to initialize the platform-state
370  // object in the executor.
371  if (auto E2 = bootstrapMachORuntime(PlatformJD)) {
372  Err = std::move(E2);
373  return;
374  }
375 
376  // PlatformJD hasn't been set up by the platform yet (since we're creating
377  // the platform now), so set it up.
378  if (auto E2 = setupJITDylib(PlatformJD)) {
379  Err = std::move(E2);
380  return;
381  }
382 
383  State = Initialized;
384 }
385 
386 Error MachOPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
388 
389  using PushInitializersSPSSig =
391  WFs[ES.intern("___orc_rt_macho_push_initializers_tag")] =
392  ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
393  this, &MachOPlatform::rt_pushInitializers);
394 
395  using LookupSymbolSPSSig =
397  WFs[ES.intern("___orc_rt_macho_symbol_lookup_tag")] =
398  ES.wrapAsyncWithSPS<LookupSymbolSPSSig>(this,
399  &MachOPlatform::rt_lookupSymbol);
400 
401  return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
402 }
403 
404 void MachOPlatform::pushInitializersLoop(
405  PushInitializersSendResultFn SendResult, JITDylibSP JD) {
408  SmallVector<JITDylib *, 16> Worklist({JD.get()});
409 
410  ES.runSessionLocked([&]() {
411  while (!Worklist.empty()) {
412  // FIXME: Check for defunct dylibs.
413 
414  auto DepJD = Worklist.back();
415  Worklist.pop_back();
416 
417  // If we've already visited this JITDylib on this iteration then continue.
418  if (JDDepMap.count(DepJD))
419  continue;
420 
421  // Add dep info.
422  auto &DM = JDDepMap[DepJD];
423  DepJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) {
424  for (auto &KV : O) {
425  if (KV.first == DepJD)
426  continue;
427  DM.push_back(KV.first);
428  Worklist.push_back(KV.first);
429  }
430  });
431 
432  // Add any registered init symbols.
433  auto RISItr = RegisteredInitSymbols.find(DepJD);
434  if (RISItr != RegisteredInitSymbols.end()) {
435  NewInitSymbols[DepJD] = std::move(RISItr->second);
436  RegisteredInitSymbols.erase(RISItr);
437  }
438  }
439  });
440 
441  // If there are no further init symbols to look up then send the link order
442  // (as a list of header addresses) to the caller.
443  if (NewInitSymbols.empty()) {
444 
445  // To make the list intelligible to the runtime we need to convert all
446  // JITDylib pointers to their header addresses. Only include JITDylibs
447  // that appear in the JITDylibToHeaderAddr map (i.e. those that have been
448  // through setupJITDylib) -- bare JITDylibs aren't managed by the platform.
450  HeaderAddrs.reserve(JDDepMap.size());
451  {
452  std::lock_guard<std::mutex> Lock(PlatformMutex);
453  for (auto &KV : JDDepMap) {
454  auto I = JITDylibToHeaderAddr.find(KV.first);
455  if (I != JITDylibToHeaderAddr.end())
456  HeaderAddrs[KV.first] = I->second;
457  }
458  }
459 
460  // Build the dep info map to return.
461  MachOJITDylibDepInfoMap DIM;
462  DIM.reserve(JDDepMap.size());
463  for (auto &KV : JDDepMap) {
464  auto HI = HeaderAddrs.find(KV.first);
465  // Skip unmanaged JITDylibs.
466  if (HI == HeaderAddrs.end())
467  continue;
468  auto H = HI->second;
469  MachOJITDylibDepInfo DepInfo;
470  for (auto &Dep : KV.second) {
471  auto HJ = HeaderAddrs.find(Dep);
472  if (HJ != HeaderAddrs.end())
473  DepInfo.DepHeaders.push_back(HJ->second);
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 (ObjCImageInfoBlocks.empty())
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)) {
824  std::optional<uint64_t> Key;
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  // Collect data sections to register.
917  StringRef DataSections[] = {DataDataSectionName, DataCommonSectionName};
918  for (auto &SecName : DataSections) {
919  if (auto *Sec = G.findSectionByName(SecName)) {
920  jitlink::SectionRange R(*Sec);
921  if (!R.empty())
922  MachOPlatformSecs.push_back({SecName, R.getRange()});
923  }
924  }
925 
926  // If any platform sections were found then add an allocation action to call
927  // the registration function.
928  bool RegistrationRequired = false;
929  StringRef PlatformSections[] = {
930  ModInitFuncSectionName, ObjCClassListSectionName,
931  ObjCImageInfoSectionName, ObjCSelRefsSectionName,
932  Swift5ProtoSectionName, Swift5ProtosSectionName,
933  Swift5TypesSectionName,
934  };
935 
936  for (auto &SecName : PlatformSections) {
937  auto *Sec = G.findSectionByName(SecName);
938  if (!Sec)
939  continue;
940  jitlink::SectionRange R(*Sec);
941  if (R.empty())
942  continue;
943 
944  RegistrationRequired = true;
945  MachOPlatformSecs.push_back({SecName, R.getRange()});
946  }
947 
948  if (!MachOPlatformSecs.empty()) {
949  std::optional<ExecutorAddr> HeaderAddr;
950  {
951  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
952  auto I = MP.JITDylibToHeaderAddr.find(&JD);
953  if (I != MP.JITDylibToHeaderAddr.end())
954  HeaderAddr = I->second;
955  }
956 
957  if (!HeaderAddr) {
958  // If we only found data sections and we're not done bootstrapping yet
959  // then continue -- this must be a data section for the runtime itself,
960  // and we don't need to register those.
961  if (MP.State != MachOPlatform::Initialized && !RegistrationRequired)
962  return Error::success();
963 
964  return make_error<StringError>("Missing header for " + JD.getName(),
966  }
967 
968  // Dump the scraped inits.
969  LLVM_DEBUG({
970  dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
971  for (auto &KV : MachOPlatformSecs)
972  dbgs() << " " << KV.first << ": " << KV.second << "\n";
973  });
974 
975  using SPSRegisterObjectPlatformSectionsArgs =
978  G.allocActions().push_back(
979  {cantFail(
980  WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
981  MP.orc_rt_macho_register_object_platform_sections, *HeaderAddr,
982  MachOPlatformSecs)),
983  cantFail(
984  WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
985  MP.orc_rt_macho_deregister_object_platform_sections,
986  *HeaderAddr, MachOPlatformSecs))});
987  }
988 
989  return Error::success();
990 }
991 
992 Error MachOPlatform::MachOPlatformPlugin::registerEHSectionsPhase1(
994 
995  // If there's no eh-frame there's nothing to do.
996  auto *EHFrameSection = G.findSectionByName(EHFrameSectionName);
997  if (!EHFrameSection)
998  return Error::success();
999 
1000  // If the eh-frame section is empty there's nothing to do.
1001  jitlink::SectionRange R(*EHFrameSection);
1002  if (R.empty())
1003  return Error::success();
1004 
1005  // Since we're linking the object containing the registration code now the
1006  // addresses won't be ready in the platform. We'll have to find them in this
1007  // graph instead.
1008  ExecutorAddr orc_rt_macho_register_ehframe_section;
1009  ExecutorAddr orc_rt_macho_deregister_ehframe_section;
1010  for (auto *Sym : G.defined_symbols()) {
1011  if (!Sym->hasName())
1012  continue;
1013  if (Sym->getName() == "___orc_rt_macho_register_ehframe_section")
1014  orc_rt_macho_register_ehframe_section = ExecutorAddr(Sym->getAddress());
1015  else if (Sym->getName() == "___orc_rt_macho_deregister_ehframe_section")
1016  orc_rt_macho_deregister_ehframe_section = ExecutorAddr(Sym->getAddress());
1017 
1018  if (orc_rt_macho_register_ehframe_section &&
1019  orc_rt_macho_deregister_ehframe_section)
1020  break;
1021  }
1022 
1023  // If we failed to find the required functions then bail out.
1024  if (!orc_rt_macho_register_ehframe_section ||
1025  !orc_rt_macho_deregister_ehframe_section)
1026  return make_error<StringError>("Could not find eh-frame registration "
1027  "functions during platform bootstrap",
1029 
1030  // Otherwise, add allocation actions to the graph to register eh-frames for
1031  // this object.
1032  G.allocActions().push_back(
1033  {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1034  orc_rt_macho_register_ehframe_section, R.getRange())),
1035  cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1036  orc_rt_macho_deregister_ehframe_section, R.getRange()))});
1037 
1038  return Error::success();
1039 }
1040 
1041 } // End namespace orc.
1042 } // End namespace llvm.
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:31
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:274
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:20
llvm::AArch64CC::HI
@ HI
Definition: AArch64BaseInfo.h:263
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::orc::JITDylib
Represents a JIT'd dynamic library.
Definition: Core.h:953
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:533
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:1199
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:245
llvm::orc::ExecutorAddr::getValue
uint64_t getValue() const
Definition: ExecutorAddress.h:105
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:1811
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:145
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:531
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:1564
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
ExecutionUtils.h
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:265
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:191
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:296
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:42
llvm::orc::MemProt::Read
@ Read
llvm::orc
Definition: COFFPlatform.h:30
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:35
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:534
llvm::orc::ExecutionSession::intern
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1416
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:1789
llvm::orc::shared::SPSExecutorAddr
Definition: ExecutorAddress.h:228
llvm::orc::ExecutionSession::runSessionLocked
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1426
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1096
llvm::orc::MaterializationUnit::Interface
Definition: Core.h:672
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
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:527
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:318
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:258
llvm::MachO::mach_header_64
Definition: MachO.h:526
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::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:48
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
llvm::AArch64PACKey::IB
@ IB
Definition: AArch64BaseInfo.h:820
size
i< reg-> size
Definition: README.txt:166
llvm::MachO::CPU_TYPE_ARM64
@ CPU_TYPE_ARM64
Definition: MachO.h:1568
llvm::MachO::CPU_SUBTYPE_ARM64_ALL
@ CPU_SUBTYPE_ARM64_ALL
Definition: MachO.h:1639
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
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:1836
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:1610
llvm::orc::ExecutionSession::getExecutorProcessControl
ExecutorProcessControl & getExecutorProcessControl()
Get the ExecutorProcessControl object associated with this ExecutionSession.
Definition: Core.h:1408
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:806
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::empty
bool empty() const
Definition: DenseMap.h:98
_
#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:50
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:744
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:274
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:1736
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:237
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::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: COFFPlatform.cpp:224
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:84
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:1365
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDepInfo, MachOPlatform::MachOJITDylibDepInfo >::size
static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI)
Definition: MachOPlatform.cpp:38
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:99
llvm::orc::symbolAliases
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
Definition: Core.h:809
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:304
llvm::orc::absoluteSymbols
std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols)
Create an AbsoluteSymbolsMaterializationUnit with the given symbols.
Definition: Core.h:763
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:1609
llvm::MachO::mach_header_64::sizeofcmds
uint32_t sizeofcmds
Definition: MachO.h:532
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:1806
llvm::MachO::mach_header_64::cpusubtype
uint32_t cpusubtype
Definition: MachO.h:529
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:103
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:288
llvm::omp::RTLDependInfoFields::Flags
@ Flags
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:1624
MachO.h
llvm::MachO::MH_MAGIC_64
@ MH_MAGIC_64
Definition: MachO.h:32
llvm::MachO::swapStruct
void swapStruct(fat_header &mh)
Definition: MachO.h:1139
llvm::MachO::mach_header_64::cputype
uint32_t cputype
Definition: MachO.h:528
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:530
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