EHFrameSupportImpl.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. //===------- EHFrameSupportImpl.h - JITLink eh-frame utils ------*- C++ -*-===//
  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. // EHFrame registration support for JITLink.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
  13. #define LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
  14. #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
  15. #include "llvm/ExecutionEngine/JITLink/JITLink.h"
  16. #include "llvm/Support/BinaryStreamReader.h"
  17. namespace llvm {
  18. namespace jitlink {
  19. /// A LinkGraph pass that splits blocks in an eh-frame section into sub-blocks
  20. /// representing individual eh-frames.
  21. /// EHFrameSplitter should not be run without EHFrameEdgeFixer, which is
  22. /// responsible for adding FDE-to-CIE edges.
  23. class EHFrameSplitter {
  24. public:
  25. EHFrameSplitter(StringRef EHFrameSectionName);
  26. Error operator()(LinkGraph &G);
  27. private:
  28. Error processBlock(LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache);
  29. StringRef EHFrameSectionName;
  30. };
  31. /// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
  32. /// edges.
  33. class EHFrameEdgeFixer {
  34. public:
  35. EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,
  36. Edge::Kind Delta64, Edge::Kind Delta32,
  37. Edge::Kind NegDelta32);
  38. Error operator()(LinkGraph &G);
  39. private:
  40. struct AugmentationInfo {
  41. bool AugmentationDataPresent = false;
  42. bool EHDataFieldPresent = false;
  43. uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0};
  44. };
  45. struct CIEInformation {
  46. CIEInformation() = default;
  47. CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}
  48. Symbol *CIESymbol = nullptr;
  49. bool FDEsHaveLSDAField = false;
  50. uint8_t FDEPointerEncoding = 0;
  51. uint8_t LSDAPointerEncoding = 0;
  52. };
  53. struct EdgeTarget {
  54. EdgeTarget() = default;
  55. EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {}
  56. Symbol *Target = nullptr;
  57. Edge::AddendT Addend = 0;
  58. };
  59. using BlockEdgeMap = DenseMap<Edge::OffsetT, EdgeTarget>;
  60. using CIEInfosMap = DenseMap<orc::ExecutorAddr, CIEInformation>;
  61. struct ParseContext {
  62. ParseContext(LinkGraph &G) : G(G) {}
  63. Expected<CIEInformation *> findCIEInfo(orc::ExecutorAddr Address) {
  64. auto I = CIEInfos.find(Address);
  65. if (I == CIEInfos.end())
  66. return make_error<JITLinkError>("No CIE found at address " +
  67. formatv("{0:x16}", Address));
  68. return &I->second;
  69. }
  70. LinkGraph &G;
  71. CIEInfosMap CIEInfos;
  72. BlockAddressMap AddrToBlock;
  73. SymbolAddressMap AddrToSyms;
  74. };
  75. Error processBlock(ParseContext &PC, Block &B);
  76. Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset,
  77. size_t RecordLength, size_t CIEDeltaFieldOffset);
  78. Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset,
  79. size_t RecordLength, size_t CIEDeltaFieldOffset,
  80. uint32_t CIEDelta, BlockEdgeMap &BlockEdges);
  81. Expected<AugmentationInfo>
  82. parseAugmentationString(BinaryStreamReader &RecordReader);
  83. static bool isSupportedPointerEncoding(uint8_t PointerEncoding);
  84. unsigned getPointerEncodingDataSize(uint8_t PointerEncoding);
  85. Expected<std::pair<orc::ExecutorAddr, Edge::Kind>>
  86. readEncodedPointer(uint8_t PointerEncoding,
  87. orc::ExecutorAddr PointerFieldAddress,
  88. BinaryStreamReader &RecordReader);
  89. Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,
  90. orc::ExecutorAddr Addr);
  91. StringRef EHFrameSectionName;
  92. unsigned PointerSize;
  93. Edge::Kind Delta64;
  94. Edge::Kind Delta32;
  95. Edge::Kind NegDelta32;
  96. };
  97. /// Add a 32-bit null-terminator to the end of the eh-frame section.
  98. class EHFrameNullTerminator {
  99. public:
  100. EHFrameNullTerminator(StringRef EHFrameSectionName);
  101. Error operator()(LinkGraph &G);
  102. private:
  103. static char NullTerminatorBlockContent[];
  104. StringRef EHFrameSectionName;
  105. };
  106. } // end namespace jitlink
  107. } // end namespace llvm
  108. #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H