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