Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
35271 views
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 adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
25
/// edges.
26
class EHFrameEdgeFixer {
27
public:
28
/// Create an eh-frame edge fixer.
29
/// If a given edge-kind is not supported on the target architecture then
30
/// Edge::Invalid should be used.
31
EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,
32
Edge::Kind Pointer32, Edge::Kind Pointer64,
33
Edge::Kind Delta32, Edge::Kind Delta64,
34
Edge::Kind NegDelta32);
35
Error operator()(LinkGraph &G);
36
37
private:
38
39
struct AugmentationInfo {
40
bool AugmentationDataPresent = false;
41
bool EHDataFieldPresent = false;
42
uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0};
43
};
44
45
struct CIEInformation {
46
CIEInformation() = default;
47
CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}
48
Symbol *CIESymbol = nullptr;
49
bool AugmentationDataPresent = false;
50
bool LSDAPresent = false;
51
uint8_t LSDAEncoding = 0;
52
uint8_t AddressEncoding = 0;
53
};
54
55
struct EdgeTarget {
56
EdgeTarget() = default;
57
EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {}
58
59
Symbol *Target = nullptr;
60
Edge::AddendT Addend = 0;
61
};
62
63
struct BlockEdgesInfo {
64
DenseMap<Edge::OffsetT, EdgeTarget> TargetMap;
65
DenseSet<Edge::OffsetT> Multiple;
66
};
67
68
using CIEInfosMap = DenseMap<orc::ExecutorAddr, CIEInformation>;
69
70
struct ParseContext {
71
ParseContext(LinkGraph &G) : G(G) {}
72
73
Expected<CIEInformation *> findCIEInfo(orc::ExecutorAddr Address) {
74
auto I = CIEInfos.find(Address);
75
if (I == CIEInfos.end())
76
return make_error<JITLinkError>("No CIE found at address " +
77
formatv("{0:x16}", Address));
78
return &I->second;
79
}
80
81
LinkGraph &G;
82
CIEInfosMap CIEInfos;
83
BlockAddressMap AddrToBlock;
84
DenseMap<orc::ExecutorAddr, Symbol *> AddrToSym;
85
};
86
87
Error processBlock(ParseContext &PC, Block &B);
88
Error processCIE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,
89
const BlockEdgesInfo &BlockEdges);
90
Error processFDE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,
91
uint32_t CIEDelta, const BlockEdgesInfo &BlockEdges);
92
93
Expected<AugmentationInfo>
94
parseAugmentationString(BinaryStreamReader &RecordReader);
95
96
Expected<uint8_t> readPointerEncoding(BinaryStreamReader &RecordReader,
97
Block &InBlock, const char *FieldName);
98
Error skipEncodedPointer(uint8_t PointerEncoding,
99
BinaryStreamReader &RecordReader);
100
Expected<Symbol *> getOrCreateEncodedPointerEdge(
101
ParseContext &PC, const BlockEdgesInfo &BlockEdges,
102
uint8_t PointerEncoding, BinaryStreamReader &RecordReader,
103
Block &BlockToFix, size_t PointerFieldOffset, const char *FieldName);
104
105
Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,
106
orc::ExecutorAddr Addr);
107
108
StringRef EHFrameSectionName;
109
unsigned PointerSize;
110
Edge::Kind Pointer32;
111
Edge::Kind Pointer64;
112
Edge::Kind Delta32;
113
Edge::Kind Delta64;
114
Edge::Kind NegDelta32;
115
};
116
117
/// Add a 32-bit null-terminator to the end of the eh-frame section.
118
class EHFrameNullTerminator {
119
public:
120
EHFrameNullTerminator(StringRef EHFrameSectionName);
121
Error operator()(LinkGraph &G);
122
123
private:
124
static char NullTerminatorBlockContent[];
125
StringRef EHFrameSectionName;
126
};
127
128
} // end namespace jitlink
129
} // end namespace llvm
130
131
#endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
132
133