EHFrameSupport.cpp 27 KB

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