1 //===----------- JITSymbol.cpp - JITSymbol class implementation -----------===//
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
7 //===----------------------------------------------------------------------===//
9 // JITSymbol class implementation plus helper functions.
11 //===----------------------------------------------------------------------===//
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/Object/ObjectFile.h"
21 JITSymbolFlags
llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue
&GV
) {
22 JITSymbolFlags Flags
= JITSymbolFlags::None
;
23 if (GV
.hasWeakLinkage() || GV
.hasLinkOnceLinkage())
24 Flags
|= JITSymbolFlags::Weak
;
25 if (GV
.hasCommonLinkage())
26 Flags
|= JITSymbolFlags::Common
;
27 if (!GV
.hasLocalLinkage() && !GV
.hasHiddenVisibility())
28 Flags
|= JITSymbolFlags::Exported
;
30 if (isa
<Function
>(GV
))
31 Flags
|= JITSymbolFlags::Callable
;
32 else if (isa
<GlobalAlias
>(GV
) &&
33 isa
<Function
>(cast
<GlobalAlias
>(GV
).getAliasee()))
34 Flags
|= JITSymbolFlags::Callable
;
39 Expected
<JITSymbolFlags
>
40 llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef
&Symbol
) {
41 JITSymbolFlags Flags
= JITSymbolFlags::None
;
42 if (Symbol
.getFlags() & object::BasicSymbolRef::SF_Weak
)
43 Flags
|= JITSymbolFlags::Weak
;
44 if (Symbol
.getFlags() & object::BasicSymbolRef::SF_Common
)
45 Flags
|= JITSymbolFlags::Common
;
46 if (Symbol
.getFlags() & object::BasicSymbolRef::SF_Exported
)
47 Flags
|= JITSymbolFlags::Exported
;
49 auto SymbolType
= Symbol
.getType();
51 return SymbolType
.takeError();
53 if (*SymbolType
& object::SymbolRef::ST_Function
)
54 Flags
|= JITSymbolFlags::Callable
;
60 llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef
&Symbol
) {
61 ARMJITSymbolFlags Flags
;
62 if (Symbol
.getFlags() & object::BasicSymbolRef::SF_Thumb
)
63 Flags
|= ARMJITSymbolFlags::Thumb
;
67 /// Performs lookup by, for each symbol, first calling
68 /// findSymbolInLogicalDylib and if that fails calling
70 void LegacyJITSymbolResolver::lookup(const LookupSet
&Symbols
,
71 OnResolvedFunction OnResolved
) {
72 JITSymbolResolver::LookupResult Result
;
73 for (auto &Symbol
: Symbols
) {
74 std::string SymName
= Symbol
.str();
75 if (auto Sym
= findSymbolInLogicalDylib(SymName
)) {
76 if (auto AddrOrErr
= Sym
.getAddress())
77 Result
[Symbol
] = JITEvaluatedSymbol(*AddrOrErr
, Sym
.getFlags());
79 OnResolved(AddrOrErr
.takeError());
82 } else if (auto Err
= Sym
.takeError()) {
83 OnResolved(std::move(Err
));
86 // findSymbolInLogicalDylib failed. Lets try findSymbol.
87 if (auto Sym
= findSymbol(SymName
)) {
88 if (auto AddrOrErr
= Sym
.getAddress())
89 Result
[Symbol
] = JITEvaluatedSymbol(*AddrOrErr
, Sym
.getFlags());
91 OnResolved(AddrOrErr
.takeError());
94 } else if (auto Err
= Sym
.takeError()) {
95 OnResolved(std::move(Err
));
98 OnResolved(make_error
<StringError
>("Symbol not found: " + Symbol
,
99 inconvertibleErrorCode()));
105 OnResolved(std::move(Result
));
108 /// Performs flags lookup by calling findSymbolInLogicalDylib and
109 /// returning the flags value for that symbol.
110 Expected
<JITSymbolResolver::LookupSet
>
111 LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet
&Symbols
) {
112 JITSymbolResolver::LookupSet Result
;
114 for (auto &Symbol
: Symbols
) {
115 std::string SymName
= Symbol
.str();
116 if (auto Sym
= findSymbolInLogicalDylib(SymName
)) {
117 // If there's an existing def but it is not strong, then the caller is
118 // responsible for it.
119 if (!Sym
.getFlags().isStrong())
120 Result
.insert(Symbol
);
121 } else if (auto Err
= Sym
.takeError())
122 return std::move(Err
);
124 // If there is no existing definition then the caller is responsible for
126 Result
.insert(Symbol
);
130 return std::move(Result
);