]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
Merge llvm-project main llvmorg-14-init-17616-g024a1fab5c35
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / ExecutionEngine / JITLink / EHFrameSupportImpl.h
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<orc::ExecutorAddr, CIEInformation>;
75
76   struct ParseContext {
77     ParseContext(LinkGraph &G) : G(G) {}
78
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));
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<orc::ExecutorAddr, Edge::Kind>>
106   readEncodedPointer(uint8_t PointerEncoding,
107                      orc::ExecutorAddr PointerFieldAddress,
108                      BinaryStreamReader &RecordReader);
109
110   Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,
111                                        orc::ExecutorAddr Addr);
112
113   StringRef EHFrameSectionName;
114   unsigned PointerSize;
115   Edge::Kind Delta64;
116   Edge::Kind Delta32;
117   Edge::Kind NegDelta32;
118 };
119
120 /// Add a 32-bit null-terminator to the end of the eh-frame section.
121 class EHFrameNullTerminator {
122 public:
123   EHFrameNullTerminator(StringRef EHFrameSectionName);
124   Error operator()(LinkGraph &G);
125
126 private:
127   static char NullTerminatorBlockContent[];
128   StringRef EHFrameSectionName;
129 };
130
131 } // end namespace jitlink
132 } // end namespace llvm
133
134 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H