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 
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 DataCommonSectionName = "__DATA,__common";
167 StringRef DataDataSectionName = "__DATA,__data";
168 StringRef EHFrameSectionName = "__TEXT,__eh_frame";
169 StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
170 StringRef ObjCClassListSectionName = "__DATA,__objc_classlist";
171 StringRef ObjCImageInfoSectionName = "__DATA,__objc_image_info";
172 StringRef ObjCSelRefsSectionName = "__DATA,__objc_selrefs";
173 StringRef Swift5ProtoSectionName = "__TEXT,__swift5_proto";
174 StringRef Swift5ProtosSectionName = "__TEXT,__swift5_protos";
175 StringRef Swift5TypesSectionName = "__TEXT,__swift5_types";
176 StringRef ThreadBSSSectionName = "__DATA,__thread_bss";
177 StringRef ThreadDataSectionName = "__DATA,__thread_data";
178 StringRef ThreadVarsSectionName = "__DATA,__thread_vars";
179 
180 StringRef InitSectionNames[] = {
181  ModInitFuncSectionName, ObjCSelRefsSectionName, ObjCClassListSectionName,
182  Swift5ProtosSectionName, Swift5ProtoSectionName, Swift5TypesSectionName};
183 
184 } // end anonymous namespace
185 
186 namespace llvm {
187 namespace orc {
188 
191  JITDylib &PlatformJD, const char *OrcRuntimePath,
192  Optional<SymbolAliasMap> RuntimeAliases) {
193 
194  auto &EPC = ES.getExecutorProcessControl();
195 
196  // If the target is not supported then bail out immediately.
197  if (!supportedTarget(EPC.getTargetTriple()))
198  return make_error<StringError>("Unsupported MachOPlatform triple: " +
199  EPC.getTargetTriple().str(),
201 
202  // Create default aliases if the caller didn't supply any.
203  if (!RuntimeAliases)
204  RuntimeAliases = standardPlatformAliases(ES);
205 
206  // Define the aliases.
207  if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))
208  return std::move(Err);
209 
210  // Add JIT-dispatch function support symbols.
211  if (auto Err = PlatformJD.define(absoluteSymbols(
212  {{ES.intern("___orc_rt_jit_dispatch"),
213  {EPC.getJITDispatchInfo().JITDispatchFunction.getValue(),
215  {ES.intern("___orc_rt_jit_dispatch_ctx"),
216  {EPC.getJITDispatchInfo().JITDispatchContext.getValue(),
218  return std::move(Err);
219 
220  // Create a generator for the ORC runtime archive.
221  auto OrcRuntimeArchiveGenerator = StaticLibraryDefinitionGenerator::Load(
222  ObjLinkingLayer, OrcRuntimePath, EPC.getTargetTriple());
223  if (!OrcRuntimeArchiveGenerator)
224  return OrcRuntimeArchiveGenerator.takeError();
225 
226  // Create the instance.
227  Error Err = Error::success();
228  auto P = std::unique_ptr<MachOPlatform>(
229  new MachOPlatform(ES, ObjLinkingLayer, PlatformJD,
230  std::move(*OrcRuntimeArchiveGenerator), Err));
231  if (Err)
232  return std::move(Err);
233  return std::move(P);
234 }
235 
237  if (auto Err = JD.define(std::make_unique<MachOHeaderMaterializationUnit>(
238  *this, MachOHeaderStartSymbol)))
239  return Err;
240 
241  return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
242 }
243 
245  std::lock_guard<std::mutex> Lock(PlatformMutex);
246  auto I = JITDylibToHeaderAddr.find(&JD);
247  if (I != JITDylibToHeaderAddr.end()) {
248  assert(HeaderAddrToJITDylib.count(I->second) &&
249  "HeaderAddrToJITDylib missing entry");
250  HeaderAddrToJITDylib.erase(I->second);
251  JITDylibToHeaderAddr.erase(I);
252  }
253  JITDylibToPThreadKey.erase(&JD);
254  return Error::success();
255 }
256 
258  const MaterializationUnit &MU) {
259  auto &JD = RT.getJITDylib();
260  const auto &InitSym = MU.getInitializerSymbol();
261  if (!InitSym)
262  return Error::success();
263 
264  RegisteredInitSymbols[&JD].add(InitSym,
266  LLVM_DEBUG({
267  dbgs() << "MachOPlatform: Registered init symbol " << *InitSym << " for MU "
268  << MU.getName() << "\n";
269  });
270  return Error::success();
271 }
272 
274  llvm_unreachable("Not supported yet");
275 }
276 
277 static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
278  ArrayRef<std::pair<const char *, const char *>> AL) {
279  for (auto &KV : AL) {
280  auto AliasName = ES.intern(KV.first);
281  assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
282  Aliases[std::move(AliasName)] = {ES.intern(KV.second),
284  }
285 }
286 
288  SymbolAliasMap Aliases;
289  addAliases(ES, Aliases, requiredCXXAliases());
290  addAliases(ES, Aliases, standardRuntimeUtilityAliases());
291  return Aliases;
292 }
293 
296  static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
297  {"___cxa_atexit", "___orc_rt_macho_cxa_atexit"}};
298 
299  return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases);
300 }
301 
304  static const std::pair<const char *, const char *>
305  StandardRuntimeUtilityAliases[] = {
306  {"___orc_rt_run_program", "___orc_rt_macho_run_program"},
307  {"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
308  {"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
309  {"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
310  {"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
311  {"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
312 
314  StandardRuntimeUtilityAliases);
315 }
316 
318  StringRef SectName) {
319  for (auto &Name : InitSectionNames) {
320  if (Name.startswith(SegName) && Name.substr(7) == SectName)
321  return true;
322  }
323  return false;
324 }
325 
326 bool MachOPlatform::supportedTarget(const Triple &TT) {
327  switch (TT.getArch()) {
328  case Triple::aarch64:
329  case Triple::x86_64:
330  return true;
331  default:
332  return false;
333  }
334 }
335 
336 MachOPlatform::MachOPlatform(
337  ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
338  JITDylib &PlatformJD,
339  std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator, Error &Err)
340  : ES(ES), ObjLinkingLayer(ObjLinkingLayer),
341  MachOHeaderStartSymbol(ES.intern("___dso_handle")) {
342  ErrorAsOutParameter _(&Err);
343 
344  ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*this));
345 
346  PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
347 
348  // Force linking of eh-frame registration functions.
349  if (auto Err2 = lookupAndRecordAddrs(
351  {{ES.intern("___orc_rt_macho_register_ehframe_section"),
352  &orc_rt_macho_register_ehframe_section},
353  {ES.intern("___orc_rt_macho_deregister_ehframe_section"),
354  &orc_rt_macho_deregister_ehframe_section}})) {
355  Err = std::move(Err2);
356  return;
357  }
358 
359  State = BootstrapPhase2;
360 
361  // Associate wrapper function tags with JIT-side function implementations.
362  if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
363  Err = std::move(E2);
364  return;
365  }
366 
367  // Lookup addresses of runtime functions callable by the platform,
368  // call the platform bootstrap function to initialize the platform-state
369  // object in the executor.
370  if (auto E2 = bootstrapMachORuntime(PlatformJD)) {
371  Err = std::move(E2);
372  return;
373  }
374 
375  // PlatformJD hasn't been set up by the platform yet (since we're creating
376  // the platform now), so set it up.
377  if (auto E2 = setupJITDylib(PlatformJD)) {
378  Err = std::move(E2);
379  return;
380  }
381 
382  State = Initialized;
383 }
384 
385 Error MachOPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
387 
388  using PushInitializersSPSSig =
390  WFs[ES.intern("___orc_rt_macho_push_initializers_tag")] =
391  ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
392  this, &MachOPlatform::rt_pushInitializers);
393 
394  using LookupSymbolSPSSig =
396  WFs[ES.intern("___orc_rt_macho_symbol_lookup_tag")] =
397  ES.wrapAsyncWithSPS<LookupSymbolSPSSig>(this,
398  &MachOPlatform::rt_lookupSymbol);
399 
400  return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
401 }
402 
403 void MachOPlatform::pushInitializersLoop(
404  PushInitializersSendResultFn SendResult, JITDylibSP JD) {
407  SmallVector<JITDylib *, 16> Worklist({JD.get()});
408 
409  ES.runSessionLocked([&]() {
410  while (!Worklist.empty()) {
411  // FIXME: Check for defunct dylibs.
412 
413  auto DepJD = Worklist.back();
414  Worklist.pop_back();
415 
416  // If we've already visited this JITDylib on this iteration then continue.
417  if (JDDepMap.count(DepJD))
418  continue;
419 
420  // Add dep info.
421  auto &DM = JDDepMap[DepJD];
422  DepJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) {
423  for (auto &KV : O) {
424  if (KV.first == DepJD)
425  continue;
426  DM.push_back(KV.first);
427  Worklist.push_back(KV.first);
428  }
429  });
430 
431  // Add any registered init symbols.
432  auto RISItr = RegisteredInitSymbols.find(DepJD);
433  if (RISItr != RegisteredInitSymbols.end()) {
434  NewInitSymbols[DepJD] = std::move(RISItr->second);
435  RegisteredInitSymbols.erase(RISItr);
436  }
437  }
438  });
439 
440  // If there are no further init symbols to look up then send the link order
441  // (as a list of header addresses) to the caller.
442  if (NewInitSymbols.empty()) {
443 
444  // To make the list intelligible to the runtime we need to convert all
445  // JITDylib pointers to their header addresses. Only include JITDylibs
446  // that appear in the JITDylibToHeaderAddr map (i.e. those that have been
447  // through setupJITDylib) -- bare JITDylibs aren't managed by the platform.
449  HeaderAddrs.reserve(JDDepMap.size());
450  {
451  std::lock_guard<std::mutex> Lock(PlatformMutex);
452  for (auto &KV : JDDepMap) {
453  auto I = JITDylibToHeaderAddr.find(KV.first);
454  if (I != JITDylibToHeaderAddr.end())
455  HeaderAddrs[KV.first] = I->second;
456  }
457  }
458 
459  // Build the dep info map to return.
460  MachOJITDylibDepInfoMap DIM;
461  DIM.reserve(JDDepMap.size());
462  for (auto &KV : JDDepMap) {
463  auto HI = HeaderAddrs.find(KV.first);
464  // Skip unmanaged JITDylibs.
465  if (HI == HeaderAddrs.end())
466  continue;
467  auto H = HI->second;
468  MachOJITDylibDepInfo DepInfo;
469  for (auto &Dep : KV.second) {
470  auto HJ = HeaderAddrs.find(Dep);
471  if (HJ != HeaderAddrs.end())
472  DepInfo.DepHeaders.push_back(HJ->second);
473  }
474  DIM.push_back(std::make_pair(H, std::move(DepInfo)));
475  }
476  SendResult(DIM);
477  return;
478  }
479 
480  // Otherwise issue a lookup and re-run this phase when it completes.
481  lookupInitSymbolsAsync(
482  [this, SendResult = std::move(SendResult), &JD](Error Err) mutable {
483  if (Err)
484  SendResult(std::move(Err));
485  else
486  pushInitializersLoop(std::move(SendResult), JD);
487  },
488  ES, std::move(NewInitSymbols));
489 }
490 
491 void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
492  ExecutorAddr JDHeaderAddr) {
493  JITDylibSP JD;
494  {
495  std::lock_guard<std::mutex> Lock(PlatformMutex);
496  auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
497  if (I != HeaderAddrToJITDylib.end())
498  JD = I->second;
499  }
500 
501  LLVM_DEBUG({
502  dbgs() << "MachOPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";
503  if (JD)
504  dbgs() << "pushing initializers for " << JD->getName() << "\n";
505  else
506  dbgs() << "No JITDylib for header address.\n";
507  });
508 
509  if (!JD) {
510  SendResult(
511  make_error<StringError>("No JITDylib with header addr " +
512  formatv("{0:x}", JDHeaderAddr.getValue()),
514  return;
515  }
516 
517  pushInitializersLoop(std::move(SendResult), JD);
518 }
519 
520 void MachOPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,
522  LLVM_DEBUG({
523  dbgs() << "MachOPlatform::rt_lookupSymbol(\""
524  << formatv("{0:x}", Handle.getValue()) << "\")\n";
525  });
526 
527  JITDylib *JD = nullptr;
528 
529  {
530  std::lock_guard<std::mutex> Lock(PlatformMutex);
531  auto I = HeaderAddrToJITDylib.find(Handle);
532  if (I != HeaderAddrToJITDylib.end())
533  JD = I->second;
534  }
535 
536  if (!JD) {
537  LLVM_DEBUG({
538  dbgs() << " No JITDylib for handle "
539  << formatv("{0:x}", Handle.getValue()) << "\n";
540  });
541  SendResult(make_error<StringError>("No JITDylib associated with handle " +
542  formatv("{0:x}", Handle.getValue()),
544  return;
545  }
546 
547  // Use functor class to work around XL build compiler issue on AIX.
548  class RtLookupNotifyComplete {
549  public:
550  RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult)
551  : SendResult(std::move(SendResult)) {}
552  void operator()(Expected<SymbolMap> Result) {
553  if (Result) {
554  assert(Result->size() == 1 && "Unexpected result map count");
555  SendResult(ExecutorAddr(Result->begin()->second.getAddress()));
556  } else {
557  SendResult(Result.takeError());
558  }
559  }
560 
561  private:
562  SendSymbolAddressFn SendResult;
563  };
564 
565  // FIXME: Proper mangling.
566  auto MangledName = ("_" + SymbolName).str();
567  ES.lookup(
568  LookupKind::DLSym, {{JD, JITDylibLookupFlags::MatchExportedSymbolsOnly}},
569  SymbolLookupSet(ES.intern(MangledName)), SymbolState::Ready,
570  RtLookupNotifyComplete(std::move(SendResult)), NoDependenciesToRegister);
571 }
572 
573 Error MachOPlatform::bootstrapMachORuntime(JITDylib &PlatformJD) {
574  if (auto Err = lookupAndRecordAddrs(
576  {{ES.intern("___orc_rt_macho_platform_bootstrap"),
577  &orc_rt_macho_platform_bootstrap},
578  {ES.intern("___orc_rt_macho_platform_shutdown"),
579  &orc_rt_macho_platform_shutdown},
580  {ES.intern("___orc_rt_macho_register_jitdylib"),
581  &orc_rt_macho_register_jitdylib},
582  {ES.intern("___orc_rt_macho_deregister_jitdylib"),
583  &orc_rt_macho_deregister_jitdylib},
584  {ES.intern("___orc_rt_macho_register_object_platform_sections"),
585  &orc_rt_macho_register_object_platform_sections},
586  {ES.intern("___orc_rt_macho_deregister_object_platform_sections"),
587  &orc_rt_macho_deregister_object_platform_sections},
588  {ES.intern("___orc_rt_macho_create_pthread_key"),
589  &orc_rt_macho_create_pthread_key}}))
590  return Err;
591 
592  return ES.callSPSWrapper<void()>(orc_rt_macho_platform_bootstrap);
593 }
594 
595 Expected<uint64_t> MachOPlatform::createPThreadKey() {
596  if (!orc_rt_macho_create_pthread_key)
597  return make_error<StringError>(
598  "Attempting to create pthread key in target, but runtime support has "
599  "not been loaded yet",
601 
603  if (auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(void)>(
604  orc_rt_macho_create_pthread_key, Result))
605  return std::move(Err);
606  return Result;
607 }
608 
609 void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
611  jitlink::PassConfiguration &Config) {
612 
613  auto PS = MP.State.load();
614 
615  // --- Handle Initializers ---
616  if (auto InitSymbol = MR.getInitializerSymbol()) {
617 
618  // If the initializer symbol is the MachOHeader start symbol then just
619  // register it and then bail out -- the header materialization unit
620  // definitely doesn't need any other passes.
621  if (InitSymbol == MP.MachOHeaderStartSymbol) {
622  Config.PostAllocationPasses.push_back([this, &MR](jitlink::LinkGraph &G) {
623  return associateJITDylibHeaderSymbol(G, MR);
624  });
625  return;
626  }
627 
628  // If the object contains an init symbol other than the header start symbol
629  // then add passes to preserve, process and register the init
630  // sections/symbols.
631  Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) {
632  if (auto Err = preserveInitSections(G, MR))
633  return Err;
634  return processObjCImageInfo(G, MR);
635  });
636  }
637 
638  // --- Add passes for eh-frame and TLV support ---
639  if (PS == MachOPlatform::BootstrapPhase1) {
640  Config.PostFixupPasses.push_back(
641  [this](jitlink::LinkGraph &G) { return registerEHSectionsPhase1(G); });
642  return;
643  }
644 
645  // Insert TLV lowering at the start of the PostPrunePasses, since we want
646  // it to run before GOT/PLT lowering.
647  Config.PostPrunePasses.insert(
648  Config.PostPrunePasses.begin(),
649  [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
650  return fixTLVSectionsAndEdges(G, JD);
651  });
652 
653  // Add a pass to register the final addresses of any special sections in the
654  // object with the runtime.
655  Config.PostAllocationPasses.push_back(
656  [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
657  return registerObjectPlatformSections(G, JD);
658  });
659 }
660 
662 MachOPlatform::MachOPlatformPlugin::getSyntheticSymbolDependencies(
664  std::lock_guard<std::mutex> Lock(PluginMutex);
665  auto I = InitSymbolDeps.find(&MR);
666  if (I != InitSymbolDeps.end()) {
667  SyntheticSymbolDependenciesMap Result;
668  Result[MR.getInitializerSymbol()] = std::move(I->second);
669  InitSymbolDeps.erase(&MR);
670  return Result;
671  }
672  return SyntheticSymbolDependenciesMap();
673 }
674 
675 Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
677  auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
678  return Sym->getName() == *MP.MachOHeaderStartSymbol;
679  });
680  assert(I != G.defined_symbols().end() && "Missing MachO header start symbol");
681 
682  auto &JD = MR.getTargetJITDylib();
683  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
684  auto HeaderAddr = (*I)->getAddress();
685  MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
686  MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
687  G.allocActions().push_back(
688  {cantFail(
689  WrapperFunctionCall::Create<SPSArgList<SPSString, SPSExecutorAddr>>(
690  MP.orc_rt_macho_register_jitdylib, JD.getName(), HeaderAddr)),
691  cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
692  MP.orc_rt_macho_deregister_jitdylib, HeaderAddr))});
693  return Error::success();
694 }
695 
696 Error MachOPlatform::MachOPlatformPlugin::preserveInitSections(
698 
699  JITLinkSymbolSet InitSectionSymbols;
700  for (auto &InitSectionName : InitSectionNames) {
701  // Skip non-init sections.
702  auto *InitSection = G.findSectionByName(InitSectionName);
703  if (!InitSection)
704  continue;
705 
706  // Make a pass over live symbols in the section: those blocks are already
707  // preserved.
708  DenseSet<jitlink::Block *> AlreadyLiveBlocks;
709  for (auto &Sym : InitSection->symbols()) {
710  auto &B = Sym->getBlock();
711  if (Sym->isLive() && Sym->getOffset() == 0 &&
712  Sym->getSize() == B.getSize() && !AlreadyLiveBlocks.count(&B)) {
713  InitSectionSymbols.insert(Sym);
714  AlreadyLiveBlocks.insert(&B);
715  }
716  }
717 
718  // Add anonymous symbols to preserve any not-already-preserved blocks.
719  for (auto *B : InitSection->blocks())
720  if (!AlreadyLiveBlocks.count(B))
721  InitSectionSymbols.insert(
722  &G.addAnonymousSymbol(*B, 0, B->getSize(), false, true));
723  }
724 
725  if (!InitSectionSymbols.empty()) {
726  std::lock_guard<std::mutex> Lock(PluginMutex);
727  InitSymbolDeps[&MR] = std::move(InitSectionSymbols);
728  }
729 
730  return Error::success();
731 }
732 
733 Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
735 
736  // If there's an ObjC imagine info then either
737  // (1) It's the first __objc_imageinfo we've seen in this JITDylib. In
738  // this case we name and record it.
739  // OR
740  // (2) We already have a recorded __objc_imageinfo for this JITDylib,
741  // in which case we just verify it.
742  auto *ObjCImageInfo = G.findSectionByName(ObjCImageInfoSectionName);
743  if (!ObjCImageInfo)
744  return Error::success();
745 
746  auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();
747 
748  // Check that the section is not empty if present.
749  if (ObjCImageInfoBlocks.empty())
750  return make_error<StringError>("Empty " + ObjCImageInfoSectionName +
751  " section in " + G.getName(),
753 
754  // Check that there's only one block in the section.
755  if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
756  return make_error<StringError>("Multiple blocks in " +
757  ObjCImageInfoSectionName +
758  " section in " + G.getName(),
760 
761  // Check that the __objc_imageinfo section is unreferenced.
762  // FIXME: We could optimize this check if Symbols had a ref-count.
763  for (auto &Sec : G.sections()) {
764  if (&Sec != ObjCImageInfo)
765  for (auto *B : Sec.blocks())
766  for (auto &E : B->edges())
767  if (E.getTarget().isDefined() &&
768  &E.getTarget().getBlock().getSection() == ObjCImageInfo)
769  return make_error<StringError>(ObjCImageInfoSectionName +
770  " is referenced within file " +
771  G.getName(),
773  }
774 
775  auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();
776  auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();
777  auto Version = support::endian::read32(ObjCImageInfoData, G.getEndianness());
778  auto Flags =
779  support::endian::read32(ObjCImageInfoData + 4, G.getEndianness());
780 
781  // Lock the mutex while we verify / update the ObjCImageInfos map.
782  std::lock_guard<std::mutex> Lock(PluginMutex);
783 
784  auto ObjCImageInfoItr = ObjCImageInfos.find(&MR.getTargetJITDylib());
785  if (ObjCImageInfoItr != ObjCImageInfos.end()) {
786  // We've already registered an __objc_imageinfo section. Verify the
787  // content of this new section matches, then delete it.
788  if (ObjCImageInfoItr->second.first != Version)
789  return make_error<StringError>(
790  "ObjC version in " + G.getName() +
791  " does not match first registered version",
793  if (ObjCImageInfoItr->second.second != Flags)
794  return make_error<StringError>("ObjC flags in " + G.getName() +
795  " do not match first registered flags",
797 
798  // __objc_imageinfo is valid. Delete the block.
799  for (auto *S : ObjCImageInfo->symbols())
800  G.removeDefinedSymbol(*S);
801  G.removeBlock(ObjCImageInfoBlock);
802  } else {
803  // We haven't registered an __objc_imageinfo section yet. Register and
804  // move on. The section should already be marked no-dead-strip.
805  ObjCImageInfos[&MR.getTargetJITDylib()] = std::make_pair(Version, Flags);
806  }
807 
808  return Error::success();
809 }
810 
811 Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
812  jitlink::LinkGraph &G, JITDylib &JD) {
813 
814  // Rename external references to __tlv_bootstrap to ___orc_rt_tlv_get_addr.
815  for (auto *Sym : G.external_symbols())
816  if (Sym->getName() == "__tlv_bootstrap") {
817  Sym->setName("___orc_rt_macho_tlv_get_addr");
818  break;
819  }
820 
821  // Store key in __thread_vars struct fields.
822  if (auto *ThreadDataSec = G.findSectionByName(ThreadVarsSectionName)) {
824  {
825  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
826  auto I = MP.JITDylibToPThreadKey.find(&JD);
827  if (I != MP.JITDylibToPThreadKey.end())
828  Key = I->second;
829  }
830 
831  if (!Key) {
832  if (auto KeyOrErr = MP.createPThreadKey())
833  Key = *KeyOrErr;
834  else
835  return KeyOrErr.takeError();
836  }
837 
838  uint64_t PlatformKeyBits =
839  support::endian::byte_swap(*Key, G.getEndianness());
840 
841  for (auto *B : ThreadDataSec->blocks()) {
842  if (B->getSize() != 3 * G.getPointerSize())
843  return make_error<StringError>("__thread_vars block at " +
844  formatv("{0:x}", B->getAddress()) +
845  " has unexpected size",
847 
848  auto NewBlockContent = G.allocateBuffer(B->getSize());
849  llvm::copy(B->getContent(), NewBlockContent.data());
850  memcpy(NewBlockContent.data() + G.getPointerSize(), &PlatformKeyBits,
851  G.getPointerSize());
852  B->setContent(NewBlockContent);
853  }
854  }
855 
856  // Transform any TLV edges into GOT edges.
857  for (auto *B : G.blocks())
858  for (auto &E : B->edges())
859  if (E.getKind() ==
861  E.setKind(jitlink::x86_64::
863 
864  return Error::success();
865 }
866 
867 Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
868  jitlink::LinkGraph &G, JITDylib &JD) {
869 
870  // Add an action to register the eh-frame.
871  if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
872  jitlink::SectionRange R(*EHFrameSection);
873  if (!R.empty())
874  G.allocActions().push_back(
875  {cantFail(
876  WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
877  MP.orc_rt_macho_register_ehframe_section, R.getRange())),
878  cantFail(
879  WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
880  MP.orc_rt_macho_deregister_ehframe_section, R.getRange()))});
881  }
882 
883  // Get a pointer to the thread data section if there is one. It will be used
884  // below.
885  jitlink::Section *ThreadDataSection =
886  G.findSectionByName(ThreadDataSectionName);
887 
888  // Handle thread BSS section if there is one.
889  if (auto *ThreadBSSSection = G.findSectionByName(ThreadBSSSectionName)) {
890  // If there's already a thread data section in this graph then merge the
891  // thread BSS section content into it, otherwise just treat the thread
892  // BSS section as the thread data section.
893  if (ThreadDataSection)
894  G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
895  else
896  ThreadDataSection = ThreadBSSSection;
897  }
898 
900 
901  // Having merged thread BSS (if present) and thread data (if present),
902  // record the resulting section range.
903  if (ThreadDataSection) {
904  jitlink::SectionRange R(*ThreadDataSection);
905  if (!R.empty()) {
906  if (MP.State != MachOPlatform::Initialized)
907  return make_error<StringError>("__thread_data section encountered, but "
908  "MachOPlatform has not finished booting",
910 
911  MachOPlatformSecs.push_back({ThreadDataSectionName, R.getRange()});
912  }
913  }
914 
915  // Collect data sections to register.
916  StringRef DataSections[] = {DataDataSectionName, DataCommonSectionName};
917  for (auto &SecName : DataSections) {
918  if (auto *Sec = G.findSectionByName(SecName)) {
919  jitlink::SectionRange R(*Sec);
920  if (!R.empty())
921  MachOPlatformSecs.push_back({SecName, R.getRange()});
922  }
923  }
924 
925  // If any platform sections were found then add an allocation action to call
926  // the registration function.
927  bool RegistrationRequired = false;
928  StringRef PlatformSections[] = {
929  ModInitFuncSectionName, ObjCClassListSectionName,
930  ObjCImageInfoSectionName, ObjCSelRefsSectionName,
931  Swift5ProtoSectionName, Swift5ProtosSectionName,
932  Swift5TypesSectionName,
933  };
934 
935  for (auto &SecName : PlatformSections) {
936  auto *Sec = G.findSectionByName(SecName);
937  if (!Sec)
938  continue;
939  jitlink::SectionRange R(*Sec);
940  if (R.empty())
941  continue;
942 
943  RegistrationRequired = true;
944  MachOPlatformSecs.push_back({SecName, R.getRange()});
945  }
946 
947  if (!MachOPlatformSecs.empty()) {
948  Optional<ExecutorAddr> HeaderAddr;
949  {
950  std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
951  auto I = MP.JITDylibToHeaderAddr.find(&JD);
952  if (I != MP.JITDylibToHeaderAddr.end())
953  HeaderAddr = I->second;
954  }
955 
956  if (!HeaderAddr) {
957  // If we only found data sections and we're not done bootstrapping yet
958  // then continue -- this must be a data section for the runtime itself,
959  // and we don't need to register those.
960  if (MP.State != MachOPlatform::Initialized && !RegistrationRequired)
961  return Error::success();
962 
963  return make_error<StringError>("Missing header for " + JD.getName(),
965  }
966 
967  // Dump the scraped inits.
968  LLVM_DEBUG({
969  dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
970  for (auto &KV : MachOPlatformSecs)
971  dbgs() << " " << KV.first << ": " << KV.second << "\n";
972  });
973 
974  using SPSRegisterObjectPlatformSectionsArgs =
977  G.allocActions().push_back(
978  {cantFail(
979  WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
980  MP.orc_rt_macho_register_object_platform_sections, *HeaderAddr,
981  MachOPlatformSecs)),
982  cantFail(
983  WrapperFunctionCall::Create<SPSRegisterObjectPlatformSectionsArgs>(
984  MP.orc_rt_macho_deregister_object_platform_sections,
985  *HeaderAddr, MachOPlatformSecs))});
986  }
987 
988  return Error::success();
989 }
990 
991 Error MachOPlatform::MachOPlatformPlugin::registerEHSectionsPhase1(
993 
994  // If there's no eh-frame there's nothing to do.
995  auto *EHFrameSection = G.findSectionByName(EHFrameSectionName);
996  if (!EHFrameSection)
997  return Error::success();
998 
999  // If the eh-frame section is empty there's nothing to do.
1000  jitlink::SectionRange R(*EHFrameSection);
1001  if (R.empty())
1002  return Error::success();
1003 
1004  // Since we're linking the object containing the registration code now the
1005  // addresses won't be ready in the platform. We'll have to find them in this
1006  // graph instead.
1007  ExecutorAddr orc_rt_macho_register_ehframe_section;
1008  ExecutorAddr orc_rt_macho_deregister_ehframe_section;
1009  for (auto *Sym : G.defined_symbols()) {
1010  if (!Sym->hasName())
1011  continue;
1012  if (Sym->getName() == "___orc_rt_macho_register_ehframe_section")
1013  orc_rt_macho_register_ehframe_section = ExecutorAddr(Sym->getAddress());
1014  else if (Sym->getName() == "___orc_rt_macho_deregister_ehframe_section")
1015  orc_rt_macho_deregister_ehframe_section = ExecutorAddr(Sym->getAddress());
1016 
1017  if (orc_rt_macho_register_ehframe_section &&
1018  orc_rt_macho_deregister_ehframe_section)
1019  break;
1020  }
1021 
1022  // If we failed to find the required functions then bail out.
1023  if (!orc_rt_macho_register_ehframe_section ||
1024  !orc_rt_macho_deregister_ehframe_section)
1025  return make_error<StringError>("Could not find eh-frame registration "
1026  "functions during platform bootstrap",
1028 
1029  // Otherwise, add allocation actions to the graph to register eh-frames for
1030  // this object.
1031  G.allocActions().push_back(
1032  {cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1033  orc_rt_macho_register_ehframe_section, R.getRange())),
1034  cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
1035  orc_rt_macho_deregister_ehframe_section, R.getRange()))});
1036 
1037  return Error::success();
1038 }
1039 
1040 } // End namespace orc.
1041 } // 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:273
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::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: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: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:1181
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:244
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:1641
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::X86II::OB
@ OB
Definition: X86BaseInfo.h:801
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:190
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:2184
llvm::orc::MachOPlatform::requiredCXXAliases
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Definition: MachOPlatform.cpp:295
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: 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: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: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: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:228
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: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:317
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:257
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: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: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:1666
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
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: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: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:1617
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:236
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:1358
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDepInfo, MachOPlatform::MachOJITDylibDepInfo >::size
static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI)
Definition: MachOPlatform.cpp:37
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: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:303
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: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:1799
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:2075
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:287
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::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