]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / ExecutionEngine / RuntimeDyld / JITSymbol.cpp
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 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;
30
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;
36
37   return Flags;
38 }
39
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;
49
50   auto SymbolType = Symbol.getType();
51   if (!SymbolType)
52     return SymbolType.takeError();
53
54   if (*SymbolType & object::SymbolRef::ST_Function)
55     Flags |= JITSymbolFlags::Callable;
56
57   return Flags;
58 }
59
60 ARMJITSymbolFlags
61 llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
62   ARMJITSymbolFlags Flags;
63   if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb)
64     Flags |= ARMJITSymbolFlags::Thumb;
65   return Flags;
66 }
67
68 /// Performs lookup by, for each symbol, first calling
69 ///        findSymbolInLogicalDylib and if that fails calling
70 ///        findSymbol.
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());
79       else {
80         OnResolved(AddrOrErr.takeError());
81         return;
82       }
83     } else if (auto Err = Sym.takeError()) {
84       OnResolved(std::move(Err));
85       return;
86     } else {
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());
91         else {
92           OnResolved(AddrOrErr.takeError());
93           return;
94         }
95       } else if (auto Err = Sym.takeError()) {
96         OnResolved(std::move(Err));
97         return;
98       } else {
99         OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
100                                            inconvertibleErrorCode()));
101         return;
102       }
103     }
104   }
105
106   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 LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {
113   JITSymbolResolver::LookupSet Result;
114
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);
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 }