1 //===------- EHFrameSupportImpl.h - JITLink eh-frame utils ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // EHFrame registration support for JITLink.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
14 #define LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
16 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
18 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
19 #include "llvm/Support/BinaryStreamReader.h"
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 {
30 EHFrameSplitter(StringRef EHFrameSectionName);
31 Error operator()(LinkGraph &G);
34 Error processBlock(LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache);
36 StringRef EHFrameSectionName;
39 /// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
41 class EHFrameEdgeFixer {
43 EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,
44 Edge::Kind Delta64, Edge::Kind Delta32,
45 Edge::Kind NegDelta32);
46 Error operator()(LinkGraph &G);
50 struct AugmentationInfo {
51 bool AugmentationDataPresent = false;
52 bool EHDataFieldPresent = false;
53 uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0};
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;
66 EdgeTarget() = default;
67 EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {}
69 Symbol *Target = nullptr;
70 Edge::AddendT Addend = 0;
73 using BlockEdgeMap = DenseMap<Edge::OffsetT, EdgeTarget>;
74 using CIEInfosMap = DenseMap<orc::ExecutorAddr, CIEInformation>;
77 ParseContext(LinkGraph &G) : G(G) {}
79 Expected<CIEInformation *> findCIEInfo(orc::ExecutorAddr 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));
89 BlockAddressMap AddrToBlock;
90 SymbolAddressMap AddrToSyms;
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);
100 Expected<AugmentationInfo>
101 parseAugmentationString(BinaryStreamReader &RecordReader);
103 static bool isSupportedPointerEncoding(uint8_t PointerEncoding);
104 unsigned getPointerEncodingDataSize(uint8_t PointerEncoding);
105 Expected<std::pair<orc::ExecutorAddr, Edge::Kind>>
106 readEncodedPointer(uint8_t PointerEncoding,
107 orc::ExecutorAddr PointerFieldAddress,
108 BinaryStreamReader &RecordReader);
110 Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,
111 orc::ExecutorAddr Addr);
113 StringRef EHFrameSectionName;
114 unsigned PointerSize;
117 Edge::Kind NegDelta32;
120 /// Add a 32-bit null-terminator to the end of the eh-frame section.
121 class EHFrameNullTerminator {
123 EHFrameNullTerminator(StringRef EHFrameSectionName);
124 Error operator()(LinkGraph &G);
127 static char NullTerminatorBlockContent[];
128 StringRef EHFrameSectionName;
131 } // end namespace jitlink
132 } // end namespace llvm
134 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H