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/GlobalValue.h"
17 #include "llvm/Object/ObjectFile.h"
18 
19 using namespace llvm;
20 
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;
29   if (isa<Function>(GV))
30     Flags |= JITSymbolFlags::Callable;
31   return Flags;
32 }
33 
34 Expected<JITSymbolFlags>
35 llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
36   JITSymbolFlags Flags = JITSymbolFlags::None;
37   if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak)
38     Flags |= JITSymbolFlags::Weak;
39   if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common)
40     Flags |= JITSymbolFlags::Common;
41   if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported)
42     Flags |= JITSymbolFlags::Exported;
43 
44   auto SymbolType = Symbol.getType();
45   if (!SymbolType)
46     return SymbolType.takeError();
47 
48   if (*SymbolType & object::SymbolRef::ST_Function)
49     Flags |= JITSymbolFlags::Callable;
50 
51   return Flags;
52 }
53 
54 ARMJITSymbolFlags
55 llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
56   ARMJITSymbolFlags Flags;
57   if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb)
58     Flags |= ARMJITSymbolFlags::Thumb;
59   return Flags;
60 }
61 
62 /// Performs lookup by, for each symbol, first calling
63 ///        findSymbolInLogicalDylib and if that fails calling
64 ///        findSymbol.
65 Expected<JITSymbolResolver::LookupResult>
66 LegacyJITSymbolResolver::lookup(const LookupSet &Symbols) {
67   JITSymbolResolver::LookupResult Result;
68   for (auto &Symbol : Symbols) {
69     std::string SymName = Symbol.str();
70     if (auto Sym = findSymbolInLogicalDylib(SymName)) {
71       if (auto AddrOrErr = Sym.getAddress())
72         Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
73       else
74         return AddrOrErr.takeError();
75     } else if (auto Err = Sym.takeError())
76       return std::move(Err);
77     else {
78       // findSymbolInLogicalDylib failed. Lets try findSymbol.
79       if (auto Sym = findSymbol(SymName)) {
80         if (auto AddrOrErr = Sym.getAddress())
81           Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
82         else
83           return AddrOrErr.takeError();
84       } else if (auto Err = Sym.takeError())
85         return std::move(Err);
86       else
87         return make_error<StringError>("Symbol not found: " + Symbol,
88                                        inconvertibleErrorCode());
89     }
90   }
91 
92   return std::move(Result);
93 }
94 
95 /// Performs flags lookup by calling findSymbolInLogicalDylib and
96 ///        returning the flags value for that symbol.
97 Expected<JITSymbolResolver::LookupFlagsResult>
98 LegacyJITSymbolResolver::lookupFlags(const LookupSet &Symbols) {
99   JITSymbolResolver::LookupFlagsResult Result;
100 
101   for (auto &Symbol : Symbols) {
102     std::string SymName = Symbol.str();
103     if (auto Sym = findSymbolInLogicalDylib(SymName))
104       Result[Symbol] = Sym.getFlags();
105     else if (auto Err = Sym.takeError())
106       return std::move(Err);
107   }
108 
109   return std::move(Result);
110 }
111