Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
35269 views
//===----------- JITSymbol.cpp - JITSymbol class implementation -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// JITSymbol class implementation plus helper functions.9//10//===----------------------------------------------------------------------===//1112#include "llvm/ExecutionEngine/JITSymbol.h"13#include "llvm/IR/Function.h"14#include "llvm/IR/GlobalAlias.h"15#include "llvm/IR/GlobalValue.h"16#include "llvm/IR/ModuleSummaryIndex.h"17#include "llvm/Object/ObjectFile.h"1819using namespace llvm;2021JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {22assert(GV.hasName() && "Can't get flags for anonymous symbol");2324JITSymbolFlags Flags = JITSymbolFlags::None;25if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())26Flags |= JITSymbolFlags::Weak;27if (GV.hasCommonLinkage())28Flags |= JITSymbolFlags::Common;29if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())30Flags |= JITSymbolFlags::Exported;3132if (isa<Function>(GV))33Flags |= JITSymbolFlags::Callable;34else if (isa<GlobalAlias>(GV) &&35isa<Function>(cast<GlobalAlias>(GV).getAliasee()))36Flags |= JITSymbolFlags::Callable;3738// Check for a linker-private-global-prefix on the symbol name, in which39// case it must be marked as non-exported.40if (auto *M = GV.getParent()) {41const auto &DL = M->getDataLayout();42StringRef LPGP = DL.getLinkerPrivateGlobalPrefix();43if (!LPGP.empty() && GV.getName().front() == '\01' &&44GV.getName().substr(1).starts_with(LPGP))45Flags &= ~JITSymbolFlags::Exported;46}4748return Flags;49}5051JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) {52JITSymbolFlags Flags = JITSymbolFlags::None;53auto L = S->linkage();54if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L))55Flags |= JITSymbolFlags::Weak;56if (GlobalValue::isCommonLinkage(L))57Flags |= JITSymbolFlags::Common;58if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L))59Flags |= JITSymbolFlags::Exported;6061if (isa<FunctionSummary>(S))62Flags |= JITSymbolFlags::Callable;6364return Flags;65}6667Expected<JITSymbolFlags>68llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {69Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();70if (!SymbolFlagsOrErr)71// TODO: Test this error.72return SymbolFlagsOrErr.takeError();7374JITSymbolFlags Flags = JITSymbolFlags::None;75if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Weak)76Flags |= JITSymbolFlags::Weak;77if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Common)78Flags |= JITSymbolFlags::Common;79if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Exported)80Flags |= JITSymbolFlags::Exported;8182auto SymbolType = Symbol.getType();83if (!SymbolType)84return SymbolType.takeError();8586if (*SymbolType == object::SymbolRef::ST_Function)87Flags |= JITSymbolFlags::Callable;8889return Flags;90}9192ARMJITSymbolFlags93llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {94Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();95if (!SymbolFlagsOrErr)96// TODO: Actually report errors helpfully.97report_fatal_error(SymbolFlagsOrErr.takeError());98ARMJITSymbolFlags Flags;99if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Thumb)100Flags |= ARMJITSymbolFlags::Thumb;101return Flags;102}103104/// Performs lookup by, for each symbol, first calling105/// findSymbolInLogicalDylib and if that fails calling106/// findSymbol.107void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,108OnResolvedFunction OnResolved) {109JITSymbolResolver::LookupResult Result;110for (auto &Symbol : Symbols) {111std::string SymName = Symbol.str();112if (auto Sym = findSymbolInLogicalDylib(SymName)) {113if (auto AddrOrErr = Sym.getAddress())114Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());115else {116OnResolved(AddrOrErr.takeError());117return;118}119} else if (auto Err = Sym.takeError()) {120OnResolved(std::move(Err));121return;122} else {123// findSymbolInLogicalDylib failed. Lets try findSymbol.124if (auto Sym = findSymbol(SymName)) {125if (auto AddrOrErr = Sym.getAddress())126Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());127else {128OnResolved(AddrOrErr.takeError());129return;130}131} else if (auto Err = Sym.takeError()) {132OnResolved(std::move(Err));133return;134} else {135OnResolved(make_error<StringError>("Symbol not found: " + Symbol,136inconvertibleErrorCode()));137return;138}139}140}141142OnResolved(std::move(Result));143}144145/// Performs flags lookup by calling findSymbolInLogicalDylib and146/// returning the flags value for that symbol.147Expected<JITSymbolResolver::LookupSet>148LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {149JITSymbolResolver::LookupSet Result;150151for (auto &Symbol : Symbols) {152std::string SymName = Symbol.str();153if (auto Sym = findSymbolInLogicalDylib(SymName)) {154// If there's an existing def but it is not strong, then the caller is155// responsible for it.156if (!Sym.getFlags().isStrong())157Result.insert(Symbol);158} else if (auto Err = Sym.takeError())159return std::move(Err);160else {161// If there is no existing definition then the caller is responsible for162// it.163Result.insert(Symbol);164}165}166167return std::move(Result);168}169170171