150
|
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, Edge::Kind FDEToCIE,
|
|
44 Edge::Kind FDEToPCBegin, Edge::Kind FDEToLSDA);
|
|
45 Error operator()(LinkGraph &G);
|
|
46
|
|
47 private:
|
|
48
|
|
49 struct AugmentationInfo {
|
|
50 bool AugmentationDataPresent = false;
|
|
51 bool EHDataFieldPresent = false;
|
|
52 uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0};
|
|
53 };
|
|
54
|
|
55 struct CIEInformation {
|
|
56 CIEInformation() = default;
|
|
57 CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}
|
|
58 Symbol *CIESymbol = nullptr;
|
|
59 bool FDEsHaveLSDAField = false;
|
|
60 };
|
|
61
|
|
62 struct EdgeTarget {
|
|
63 EdgeTarget() = default;
|
|
64 EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {}
|
|
65
|
|
66 Symbol *Target = nullptr;
|
|
67 Edge::AddendT Addend = 0;
|
|
68 };
|
|
69
|
|
70 using BlockEdgeMap = DenseMap<Edge::OffsetT, EdgeTarget>;
|
|
71 using CIEInfosMap = DenseMap<JITTargetAddress, CIEInformation>;
|
|
72
|
|
73 struct ParseContext {
|
|
74 ParseContext(LinkGraph &G) : G(G) {}
|
|
75
|
|
76 Expected<CIEInformation *> findCIEInfo(JITTargetAddress Address) {
|
|
77 auto I = CIEInfos.find(Address);
|
|
78 if (I == CIEInfos.end())
|
|
79 return make_error<JITLinkError>("No CIE found at address " +
|
|
80 formatv("{0:x16}", Address));
|
|
81 return &I->second;
|
|
82 }
|
|
83
|
|
84 LinkGraph &G;
|
|
85 CIEInfosMap CIEInfos;
|
|
86 BlockAddressMap AddrToBlock;
|
|
87 SymbolAddressMap AddrToSyms;
|
|
88 };
|
|
89
|
|
90 Error processBlock(ParseContext &PC, Block &B);
|
|
91 Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset,
|
|
92 size_t RecordLength, size_t CIEDeltaFieldOffset);
|
|
93 Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset,
|
|
94 size_t RecordLength, size_t CIEDeltaFieldOffset,
|
|
95 uint32_t CIEDelta, BlockEdgeMap &BlockEdges);
|
|
96
|
|
97 Expected<AugmentationInfo>
|
|
98 parseAugmentationString(BinaryStreamReader &RecordReader);
|
|
99 Expected<JITTargetAddress>
|
|
100 readAbsolutePointer(LinkGraph &G, BinaryStreamReader &RecordReader);
|
|
101 Expected<Symbol &> getOrCreateSymbol(ParseContext &PC, JITTargetAddress Addr);
|
|
102
|
|
103 StringRef EHFrameSectionName;
|
|
104 Edge::Kind FDEToCIE;
|
|
105 Edge::Kind FDEToPCBegin;
|
|
106 Edge::Kind FDEToLSDA;
|
|
107 };
|
|
108
|
|
109 } // end namespace jitlink
|
|
110 } // end namespace llvm
|
|
111
|
|
112 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
|