blob: b6ef8ad9675a196a7259c79b6dd43ad81e04a5de [file] [log] [blame]
Lang Hamesaac59a22016-08-04 20:32:37 +00001//===----------- 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"
Lang Hamesbfea8cd2018-08-01 22:42:23 +000015#include "llvm/IR/Function.h"
Lang Hamesaac59a22016-08-04 20:32:37 +000016#include "llvm/IR/GlobalValue.h"
Lang Hamesbfea8cd2018-08-01 22:42:23 +000017#include "llvm/Object/ObjectFile.h"
Lang Hamesaac59a22016-08-04 20:32:37 +000018
19using namespace llvm;
20
21JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {
22 JITSymbolFlags Flags = JITSymbolFlags::None;
Lang Hames73976f62016-08-06 22:36:26 +000023 if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())
Lang Hamesaac59a22016-08-04 20:32:37 +000024 Flags |= JITSymbolFlags::Weak;
25 if (GV.hasCommonLinkage())
26 Flags |= JITSymbolFlags::Common;
27 if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
28 Flags |= JITSymbolFlags::Exported;
Lang Hamesbfea8cd2018-08-01 22:42:23 +000029 if (isa<Function>(GV))
30 Flags |= JITSymbolFlags::Callable;
Lang Hamesaac59a22016-08-04 20:32:37 +000031 return Flags;
32}
33
Lang Hamesbfea8cd2018-08-01 22:42:23 +000034Expected<JITSymbolFlags>
35llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
Lang Hamesaac59a22016-08-04 20:32:37 +000036 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;
Lang Hamesbfea8cd2018-08-01 22:42:23 +000043
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
Lang Hamesaac59a22016-08-04 20:32:37 +000051 return Flags;
52}
Lang Hames14a22a42017-08-09 20:19:27 +000053
Lang Hamesbfea8cd2018-08-01 22:42:23 +000054ARMJITSymbolFlags
55llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
Lang Hames14a22a42017-08-09 20:19:27 +000056 ARMJITSymbolFlags Flags;
57 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb)
58 Flags |= ARMJITSymbolFlags::Thumb;
59 return Flags;
60}
Lang Hamesb72f4842018-01-19 22:24:13 +000061
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +000062/// Performs lookup by, for each symbol, first calling
Lang Hamesb72f4842018-01-19 22:24:13 +000063/// findSymbolInLogicalDylib and if that fails calling
64/// findSymbol.
Lang Hamesadde5ba2018-09-25 19:48:46 +000065void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,
66 OnResolvedFunction OnResolved) {
Lang Hamesb72f4842018-01-19 22:24:13 +000067 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());
Lang Hamesadde5ba2018-09-25 19:48:46 +000073 else {
74 OnResolved(AddrOrErr.takeError());
75 return;
76 }
77 } else if (auto Err = Sym.takeError()) {
78 OnResolved(std::move(Err));
79 return;
80 } else {
Lang Hamesb72f4842018-01-19 22:24:13 +000081 // findSymbolInLogicalDylib failed. Lets try findSymbol.
82 if (auto Sym = findSymbol(SymName)) {
83 if (auto AddrOrErr = Sym.getAddress())
84 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
Lang Hamesadde5ba2018-09-25 19:48:46 +000085 else {
86 OnResolved(AddrOrErr.takeError());
87 return;
88 }
89 } else if (auto Err = Sym.takeError()) {
90 OnResolved(std::move(Err));
91 return;
92 } else {
93 OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
94 inconvertibleErrorCode()));
95 return;
96 }
Lang Hamesb72f4842018-01-19 22:24:13 +000097 }
98 }
99
Lang Hamesadde5ba2018-09-25 19:48:46 +0000100 OnResolved(std::move(Result));
Lang Hamesb72f4842018-01-19 22:24:13 +0000101}
102
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +0000103/// Performs flags lookup by calling findSymbolInLogicalDylib and
Lang Hamesb72f4842018-01-19 22:24:13 +0000104/// returning the flags value for that symbol.
Lang Hames6cadc7c2018-08-28 21:18:05 +0000105Expected<JITSymbolResolver::LookupSet>
106LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {
107 JITSymbolResolver::LookupSet Result;
Lang Hamesb72f4842018-01-19 22:24:13 +0000108
109 for (auto &Symbol : Symbols) {
110 std::string SymName = Symbol.str();
Lang Hames6cadc7c2018-08-28 21:18:05 +0000111 if (auto Sym = findSymbolInLogicalDylib(SymName)) {
112 // If there's an existing def but it is not strong, then the caller is
113 // responsible for it.
114 if (!Sym.getFlags().isStrong())
115 Result.insert(Symbol);
116 } else if (auto Err = Sym.takeError())
Lang Hamesb72f4842018-01-19 22:24:13 +0000117 return std::move(Err);
Lang Hames6cadc7c2018-08-28 21:18:05 +0000118 else {
119 // If there is no existing definition then the caller is responsible for
120 // it.
121 Result.insert(Symbol);
122 }
Lang Hamesb72f4842018-01-19 22:24:13 +0000123 }
124
125 return std::move(Result);
126}