LLVM  10.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 "MachOLinkGraphBuilder.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 MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
27 public:
28  MachOLinkGraphBuilder_x86_64(const object::MachOObjectFile &Obj)
29  : MachOLinkGraphBuilder(Obj) {
30  addCustomSectionParser(
31  "__eh_frame", [this](NormalizedSection &EHFrameSection) {
32  if (!EHFrameSection.Data)
33  return make_error<JITLinkError>(
34  "__eh_frame section is marked zero-fill");
35  return MachOEHFrameBinaryParser(
36  *this, EHFrameSection.Address,
37  StringRef(EHFrameSection.Data, EHFrameSection.Size),
38  *EHFrameSection.GraphSection, 8, 4, NegDelta32, Delta64)
39  .addToGraph();
40  });
41  }
42 
43 private:
45  getRelocationKind(const MachO::relocation_info &RI) {
46  switch (RI.r_type) {
48  if (!RI.r_pcrel) {
49  if (RI.r_length == 3)
50  return RI.r_extern ? Pointer64 : Pointer64Anon;
51  else if (RI.r_extern && RI.r_length == 2)
52  return Pointer32;
53  }
54  break;
56  if (RI.r_pcrel && RI.r_length == 2)
57  return RI.r_extern ? PCRel32 : PCRel32Anon;
58  break;
60  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
61  return Branch32;
62  break;
64  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
65  return PCRel32GOTLoad;
66  break;
68  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
69  return PCRel32GOT;
70  break;
72  // SUBTRACTOR must be non-pc-rel, extern, with length 2 or 3.
73  // Initially represent SUBTRACTOR relocations with 'Delta<W>'. They may
74  // be turned into NegDelta<W> by parsePairRelocation.
75  if (!RI.r_pcrel && RI.r_extern) {
76  if (RI.r_length == 2)
77  return Delta32;
78  else if (RI.r_length == 3)
79  return Delta64;
80  }
81  break;
83  if (RI.r_pcrel && RI.r_length == 2)
85  break;
87  if (RI.r_pcrel && RI.r_length == 2)
89  break;
91  if (RI.r_pcrel && RI.r_length == 2)
93  break;
95  if (RI.r_pcrel && RI.r_extern && RI.r_length == 2)
96  return PCRel32TLV;
97  break;
98  }
99 
100  return make_error<JITLinkError>(
101  "Unsupported x86-64 relocation: address=" +
102  formatv("{0:x8}", RI.r_address) +
103  ", symbolnum=" + formatv("{0:x6}", RI.r_symbolnum) +
104  ", kind=" + formatv("{0:x1}", RI.r_type) +
105  ", pc_rel=" + (RI.r_pcrel ? "true" : "false") +
106  ", extern=" + (RI.r_extern ? "true" : "false") +
107  ", length=" + formatv("{0:d}", RI.r_length));
108  }
109 
111  getRelocationInfo(const object::relocation_iterator RelItr) {
113  getObject().getRelocation(RelItr->getRawDataRefImpl());
115  memcpy(&RI, &ARI, sizeof(MachO::relocation_info));
116  return RI;
117  }
118 
119  using PairRelocInfo = std::tuple<MachOX86RelocationKind, Symbol *, uint64_t>;
120 
121  // Parses paired SUBTRACTOR/UNSIGNED relocations and, on success,
122  // returns the edge kind and addend to be used.
124  parsePairRelocation(Block &BlockToFix, Edge::Kind SubtractorKind,
125  const MachO::relocation_info &SubRI,
126  JITTargetAddress FixupAddress, const char *FixupContent,
127  object::relocation_iterator &UnsignedRelItr,
128  object::relocation_iterator &RelEnd) {
129  using namespace support;
130 
131  assert(((SubtractorKind == Delta32 && SubRI.r_length == 2) ||
132  (SubtractorKind == Delta64 && SubRI.r_length == 3)) &&
133  "Subtractor kind should match length");
134  assert(SubRI.r_extern && "SUBTRACTOR reloc symbol should be extern");
135  assert(!SubRI.r_pcrel && "SUBTRACTOR reloc should not be PCRel");
136 
137  if (UnsignedRelItr == RelEnd)
138  return make_error<JITLinkError>("x86_64 SUBTRACTOR without paired "
139  "UNSIGNED relocation");
140 
141  auto UnsignedRI = getRelocationInfo(UnsignedRelItr);
142 
143  if (SubRI.r_address != UnsignedRI.r_address)
144  return make_error<JITLinkError>("x86_64 SUBTRACTOR and paired UNSIGNED "
145  "point to different addresses");
146 
147  if (SubRI.r_length != UnsignedRI.r_length)
148  return make_error<JITLinkError>("length of x86_64 SUBTRACTOR and paired "
149  "UNSIGNED reloc must match");
150 
151  Symbol *FromSymbol;
152  if (auto FromSymbolOrErr = findSymbolByIndex(SubRI.r_symbolnum))
153  FromSymbol = FromSymbolOrErr->GraphSymbol;
154  else
155  return FromSymbolOrErr.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 'ToSymbol' using symbol number or address, depending on whether the
165  // paired UNSIGNED relocation is extern.
166  Symbol *ToSymbol = nullptr;
167  if (UnsignedRI.r_extern) {
168  // Find target symbol by symbol index.
169  if (auto ToSymbolOrErr = findSymbolByIndex(UnsignedRI.r_symbolnum))
170  ToSymbol = ToSymbolOrErr->GraphSymbol;
171  else
172  return ToSymbolOrErr.takeError();
173  } else {
174  if (auto ToSymbolOrErr = findSymbolByAddress(FixupValue))
175  ToSymbol = &*ToSymbolOrErr;
176  else
177  return ToSymbolOrErr.takeError();
178  FixupValue -= ToSymbol->getAddress();
179  }
180 
181  MachOX86RelocationKind DeltaKind;
182  Symbol *TargetSymbol;
183  uint64_t Addend;
184  if (&BlockToFix == &FromSymbol->getAddressable()) {
185  TargetSymbol = ToSymbol;
186  DeltaKind = (SubRI.r_length == 3) ? Delta64 : Delta32;
187  Addend = FixupValue + (FixupAddress - FromSymbol->getAddress());
188  // FIXME: handle extern 'from'.
189  } else if (&BlockToFix == &ToSymbol->getAddressable()) {
190  TargetSymbol = FromSymbol;
191  DeltaKind = (SubRI.r_length == 3) ? NegDelta64 : NegDelta32;
192  Addend = FixupValue - (FixupAddress - ToSymbol->getAddress());
193  } else {
194  // BlockToFix was neither FromSymbol nor ToSymbol.
195  return make_error<JITLinkError>("SUBTRACTOR relocation must fix up "
196  "either 'A' or 'B' (or a symbol in one "
197  "of their alt-entry chains)");
198  }
199 
200  return PairRelocInfo(DeltaKind, TargetSymbol, Addend);
201  }
202 
203  Error addRelocations() override {
204  using namespace support;
205  auto &Obj = getObject();
206 
207  for (auto &S : Obj.sections()) {
208 
209  JITTargetAddress SectionAddress = S.getAddress();
210 
211  if (S.isVirtual()) {
212  if (S.relocation_begin() != S.relocation_end())
213  return make_error<JITLinkError>("Virtual section contains "
214  "relocations");
215  continue;
216  }
217 
218  for (auto RelItr = S.relocation_begin(), RelEnd = S.relocation_end();
219  RelItr != RelEnd; ++RelItr) {
220 
221  MachO::relocation_info RI = getRelocationInfo(RelItr);
222 
223  // Sanity check the relocation kind.
224  auto Kind = getRelocationKind(RI);
225  if (!Kind)
226  return Kind.takeError();
227 
228  // Find the address of the value to fix up.
229  JITTargetAddress FixupAddress = SectionAddress + (uint32_t)RI.r_address;
230 
231  LLVM_DEBUG({
232  dbgs() << "Processing relocation at "
233  << format("0x%016" PRIx64, FixupAddress) << "\n";
234  });
235 
236  // Find the block that the fixup points to.
237  Block *BlockToFix = nullptr;
238  {
239  auto SymbolToFixOrErr = findSymbolByAddress(FixupAddress);
240  if (!SymbolToFixOrErr)
241  return SymbolToFixOrErr.takeError();
242  BlockToFix = &SymbolToFixOrErr->getBlock();
243  }
244 
245  if (FixupAddress + static_cast<JITTargetAddress>(1ULL << RI.r_length) >
246  BlockToFix->getAddress() + BlockToFix->getContent().size())
247  return make_error<JITLinkError>(
248  "Relocation extends past end of fixup block");
249 
250  // Get a pointer to the fixup content.
251  const char *FixupContent = BlockToFix->getContent().data() +
252  (FixupAddress - BlockToFix->getAddress());
253 
254  // The target symbol and addend will be populated by the switch below.
255  Symbol *TargetSymbol = nullptr;
256  uint64_t Addend = 0;
257 
258  switch (*Kind) {
259  case Branch32:
260  case PCRel32:
261  case PCRel32GOTLoad:
262  case PCRel32GOT:
263  if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
264  TargetSymbol = TargetSymbolOrErr->GraphSymbol;
265  else
266  return TargetSymbolOrErr.takeError();
267  Addend = *(const ulittle32_t *)FixupContent;
268  break;
269  case Pointer32:
270  if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
271  TargetSymbol = TargetSymbolOrErr->GraphSymbol;
272  else
273  return TargetSymbolOrErr.takeError();
274  Addend = *(const ulittle32_t *)FixupContent;
275  break;
276  case Pointer64:
277  if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
278  TargetSymbol = TargetSymbolOrErr->GraphSymbol;
279  else
280  return TargetSymbolOrErr.takeError();
281  Addend = *(const ulittle64_t *)FixupContent;
282  break;
283  case Pointer64Anon: {
284  JITTargetAddress TargetAddress = *(const ulittle64_t *)FixupContent;
285  if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
286  TargetSymbol = &*TargetSymbolOrErr;
287  else
288  return TargetSymbolOrErr.takeError();
289  Addend = TargetAddress - TargetSymbol->getAddress();
290  break;
291  }
292  case PCRel32Minus1:
293  case PCRel32Minus2:
294  case PCRel32Minus4:
295  if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
296  TargetSymbol = TargetSymbolOrErr->GraphSymbol;
297  else
298  return TargetSymbolOrErr.takeError();
299  Addend = *(const ulittle32_t *)FixupContent +
300  (1 << (*Kind - PCRel32Minus1));
301  break;
302  case PCRel32Anon: {
303  JITTargetAddress TargetAddress =
304  FixupAddress + 4 + *(const ulittle32_t *)FixupContent;
305  if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
306  TargetSymbol = &*TargetSymbolOrErr;
307  else
308  return TargetSymbolOrErr.takeError();
309  Addend = TargetAddress - TargetSymbol->getAddress();
310  break;
311  }
312  case PCRel32Minus1Anon:
313  case PCRel32Minus2Anon:
314  case PCRel32Minus4Anon: {
315  JITTargetAddress Delta =
316  static_cast<JITTargetAddress>(1ULL << (*Kind - PCRel32Minus1Anon));
317  JITTargetAddress TargetAddress =
318  FixupAddress + 4 + Delta + *(const ulittle32_t *)FixupContent;
319  if (auto TargetSymbolOrErr = findSymbolByAddress(TargetAddress))
320  TargetSymbol = &*TargetSymbolOrErr;
321  else
322  return TargetSymbolOrErr.takeError();
323  Addend = TargetAddress - TargetSymbol->getAddress();
324  break;
325  }
326  case Delta32:
327  case Delta64: {
328  // We use Delta32/Delta64 to represent SUBTRACTOR relocations.
329  // parsePairRelocation handles the paired reloc, and returns the
330  // edge kind to be used (either Delta32/Delta64, or
331  // NegDelta32/NegDelta64, depending on the direction of the
332  // subtraction) along with the addend.
333  auto PairInfo =
334  parsePairRelocation(*BlockToFix, *Kind, RI, FixupAddress,
335  FixupContent, ++RelItr, RelEnd);
336  if (!PairInfo)
337  return PairInfo.takeError();
338  std::tie(*Kind, TargetSymbol, Addend) = *PairInfo;
339  assert(TargetSymbol && "No target symbol from parsePairRelocation?");
340  break;
341  }
342  default:
343  llvm_unreachable("Special relocation kind should not appear in "
344  "mach-o file");
345  }
346 
347  LLVM_DEBUG({
348  Edge GE(*Kind, FixupAddress - BlockToFix->getAddress(), *TargetSymbol,
349  Addend);
350  printEdge(dbgs(), *BlockToFix, GE,
352  dbgs() << "\n";
353  });
354  BlockToFix->addEdge(*Kind, FixupAddress - BlockToFix->getAddress(),
355  *TargetSymbol, Addend);
356  }
357  }
358  return Error::success();
359  }
360 };
361 
362 class MachO_x86_64_GOTAndStubsBuilder
363  : public BasicGOTAndStubsBuilder<MachO_x86_64_GOTAndStubsBuilder> {
364 public:
365  MachO_x86_64_GOTAndStubsBuilder(LinkGraph &G)
367 
368  bool isGOTEdge(Edge &E) const {
369  return E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad;
370  }
371 
372  Symbol &createGOTEntry(Symbol &Target) {
373  auto &GOTEntryBlock = G.createContentBlock(
374  getGOTSection(), getGOTEntryBlockContent(), 0, 8, 0);
375  GOTEntryBlock.addEdge(Pointer64, 0, Target, 0);
376  return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false);
377  }
378 
379  void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
380  assert((E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad) &&
381  "Not a GOT edge?");
382  E.setKind(PCRel32);
383  E.setTarget(GOTEntry);
384  // Leave the edge addend as-is.
385  }
386 
387  bool isExternalBranchEdge(Edge &E) {
388  return E.getKind() == Branch32 && !E.getTarget().isDefined();
389  }
390 
391  Symbol &createStub(Symbol &Target) {
392  auto &StubContentBlock =
393  G.createContentBlock(getStubsSection(), getStubBlockContent(), 0, 1, 0);
394  // Re-use GOT entries for stub targets.
395  auto &GOTEntrySymbol = getGOTEntrySymbol(Target);
396  StubContentBlock.addEdge(PCRel32, 2, GOTEntrySymbol, 0);
397  return G.addAnonymousSymbol(StubContentBlock, 0, 6, true, false);
398  }
399 
400  void fixExternalBranchEdge(Edge &E, Symbol &Stub) {
401  assert(E.getKind() == Branch32 && "Not a Branch32 edge?");
402  assert(E.getAddend() == 0 && "Branch32 edge has non-zero addend?");
403  E.setTarget(Stub);
404  }
405 
406 private:
407  Section &getGOTSection() {
408  if (!GOTSection)
409  GOTSection = &G.createSection("$__GOT", sys::Memory::MF_READ);
410  return *GOTSection;
411  }
412 
413  Section &getStubsSection() {
414  if (!StubsSection) {
415  auto StubsProt = static_cast<sys::Memory::ProtectionFlags>(
417  StubsSection = &G.createSection("$__STUBS", StubsProt);
418  }
419  return *StubsSection;
420  }
421 
422  StringRef getGOTEntryBlockContent() {
423  return StringRef(reinterpret_cast<const char *>(NullGOTEntryContent),
424  sizeof(NullGOTEntryContent));
425  }
426 
427  StringRef getStubBlockContent() {
428  return StringRef(reinterpret_cast<const char *>(StubContent),
429  sizeof(StubContent));
430  }
431 
432  static const uint8_t NullGOTEntryContent[8];
433  static const uint8_t StubContent[6];
434  Section *GOTSection = nullptr;
435  Section *StubsSection = nullptr;
436 };
437 
438 const uint8_t MachO_x86_64_GOTAndStubsBuilder::NullGOTEntryContent[8] = {
439  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
440 const uint8_t MachO_x86_64_GOTAndStubsBuilder::StubContent[6] = {
441  0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
442 } // namespace
443 
444 namespace llvm {
445 namespace jitlink {
446 
447 class MachOJITLinker_x86_64 : public JITLinker<MachOJITLinker_x86_64> {
449 
450 public:
451  MachOJITLinker_x86_64(std::unique_ptr<JITLinkContext> Ctx,
452  PassConfiguration PassConfig)
453  : JITLinker(std::move(Ctx), std::move(PassConfig)) {}
454 
455 private:
456  StringRef getEdgeKindName(Edge::Kind R) const override {
458  }
459 
461  buildGraph(MemoryBufferRef ObjBuffer) override {
462  auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjBuffer);
463  if (!MachOObj)
464  return MachOObj.takeError();
465  return MachOLinkGraphBuilder_x86_64(**MachOObj).buildGraph();
466  }
467 
468  static Error targetOutOfRangeError(const Block &B, const Edge &E) {
469  std::string ErrMsg;
470  {
471  raw_string_ostream ErrStream(ErrMsg);
472  ErrStream << "Relocation target out of range: ";
473  printEdge(ErrStream, B, E, getMachOX86RelocationKindName(E.getKind()));
474  ErrStream << "\n";
475  }
476  return make_error<JITLinkError>(std::move(ErrMsg));
477  }
478 
479  Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) const {
480 
481  using namespace support;
482 
483  char *FixupPtr = BlockWorkingMem + E.getOffset();
484  JITTargetAddress FixupAddress = B.getAddress() + E.getOffset();
485 
486  switch (E.getKind()) {
487  case Branch32:
488  case PCRel32:
489  case PCRel32Anon: {
490  int64_t Value =
491  E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
492  if (Value < std::numeric_limits<int32_t>::min() ||
494  return targetOutOfRangeError(B, E);
495  *(little32_t *)FixupPtr = Value;
496  break;
497  }
498  case Pointer64:
499  case Pointer64Anon: {
500  uint64_t Value = E.getTarget().getAddress() + E.getAddend();
501  *(ulittle64_t *)FixupPtr = Value;
502  break;
503  }
504  case PCRel32Minus1:
505  case PCRel32Minus2:
506  case PCRel32Minus4: {
507  int Delta = 4 + (1 << (E.getKind() - PCRel32Minus1));
508  int64_t Value =
509  E.getTarget().getAddress() - (FixupAddress + Delta) + E.getAddend();
510  if (Value < std::numeric_limits<int32_t>::min() ||
512  return targetOutOfRangeError(B, E);
513  *(little32_t *)FixupPtr = Value;
514  break;
515  }
516  case PCRel32Minus1Anon:
517  case PCRel32Minus2Anon:
518  case PCRel32Minus4Anon: {
519  int Delta = 4 + (1 << (E.getKind() - PCRel32Minus1Anon));
520  int64_t Value =
521  E.getTarget().getAddress() - (FixupAddress + Delta) + E.getAddend();
522  if (Value < std::numeric_limits<int32_t>::min() ||
524  return targetOutOfRangeError(B, E);
525  *(little32_t *)FixupPtr = Value;
526  break;
527  }
528  case Delta32:
529  case Delta64:
530  case NegDelta32:
531  case NegDelta64: {
532  int64_t Value;
533  if (E.getKind() == Delta32 || E.getKind() == Delta64)
534  Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
535  else
536  Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
537 
538  if (E.getKind() == Delta32 || E.getKind() == NegDelta32) {
539  if (Value < std::numeric_limits<int32_t>::min() ||
541  return targetOutOfRangeError(B, E);
542  *(little32_t *)FixupPtr = Value;
543  } else
544  *(little64_t *)FixupPtr = Value;
545  break;
546  }
547  case Pointer32: {
548  uint64_t Value = E.getTarget().getAddress() + E.getAddend();
550  return targetOutOfRangeError(B, E);
551  *(ulittle32_t *)FixupPtr = Value;
552  break;
553  }
554  default:
555  llvm_unreachable("Unrecognized edge kind");
556  }
557 
558  return Error::success();
559  }
560 
561  uint64_t NullValue = 0;
562 };
563 
564 void jitLink_MachO_x86_64(std::unique_ptr<JITLinkContext> Ctx) {
565  PassConfiguration Config;
566  Triple TT("x86_64-apple-macosx");
567 
568  if (Ctx->shouldAddDefaultTargetPasses(TT)) {
569  // Add a mark-live pass.
570  if (auto MarkLive = Ctx->getMarkLivePass(TT))
571  Config.PrePrunePasses.push_back(std::move(MarkLive));
572  else
573  Config.PrePrunePasses.push_back(markAllSymbolsLive);
574 
575  // Add an in-place GOT/Stubs pass.
576  Config.PostPrunePasses.push_back([](LinkGraph &G) -> Error {
577  MachO_x86_64_GOTAndStubsBuilder(G).run();
578  return Error::success();
579  });
580  }
581 
582  if (auto Err = Ctx->modifyPassConfig(TT, Config))
583  return Ctx->notifyFailed(std::move(Err));
584 
585  // Construct a JITLinker and run the link function.
586  MachOJITLinker_x86_64::link(std::move(Ctx), std::move(Config));
587 }
588 
590  switch (R) {
591  case Branch32:
592  return "Branch32";
593  case Pointer32:
594  return "Pointer32";
595  case Pointer64:
596  return "Pointer64";
597  case Pointer64Anon:
598  return "Pointer64Anon";
599  case PCRel32:
600  return "PCRel32";
601  case PCRel32Minus1:
602  return "PCRel32Minus1";
603  case PCRel32Minus2:
604  return "PCRel32Minus2";
605  case PCRel32Minus4:
606  return "PCRel32Minus4";
607  case PCRel32Anon:
608  return "PCRel32Anon";
609  case PCRel32Minus1Anon:
610  return "PCRel32Minus1Anon";
611  case PCRel32Minus2Anon:
612  return "PCRel32Minus2Anon";
613  case PCRel32Minus4Anon:
614  return "PCRel32Minus4Anon";
615  case PCRel32GOTLoad:
616  return "PCRel32GOTLoad";
617  case PCRel32GOT:
618  return "PCRel32GOT";
619  case PCRel32TLV:
620  return "PCRel32TLV";
621  case Delta32:
622  return "Delta32";
623  case Delta64:
624  return "Delta64";
625  case NegDelta32:
626  return "NegDelta32";
627  case NegDelta64:
628  return "NegDelta64";
629  default:
630  return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
631  }
632 }
633 
634 } // end namespace jitlink
635 } // end namespace llvm
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
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:124
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: yaml2obj.h:21
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
section_iterator_range sections() const
Definition: ObjectFile.h:310
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:41
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
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
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:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
LLVM Value Representation.
Definition: Value.h:74
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