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