LLVM  16.0.0git
EHFrameSupport.cpp
Go to the documentation of this file.
1 //===-------- JITLink_EHFrameSupport.cpp - JITLink eh-frame utils ---------===//
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 #include "EHFrameSupportImpl.h"
10 
12 #include "llvm/Config/config.h"
16 
17 #define DEBUG_TYPE "jitlink"
18 
19 namespace llvm {
20 namespace jitlink {
21 
26  : EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize),
29 
31  auto *EHFrame = G.findSectionByName(EHFrameSectionName);
32 
33  if (!EHFrame) {
34  LLVM_DEBUG({
35  dbgs() << "EHFrameEdgeFixer: No " << EHFrameSectionName
36  << " section in \"" << G.getName() << "\". Nothing to do.\n";
37  });
38  return Error::success();
39  }
40 
41  // Check that we support the graph's pointer size.
42  if (G.getPointerSize() != 4 && G.getPointerSize() != 8)
43  return make_error<JITLinkError>(
44  "EHFrameEdgeFixer only supports 32 and 64 bit targets");
45 
46  LLVM_DEBUG({
47  dbgs() << "EHFrameEdgeFixer: Processing " << EHFrameSectionName << " in \""
48  << G.getName() << "\"...\n";
49  });
50 
51  ParseContext PC(G);
52 
53  // Build a map of all blocks and symbols in the text sections. We will use
54  // these for finding / building edge targets when processing FDEs.
55  for (auto &Sec : G.sections()) {
56  // Just record the most-canonical symbol (for eh-frame purposes) at each
57  // address.
58  for (auto *Sym : Sec.symbols()) {
59  auto &CurSym = PC.AddrToSym[Sym->getAddress()];
60  if (!CurSym || (std::make_tuple(Sym->getLinkage(), Sym->getScope(),
61  !Sym->hasName(), Sym->getName()) <
62  std::make_tuple(CurSym->getLinkage(), CurSym->getScope(),
63  !CurSym->hasName(), CurSym->getName())))
64  CurSym = Sym;
65  }
66  if (auto Err = PC.AddrToBlock.addBlocks(Sec.blocks(),
68  return Err;
69  }
70 
71  // Sort eh-frame blocks into address order to ensure we visit CIEs before
72  // their child FDEs.
73  std::vector<Block *> EHFrameBlocks;
74  for (auto *B : EHFrame->blocks())
75  EHFrameBlocks.push_back(B);
76  llvm::sort(EHFrameBlocks, [](const Block *LHS, const Block *RHS) {
77  return LHS->getAddress() < RHS->getAddress();
78  });
79 
80  // Loop over the blocks in address order.
81  for (auto *B : EHFrameBlocks)
82  if (auto Err = processBlock(PC, *B))
83  return Err;
84 
85  return Error::success();
86 }
87 
89  BinaryStreamReader &R) {
90  uint32_t Length;
91  if (auto Err = R.readInteger(Length))
92  return std::move(Err);
93 
94  // If Length < 0xffffffff then use the regular length field, otherwise
95  // read the extended length field.
96  if (Length != 0xffffffff)
97  return Length;
98 
99  uint64_t ExtendedLength;
100  if (auto Err = R.readInteger(ExtendedLength))
101  return std::move(Err);
102 
103  if (ExtendedLength > std::numeric_limits<size_t>::max())
104  return make_error<JITLinkError>(
105  "In CFI record at " +
106  formatv("{0:x}", B.getAddress() + R.getOffset() - 12) +
107  ", extended length of " + formatv("{0:x}", ExtendedLength) +
108  " exceeds address-range max (" +
110 
111  return ExtendedLength;
112 }
113 
114 Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
115 
116  LLVM_DEBUG(dbgs() << " Processing block at " << B.getAddress() << "\n");
117 
118  // eh-frame should not contain zero-fill blocks.
119  if (B.isZeroFill())
120  return make_error<JITLinkError>("Unexpected zero-fill block in " +
121  EHFrameSectionName + " section");
122 
123  if (B.getSize() == 0) {
124  LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n");
125  return Error::success();
126  }
127 
128  // Find the offsets of any existing edges from this block.
129  BlockEdgeMap BlockEdges;
130  for (auto &E : B.edges())
131  if (E.isRelocation()) {
132  if (BlockEdges.count(E.getOffset()))
133  return make_error<JITLinkError>(
134  "Multiple relocations at offset " +
135  formatv("{0:x16}", E.getOffset()) + " in " + EHFrameSectionName +
136  " block at address " + formatv("{0:x16}", B.getAddress()));
137 
138  BlockEdges[E.getOffset()] = EdgeTarget(E);
139  }
140 
141  CIEInfosMap CIEInfos;
142  BinaryStreamReader BlockReader(
143  StringRef(B.getContent().data(), B.getContent().size()),
144  PC.G.getEndianness());
145  while (!BlockReader.empty()) {
146  size_t RecordStartOffset = BlockReader.getOffset();
147 
148  LLVM_DEBUG({
149  dbgs() << " Processing CFI record at "
150  << (B.getAddress() + RecordStartOffset) << "\n";
151  });
152 
153  // Get the record length.
154  Expected<size_t> RecordRemaining = readCFIRecordLength(B, BlockReader);
155  if (!RecordRemaining)
156  return RecordRemaining.takeError();
157 
158  if (BlockReader.bytesRemaining() < *RecordRemaining)
159  return make_error<JITLinkError>(
160  "Incomplete CFI record at " +
161  formatv("{0:x16}", B.getAddress() + RecordStartOffset));
162 
163  // Read the CIE delta for this record.
164  uint64_t CIEDeltaFieldOffset = BlockReader.getOffset() - RecordStartOffset;
165  uint32_t CIEDelta;
166  if (auto Err = BlockReader.readInteger(CIEDelta))
167  return Err;
168 
169  if (CIEDelta == 0) {
170  if (auto Err = processCIE(PC, B, RecordStartOffset,
171  CIEDeltaFieldOffset + *RecordRemaining,
172  CIEDeltaFieldOffset, BlockEdges))
173  return Err;
174  } else {
175  if (auto Err = processFDE(PC, B, RecordStartOffset,
176  CIEDeltaFieldOffset + *RecordRemaining,
177  CIEDeltaFieldOffset, CIEDelta, BlockEdges))
178  return Err;
179  }
180 
181  // Move to the next record.
182  BlockReader.setOffset(RecordStartOffset + CIEDeltaFieldOffset +
183  *RecordRemaining);
184  }
185 
186  return Error::success();
187 }
188 
189 Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
190  size_t RecordOffset, size_t RecordLength,
191  size_t CIEDeltaFieldOffset,
192  const BlockEdgeMap &BlockEdges) {
193 
194  LLVM_DEBUG(dbgs() << " Record is CIE\n");
195 
196  auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
197  BinaryStreamReader RecordReader(
198  StringRef(RecordContent.data(), RecordContent.size()),
199  PC.G.getEndianness());
200 
201  // Skip past the CIE delta field: we've already processed this far.
202  RecordReader.setOffset(CIEDeltaFieldOffset + 4);
203 
204  auto &CIESymbol =
205  PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
206  CIEInformation CIEInfo(CIESymbol);
207 
208  uint8_t Version = 0;
209  if (auto Err = RecordReader.readInteger(Version))
210  return Err;
211 
212  if (Version != 0x01)
213  return make_error<JITLinkError>("Bad CIE version " + Twine(Version) +
214  " (should be 0x01) in eh-frame");
215 
216  auto AugInfo = parseAugmentationString(RecordReader);
217  if (!AugInfo)
218  return AugInfo.takeError();
219 
220  // Skip the EH Data field if present.
221  if (AugInfo->EHDataFieldPresent)
222  if (auto Err = RecordReader.skip(PC.G.getPointerSize()))
223  return Err;
224 
225  // Read and validate the code alignment factor.
226  {
227  uint64_t CodeAlignmentFactor = 0;
228  if (auto Err = RecordReader.readULEB128(CodeAlignmentFactor))
229  return Err;
230  }
231 
232  // Read and validate the data alignment factor.
233  {
234  int64_t DataAlignmentFactor = 0;
235  if (auto Err = RecordReader.readSLEB128(DataAlignmentFactor))
236  return Err;
237  }
238 
239  // Skip the return address register field.
240  if (auto Err = RecordReader.skip(1))
241  return Err;
242 
243  if (AugInfo->AugmentationDataPresent) {
244 
245  CIEInfo.AugmentationDataPresent = true;
246 
247  uint64_t AugmentationDataLength = 0;
248  if (auto Err = RecordReader.readULEB128(AugmentationDataLength))
249  return Err;
250 
251  uint32_t AugmentationDataStartOffset = RecordReader.getOffset();
252 
253  uint8_t *NextField = &AugInfo->Fields[0];
254  while (uint8_t Field = *NextField++) {
255  switch (Field) {
256  case 'L':
257  CIEInfo.LSDAPresent = true;
258  if (auto PE = readPointerEncoding(RecordReader, B, "LSDA"))
259  CIEInfo.LSDAEncoding = *PE;
260  else
261  return PE.takeError();
262  break;
263  case 'P': {
264  auto PersonalityPointerEncoding =
265  readPointerEncoding(RecordReader, B, "personality");
266  if (!PersonalityPointerEncoding)
267  return PersonalityPointerEncoding.takeError();
268  if (auto Err =
269  getOrCreateEncodedPointerEdge(
270  PC, BlockEdges, *PersonalityPointerEncoding, RecordReader,
271  B, RecordOffset + RecordReader.getOffset(), "personality")
272  .takeError())
273  return Err;
274  break;
275  }
276  case 'R':
277  if (auto PE = readPointerEncoding(RecordReader, B, "address")) {
278  CIEInfo.AddressEncoding = *PE;
279  if (CIEInfo.AddressEncoding == dwarf::DW_EH_PE_omit)
280  return make_error<JITLinkError>(
281  "Invalid address encoding DW_EH_PE_omit in CIE at " +
282  formatv("{0:x}", (B.getAddress() + RecordOffset).getValue()));
283  } else
284  return PE.takeError();
285  break;
286  default:
287  llvm_unreachable("Invalid augmentation string field");
288  }
289  }
290 
291  if (RecordReader.getOffset() - AugmentationDataStartOffset >
292  AugmentationDataLength)
293  return make_error<JITLinkError>("Read past the end of the augmentation "
294  "data while parsing fields");
295  }
296 
297  assert(!PC.CIEInfos.count(CIESymbol.getAddress()) &&
298  "Multiple CIEs recorded at the same address?");
299  PC.CIEInfos[CIESymbol.getAddress()] = std::move(CIEInfo);
300 
301  return Error::success();
302 }
303 
304 Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
305  size_t RecordOffset, size_t RecordLength,
306  size_t CIEDeltaFieldOffset,
307  uint32_t CIEDelta,
308  const BlockEdgeMap &BlockEdges) {
309  LLVM_DEBUG(dbgs() << " Record is FDE\n");
310 
311  orc::ExecutorAddr RecordAddress = B.getAddress() + RecordOffset;
312 
313  auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
314  BinaryStreamReader RecordReader(
315  StringRef(RecordContent.data(), RecordContent.size()),
316  PC.G.getEndianness());
317 
318  // Skip past the CIE delta field: we've already read this far.
319  RecordReader.setOffset(CIEDeltaFieldOffset + 4);
320 
321  auto &FDESymbol =
322  PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
323 
324  CIEInformation *CIEInfo = nullptr;
325 
326  {
327  // Process the CIE pointer field.
328  auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset);
329  orc::ExecutorAddr CIEAddress =
330  RecordAddress + orc::ExecutorAddrDiff(CIEDeltaFieldOffset) -
331  orc::ExecutorAddrDiff(CIEDelta);
332  if (CIEEdgeItr == BlockEdges.end()) {
333 
334  LLVM_DEBUG({
335  dbgs() << " Adding edge at "
336  << (RecordAddress + CIEDeltaFieldOffset)
337  << " to CIE at: " << CIEAddress << "\n";
338  });
339  if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
340  CIEInfo = *CIEInfoOrErr;
341  else
342  return CIEInfoOrErr.takeError();
343  assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
344  B.addEdge(NegDelta32, RecordOffset + CIEDeltaFieldOffset,
345  *CIEInfo->CIESymbol, 0);
346  } else {
347  LLVM_DEBUG({
348  dbgs() << " Already has edge at "
349  << (RecordAddress + CIEDeltaFieldOffset) << " to CIE at "
350  << CIEAddress << "\n";
351  });
352  auto &EI = CIEEdgeItr->second;
353  if (EI.Addend)
354  return make_error<JITLinkError>(
355  "CIE edge at " +
356  formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) +
357  " has non-zero addend");
358  if (auto CIEInfoOrErr = PC.findCIEInfo(EI.Target->getAddress()))
359  CIEInfo = *CIEInfoOrErr;
360  else
361  return CIEInfoOrErr.takeError();
362  }
363  }
364 
365  // Process the PC-Begin field.
366  LLVM_DEBUG({
367  dbgs() << " Processing PC-begin at "
368  << (RecordAddress + RecordReader.getOffset()) << "\n";
369  });
370  if (auto PCBegin = getOrCreateEncodedPointerEdge(
371  PC, BlockEdges, CIEInfo->AddressEncoding, RecordReader, B,
372  RecordReader.getOffset(), "PC begin")) {
373  assert(*PCBegin && "PC-begin symbol not set");
374  if ((*PCBegin)->isDefined()) {
375  // Add a keep-alive edge from the FDE target to the FDE to ensure that the
376  // FDE is kept alive if its target is.
377  LLVM_DEBUG({
378  dbgs() << " Adding keep-alive edge from target at "
379  << (*PCBegin)->getBlock().getAddress() << " to FDE at "
380  << RecordAddress << "\n";
381  });
382  (*PCBegin)->getBlock().addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
383  } else {
384  LLVM_DEBUG({
385  dbgs() << " WARNING: Not adding keep-alive edge to FDE at "
386  << RecordAddress << ", which points to "
387  << ((*PCBegin)->isExternal() ? "external" : "absolute")
388  << " symbol \"" << (*PCBegin)->getName()
389  << "\" -- FDE must be kept alive manually or it will be "
390  << "dead stripped.\n";
391  });
392  }
393  } else
394  return PCBegin.takeError();
395 
396  // Skip over the PC range size field.
397  if (auto Err = skipEncodedPointer(CIEInfo->AddressEncoding, RecordReader))
398  return Err;
399 
400  if (CIEInfo->AugmentationDataPresent) {
401  uint64_t AugmentationDataSize;
402  if (auto Err = RecordReader.readULEB128(AugmentationDataSize))
403  return Err;
404 
405  if (CIEInfo->LSDAPresent)
406  if (auto Err = getOrCreateEncodedPointerEdge(
407  PC, BlockEdges, CIEInfo->LSDAEncoding, RecordReader, B,
408  RecordReader.getOffset(), "LSDA")
409  .takeError())
410  return Err;
411  } else {
412  LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
413  }
414 
415  return Error::success();
416 }
417 
418 Expected<EHFrameEdgeFixer::AugmentationInfo>
419 EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) {
420  AugmentationInfo AugInfo;
421  uint8_t NextChar;
422  uint8_t *NextField = &AugInfo.Fields[0];
423 
424  if (auto Err = RecordReader.readInteger(NextChar))
425  return std::move(Err);
426 
427  while (NextChar != 0) {
428  switch (NextChar) {
429  case 'z':
430  AugInfo.AugmentationDataPresent = true;
431  break;
432  case 'e':
433  if (auto Err = RecordReader.readInteger(NextChar))
434  return std::move(Err);
435  if (NextChar != 'h')
436  return make_error<JITLinkError>("Unrecognized substring e" +
437  Twine(NextChar) +
438  " in augmentation string");
439  AugInfo.EHDataFieldPresent = true;
440  break;
441  case 'L':
442  case 'P':
443  case 'R':
444  *NextField++ = NextChar;
445  break;
446  default:
447  return make_error<JITLinkError>("Unrecognized character " +
448  Twine(NextChar) +
449  " in augmentation string");
450  }
451 
452  if (auto Err = RecordReader.readInteger(NextChar))
453  return std::move(Err);
454  }
455 
456  return std::move(AugInfo);
457 }
458 
459 Expected<uint8_t> EHFrameEdgeFixer::readPointerEncoding(BinaryStreamReader &R,
460  Block &InBlock,
461  const char *FieldName) {
462  using namespace dwarf;
463 
464  uint8_t PointerEncoding;
465  if (auto Err = R.readInteger(PointerEncoding))
466  return std::move(Err);
467 
468  bool Supported = true;
469  switch (PointerEncoding & 0xf) {
470  case DW_EH_PE_uleb128:
471  case DW_EH_PE_udata2:
472  case DW_EH_PE_sleb128:
473  case DW_EH_PE_sdata2:
474  Supported = false;
475  break;
476  }
477  if (Supported) {
478  switch (PointerEncoding & 0x70) {
479  case DW_EH_PE_textrel:
480  case DW_EH_PE_datarel:
481  case DW_EH_PE_funcrel:
482  case DW_EH_PE_aligned:
483  Supported = false;
484  break;
485  }
486  }
487 
488  if (Supported)
489  return PointerEncoding;
490 
491  return make_error<JITLinkError>("Unsupported pointer encoding " +
492  formatv("{0:x2}", PointerEncoding) + " for " +
493  FieldName + "in CFI record at " +
494  formatv("{0:x16}", InBlock.getAddress()));
495 }
496 
497 Error EHFrameEdgeFixer::skipEncodedPointer(uint8_t PointerEncoding,
498  BinaryStreamReader &RecordReader) {
499  using namespace dwarf;
500 
501  // Switch absptr to corresponding udata encoding.
502  if ((PointerEncoding & 0xf) == DW_EH_PE_absptr)
503  PointerEncoding |= (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
504 
505  switch (PointerEncoding & 0xf) {
506  case DW_EH_PE_udata4:
507  case DW_EH_PE_sdata4:
508  if (auto Err = RecordReader.skip(4))
509  return Err;
510  break;
511  case DW_EH_PE_udata8:
512  case DW_EH_PE_sdata8:
513  if (auto Err = RecordReader.skip(8))
514  return Err;
515  break;
516  default:
517  llvm_unreachable("Unrecognized encoding");
518  }
519  return Error::success();
520 }
521 
522 Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
523  ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
524  BinaryStreamReader &RecordReader, Block &BlockToFix,
525  size_t PointerFieldOffset, const char *FieldName) {
526  using namespace dwarf;
527 
528  if (PointerEncoding == DW_EH_PE_omit)
529  return nullptr;
530 
531  // If there's already an edge here then just skip the encoded pointer and
532  // return the edge's target.
533  {
534  auto EdgeI = BlockEdges.find(PointerFieldOffset);
535  if (EdgeI != BlockEdges.end()) {
536  LLVM_DEBUG({
537  dbgs() << " Existing edge at "
538  << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
539  << FieldName << " at " << EdgeI->second.Target->getAddress();
540  if (EdgeI->second.Target->hasName())
541  dbgs() << " (" << EdgeI->second.Target->getName() << ")";
542  dbgs() << "\n";
543  });
544  if (auto Err = skipEncodedPointer(PointerEncoding, RecordReader))
545  return std::move(Err);
546  return EdgeI->second.Target;
547  }
548  }
549 
550  // Switch absptr to corresponding udata encoding.
551  if ((PointerEncoding & 0xf) == DW_EH_PE_absptr)
552  PointerEncoding |= (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
553 
554  // We need to create an edge. Start by reading the field value.
555  uint64_t FieldValue;
556  bool Is64Bit = false;
557  switch (PointerEncoding & 0xf) {
558  case DW_EH_PE_udata4: {
559  uint32_t Val;
560  if (auto Err = RecordReader.readInteger(Val))
561  return std::move(Err);
562  FieldValue = Val;
563  break;
564  }
565  case DW_EH_PE_sdata4: {
566  uint32_t Val;
567  if (auto Err = RecordReader.readInteger(Val))
568  return std::move(Err);
569  FieldValue = Val;
570  break;
571  }
572  case DW_EH_PE_udata8:
573  case DW_EH_PE_sdata8:
574  Is64Bit = true;
575  if (auto Err = RecordReader.readInteger(FieldValue))
576  return std::move(Err);
577  break;
578  default:
579  llvm_unreachable("Unsupported encoding");
580  }
581 
582  // Find the edge target and edge kind to use.
583  orc::ExecutorAddr Target;
584  Edge::Kind PtrEdgeKind = Edge::Invalid;
585  if ((PointerEncoding & 0x70) == DW_EH_PE_pcrel) {
586  Target = BlockToFix.getAddress() + PointerFieldOffset;
587  PtrEdgeKind = Is64Bit ? Delta64 : Delta32;
588  } else
589  PtrEdgeKind = Is64Bit ? Pointer64 : Pointer32;
590  Target += FieldValue;
591 
592  // Find or create a symbol to point the edge at.
593  auto TargetSym = getOrCreateSymbol(PC, Target);
594  if (!TargetSym)
595  return TargetSym.takeError();
596  BlockToFix.addEdge(PtrEdgeKind, PointerFieldOffset, *TargetSym, 0);
597 
598  LLVM_DEBUG({
599  dbgs() << " Adding edge at "
600  << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
601  << FieldName << " at " << TargetSym->getAddress();
602  if (TargetSym->hasName())
603  dbgs() << " (" << TargetSym->getName() << ")";
604  dbgs() << "\n";
605  });
606 
607  return &*TargetSym;
608 }
609 
610 Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
611  orc::ExecutorAddr Addr) {
612  // See whether we have a canonical symbol for the given address already.
613  auto CanonicalSymI = PC.AddrToSym.find(Addr);
614  if (CanonicalSymI != PC.AddrToSym.end())
615  return *CanonicalSymI->second;
616 
617  // Otherwise search for a block covering the address and create a new symbol.
618  auto *B = PC.AddrToBlock.getBlockCovering(Addr);
619  if (!B)
620  return make_error<JITLinkError>("No symbol or block covering address " +
621  formatv("{0:x16}", Addr));
622 
623  auto &S =
624  PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
625  PC.AddrToSym[S.getAddress()] = &S;
626  return S;
627 }
628 
629 char EHFrameNullTerminator::NullTerminatorBlockContent[4] = {0, 0, 0, 0};
630 
632  : EHFrameSectionName(EHFrameSectionName) {}
633 
635  auto *EHFrame = G.findSectionByName(EHFrameSectionName);
636 
637  if (!EHFrame)
638  return Error::success();
639 
640  LLVM_DEBUG({
641  dbgs() << "EHFrameNullTerminator adding null terminator to "
642  << EHFrameSectionName << "\n";
643  });
644 
645  auto &NullTerminatorBlock =
646  G.createContentBlock(*EHFrame, NullTerminatorBlockContent,
647  orc::ExecutorAddr(~uint64_t(4)), 1, 0);
648  G.addAnonymousSymbol(NullTerminatorBlock, 0, 4, false, true);
649  return Error::success();
650 }
651 
653 
655  orc::ExecutorAddrRange EHFrameSection) {
656  return orc::registerEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
657  EHFrameSection.size());
658 }
659 
661  orc::ExecutorAddrRange EHFrameSection) {
662  return orc::deregisterEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
663  EHFrameSection.size());
664 }
665 
667  if (B.edges_empty())
668  return EHFrameCFIBlockInspector(nullptr);
669  if (B.edges_size() == 1)
670  return EHFrameCFIBlockInspector(&*B.edges().begin());
672  for (auto &E : B.edges())
673  Es.push_back(&E);
674  assert(Es.size() >= 2 && Es.size() <= 3 && "Unexpected number of edges");
675  llvm::sort(Es, [](const Edge *LHS, const Edge *RHS) {
676  return LHS->getOffset() < RHS->getOffset();
677  });
678  return EHFrameCFIBlockInspector(*Es[0], *Es[1],
679  Es.size() == 3 ? Es[2] : nullptr);
680  return EHFrameCFIBlockInspector(nullptr);
681 }
682 
683 EHFrameCFIBlockInspector::EHFrameCFIBlockInspector(Edge *PersonalityEdge)
684  : PersonalityEdge(PersonalityEdge) {}
685 
686 EHFrameCFIBlockInspector::EHFrameCFIBlockInspector(Edge &CIEEdge,
687  Edge &PCBeginEdge,
688  Edge *LSDAEdge)
689  : CIEEdge(&CIEEdge), PCBeginEdge(&PCBeginEdge), LSDAEdge(LSDAEdge) {}
690 
693  StoreFrameRangeFunction StoreRangeAddress) {
694  const char *EHFrameSectionName = nullptr;
695  if (TT.getObjectFormat() == Triple::MachO)
696  EHFrameSectionName = "__TEXT,__eh_frame";
697  else
698  EHFrameSectionName = ".eh_frame";
699 
700  auto RecordEHFrame =
701  [EHFrameSectionName,
702  StoreFrameRange = std::move(StoreRangeAddress)](LinkGraph &G) -> Error {
703  // Search for a non-empty eh-frame and record the address of the first
704  // symbol in it.
706  size_t Size = 0;
707  if (auto *S = G.findSectionByName(EHFrameSectionName)) {
708  auto R = SectionRange(*S);
709  Addr = R.getStart();
710  Size = R.getSize();
711  }
712  if (!Addr && Size != 0)
713  return make_error<JITLinkError>(
714  StringRef(EHFrameSectionName) +
715  " section can not have zero address with non-zero size");
716  StoreFrameRange(Addr, Size);
717  return Error::success();
718  };
719 
720  return RecordEHFrame;
721 }
722 
723 } // end namespace jitlink
724 } // end namespace llvm
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::dwarf::DW_EH_PE_sdata4
@ DW_EH_PE_sdata4
Definition: Dwarf.h:445
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1182
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::dwarf::DW_EH_PE_sdata8
@ DW_EH_PE_sdata8
Definition: Dwarf.h:446
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
DynamicLibrary.h
llvm::orc::deregisterEHFrameSection
Error deregisterEHFrameSection(const void *EHFrameSectionAddr, size_t EHFrameSectionSize)
Unregister frames in the given eh-frame section with libunwind.
Definition: RegisterEHFrames.cpp:147
llvm::AMDGPU::Exp::Target
Target
Definition: SIDefines.h:858
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::dwarf::DW_EH_PE_textrel
@ DW_EH_PE_textrel
Definition: Dwarf.h:449
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:265
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
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::ExecutorAddr::toPtr
std::enable_if_t< std::is_pointer< T >::value, T > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given type.
Definition: ExecutorAddress.h:89
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::dwarf::DW_EH_PE_udata2
@ DW_EH_PE_udata2
Definition: Dwarf.h:440
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::orc::ExecutorAddrDiff
uint64_t ExecutorAddrDiff
Definition: ExecutorAddress.h:28
RegisterEHFrames.h
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
llvm::orc::ExecutorAddrRange
Represents an address range in the exceutor process.
Definition: ExecutorAddress.h:191
llvm::dwarf::DW_EH_PE_funcrel
@ DW_EH_PE_funcrel
Definition: Dwarf.h:451
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:29
llvm::dwarf::DW_EH_PE_udata4
@ DW_EH_PE_udata4
Definition: Dwarf.h:441
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1538
llvm::orc::ExecutorAddrRange::size
ExecutorAddrDiff size() const
Definition: ExecutorAddress.h:199
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
InBlock
static bool InBlock(const Value *V, const BasicBlock *BB)
Definition: SelectionDAGBuilder.cpp:2178
llvm::dwarf::DW_EH_PE_udata8
@ DW_EH_PE_udata8
Definition: Dwarf.h:442
uint64_t
llvm::dwarf::DW_EH_PE_pcrel
@ DW_EH_PE_pcrel
Definition: Dwarf.h:448
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
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
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::orc::ExecutorAddrRange::Start
ExecutorAddr Start
Definition: ExecutorAddress.h:214
llvm::dwarf::DW_EH_PE_datarel
@ DW_EH_PE_datarel
Definition: Dwarf.h:450
llvm::dwarf::DW_EH_PE_uleb128
@ DW_EH_PE_uleb128
Definition: Dwarf.h:439
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Dwarf.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
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::dwarf::DW_EH_PE_sleb128
@ DW_EH_PE_sleb128
Definition: Dwarf.h:443
llvm::dwarf::DW_EH_PE_absptr
@ DW_EH_PE_absptr
Definition: Dwarf.h:437
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::Triple::MachO
@ MachO
Definition: Triple.h:277
EHFrameSupportImpl.h
DWARFRecordSectionSplitter.h
llvm::orc::registerEHFrameSection
Error registerEHFrameSection(const void *EHFrameSectionAddr, size_t EHFrameSectionSize)
Register frames in the given eh-frame section with libunwind.
Definition: RegisterEHFrames.cpp:128
llvm::dwarf::DW_EH_PE_omit
@ DW_EH_PE_omit
Definition: Dwarf.h:438
llvm::dwarf::DW_EH_PE_sdata2
@ DW_EH_PE_sdata2
Definition: Dwarf.h:444
llvm::dwarf::DW_EH_PE_aligned
@ DW_EH_PE_aligned
Definition: Dwarf.h:452
llvm::OptimizedStructLayoutField
A field in a structure.
Definition: OptimizedStructLayout.h:45