EHFrameSupport.cpp 24 KB

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