1 //===----------- JITSymbol.cpp - JITSymbol class implementation -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // JITSymbol class implementation plus helper functions.
12 //===----------------------------------------------------------------------===//
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"
22 JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {
23 JITSymbolFlags Flags = JITSymbolFlags::None;
24 if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())
25 Flags |= JITSymbolFlags::Weak;
26 if (GV.hasCommonLinkage())
27 Flags |= JITSymbolFlags::Common;
28 if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
29 Flags |= JITSymbolFlags::Exported;
31 if (isa<Function>(GV))
32 Flags |= JITSymbolFlags::Callable;
33 else if (isa<GlobalAlias>(GV) &&
34 isa<Function>(cast<GlobalAlias>(GV).getAliasee()))
35 Flags |= JITSymbolFlags::Callable;
40 Expected<JITSymbolFlags>
41 llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
42 JITSymbolFlags Flags = JITSymbolFlags::None;
43 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak)
44 Flags |= JITSymbolFlags::Weak;
45 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common)
46 Flags |= JITSymbolFlags::Common;
47 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported)
48 Flags |= JITSymbolFlags::Exported;
50 auto SymbolType = Symbol.getType();
52 return SymbolType.takeError();
54 if (*SymbolType & object::SymbolRef::ST_Function)
55 Flags |= JITSymbolFlags::Callable;
61 llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
62 ARMJITSymbolFlags Flags;
63 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb)
64 Flags |= ARMJITSymbolFlags::Thumb;
68 /// Performs lookup by, for each symbol, first calling
69 /// findSymbolInLogicalDylib and if that fails calling
71 void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,
72 OnResolvedFunction OnResolved) {
73 JITSymbolResolver::LookupResult Result;
74 for (auto &Symbol : Symbols) {
75 std::string SymName = Symbol.str();
76 if (auto Sym = findSymbolInLogicalDylib(SymName)) {
77 if (auto AddrOrErr = Sym.getAddress())
78 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
80 OnResolved(AddrOrErr.takeError());
83 } else if (auto Err = Sym.takeError()) {
84 OnResolved(std::move(Err));
87 // findSymbolInLogicalDylib failed. Lets try findSymbol.
88 if (auto Sym = findSymbol(SymName)) {
89 if (auto AddrOrErr = Sym.getAddress())
90 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
92 OnResolved(AddrOrErr.takeError());
95 } else if (auto Err = Sym.takeError()) {
96 OnResolved(std::move(Err));
99 OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
100 inconvertibleErrorCode()));
106 OnResolved(std::move(Result));
109 /// Performs flags lookup by calling findSymbolInLogicalDylib and
110 /// returning the flags value for that symbol.
111 Expected<JITSymbolResolver::LookupSet>
112 LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {
113 JITSymbolResolver::LookupSet Result;
115 for (auto &Symbol : Symbols) {
116 std::string SymName = Symbol.str();
117 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 } else if (auto Err = Sym.takeError())
123 return std::move(Err);
125 // If there is no existing definition then the caller is responsible for
127 Result.insert(Symbol);
131 return std::move(Result);