LLVM  9.0.0svn
MachO_x86_64.cpp
Go to the documentation of this file.
1 //===---- MachO_x86_64.cpp -JIT linker implementation for MachO/x86-64 ----===//
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 //
9 // MachO/x86-64 jit-link implementation.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 
16 #include "MachOAtomGraphBuilder.h"
17 
18 #define DEBUG_TYPE "jitlink"
19 
20 using namespace llvm;
21 using namespace llvm::jitlink;
22 using namespace llvm::jitlink::MachO_x86_64_Edges;
23 
24 namespace {
25 
26 class MachOAtomGraphBuilder_x86_64 : public MachOAtomGraphBuilder {
27 public:
28  MachOAtomGraphBuilder_x86_64(const object::MachOObjectFile &Obj)
29  : MachOAtomGraphBuilder(Obj),
30  NumSymbols(Obj.getSymtabLoadCommand().nsyms) {
31  addCustomAtomizer("__eh_frame", [this](MachOSection &EHFrameSection) {
32  return addEHFrame(getGraph(), EHFrameSection.getGenericSection(),
33  EHFrameSection.getContent(),
34  EHFrameSection.getAddress(), NegDelta32, Delta64);
35  });
36  }
37 
38 private:
40  getRelocationKind(const MachO::relocation_info &RI) {
41  switch (RI.r_type) {
43  if (!RI.r_pcrel && RI.r_length == 3)
44  return RI.r_extern ? Pointer64 : Pointer64Anon;
45  break;
47  if (RI.r_pcrel && RI.r_length == 2)
48  return RI.r_extern ? PCRel32 : PCRel32Anon;
49  break;
51  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
52  return Branch32;
53  break;
55  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
56  return PCRel32GOTLoad;
57  break;
59  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
60  return PCRel32GOT;
61  break;
63  // SUBTRACTOR must be non-pc-rel, extern, with length 2 or 3.
64  // Initially represent SUBTRACTOR relocations with 'Delta<W>'. They may
65  // be turned into NegDelta<W> by parsePairRelocation.
66  if (!RI.r_pcrel && RI.r_extern) {
67  if (RI.r_length == 2)
68  return Delta32;
69  else if (RI.r_length == 3)
70  return Delta64;
71  }
72  break;
74  if (RI.r_pcrel && RI.r_length == 2)
76  break;
78  if (RI.r_pcrel && RI.r_length == 2)
80  break;
82  if (RI.r_pcrel && RI.r_length == 2)
84  break;
86  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
87  return PCRel32TLV;
88  break;
89  }
90 
91  return make_error<JITLinkError>(
92  "Unsupported x86-64 relocation: address=" +
93  formatv("{0:x8}", RI.r_address) +
94  ", symbolnum=" + formatv("{0:x6}", RI.r_symbolnum) +
95  ", kind=" + formatv("{0:x1}", RI.r_type) +
96  ", pc_rel=" + (RI.r_pcrel ? "true" : "false") +
97  ", extern= " + (RI.r_extern ? "true" : "false") +
98  ", length=" + formatv("{0:d}", RI.r_length));
99  }
100 
101  Expected<Atom &> findAtomBySymbolIndex(const MachO::relocation_info &RI) {
102  auto &Obj = getObject();
103  if (RI.r_symbolnum >= NumSymbols)
104  return make_error<JITLinkError>("Symbol index out of range");
105  auto SymI = Obj.getSymbolByIndex(RI.r_symbolnum);
106  auto Name = SymI->getName();
107  if (!Name)
108  return Name.takeError();
109  return getGraph().getAtomByName(*Name);
110  }
111 
113  getRelocationInfo(const object::relocation_iterator RelItr) {
115  getObject().getRelocation(RelItr->getRawDataRefImpl());
117  memcpy(&RI, &ARI, sizeof(MachO::relocation_info));
118  return RI;
119  }
120 
121  using PairRelocInfo = std::tuple<MachOX86RelocationKind, Atom *, uint64_t>;
122 
123  // Parses paired SUBTRACTOR/UNSIGNED relocations and, on success,
124  // returns the edge kind and addend to be used.
126  parsePairRelocation(DefinedAtom &AtomToFix, Edge::Kind SubtractorKind,
127  const MachO::relocation_info &SubRI,
128  JITTargetAddress FixupAddress, const char *FixupContent,
129  object::relocation_iterator &UnsignedRelItr,
130  object::relocation_iterator &RelEnd) {
131  using namespace support;
132 
133  assert(((SubtractorKind == Delta32 && SubRI.r_length == 2) ||
134  (SubtractorKind == Delta64 && SubRI.r_length == 3)) &&
135  "Subtractor kind should match length");
136  assert(SubRI.r_extern && "SUBTRACTOR reloc symbol should be extern");
137  assert(!SubRI.r_pcrel && "SUBTRACTOR reloc should not be PCRel");
138 
139  if (UnsignedRelItr == RelEnd)
140  return make_error<JITLinkError>("x86_64 SUBTRACTOR without paired "
141  "UNSIGNED relocation");
142 
143  auto UnsignedRI = getRelocationInfo(UnsignedRelItr);
144 
145  if (SubRI.r_address != UnsignedRI.r_address)
146  return make_error<JITLinkError>("x86_64 SUBTRACTOR and paired UNSIGNED "
147  "point to different addresses");
148 
149  if (SubRI.r_length != UnsignedRI.r_length)
150  return make_error<JITLinkError>("length of x86_64 SUBTRACTOR and paired "
151  "UNSIGNED reloc must match");
152 
153  auto FromAtom = findAtomBySymbolIndex(SubRI);
154  if (!FromAtom)
155  return FromAtom.takeError();
156 
157  // Read the current fixup value.
158  uint64_t FixupValue = 0;
159  if (SubRI.r_length == 3)
160  FixupValue = *(const little64_t *)FixupContent;
161  else
162  FixupValue = *(const little32_t *)FixupContent;
163 
164  // Find 'ToAtom' using symbol number or address, depending on whether the
165  // paired UNSIGNED relocation is extern.
166  Atom *ToAtom = nullptr;
167  if (UnsignedRI.r_extern) {
168  // Find target atom by symbol index.
169  if (auto ToAtomOrErr = findAtomBySymbolIndex(UnsignedRI))
170  ToAtom = &*ToAtomOrErr;
171  else
172  return ToAtomOrErr.takeError();
173  } else {
174  if (auto ToAtomOrErr = getGraph().findAtomByAddress(FixupValue))
175  ToAtom = &*ToAtomOrErr;
176  else
177  return ToAtomOrErr.takeError();
178  FixupValue -= ToAtom->getAddress();
179  }
180 
181  MachOX86RelocationKind DeltaKind;
182  Atom *TargetAtom;
183  uint64_t Addend;
184  if (areLayoutLocked(AtomToFix, *FromAtom)) {
185  TargetAtom = ToAtom;
186  DeltaKind = (SubRI.r_length == 3) ? Delta64 : Delta32;
187  Addend = FixupValue + (FixupAddress - FromAtom->getAddress());
188  // FIXME: handle extern 'from'.
189  } else if (areLayoutLocked(AtomToFix, *ToAtom)) {
190  TargetAtom = &*FromAtom;
191  DeltaKind = (SubRI.r_length == 3) ? NegDelta64 : NegDelta32;
192  Addend = FixupValue - (FixupAddress - ToAtom->getAddress());
193  } else {
194  // AtomToFix was neither FromAtom nor ToAtom.
195  return make_error<JITLinkError>("SUBTRACTOR relocation must fix up "
196  "either 'A' or 'B' (or an atom in one "
197  "of their alt-entry groups)");
198  }
199 
200  return PairRelocInfo(DeltaKind, TargetAtom, Addend);
201  }
202 
203  Error addRelocations() override {
204  using namespace support;
205  auto &G = getGraph();
206  auto &Obj = getObject();
207 
208  for (auto &S : Obj.sections()) {
209 
210  JITTargetAddress SectionAddress = S.getAddress();
211 
212  for (auto RelItr = S.relocation_begin(), RelEnd = S.relocation_end();
213  RelItr != RelEnd; ++RelItr) {
214 
215  MachO::relocation_info RI = getRelocationInfo(RelItr);
216 
217  // Sanity check the relocation kind.
218  auto Kind = getRelocationKind(RI);
219  if (!Kind)
220  return Kind.takeError();
221 
222  // Find the address of the value to fix up.
223  JITTargetAddress FixupAddress = SectionAddress + (uint32_t)RI.r_address;
224 
225  LLVM_DEBUG({
226  dbgs() << "Processing relocation at "
227  << format("0x%016" PRIx64, FixupAddress) << "\n";
228  });
229 
230  // Find the atom that the fixup points to.
231  DefinedAtom *AtomToFix = nullptr;
232  {
233  auto AtomToFixOrErr = G.findAtomByAddress(FixupAddress);
234  if (!AtomToFixOrErr)
235  return AtomToFixOrErr.takeError();
236  AtomToFix = &*AtomToFixOrErr;
237  }
238 
239  if (FixupAddress + static_cast<JITTargetAddress>(1ULL << RI.r_length) >
240  AtomToFix->getAddress() + AtomToFix->getContent().size())
241  return make_error<JITLinkError>(
242  "Relocation content extends past end of fixup atom");
243 
244  // Get a pointer to the fixup content.
245  const char *FixupContent = AtomToFix->getContent().data() +
246  (FixupAddress - AtomToFix->getAddress());
247 
248  // The target atom and addend will be populated by the switch below.
249  Atom *TargetAtom = nullptr;
250  uint64_t Addend = 0;
251 
252  switch (*Kind) {
253  case Branch32:
254  case PCRel32:
255  case PCRel32GOTLoad:
256  case PCRel32GOT:
257  if (auto TargetAtomOrErr = findAtomBySymbolIndex(RI))
258  TargetAtom = &*TargetAtomOrErr;
259  else
260  return TargetAtomOrErr.takeError();
261  Addend = *(const ulittle32_t *)FixupContent;
262  break;
263  case Pointer64:
264  if (auto TargetAtomOrErr = findAtomBySymbolIndex(RI))
265  TargetAtom = &*TargetAtomOrErr;
266  else
267  return TargetAtomOrErr.takeError();
268  Addend = *(const ulittle64_t *)FixupContent;
269  break;
270  case Pointer64Anon: {
271  JITTargetAddress TargetAddress = *(const ulittle64_t *)FixupContent;
272  if (auto TargetAtomOrErr = G.findAtomByAddress(TargetAddress))
273  TargetAtom = &*TargetAtomOrErr;
274  else
275  return TargetAtomOrErr.takeError();
276  Addend = TargetAddress - TargetAtom->getAddress();
277  break;
278  }
279  case PCRel32Minus1:
280  case PCRel32Minus2:
281  case PCRel32Minus4:
282  if (auto TargetAtomOrErr = findAtomBySymbolIndex(RI))
283  TargetAtom = &*TargetAtomOrErr;
284  else
285  return TargetAtomOrErr.takeError();
286  Addend = *(const ulittle32_t *)FixupContent +
287  (1 << (*Kind - PCRel32Minus1));
288  break;
289  case PCRel32Anon: {
290  JITTargetAddress TargetAddress =
291  FixupAddress + 4 + *(const ulittle32_t *)FixupContent;
292  if (auto TargetAtomOrErr = G.findAtomByAddress(TargetAddress))
293  TargetAtom = &*TargetAtomOrErr;
294  else
295  return TargetAtomOrErr.takeError();
296  Addend = TargetAddress - TargetAtom->getAddress();
297  break;
298  }
299  case PCRel32Minus1Anon:
300  case PCRel32Minus2Anon:
301  case PCRel32Minus4Anon: {
302  JITTargetAddress Delta =
303  static_cast<JITTargetAddress>(1ULL << (*Kind - PCRel32Minus1Anon));
304  JITTargetAddress TargetAddress =
305  FixupAddress + 4 + Delta + *(const ulittle32_t *)FixupContent;
306  if (auto TargetAtomOrErr = G.findAtomByAddress(TargetAddress))
307  TargetAtom = &*TargetAtomOrErr;
308  else
309  return TargetAtomOrErr.takeError();
310  Addend = TargetAddress - TargetAtom->getAddress();
311  break;
312  }
313  case Delta32:
314  case Delta64: {
315  // We use Delta32/Delta64 to represent SUBTRACTOR relocations.
316  // parsePairRelocation handles the paired reloc, and returns the
317  // edge kind to be used (either Delta32/Delta64, or
318  // NegDelta32/NegDelta64, depending on the direction of the
319  // subtraction) along with the addend.
320  auto PairInfo =
321  parsePairRelocation(*AtomToFix, *Kind, RI, FixupAddress,
322  FixupContent, ++RelItr, RelEnd);
323  if (!PairInfo)
324  return PairInfo.takeError();
325  std::tie(*Kind, TargetAtom, Addend) = *PairInfo;
326  assert(TargetAtom && "No target atom from parsePairRelocation?");
327  break;
328  }
329  default:
330  llvm_unreachable("Special relocation kind should not appear in "
331  "mach-o file");
332  }
333 
334  LLVM_DEBUG({
335  Edge GE(*Kind, FixupAddress - AtomToFix->getAddress(), *TargetAtom,
336  Addend);
337  printEdge(dbgs(), *AtomToFix, GE,
339  dbgs() << "\n";
340  });
341  AtomToFix->addEdge(*Kind, FixupAddress - AtomToFix->getAddress(),
342  *TargetAtom, Addend);
343  }
344  }
345  return Error::success();
346  }
347 
348  unsigned NumSymbols = 0;
349 };
350 
351 class MachO_x86_64_GOTAndStubsBuilder
352  : public BasicGOTAndStubsBuilder<MachO_x86_64_GOTAndStubsBuilder> {
353 public:
354  MachO_x86_64_GOTAndStubsBuilder(AtomGraph &G)
356 
357  bool isGOTEdge(Edge &E) const {
358  return E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad;
359  }
360 
361  DefinedAtom &createGOTEntry(Atom &Target) {
362  auto &GOTEntryAtom = G.addAnonymousAtom(getGOTSection(), 0x0, 8);
363  GOTEntryAtom.setContent(
364  StringRef(reinterpret_cast<const char *>(NullGOTEntryContent), 8));
365  GOTEntryAtom.addEdge(Pointer64, 0, Target, 0);
366  return GOTEntryAtom;
367  }
368 
369  void fixGOTEdge(Edge &E, Atom &GOTEntry) {
370  assert((E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad) &&
371  "Not a GOT edge?");
372  E.setKind(PCRel32);
373  E.setTarget(GOTEntry);
374  // Leave the edge addend as-is.
375  }
376 
377  bool isExternalBranchEdge(Edge &E) {
378  return E.getKind() == Branch32 && !E.getTarget().isDefined();
379  }
380 
381  DefinedAtom &createStub(Atom &Target) {
382  auto &StubAtom = G.addAnonymousAtom(getStubsSection(), 0x0, 2);
383  StubAtom.setContent(
384  StringRef(reinterpret_cast<const char *>(StubContent), 6));
385 
386  // Re-use GOT entries for stub targets.
387  auto &GOTEntryAtom = getGOTEntryAtom(Target);
388  StubAtom.addEdge(PCRel32, 2, GOTEntryAtom, 0);
389 
390  return StubAtom;
391  }
392 
393  void fixExternalBranchEdge(Edge &E, Atom &Stub) {
394  assert(E.getKind() == Branch32 && "Not a Branch32 edge?");
395  assert(E.getAddend() == 0 && "Branch32 edge has non-zero addend?");
396  E.setTarget(Stub);
397  }
398 
399 private:
400  Section &getGOTSection() {
401  if (!GOTSection)
402  GOTSection = &G.createSection("$__GOT", 8, sys::Memory::MF_READ, false);
403  return *GOTSection;
404  }
405 
406  Section &getStubsSection() {
407  if (!StubsSection) {
408  auto StubsProt = static_cast<sys::Memory::ProtectionFlags>(
410  StubsSection = &G.createSection("$__STUBS", 8, StubsProt, false);
411  }
412  return *StubsSection;
413  }
414 
415  static const uint8_t NullGOTEntryContent[8];
416  static const uint8_t StubContent[6];
417  Section *GOTSection = nullptr;
418  Section *StubsSection = nullptr;
419 };
420 
421 const uint8_t MachO_x86_64_GOTAndStubsBuilder::NullGOTEntryContent[8] = {
422  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
423 const uint8_t MachO_x86_64_GOTAndStubsBuilder::StubContent[6] = {
424  0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
425 } // namespace
426 
427 namespace llvm {
428 namespace jitlink {
429 
430 class MachOJITLinker_x86_64 : public JITLinker<MachOJITLinker_x86_64> {
432 
433 public:
434  MachOJITLinker_x86_64(std::unique_ptr<JITLinkContext> Ctx,
435  PassConfiguration PassConfig)
436  : JITLinker(std::move(Ctx), std::move(PassConfig)) {}
437 
438 private:
439  StringRef getEdgeKindName(Edge::Kind R) const override {
441  }
442 
444  buildGraph(MemoryBufferRef ObjBuffer) override {
445  auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjBuffer);
446  if (!MachOObj)
447  return MachOObj.takeError();
448  return MachOAtomGraphBuilder_x86_64(**MachOObj).buildGraph();
449  }
450 
451  static Error targetOutOfRangeError(const Atom &A, const Edge &E) {
452  std::string ErrMsg;
453  {
454  raw_string_ostream ErrStream(ErrMsg);
455  ErrStream << "Relocation target out of range: ";
456  printEdge(ErrStream, A, E, getMachOX86RelocationKindName(E.getKind()));
457  ErrStream << "\n";
458  }
459  return make_error<JITLinkError>(std::move(ErrMsg));
460  }
461 
462  Error applyFixup(DefinedAtom &A, const Edge &E, char *AtomWorkingMem) const {
463  using namespace support;
464 
465  char *FixupPtr = AtomWorkingMem + E.getOffset();
466  JITTargetAddress FixupAddress = A.getAddress() + E.getOffset();
467 
468  switch (E.getKind()) {
469  case Branch32:
470  case PCRel32:
471  case PCRel32Anon: {
472  int64_t Value =
473  E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
474  if (Value < std::numeric_limits<int32_t>::min() ||
476  return targetOutOfRangeError(A, E);
477  *(little32_t *)FixupPtr = Value;
478  break;
479  }
480  case Pointer64:
481  case Pointer64Anon: {
482  uint64_t Value = E.getTarget().getAddress() + E.getAddend();
483  *(ulittle64_t *)FixupPtr = Value;
484  break;
485  }
486  case PCRel32Minus1:
487  case PCRel32Minus2:
488  case PCRel32Minus4: {
489  int Delta = 4 + (1 << (E.getKind() - PCRel32Minus1));
490  int64_t Value =
491  E.getTarget().getAddress() - (FixupAddress + Delta) + E.getAddend();
492  if (Value < std::numeric_limits<int32_t>::min() ||
494  return targetOutOfRangeError(A, E);
495  *(little32_t *)FixupPtr = Value;
496  break;
497  }
498  case PCRel32Minus1Anon:
499  case PCRel32Minus2Anon:
500  case PCRel32Minus4Anon: {
501  int Delta = 4 + (1 << (E.getKind() - PCRel32Minus1Anon));
502  int64_t Value =
503  E.getTarget().getAddress() - (FixupAddress + Delta) + E.getAddend();
504  if (Value < std::numeric_limits<int32_t>::min() ||
506  return targetOutOfRangeError(A, E);
507  *(little32_t *)FixupPtr = Value;
508  break;
509  }
510  case Delta32:
511  case Delta64:
512  case NegDelta32:
513  case NegDelta64: {
514  int64_t Value;
515  if (E.getKind() == Delta32 || E.getKind() == Delta64)
516  Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
517  else
518  Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
519 
520  if (E.getKind() == Delta32 || E.getKind() == NegDelta32) {
521  if (Value < std::numeric_limits<int32_t>::min() ||
523  return targetOutOfRangeError(A, E);
524  *(little32_t *)FixupPtr = Value;
525  } else
526  *(little64_t *)FixupPtr = Value;
527  break;
528  }
529  default:
530  llvm_unreachable("Unrecognized edge kind");
531  }
532 
533  return Error::success();
534  }
535 
536  uint64_t NullValue = 0;
537 };
538 
539 void jitLink_MachO_x86_64(std::unique_ptr<JITLinkContext> Ctx) {
540  PassConfiguration Config;
541  Triple TT("x86_64-apple-macosx");
542 
543  if (Ctx->shouldAddDefaultTargetPasses(TT)) {
544  // Add a mark-live pass.
545  if (auto MarkLive = Ctx->getMarkLivePass(TT))
546  Config.PrePrunePasses.push_back(std::move(MarkLive));
547  else
548  Config.PrePrunePasses.push_back(markAllAtomsLive);
549 
550  // Add an in-place GOT/Stubs pass.
551  Config.PostPrunePasses.push_back([](AtomGraph &G) -> Error {
552  MachO_x86_64_GOTAndStubsBuilder(G).run();
553  return Error::success();
554  });
555  }
556 
557  if (auto Err = Ctx->modifyPassConfig(TT, Config))
558  return Ctx->notifyFailed(std::move(Err));
559 
560  // Construct a JITLinker and run the link function.
561  MachOJITLinker_x86_64::link(std::move(Ctx), std::move(Config));
562 }
563 
565  switch (R) {
566  case Branch32:
567  return "Branch32";
568  case Pointer64:
569  return "Pointer64";
570  case Pointer64Anon:
571  return "Pointer64Anon";
572  case PCRel32:
573  return "PCRel32";
574  case PCRel32Minus1:
575  return "PCRel32Minus1";
576  case PCRel32Minus2:
577  return "PCRel32Minus2";
578  case PCRel32Minus4:
579  return "PCRel32Minus4";
580  case PCRel32Anon:
581  return "PCRel32Anon";
582  case PCRel32Minus1Anon:
583  return "PCRel32Minus1Anon";
584  case PCRel32Minus2Anon:
585  return "PCRel32Minus2Anon";
586  case PCRel32Minus4Anon:
587  return "PCRel32Minus4Anon";
588  case PCRel32GOTLoad:
589  return "PCRel32GOTLoad";
590  case PCRel32GOT:
591  return "PCRel32GOT";
592  case PCRel32TLV:
593  return "PCRel32TLV";
594  case Delta32:
595  return "Delta32";
596  case Delta64:
597  return "Delta64";
598  case NegDelta32:
599  return "NegDelta32";
600  case NegDelta64:
601  return "NegDelta64";
602  default:
603  return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
604  }
605 }
606 
607 } // end namespace jitlink
608 } // end namespace llvm
MachO::symtab_command getSymtabLoadCommand() const
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
detail::packed_endian_specific_integral< int64_t, little, unaligned > little64_t
Definition: Endian.h:283
This class represents lattice values for constants.
Definition: AllocatorList.h:23
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
static std::error_code getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:123
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
detail::packed_endian_specific_integral< uint64_t, little, unaligned > ulittle64_t
Definition: Endian.h:276
Definition: BitVector.h:937
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
symbol_iterator getSymbolByIndex(unsigned Index) const
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
section_iterator_range sections() const
Definition: ObjectFile.h:315
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:274
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
static Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0)
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Target - Wrapper for Target specific information.
detail::packed_endian_specific_integral< int32_t, little, unaligned > little32_t
Definition: Endian.h:281
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
LLVM Value Representation.
Definition: Value.h:72
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
#define LLVM_DEBUG(X)
Definition: Debug.h:122