EHFrameSupportImpl.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
  20. /// edges.
  21. class EHFrameEdgeFixer {
  22. public:
  23. /// Create an eh-frame edge fixer.
  24. /// If a given edge-kind is not supported on the target architecture then
  25. /// Edge::Invalid should be used.
  26. EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,
  27. Edge::Kind Pointer32, Edge::Kind Pointer64,
  28. Edge::Kind Delta32, Edge::Kind Delta64,
  29. Edge::Kind NegDelta32);
  30. Error operator()(LinkGraph &G);
  31. private:
  32. struct AugmentationInfo {
  33. bool AugmentationDataPresent = false;
  34. bool EHDataFieldPresent = false;
  35. uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0};
  36. };
  37. struct CIEInformation {
  38. CIEInformation() = default;
  39. CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}
  40. Symbol *CIESymbol = nullptr;
  41. bool AugmentationDataPresent = false;
  42. bool LSDAPresent = false;
  43. uint8_t LSDAEncoding = 0;
  44. uint8_t AddressEncoding = 0;
  45. };
  46. struct EdgeTarget {
  47. EdgeTarget() = default;
  48. EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {}
  49. Symbol *Target = nullptr;
  50. Edge::AddendT Addend = 0;
  51. };
  52. using BlockEdgeMap = DenseMap<Edge::OffsetT, EdgeTarget>;
  53. using CIEInfosMap = DenseMap<orc::ExecutorAddr, CIEInformation>;
  54. struct ParseContext {
  55. ParseContext(LinkGraph &G) : G(G) {}
  56. Expected<CIEInformation *> findCIEInfo(orc::ExecutorAddr Address) {
  57. auto I = CIEInfos.find(Address);
  58. if (I == CIEInfos.end())
  59. return make_error<JITLinkError>("No CIE found at address " +
  60. formatv("{0:x16}", Address));
  61. return &I->second;
  62. }
  63. LinkGraph &G;
  64. CIEInfosMap CIEInfos;
  65. BlockAddressMap AddrToBlock;
  66. DenseMap<orc::ExecutorAddr, Symbol *> AddrToSym;
  67. };
  68. Error processBlock(ParseContext &PC, Block &B);
  69. Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset,
  70. size_t RecordLength, size_t CIEDeltaFieldOffset,
  71. const BlockEdgeMap &BlockEdges);
  72. Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset,
  73. size_t RecordLength, size_t CIEDeltaFieldOffset,
  74. uint32_t CIEDelta, const BlockEdgeMap &BlockEdges);
  75. Expected<AugmentationInfo>
  76. parseAugmentationString(BinaryStreamReader &RecordReader);
  77. Expected<uint8_t> readPointerEncoding(BinaryStreamReader &RecordReader,
  78. Block &InBlock, const char *FieldName);
  79. Error skipEncodedPointer(uint8_t PointerEncoding,
  80. BinaryStreamReader &RecordReader);
  81. Expected<Symbol *> getOrCreateEncodedPointerEdge(
  82. ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
  83. BinaryStreamReader &RecordReader, Block &BlockToFix,
  84. size_t PointerFieldOffset, const char *FieldName);
  85. Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,
  86. orc::ExecutorAddr Addr);
  87. StringRef EHFrameSectionName;
  88. unsigned PointerSize;
  89. Edge::Kind Pointer32;
  90. Edge::Kind Pointer64;
  91. Edge::Kind Delta32;
  92. Edge::Kind Delta64;
  93. Edge::Kind NegDelta32;
  94. };
  95. /// Add a 32-bit null-terminator to the end of the eh-frame section.
  96. class EHFrameNullTerminator {
  97. public:
  98. EHFrameNullTerminator(StringRef EHFrameSectionName);
  99. Error operator()(LinkGraph &G);
  100. private:
  101. static char NullTerminatorBlockContent[];
  102. StringRef EHFrameSectionName;
  103. };
  104. } // end namespace jitlink
  105. } // end namespace llvm
  106. #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H