Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
35269 views
1
//===----------- JITSymbol.cpp - JITSymbol class implementation -----------===//
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
// JITSymbol class implementation plus helper functions.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/ExecutionEngine/JITSymbol.h"
14
#include "llvm/IR/Function.h"
15
#include "llvm/IR/GlobalAlias.h"
16
#include "llvm/IR/GlobalValue.h"
17
#include "llvm/IR/ModuleSummaryIndex.h"
18
#include "llvm/Object/ObjectFile.h"
19
20
using namespace llvm;
21
22
JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {
23
assert(GV.hasName() && "Can't get flags for anonymous symbol");
24
25
JITSymbolFlags Flags = JITSymbolFlags::None;
26
if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())
27
Flags |= JITSymbolFlags::Weak;
28
if (GV.hasCommonLinkage())
29
Flags |= JITSymbolFlags::Common;
30
if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
31
Flags |= JITSymbolFlags::Exported;
32
33
if (isa<Function>(GV))
34
Flags |= JITSymbolFlags::Callable;
35
else if (isa<GlobalAlias>(GV) &&
36
isa<Function>(cast<GlobalAlias>(GV).getAliasee()))
37
Flags |= JITSymbolFlags::Callable;
38
39
// Check for a linker-private-global-prefix on the symbol name, in which
40
// case it must be marked as non-exported.
41
if (auto *M = GV.getParent()) {
42
const auto &DL = M->getDataLayout();
43
StringRef LPGP = DL.getLinkerPrivateGlobalPrefix();
44
if (!LPGP.empty() && GV.getName().front() == '\01' &&
45
GV.getName().substr(1).starts_with(LPGP))
46
Flags &= ~JITSymbolFlags::Exported;
47
}
48
49
return Flags;
50
}
51
52
JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) {
53
JITSymbolFlags Flags = JITSymbolFlags::None;
54
auto L = S->linkage();
55
if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L))
56
Flags |= JITSymbolFlags::Weak;
57
if (GlobalValue::isCommonLinkage(L))
58
Flags |= JITSymbolFlags::Common;
59
if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L))
60
Flags |= JITSymbolFlags::Exported;
61
62
if (isa<FunctionSummary>(S))
63
Flags |= JITSymbolFlags::Callable;
64
65
return Flags;
66
}
67
68
Expected<JITSymbolFlags>
69
llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
70
Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();
71
if (!SymbolFlagsOrErr)
72
// TODO: Test this error.
73
return SymbolFlagsOrErr.takeError();
74
75
JITSymbolFlags Flags = JITSymbolFlags::None;
76
if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Weak)
77
Flags |= JITSymbolFlags::Weak;
78
if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Common)
79
Flags |= JITSymbolFlags::Common;
80
if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Exported)
81
Flags |= JITSymbolFlags::Exported;
82
83
auto SymbolType = Symbol.getType();
84
if (!SymbolType)
85
return SymbolType.takeError();
86
87
if (*SymbolType == object::SymbolRef::ST_Function)
88
Flags |= JITSymbolFlags::Callable;
89
90
return Flags;
91
}
92
93
ARMJITSymbolFlags
94
llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
95
Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();
96
if (!SymbolFlagsOrErr)
97
// TODO: Actually report errors helpfully.
98
report_fatal_error(SymbolFlagsOrErr.takeError());
99
ARMJITSymbolFlags Flags;
100
if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Thumb)
101
Flags |= ARMJITSymbolFlags::Thumb;
102
return Flags;
103
}
104
105
/// Performs lookup by, for each symbol, first calling
106
/// findSymbolInLogicalDylib and if that fails calling
107
/// findSymbol.
108
void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,
109
OnResolvedFunction OnResolved) {
110
JITSymbolResolver::LookupResult Result;
111
for (auto &Symbol : Symbols) {
112
std::string SymName = Symbol.str();
113
if (auto Sym = findSymbolInLogicalDylib(SymName)) {
114
if (auto AddrOrErr = Sym.getAddress())
115
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
116
else {
117
OnResolved(AddrOrErr.takeError());
118
return;
119
}
120
} else if (auto Err = Sym.takeError()) {
121
OnResolved(std::move(Err));
122
return;
123
} else {
124
// findSymbolInLogicalDylib failed. Lets try findSymbol.
125
if (auto Sym = findSymbol(SymName)) {
126
if (auto AddrOrErr = Sym.getAddress())
127
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
128
else {
129
OnResolved(AddrOrErr.takeError());
130
return;
131
}
132
} else if (auto Err = Sym.takeError()) {
133
OnResolved(std::move(Err));
134
return;
135
} else {
136
OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
137
inconvertibleErrorCode()));
138
return;
139
}
140
}
141
}
142
143
OnResolved(std::move(Result));
144
}
145
146
/// Performs flags lookup by calling findSymbolInLogicalDylib and
147
/// returning the flags value for that symbol.
148
Expected<JITSymbolResolver::LookupSet>
149
LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {
150
JITSymbolResolver::LookupSet Result;
151
152
for (auto &Symbol : Symbols) {
153
std::string SymName = Symbol.str();
154
if (auto Sym = findSymbolInLogicalDylib(SymName)) {
155
// If there's an existing def but it is not strong, then the caller is
156
// responsible for it.
157
if (!Sym.getFlags().isStrong())
158
Result.insert(Symbol);
159
} else if (auto Err = Sym.takeError())
160
return std::move(Err);
161
else {
162
// If there is no existing definition then the caller is responsible for
163
// it.
164
Result.insert(Symbol);
165
}
166
}
167
168
return std::move(Result);
169
}
170
171