Line data Source code
1 : //===----------- JITSymbol.cpp - JITSymbol class implementation -----------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // JITSymbol class implementation plus helper functions.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "llvm/ExecutionEngine/JITSymbol.h"
15 : #include "llvm/IR/Function.h"
16 : #include "llvm/IR/GlobalAlias.h"
17 : #include "llvm/IR/GlobalValue.h"
18 : #include "llvm/Object/ObjectFile.h"
19 :
20 : using namespace llvm;
21 :
22 207 : JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {
23 : JITSymbolFlags Flags = JITSymbolFlags::None;
24 206 : if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())
25 : Flags |= JITSymbolFlags::Weak;
26 207 : if (GV.hasCommonLinkage())
27 : Flags |= JITSymbolFlags::Common;
28 207 : if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
29 : Flags |= JITSymbolFlags::Exported;
30 :
31 207 : if (isa<Function>(GV))
32 : Flags |= JITSymbolFlags::Callable;
33 40 : else if (isa<GlobalAlias>(GV) &&
34 : isa<Function>(cast<GlobalAlias>(GV).getAliasee()))
35 : Flags |= JITSymbolFlags::Callable;
36 :
37 207 : return Flags;
38 : }
39 :
40 : Expected<JITSymbolFlags>
41 2141 : llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
42 : JITSymbolFlags Flags = JITSymbolFlags::None;
43 2141 : if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak)
44 : Flags |= JITSymbolFlags::Weak;
45 2141 : if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common)
46 : Flags |= JITSymbolFlags::Common;
47 2141 : if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported)
48 : Flags |= JITSymbolFlags::Exported;
49 :
50 : auto SymbolType = Symbol.getType();
51 2141 : if (!SymbolType)
52 : return SymbolType.takeError();
53 :
54 2141 : if (*SymbolType & object::SymbolRef::ST_Function)
55 : Flags |= JITSymbolFlags::Callable;
56 :
57 : return Flags;
58 : }
59 :
60 : ARMJITSymbolFlags
61 19 : llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
62 : ARMJITSymbolFlags Flags;
63 19 : if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb)
64 : Flags |= ARMJITSymbolFlags::Thumb;
65 19 : return Flags;
66 : }
67 :
68 : /// Performs lookup by, for each symbol, first calling
69 : /// findSymbolInLogicalDylib and if that fails calling
70 : /// findSymbol.
71 59 : void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,
72 : OnResolvedFunction OnResolved) {
73 : JITSymbolResolver::LookupResult Result;
74 157 : for (auto &Symbol : Symbols) {
75 98 : std::string SymName = Symbol.str();
76 196 : if (auto Sym = findSymbolInLogicalDylib(SymName)) {
77 0 : if (auto AddrOrErr = Sym.getAddress())
78 0 : Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
79 : else {
80 0 : OnResolved(AddrOrErr.takeError());
81 : return;
82 : }
83 98 : } else if (auto Err = Sym.takeError()) {
84 0 : OnResolved(std::move(Err));
85 0 : return;
86 : } else {
87 : // findSymbolInLogicalDylib failed. Lets try findSymbol.
88 196 : if (auto Sym = findSymbol(SymName)) {
89 98 : if (auto AddrOrErr = Sym.getAddress())
90 98 : Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
91 : else {
92 0 : OnResolved(AddrOrErr.takeError());
93 : return;
94 : }
95 0 : } else if (auto Err = Sym.takeError()) {
96 0 : OnResolved(std::move(Err));
97 0 : return;
98 : } else {
99 0 : OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
100 0 : inconvertibleErrorCode()));
101 0 : return;
102 : }
103 : }
104 : }
105 :
106 59 : OnResolved(std::move(Result));
107 : }
108 :
109 : /// Performs flags lookup by calling findSymbolInLogicalDylib and
110 : /// returning the flags value for that symbol.
111 : Expected<JITSymbolResolver::LookupSet>
112 217 : LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {
113 : JITSymbolResolver::LookupSet Result;
114 :
115 292 : for (auto &Symbol : Symbols) {
116 75 : std::string SymName = Symbol.str();
117 150 : if (auto Sym = findSymbolInLogicalDylib(SymName)) {
118 : // If there's an existing def but it is not strong, then the caller is
119 : // responsible for it.
120 : if (!Sym.getFlags().isStrong())
121 : Result.insert(Symbol);
122 75 : } else if (auto Err = Sym.takeError())
123 : return std::move(Err);
124 : else {
125 : // If there is no existing definition then the caller is responsible for
126 : // it.
127 : Result.insert(Symbol);
128 : }
129 : }
130 :
131 : return std::move(Result);
132 : }
|