10b57cec5SDimitry Andric //===----------- JITSymbol.cpp - JITSymbol class implementation -----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // JITSymbol class implementation plus helper functions. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h" 140b57cec5SDimitry Andric #include "llvm/IR/Function.h" 150b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 160b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 17*5ffd83dbSDimitry Andric #include "llvm/IR/ModuleSummaryIndex.h" 180b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric using namespace llvm; 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) { 23*5ffd83dbSDimitry Andric assert(GV.hasName() && "Can't get flags for anonymous symbol"); 24*5ffd83dbSDimitry Andric 250b57cec5SDimitry Andric JITSymbolFlags Flags = JITSymbolFlags::None; 260b57cec5SDimitry Andric if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage()) 270b57cec5SDimitry Andric Flags |= JITSymbolFlags::Weak; 280b57cec5SDimitry Andric if (GV.hasCommonLinkage()) 290b57cec5SDimitry Andric Flags |= JITSymbolFlags::Common; 300b57cec5SDimitry Andric if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) 310b57cec5SDimitry Andric Flags |= JITSymbolFlags::Exported; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric if (isa<Function>(GV)) 340b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 350b57cec5SDimitry Andric else if (isa<GlobalAlias>(GV) && 360b57cec5SDimitry Andric isa<Function>(cast<GlobalAlias>(GV).getAliasee())) 370b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 380b57cec5SDimitry Andric 39*5ffd83dbSDimitry Andric // Check for a linker-private-global-prefix on the symbol name, in which 40*5ffd83dbSDimitry Andric // case it must be marked as non-exported. 41*5ffd83dbSDimitry Andric if (auto *M = GV.getParent()) { 42*5ffd83dbSDimitry Andric const auto &DL = M->getDataLayout(); 43*5ffd83dbSDimitry Andric StringRef LPGP = DL.getLinkerPrivateGlobalPrefix(); 44*5ffd83dbSDimitry Andric if (!LPGP.empty() && GV.getName().front() == '\01' && 45*5ffd83dbSDimitry Andric GV.getName().substr(1).startswith(LPGP)) 46*5ffd83dbSDimitry Andric Flags &= ~JITSymbolFlags::Exported; 47*5ffd83dbSDimitry Andric } 48*5ffd83dbSDimitry Andric 49*5ffd83dbSDimitry Andric return Flags; 50*5ffd83dbSDimitry Andric } 51*5ffd83dbSDimitry Andric 52*5ffd83dbSDimitry Andric JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) { 53*5ffd83dbSDimitry Andric JITSymbolFlags Flags = JITSymbolFlags::None; 54*5ffd83dbSDimitry Andric auto L = S->linkage(); 55*5ffd83dbSDimitry Andric if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L)) 56*5ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Weak; 57*5ffd83dbSDimitry Andric if (GlobalValue::isCommonLinkage(L)) 58*5ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Common; 59*5ffd83dbSDimitry Andric if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L)) 60*5ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Exported; 61*5ffd83dbSDimitry Andric 62*5ffd83dbSDimitry Andric if (isa<FunctionSummary>(S)) 63*5ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Callable; 64*5ffd83dbSDimitry Andric 650b57cec5SDimitry Andric return Flags; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric Expected<JITSymbolFlags> 690b57cec5SDimitry Andric llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 70*5ffd83dbSDimitry Andric Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags(); 71*5ffd83dbSDimitry Andric if (!SymbolFlagsOrErr) 72*5ffd83dbSDimitry Andric // TODO: Test this error. 73*5ffd83dbSDimitry Andric return SymbolFlagsOrErr.takeError(); 74*5ffd83dbSDimitry Andric 750b57cec5SDimitry Andric JITSymbolFlags Flags = JITSymbolFlags::None; 76*5ffd83dbSDimitry Andric if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Weak) 770b57cec5SDimitry Andric Flags |= JITSymbolFlags::Weak; 78*5ffd83dbSDimitry Andric if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Common) 790b57cec5SDimitry Andric Flags |= JITSymbolFlags::Common; 80*5ffd83dbSDimitry Andric if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Exported) 810b57cec5SDimitry Andric Flags |= JITSymbolFlags::Exported; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric auto SymbolType = Symbol.getType(); 840b57cec5SDimitry Andric if (!SymbolType) 850b57cec5SDimitry Andric return SymbolType.takeError(); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric if (*SymbolType & object::SymbolRef::ST_Function) 880b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric return Flags; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric ARMJITSymbolFlags 940b57cec5SDimitry Andric llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 95*5ffd83dbSDimitry Andric Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags(); 96*5ffd83dbSDimitry Andric if (!SymbolFlagsOrErr) 97*5ffd83dbSDimitry Andric // TODO: Actually report errors helpfully. 98*5ffd83dbSDimitry Andric report_fatal_error(SymbolFlagsOrErr.takeError()); 990b57cec5SDimitry Andric ARMJITSymbolFlags Flags; 100*5ffd83dbSDimitry Andric if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Thumb) 1010b57cec5SDimitry Andric Flags |= ARMJITSymbolFlags::Thumb; 1020b57cec5SDimitry Andric return Flags; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric /// Performs lookup by, for each symbol, first calling 1060b57cec5SDimitry Andric /// findSymbolInLogicalDylib and if that fails calling 1070b57cec5SDimitry Andric /// findSymbol. 1080b57cec5SDimitry Andric void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols, 1090b57cec5SDimitry Andric OnResolvedFunction OnResolved) { 1100b57cec5SDimitry Andric JITSymbolResolver::LookupResult Result; 1110b57cec5SDimitry Andric for (auto &Symbol : Symbols) { 1120b57cec5SDimitry Andric std::string SymName = Symbol.str(); 1130b57cec5SDimitry Andric if (auto Sym = findSymbolInLogicalDylib(SymName)) { 1140b57cec5SDimitry Andric if (auto AddrOrErr = Sym.getAddress()) 1150b57cec5SDimitry Andric Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 1160b57cec5SDimitry Andric else { 1170b57cec5SDimitry Andric OnResolved(AddrOrErr.takeError()); 1180b57cec5SDimitry Andric return; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric } else if (auto Err = Sym.takeError()) { 1210b57cec5SDimitry Andric OnResolved(std::move(Err)); 1220b57cec5SDimitry Andric return; 1230b57cec5SDimitry Andric } else { 1240b57cec5SDimitry Andric // findSymbolInLogicalDylib failed. Lets try findSymbol. 1250b57cec5SDimitry Andric if (auto Sym = findSymbol(SymName)) { 1260b57cec5SDimitry Andric if (auto AddrOrErr = Sym.getAddress()) 1270b57cec5SDimitry Andric Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 1280b57cec5SDimitry Andric else { 1290b57cec5SDimitry Andric OnResolved(AddrOrErr.takeError()); 1300b57cec5SDimitry Andric return; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric } else if (auto Err = Sym.takeError()) { 1330b57cec5SDimitry Andric OnResolved(std::move(Err)); 1340b57cec5SDimitry Andric return; 1350b57cec5SDimitry Andric } else { 1360b57cec5SDimitry Andric OnResolved(make_error<StringError>("Symbol not found: " + Symbol, 1370b57cec5SDimitry Andric inconvertibleErrorCode())); 1380b57cec5SDimitry Andric return; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric OnResolved(std::move(Result)); 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric /// Performs flags lookup by calling findSymbolInLogicalDylib and 1470b57cec5SDimitry Andric /// returning the flags value for that symbol. 1480b57cec5SDimitry Andric Expected<JITSymbolResolver::LookupSet> 1490b57cec5SDimitry Andric LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) { 1500b57cec5SDimitry Andric JITSymbolResolver::LookupSet Result; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric for (auto &Symbol : Symbols) { 1530b57cec5SDimitry Andric std::string SymName = Symbol.str(); 1540b57cec5SDimitry Andric if (auto Sym = findSymbolInLogicalDylib(SymName)) { 1550b57cec5SDimitry Andric // If there's an existing def but it is not strong, then the caller is 1560b57cec5SDimitry Andric // responsible for it. 1570b57cec5SDimitry Andric if (!Sym.getFlags().isStrong()) 1580b57cec5SDimitry Andric Result.insert(Symbol); 1590b57cec5SDimitry Andric } else if (auto Err = Sym.takeError()) 1600b57cec5SDimitry Andric return std::move(Err); 1610b57cec5SDimitry Andric else { 1620b57cec5SDimitry Andric // If there is no existing definition then the caller is responsible for 1630b57cec5SDimitry Andric // it. 1640b57cec5SDimitry Andric Result.insert(Symbol); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric return std::move(Result); 1690b57cec5SDimitry Andric } 170