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" 175ffd83dbSDimitry 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) { 235ffd83dbSDimitry Andric assert(GV.hasName() && "Can't get flags for anonymous symbol"); 245ffd83dbSDimitry 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 395ffd83dbSDimitry Andric // Check for a linker-private-global-prefix on the symbol name, in which 405ffd83dbSDimitry Andric // case it must be marked as non-exported. 415ffd83dbSDimitry Andric if (auto *M = GV.getParent()) { 425ffd83dbSDimitry Andric const auto &DL = M->getDataLayout(); 435ffd83dbSDimitry Andric StringRef LPGP = DL.getLinkerPrivateGlobalPrefix(); 445ffd83dbSDimitry Andric if (!LPGP.empty() && GV.getName().front() == '\01' && 45*5f757f3fSDimitry Andric GV.getName().substr(1).starts_with(LPGP)) 465ffd83dbSDimitry Andric Flags &= ~JITSymbolFlags::Exported; 475ffd83dbSDimitry Andric } 485ffd83dbSDimitry Andric 495ffd83dbSDimitry Andric return Flags; 505ffd83dbSDimitry Andric } 515ffd83dbSDimitry Andric 525ffd83dbSDimitry Andric JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) { 535ffd83dbSDimitry Andric JITSymbolFlags Flags = JITSymbolFlags::None; 545ffd83dbSDimitry Andric auto L = S->linkage(); 555ffd83dbSDimitry Andric if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L)) 565ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Weak; 575ffd83dbSDimitry Andric if (GlobalValue::isCommonLinkage(L)) 585ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Common; 595ffd83dbSDimitry Andric if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L)) 605ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Exported; 615ffd83dbSDimitry Andric 625ffd83dbSDimitry Andric if (isa<FunctionSummary>(S)) 635ffd83dbSDimitry Andric Flags |= JITSymbolFlags::Callable; 645ffd83dbSDimitry Andric 650b57cec5SDimitry Andric return Flags; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric Expected<JITSymbolFlags> 690b57cec5SDimitry Andric llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 705ffd83dbSDimitry Andric Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags(); 715ffd83dbSDimitry Andric if (!SymbolFlagsOrErr) 725ffd83dbSDimitry Andric // TODO: Test this error. 735ffd83dbSDimitry Andric return SymbolFlagsOrErr.takeError(); 745ffd83dbSDimitry Andric 750b57cec5SDimitry Andric JITSymbolFlags Flags = JITSymbolFlags::None; 765ffd83dbSDimitry Andric if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Weak) 770b57cec5SDimitry Andric Flags |= JITSymbolFlags::Weak; 785ffd83dbSDimitry Andric if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Common) 790b57cec5SDimitry Andric Flags |= JITSymbolFlags::Common; 805ffd83dbSDimitry 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 87349cc55cSDimitry 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) { 955ffd83dbSDimitry Andric Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags(); 965ffd83dbSDimitry Andric if (!SymbolFlagsOrErr) 975ffd83dbSDimitry Andric // TODO: Actually report errors helpfully. 985ffd83dbSDimitry Andric report_fatal_error(SymbolFlagsOrErr.takeError()); 990b57cec5SDimitry Andric ARMJITSymbolFlags Flags; 1005ffd83dbSDimitry 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