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/DefineExternalSectionStartAndEndSymbols.h
35271 views
1
//===--------- DefineExternalSectionStartAndEndSymbols.h --------*- 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
// Utility class for recognizing external section start and end symbols and
10
// transforming them into defined symbols for the start and end blocks of the
11
// associated Section.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
16
#define LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
17
18
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
19
#include "llvm/Support/Debug.h"
20
21
#define DEBUG_TYPE "jitlink"
22
23
namespace llvm {
24
namespace jitlink {
25
26
struct SectionRangeSymbolDesc {
27
SectionRangeSymbolDesc() = default;
28
SectionRangeSymbolDesc(Section &Sec, bool IsStart)
29
: Sec(&Sec), IsStart(IsStart) {}
30
Section *Sec = nullptr;
31
bool IsStart = false;
32
};
33
34
/// Pass implementation for the createDefineExternalSectionStartAndEndSymbols
35
/// function.
36
template <typename SymbolIdentifierFunction>
37
class DefineExternalSectionStartAndEndSymbols {
38
public:
39
DefineExternalSectionStartAndEndSymbols(SymbolIdentifierFunction F)
40
: F(std::move(F)) {}
41
42
Error operator()(LinkGraph &G) {
43
44
// This pass will affect the external symbols set, so copy them out into a
45
// vector and iterate over that.
46
std::vector<Symbol *> Externals(G.external_symbols().begin(),
47
G.external_symbols().end());
48
49
for (auto *Sym : Externals) {
50
SectionRangeSymbolDesc D = F(G, *Sym);
51
if (D.Sec) {
52
auto &SR = getSectionRange(*D.Sec);
53
if (D.IsStart) {
54
if (SR.empty())
55
G.makeAbsolute(*Sym, orc::ExecutorAddr());
56
else
57
G.makeDefined(*Sym, *SR.getFirstBlock(), 0, 0, Linkage::Strong,
58
Scope::Local, false);
59
} else {
60
if (SR.empty())
61
G.makeAbsolute(*Sym, orc::ExecutorAddr());
62
else
63
G.makeDefined(*Sym, *SR.getLastBlock(),
64
SR.getLastBlock()->getSize(), 0, Linkage::Strong,
65
Scope::Local, false);
66
}
67
}
68
}
69
return Error::success();
70
}
71
72
private:
73
SectionRange &getSectionRange(Section &Sec) {
74
auto I = SectionRanges.find(&Sec);
75
if (I == SectionRanges.end())
76
I = SectionRanges.insert(std::make_pair(&Sec, SectionRange(Sec))).first;
77
return I->second;
78
}
79
80
DenseMap<Section *, SectionRange> SectionRanges;
81
SymbolIdentifierFunction F;
82
};
83
84
/// Returns a JITLink pass (as a function class) that uses the given symbol
85
/// identification function to identify external section start and end symbols
86
/// (and their associated Section*s) and transform the identified externals
87
/// into defined symbols pointing to the start of the first block in the
88
/// section and the end of the last (start and end symbols for empty sections
89
/// will be transformed into absolute symbols at address 0).
90
///
91
/// The identification function should be callable as
92
///
93
/// SectionRangeSymbolDesc (LinkGraph &G, Symbol &Sym)
94
///
95
/// If Sym is not a section range start or end symbol then a default
96
/// constructed SectionRangeSymbolDesc should be returned. If Sym is a start
97
/// symbol then SectionRangeSymbolDesc(Sec, true), where Sec is a reference to
98
/// the target Section. If Sym is an end symbol then
99
/// SectionRangeSymbolDesc(Sec, false) should be returned.
100
///
101
/// This pass should be run in the PostAllocationPass pipeline, at which point
102
/// all blocks should have been assigned their final addresses.
103
template <typename SymbolIdentifierFunction>
104
DefineExternalSectionStartAndEndSymbols<SymbolIdentifierFunction>
105
createDefineExternalSectionStartAndEndSymbolsPass(
106
SymbolIdentifierFunction &&F) {
107
return DefineExternalSectionStartAndEndSymbols<SymbolIdentifierFunction>(
108
std::forward<SymbolIdentifierFunction>(F));
109
}
110
111
/// ELF section start/end symbol detection.
112
inline SectionRangeSymbolDesc
113
identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
114
constexpr StringRef StartSymbolPrefix = "__start_";
115
constexpr StringRef EndSymbolPrefix = "__stop_";
116
117
auto SymName = Sym.getName();
118
if (SymName.starts_with(StartSymbolPrefix)) {
119
if (auto *Sec =
120
G.findSectionByName(SymName.drop_front(StartSymbolPrefix.size())))
121
return {*Sec, true};
122
} else if (SymName.starts_with(EndSymbolPrefix)) {
123
if (auto *Sec =
124
G.findSectionByName(SymName.drop_front(EndSymbolPrefix.size())))
125
return {*Sec, false};
126
}
127
return {};
128
}
129
130
/// MachO section start/end symbol detection.
131
inline SectionRangeSymbolDesc
132
identifyMachOSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
133
constexpr StringRef StartSymbolPrefix = "section$start$";
134
constexpr StringRef EndSymbolPrefix = "section$end$";
135
136
auto SymName = Sym.getName();
137
if (SymName.starts_with(StartSymbolPrefix)) {
138
auto [SegName, SecName] =
139
SymName.drop_front(StartSymbolPrefix.size()).split('$');
140
std::string SectionName = (SegName + "," + SecName).str();
141
if (auto *Sec = G.findSectionByName(SectionName))
142
return {*Sec, true};
143
} else if (SymName.starts_with(EndSymbolPrefix)) {
144
auto [SegName, SecName] =
145
SymName.drop_front(EndSymbolPrefix.size()).split('$');
146
std::string SectionName = (SegName + "," + SecName).str();
147
if (auto *Sec = G.findSectionByName(SectionName))
148
return {*Sec, false};
149
}
150
return {};
151
}
152
153
} // end namespace jitlink
154
} // end namespace llvm
155
156
#undef DEBUG_TYPE
157
158
#endif // LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
159
160