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