EHFrameSupport.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. //===-------- JITLink_EHFrameSupport.cpp - JITLink eh-frame utils ---------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "EHFrameSupportImpl.h"
  10. #include "llvm/BinaryFormat/Dwarf.h"
  11. #include "llvm/Config/config.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. EHFrameSplitter::EHFrameSplitter(StringRef EHFrameSectionName)
  18. : EHFrameSectionName(EHFrameSectionName) {}
  19. Error EHFrameSplitter::operator()(LinkGraph &G) {
  20. auto *EHFrame = G.findSectionByName(EHFrameSectionName);
  21. if (!EHFrame) {
  22. LLVM_DEBUG({
  23. dbgs() << "EHFrameSplitter: No " << EHFrameSectionName
  24. << " section. Nothing to do\n";
  25. });
  26. return Error::success();
  27. }
  28. LLVM_DEBUG({
  29. dbgs() << "EHFrameSplitter: Processing " << EHFrameSectionName << "...\n";
  30. });
  31. DenseMap<Block *, LinkGraph::SplitBlockCache> Caches;
  32. {
  33. // Pre-build the split caches.
  34. for (auto *B : EHFrame->blocks())
  35. Caches[B] = LinkGraph::SplitBlockCache::value_type();
  36. for (auto *Sym : EHFrame->symbols())
  37. Caches[&Sym->getBlock()]->push_back(Sym);
  38. for (auto *B : EHFrame->blocks())
  39. llvm::sort(*Caches[B], [](const Symbol *LHS, const Symbol *RHS) {
  40. return LHS->getOffset() > RHS->getOffset();
  41. });
  42. }
  43. // Iterate over blocks (we do this by iterating over Caches entries rather
  44. // than EHFrame->blocks() as we will be inserting new blocks along the way,
  45. // which would invalidate iterators in the latter sequence.
  46. for (auto &KV : Caches) {
  47. auto &B = *KV.first;
  48. auto &BCache = KV.second;
  49. if (auto Err = processBlock(G, B, BCache))
  50. return Err;
  51. }
  52. return Error::success();
  53. }
  54. Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B,
  55. LinkGraph::SplitBlockCache &Cache) {
  56. LLVM_DEBUG({
  57. dbgs() << " Processing block at " << formatv("{0:x16}", B.getAddress())
  58. << "\n";
  59. });
  60. // eh-frame should not contain zero-fill blocks.
  61. if (B.isZeroFill())
  62. return make_error<JITLinkError>("Unexpected zero-fill block in " +
  63. EHFrameSectionName + " section");
  64. if (B.getSize() == 0) {
  65. LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n");
  66. return Error::success();
  67. }
  68. BinaryStreamReader BlockReader(B.getContent(), G.getEndianness());
  69. while (true) {
  70. uint64_t RecordStartOffset = BlockReader.getOffset();
  71. LLVM_DEBUG({
  72. dbgs() << " Processing CFI record at "
  73. << formatv("{0:x16}", B.getAddress()) << "\n";
  74. });
  75. uint32_t Length;
  76. if (auto Err = BlockReader.readInteger(Length))
  77. return Err;
  78. if (Length != 0xffffffff) {
  79. if (auto Err = BlockReader.skip(Length))
  80. return Err;
  81. } else {
  82. uint64_t ExtendedLength;
  83. if (auto Err = BlockReader.readInteger(ExtendedLength))
  84. return Err;
  85. if (auto Err = BlockReader.skip(ExtendedLength))
  86. return Err;
  87. }
  88. // If this was the last block then there's nothing to split
  89. if (BlockReader.empty()) {
  90. LLVM_DEBUG(dbgs() << " Extracted " << B << "\n");
  91. return Error::success();
  92. }
  93. uint64_t BlockSize = BlockReader.getOffset() - RecordStartOffset;
  94. auto &NewBlock = G.splitBlock(B, BlockSize);
  95. (void)NewBlock;
  96. LLVM_DEBUG(dbgs() << " Extracted " << NewBlock << "\n");
  97. }
  98. }
  99. EHFrameEdgeFixer::EHFrameEdgeFixer(StringRef EHFrameSectionName,
  100. unsigned PointerSize, Edge::Kind Delta64,
  101. Edge::Kind Delta32, Edge::Kind NegDelta32)
  102. : EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize),
  103. Delta64(Delta64), Delta32(Delta32), NegDelta32(NegDelta32) {}
  104. Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
  105. auto *EHFrame = G.findSectionByName(EHFrameSectionName);
  106. if (!EHFrame) {
  107. LLVM_DEBUG({
  108. dbgs() << "EHFrameEdgeFixer: No " << EHFrameSectionName
  109. << " section. Nothing to do\n";
  110. });
  111. return Error::success();
  112. }
  113. // Check that we support the graph's pointer size.
  114. if (G.getPointerSize() != 4 && G.getPointerSize() != 8)
  115. return make_error<JITLinkError>(
  116. "EHFrameEdgeFixer only supports 32 and 64 bit targets");
  117. LLVM_DEBUG({
  118. dbgs() << "EHFrameEdgeFixer: Processing " << EHFrameSectionName << "...\n";
  119. });
  120. ParseContext PC(G);
  121. // Build a map of all blocks and symbols in the text sections. We will use
  122. // these for finding / building edge targets when processing FDEs.
  123. for (auto &Sec : G.sections()) {
  124. PC.AddrToSyms.addSymbols(Sec.symbols());
  125. if (auto Err = PC.AddrToBlock.addBlocks(Sec.blocks(),
  126. BlockAddressMap::includeNonNull))
  127. return Err;
  128. }
  129. // Sort eh-frame blocks into address order to ensure we visit CIEs before
  130. // their child FDEs.
  131. std::vector<Block *> EHFrameBlocks;
  132. for (auto *B : EHFrame->blocks())
  133. EHFrameBlocks.push_back(B);
  134. llvm::sort(EHFrameBlocks, [](const Block *LHS, const Block *RHS) {
  135. return LHS->getAddress() < RHS->getAddress();
  136. });
  137. // Loop over the blocks in address order.
  138. for (auto *B : EHFrameBlocks)
  139. if (auto Err = processBlock(PC, *B))
  140. return Err;
  141. return Error::success();
  142. }
  143. Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
  144. LLVM_DEBUG({
  145. dbgs() << " Processing block at " << formatv("{0:x16}", B.getAddress())
  146. << "\n";
  147. });
  148. // eh-frame should not contain zero-fill blocks.
  149. if (B.isZeroFill())
  150. return make_error<JITLinkError>("Unexpected zero-fill block in " +
  151. EHFrameSectionName + " section");
  152. if (B.getSize() == 0) {
  153. LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n");
  154. return Error::success();
  155. }
  156. // Find the offsets of any existing edges from this block.
  157. BlockEdgeMap BlockEdges;
  158. for (auto &E : B.edges())
  159. if (E.isRelocation()) {
  160. if (BlockEdges.count(E.getOffset()))
  161. return make_error<JITLinkError>(
  162. "Multiple relocations at offset " +
  163. formatv("{0:x16}", E.getOffset()) + " in " + EHFrameSectionName +
  164. " block at address " + formatv("{0:x16}", B.getAddress()));
  165. BlockEdges[E.getOffset()] = EdgeTarget(E);
  166. }
  167. CIEInfosMap CIEInfos;
  168. BinaryStreamReader BlockReader(B.getContent(), PC.G.getEndianness());
  169. while (!BlockReader.empty()) {
  170. size_t RecordStartOffset = BlockReader.getOffset();
  171. LLVM_DEBUG({
  172. dbgs() << " Processing CFI record at "
  173. << formatv("{0:x16}", B.getAddress() + RecordStartOffset) << "\n";
  174. });
  175. // Get the record length.
  176. size_t RecordRemaining;
  177. {
  178. uint32_t Length;
  179. if (auto Err = BlockReader.readInteger(Length))
  180. return Err;
  181. // If Length < 0xffffffff then use the regular length field, otherwise
  182. // read the extended length field.
  183. if (Length != 0xffffffff)
  184. RecordRemaining = Length;
  185. else {
  186. uint64_t ExtendedLength;
  187. if (auto Err = BlockReader.readInteger(ExtendedLength))
  188. return Err;
  189. RecordRemaining = ExtendedLength;
  190. }
  191. }
  192. if (BlockReader.bytesRemaining() < RecordRemaining)
  193. return make_error<JITLinkError>(
  194. "Incomplete CFI record at " +
  195. formatv("{0:x16}", B.getAddress() + RecordStartOffset));
  196. // Read the CIE delta for this record.
  197. uint64_t CIEDeltaFieldOffset = BlockReader.getOffset() - RecordStartOffset;
  198. uint32_t CIEDelta;
  199. if (auto Err = BlockReader.readInteger(CIEDelta))
  200. return Err;
  201. if (CIEDelta == 0) {
  202. if (auto Err = processCIE(PC, B, RecordStartOffset,
  203. CIEDeltaFieldOffset + RecordRemaining,
  204. CIEDeltaFieldOffset))
  205. return Err;
  206. } else {
  207. if (auto Err = processFDE(PC, B, RecordStartOffset,
  208. CIEDeltaFieldOffset + RecordRemaining,
  209. CIEDeltaFieldOffset, CIEDelta, BlockEdges))
  210. return Err;
  211. }
  212. // Move to the next record.
  213. BlockReader.setOffset(RecordStartOffset + CIEDeltaFieldOffset +
  214. RecordRemaining);
  215. }
  216. return Error::success();
  217. }
  218. Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
  219. size_t RecordOffset, size_t RecordLength,
  220. size_t CIEDeltaFieldOffset) {
  221. LLVM_DEBUG(dbgs() << " Record is CIE\n");
  222. auto RecordContent = B.getContent().substr(RecordOffset, RecordLength);
  223. BinaryStreamReader RecordReader(RecordContent, PC.G.getEndianness());
  224. // Skip past the CIE delta field: we've already processed this far.
  225. RecordReader.setOffset(CIEDeltaFieldOffset + 4);
  226. auto &CIESymbol =
  227. PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
  228. CIEInformation CIEInfo(CIESymbol);
  229. uint8_t Version = 0;
  230. if (auto Err = RecordReader.readInteger(Version))
  231. return Err;
  232. if (Version != 0x01)
  233. return make_error<JITLinkError>("Bad CIE version " + Twine(Version) +
  234. " (should be 0x01) in eh-frame");
  235. auto AugInfo = parseAugmentationString(RecordReader);
  236. if (!AugInfo)
  237. return AugInfo.takeError();
  238. // Skip the EH Data field if present.
  239. if (AugInfo->EHDataFieldPresent)
  240. if (auto Err = RecordReader.skip(PC.G.getPointerSize()))
  241. return Err;
  242. // Read and sanity check the code alignment factor.
  243. {
  244. uint64_t CodeAlignmentFactor = 0;
  245. if (auto Err = RecordReader.readULEB128(CodeAlignmentFactor))
  246. return Err;
  247. if (CodeAlignmentFactor != 1)
  248. return make_error<JITLinkError>("Unsupported CIE code alignment factor " +
  249. Twine(CodeAlignmentFactor) +
  250. " (expected 1)");
  251. }
  252. // Read and sanity check the data alignment factor.
  253. {
  254. int64_t DataAlignmentFactor = 0;
  255. if (auto Err = RecordReader.readSLEB128(DataAlignmentFactor))
  256. return Err;
  257. if (DataAlignmentFactor != -8)
  258. return make_error<JITLinkError>("Unsupported CIE data alignment factor " +
  259. Twine(DataAlignmentFactor) +
  260. " (expected -8)");
  261. }
  262. // Skip the return address register field.
  263. if (auto Err = RecordReader.skip(1))
  264. return Err;
  265. uint64_t AugmentationDataLength = 0;
  266. if (auto Err = RecordReader.readULEB128(AugmentationDataLength))
  267. return Err;
  268. uint32_t AugmentationDataStartOffset = RecordReader.getOffset();
  269. uint8_t *NextField = &AugInfo->Fields[0];
  270. while (uint8_t Field = *NextField++) {
  271. switch (Field) {
  272. case 'L': {
  273. CIEInfo.FDEsHaveLSDAField = true;
  274. uint8_t LSDAPointerEncoding;
  275. if (auto Err = RecordReader.readInteger(LSDAPointerEncoding))
  276. return Err;
  277. if (!isSupportedPointerEncoding(LSDAPointerEncoding))
  278. return make_error<JITLinkError>(
  279. "Unsupported LSDA pointer encoding " +
  280. formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " +
  281. formatv("{0:x16}", CIESymbol.getAddress()));
  282. CIEInfo.LSDAPointerEncoding = LSDAPointerEncoding;
  283. break;
  284. }
  285. case 'P': {
  286. uint8_t PersonalityPointerEncoding = 0;
  287. if (auto Err = RecordReader.readInteger(PersonalityPointerEncoding))
  288. return Err;
  289. if (PersonalityPointerEncoding !=
  290. (dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
  291. dwarf::DW_EH_PE_sdata4))
  292. return make_error<JITLinkError>(
  293. "Unspported personality pointer "
  294. "encoding " +
  295. formatv("{0:x2}", PersonalityPointerEncoding) + " in CIE at " +
  296. formatv("{0:x16}", CIESymbol.getAddress()));
  297. uint32_t PersonalityPointerAddress;
  298. if (auto Err = RecordReader.readInteger(PersonalityPointerAddress))
  299. return Err;
  300. break;
  301. }
  302. case 'R': {
  303. uint8_t FDEPointerEncoding;
  304. if (auto Err = RecordReader.readInteger(FDEPointerEncoding))
  305. return Err;
  306. if (!isSupportedPointerEncoding(FDEPointerEncoding))
  307. return make_error<JITLinkError>(
  308. "Unsupported FDE pointer encoding " +
  309. formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " +
  310. formatv("{0:x16}", CIESymbol.getAddress()));
  311. CIEInfo.FDEPointerEncoding = FDEPointerEncoding;
  312. break;
  313. }
  314. default:
  315. llvm_unreachable("Invalid augmentation string field");
  316. }
  317. }
  318. if (RecordReader.getOffset() - AugmentationDataStartOffset >
  319. AugmentationDataLength)
  320. return make_error<JITLinkError>("Read past the end of the augmentation "
  321. "data while parsing fields");
  322. assert(!PC.CIEInfos.count(CIESymbol.getAddress()) &&
  323. "Multiple CIEs recorded at the same address?");
  324. PC.CIEInfos[CIESymbol.getAddress()] = std::move(CIEInfo);
  325. return Error::success();
  326. }
  327. Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
  328. size_t RecordOffset, size_t RecordLength,
  329. size_t CIEDeltaFieldOffset,
  330. uint32_t CIEDelta,
  331. BlockEdgeMap &BlockEdges) {
  332. LLVM_DEBUG(dbgs() << " Record is FDE\n");
  333. JITTargetAddress RecordAddress = B.getAddress() + RecordOffset;
  334. auto RecordContent = B.getContent().substr(RecordOffset, RecordLength);
  335. BinaryStreamReader RecordReader(RecordContent, PC.G.getEndianness());
  336. // Skip past the CIE delta field: we've already read this far.
  337. RecordReader.setOffset(CIEDeltaFieldOffset + 4);
  338. auto &FDESymbol =
  339. PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
  340. CIEInformation *CIEInfo = nullptr;
  341. {
  342. // Process the CIE pointer field.
  343. auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset);
  344. JITTargetAddress CIEAddress =
  345. RecordAddress + CIEDeltaFieldOffset - CIEDelta;
  346. if (CIEEdgeItr == BlockEdges.end()) {
  347. LLVM_DEBUG({
  348. dbgs() << " Adding edge at "
  349. << formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset)
  350. << " to CIE at: " << formatv("{0:x16}", CIEAddress) << "\n";
  351. });
  352. if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
  353. CIEInfo = *CIEInfoOrErr;
  354. else
  355. return CIEInfoOrErr.takeError();
  356. assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
  357. B.addEdge(NegDelta32, RecordOffset + CIEDeltaFieldOffset,
  358. *CIEInfo->CIESymbol, 0);
  359. } else {
  360. LLVM_DEBUG({
  361. dbgs() << " Already has edge at "
  362. << formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset)
  363. << " to CIE at " << formatv("{0:x16}", CIEAddress) << "\n";
  364. });
  365. auto &EI = CIEEdgeItr->second;
  366. if (EI.Addend)
  367. return make_error<JITLinkError>(
  368. "CIE edge at " +
  369. formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) +
  370. " has non-zero addend");
  371. if (auto CIEInfoOrErr = PC.findCIEInfo(EI.Target->getAddress()))
  372. CIEInfo = *CIEInfoOrErr;
  373. else
  374. return CIEInfoOrErr.takeError();
  375. }
  376. }
  377. {
  378. // Process the PC-Begin field.
  379. Block *PCBeginBlock = nullptr;
  380. JITTargetAddress PCBeginFieldOffset = RecordReader.getOffset();
  381. auto PCEdgeItr = BlockEdges.find(RecordOffset + PCBeginFieldOffset);
  382. if (PCEdgeItr == BlockEdges.end()) {
  383. auto PCBeginPtrInfo =
  384. readEncodedPointer(CIEInfo->FDEPointerEncoding,
  385. RecordAddress + PCBeginFieldOffset, RecordReader);
  386. if (!PCBeginPtrInfo)
  387. return PCBeginPtrInfo.takeError();
  388. JITTargetAddress PCBegin = PCBeginPtrInfo->first;
  389. Edge::Kind PCBeginEdgeKind = PCBeginPtrInfo->second;
  390. LLVM_DEBUG({
  391. dbgs() << " Adding edge at "
  392. << formatv("{0:x16}", RecordAddress + PCBeginFieldOffset)
  393. << " to PC at " << formatv("{0:x16}", PCBegin) << "\n";
  394. });
  395. auto PCBeginSym = getOrCreateSymbol(PC, PCBegin);
  396. if (!PCBeginSym)
  397. return PCBeginSym.takeError();
  398. B.addEdge(PCBeginEdgeKind, RecordOffset + PCBeginFieldOffset, *PCBeginSym,
  399. 0);
  400. PCBeginBlock = &PCBeginSym->getBlock();
  401. } else {
  402. auto &EI = PCEdgeItr->second;
  403. LLVM_DEBUG({
  404. dbgs() << " Already has edge at "
  405. << formatv("{0:x16}", RecordAddress + PCBeginFieldOffset)
  406. << " to PC at " << formatv("{0:x16}", EI.Target->getAddress());
  407. if (EI.Addend)
  408. dbgs() << " + " << formatv("{0:x16}", EI.Addend);
  409. dbgs() << "\n";
  410. });
  411. // Make sure the existing edge points at a defined block.
  412. if (!EI.Target->isDefined()) {
  413. auto EdgeAddr = RecordAddress + PCBeginFieldOffset;
  414. return make_error<JITLinkError>("FDE edge at " +
  415. formatv("{0:x16}", EdgeAddr) +
  416. " points at external block");
  417. }
  418. PCBeginBlock = &EI.Target->getBlock();
  419. if (auto Err = RecordReader.skip(
  420. getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding)))
  421. return Err;
  422. }
  423. // Add a keep-alive edge from the FDE target to the FDE to ensure that the
  424. // FDE is kept alive if its target is.
  425. assert(PCBeginBlock && "PC-begin block not recorded");
  426. LLVM_DEBUG({
  427. dbgs() << " Adding keep-alive edge from target at "
  428. << formatv("{0:x16}", PCBeginBlock->getAddress()) << " to FDE at "
  429. << formatv("{0:x16}", RecordAddress) << "\n";
  430. });
  431. PCBeginBlock->addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
  432. }
  433. // Skip over the PC range size field.
  434. if (auto Err = RecordReader.skip(
  435. getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding)))
  436. return Err;
  437. if (CIEInfo->FDEsHaveLSDAField) {
  438. uint64_t AugmentationDataSize;
  439. if (auto Err = RecordReader.readULEB128(AugmentationDataSize))
  440. return Err;
  441. JITTargetAddress LSDAFieldOffset = RecordReader.getOffset();
  442. auto LSDAEdgeItr = BlockEdges.find(RecordOffset + LSDAFieldOffset);
  443. if (LSDAEdgeItr == BlockEdges.end()) {
  444. auto LSDAPointerInfo =
  445. readEncodedPointer(CIEInfo->LSDAPointerEncoding,
  446. RecordAddress + LSDAFieldOffset, RecordReader);
  447. if (!LSDAPointerInfo)
  448. return LSDAPointerInfo.takeError();
  449. JITTargetAddress LSDA = LSDAPointerInfo->first;
  450. Edge::Kind LSDAEdgeKind = LSDAPointerInfo->second;
  451. auto LSDASym = getOrCreateSymbol(PC, LSDA);
  452. if (!LSDASym)
  453. return LSDASym.takeError();
  454. LLVM_DEBUG({
  455. dbgs() << " Adding edge at "
  456. << formatv("{0:x16}", RecordAddress + LSDAFieldOffset)
  457. << " to LSDA at " << formatv("{0:x16}", LSDA) << "\n";
  458. });
  459. B.addEdge(LSDAEdgeKind, RecordOffset + LSDAFieldOffset, *LSDASym, 0);
  460. } else {
  461. LLVM_DEBUG({
  462. auto &EI = LSDAEdgeItr->second;
  463. dbgs() << " Already has edge at "
  464. << formatv("{0:x16}", RecordAddress + LSDAFieldOffset)
  465. << " to LSDA at " << formatv("{0:x16}", EI.Target->getAddress());
  466. if (EI.Addend)
  467. dbgs() << " + " << formatv("{0:x16}", EI.Addend);
  468. dbgs() << "\n";
  469. });
  470. if (auto Err = RecordReader.skip(AugmentationDataSize))
  471. return Err;
  472. }
  473. } else {
  474. LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
  475. }
  476. return Error::success();
  477. }
  478. Expected<EHFrameEdgeFixer::AugmentationInfo>
  479. EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) {
  480. AugmentationInfo AugInfo;
  481. uint8_t NextChar;
  482. uint8_t *NextField = &AugInfo.Fields[0];
  483. if (auto Err = RecordReader.readInteger(NextChar))
  484. return std::move(Err);
  485. while (NextChar != 0) {
  486. switch (NextChar) {
  487. case 'z':
  488. AugInfo.AugmentationDataPresent = true;
  489. break;
  490. case 'e':
  491. if (auto Err = RecordReader.readInteger(NextChar))
  492. return std::move(Err);
  493. if (NextChar != 'h')
  494. return make_error<JITLinkError>("Unrecognized substring e" +
  495. Twine(NextChar) +
  496. " in augmentation string");
  497. AugInfo.EHDataFieldPresent = true;
  498. break;
  499. case 'L':
  500. case 'P':
  501. case 'R':
  502. *NextField++ = NextChar;
  503. break;
  504. default:
  505. return make_error<JITLinkError>("Unrecognized character " +
  506. Twine(NextChar) +
  507. " in augmentation string");
  508. }
  509. if (auto Err = RecordReader.readInteger(NextChar))
  510. return std::move(Err);
  511. }
  512. return std::move(AugInfo);
  513. }
  514. bool EHFrameEdgeFixer::isSupportedPointerEncoding(uint8_t PointerEncoding) {
  515. using namespace dwarf;
  516. // We only support PC-rel for now.
  517. if ((PointerEncoding & 0x70) != DW_EH_PE_pcrel)
  518. return false;
  519. // readEncodedPointer does not handle indirect.
  520. if (PointerEncoding & DW_EH_PE_indirect)
  521. return false;
  522. // Supported datatypes.
  523. switch (PointerEncoding & 0xf) {
  524. case DW_EH_PE_absptr:
  525. case DW_EH_PE_udata4:
  526. case DW_EH_PE_udata8:
  527. case DW_EH_PE_sdata4:
  528. case DW_EH_PE_sdata8:
  529. return true;
  530. }
  531. return false;
  532. }
  533. unsigned EHFrameEdgeFixer::getPointerEncodingDataSize(uint8_t PointerEncoding) {
  534. using namespace dwarf;
  535. assert(isSupportedPointerEncoding(PointerEncoding) &&
  536. "Unsupported pointer encoding");
  537. switch (PointerEncoding & 0xf) {
  538. case DW_EH_PE_absptr:
  539. return PointerSize;
  540. case DW_EH_PE_udata4:
  541. case DW_EH_PE_sdata4:
  542. return 4;
  543. case DW_EH_PE_udata8:
  544. case DW_EH_PE_sdata8:
  545. return 8;
  546. default:
  547. llvm_unreachable("Unsupported encoding");
  548. }
  549. }
  550. Expected<std::pair<JITTargetAddress, Edge::Kind>>
  551. EHFrameEdgeFixer::readEncodedPointer(uint8_t PointerEncoding,
  552. JITTargetAddress PointerFieldAddress,
  553. BinaryStreamReader &RecordReader) {
  554. static_assert(sizeof(JITTargetAddress) == sizeof(uint64_t),
  555. "Result must be able to hold a uint64_t");
  556. assert(isSupportedPointerEncoding(PointerEncoding) &&
  557. "Unsupported pointer encoding");
  558. using namespace dwarf;
  559. // Isolate data type, remap absptr to udata4 or udata8. This relies on us
  560. // having verified that the graph uses 32-bit or 64-bit pointers only at the
  561. // start of this pass.
  562. uint8_t EffectiveType = PointerEncoding & 0xf;
  563. if (EffectiveType == DW_EH_PE_absptr)
  564. EffectiveType = (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;
  565. JITTargetAddress Addr;
  566. Edge::Kind PointerEdgeKind;
  567. switch (EffectiveType) {
  568. case DW_EH_PE_udata4: {
  569. uint32_t Val;
  570. if (auto Err = RecordReader.readInteger(Val))
  571. return std::move(Err);
  572. Addr = PointerFieldAddress + Val;
  573. PointerEdgeKind = Delta32;
  574. break;
  575. }
  576. case DW_EH_PE_udata8: {
  577. uint64_t Val;
  578. if (auto Err = RecordReader.readInteger(Val))
  579. return std::move(Err);
  580. Addr = PointerFieldAddress + Val;
  581. PointerEdgeKind = Delta64;
  582. break;
  583. }
  584. case DW_EH_PE_sdata4: {
  585. int32_t Val;
  586. if (auto Err = RecordReader.readInteger(Val))
  587. return std::move(Err);
  588. Addr = PointerFieldAddress + Val;
  589. PointerEdgeKind = Delta32;
  590. break;
  591. }
  592. case DW_EH_PE_sdata8: {
  593. int64_t Val;
  594. if (auto Err = RecordReader.readInteger(Val))
  595. return std::move(Err);
  596. Addr = PointerFieldAddress + Val;
  597. PointerEdgeKind = Delta64;
  598. break;
  599. }
  600. }
  601. if (PointerEdgeKind == Edge::Invalid)
  602. return make_error<JITLinkError>(
  603. "Unspported edge kind for encoded pointer at " +
  604. formatv("{0:x}", PointerFieldAddress));
  605. return std::make_pair(Addr, Delta64);
  606. }
  607. Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
  608. JITTargetAddress Addr) {
  609. Symbol *CanonicalSym = nullptr;
  610. auto UpdateCanonicalSym = [&](Symbol *Sym) {
  611. if (!CanonicalSym || Sym->getLinkage() < CanonicalSym->getLinkage() ||
  612. Sym->getScope() < CanonicalSym->getScope() ||
  613. (Sym->hasName() && !CanonicalSym->hasName()) ||
  614. Sym->getName() < CanonicalSym->getName())
  615. CanonicalSym = Sym;
  616. };
  617. if (auto *SymbolsAtAddr = PC.AddrToSyms.getSymbolsAt(Addr))
  618. for (auto *Sym : *SymbolsAtAddr)
  619. UpdateCanonicalSym(Sym);
  620. // If we found an existing symbol at the given address then use it.
  621. if (CanonicalSym)
  622. return *CanonicalSym;
  623. // Otherwise search for a block covering the address and create a new symbol.
  624. auto *B = PC.AddrToBlock.getBlockCovering(Addr);
  625. if (!B)
  626. return make_error<JITLinkError>("No symbol or block covering address " +
  627. formatv("{0:x16}", Addr));
  628. return PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
  629. }
  630. EHFrameRegistrar::~EHFrameRegistrar() {}
  631. Error InProcessEHFrameRegistrar::registerEHFrames(
  632. JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) {
  633. return orc::registerEHFrameSection(
  634. jitTargetAddressToPointer<void *>(EHFrameSectionAddr),
  635. EHFrameSectionSize);
  636. }
  637. Error InProcessEHFrameRegistrar::deregisterEHFrames(
  638. JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) {
  639. return orc::deregisterEHFrameSection(
  640. jitTargetAddressToPointer<void *>(EHFrameSectionAddr),
  641. EHFrameSectionSize);
  642. }
  643. LinkGraphPassFunction
  644. createEHFrameRecorderPass(const Triple &TT,
  645. StoreFrameRangeFunction StoreRangeAddress) {
  646. const char *EHFrameSectionName = nullptr;
  647. if (TT.getObjectFormat() == Triple::MachO)
  648. EHFrameSectionName = "__eh_frame";
  649. else
  650. EHFrameSectionName = ".eh_frame";
  651. auto RecordEHFrame =
  652. [EHFrameSectionName,
  653. StoreFrameRange = std::move(StoreRangeAddress)](LinkGraph &G) -> Error {
  654. // Search for a non-empty eh-frame and record the address of the first
  655. // symbol in it.
  656. JITTargetAddress Addr = 0;
  657. size_t Size = 0;
  658. if (auto *S = G.findSectionByName(EHFrameSectionName)) {
  659. auto R = SectionRange(*S);
  660. Addr = R.getStart();
  661. Size = R.getSize();
  662. }
  663. if (Addr == 0 && Size != 0)
  664. return make_error<JITLinkError>("__eh_frame section can not have zero "
  665. "address with non-zero size");
  666. StoreFrameRange(Addr, Size);
  667. return Error::success();
  668. };
  669. return RecordEHFrame;
  670. }
  671. } // end namespace jitlink
  672. } // end namespace llvm