brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · c153b44 Raw
170 lines · cpp
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-exception6//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/IR/ModuleSummaryIndex.h"18#include "llvm/Object/ObjectFile.h"19 20using namespace llvm;21 22JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {23  assert(GV.hasName() && "Can't get flags for anonymous symbol");24 25  JITSymbolFlags Flags = JITSymbolFlags::None;26  if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())27    Flags |= JITSymbolFlags::Weak;28  if (GV.hasCommonLinkage())29    Flags |= JITSymbolFlags::Common;30  if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())31    Flags |= JITSymbolFlags::Exported;32 33  if (isa<Function>(GV))34    Flags |= JITSymbolFlags::Callable;35  else if (isa<GlobalAlias>(GV) &&36           isa<Function>(cast<GlobalAlias>(GV).getAliasee()))37    Flags |= JITSymbolFlags::Callable;38 39  // Check for a linker-private-global-prefix on the symbol name, in which40  // case it must be marked as non-exported.41  if (auto *M = GV.getParent()) {42    const auto &DL = M->getDataLayout();43    StringRef LPGP = DL.getLinkerPrivateGlobalPrefix();44    if (!LPGP.empty() && GV.getName().front() == '\01' &&45        GV.getName().substr(1).starts_with(LPGP))46      Flags &= ~JITSymbolFlags::Exported;47  }48 49  return Flags;50}51 52JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) {53  JITSymbolFlags Flags = JITSymbolFlags::None;54  auto L = S->linkage();55  if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L))56    Flags |= JITSymbolFlags::Weak;57  if (GlobalValue::isCommonLinkage(L))58    Flags |= JITSymbolFlags::Common;59  if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L))60    Flags |= JITSymbolFlags::Exported;61 62  if (isa<FunctionSummary>(S))63    Flags |= JITSymbolFlags::Callable;64 65  return Flags;66}67 68Expected<JITSymbolFlags>69llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {70  Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();71  if (!SymbolFlagsOrErr)72    // TODO: Test this error.73    return SymbolFlagsOrErr.takeError();74 75  JITSymbolFlags Flags = JITSymbolFlags::None;76  if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Weak)77    Flags |= JITSymbolFlags::Weak;78  if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Common)79    Flags |= JITSymbolFlags::Common;80  if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Exported)81    Flags |= JITSymbolFlags::Exported;82 83  auto SymbolType = Symbol.getType();84  if (!SymbolType)85    return SymbolType.takeError();86 87  if (*SymbolType == object::SymbolRef::ST_Function)88    Flags |= JITSymbolFlags::Callable;89 90  return Flags;91}92 93ARMJITSymbolFlags94llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {95  Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();96  if (!SymbolFlagsOrErr)97    // TODO: Actually report errors helpfully.98    report_fatal_error(SymbolFlagsOrErr.takeError());99  ARMJITSymbolFlags Flags;100  if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Thumb)101    Flags |= ARMJITSymbolFlags::Thumb;102  return Flags;103}104 105/// Performs lookup by, for each symbol, first calling106///        findSymbolInLogicalDylib and if that fails calling107///        findSymbol.108void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,109                                     OnResolvedFunction OnResolved) {110  JITSymbolResolver::LookupResult Result;111  for (auto &Symbol : Symbols) {112    std::string SymName = Symbol.str();113    if (auto Sym = findSymbolInLogicalDylib(SymName)) {114      if (auto AddrOrErr = Sym.getAddress())115        Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());116      else {117        OnResolved(AddrOrErr.takeError());118        return;119      }120    } else if (auto Err = Sym.takeError()) {121      OnResolved(std::move(Err));122      return;123    } else {124      // findSymbolInLogicalDylib failed. Lets try findSymbol.125      if (auto Sym = findSymbol(SymName)) {126        if (auto AddrOrErr = Sym.getAddress())127          Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());128        else {129          OnResolved(AddrOrErr.takeError());130          return;131        }132      } else if (auto Err = Sym.takeError()) {133        OnResolved(std::move(Err));134        return;135      } else {136        OnResolved(make_error<StringError>("Symbol not found: " + Symbol,137                                           inconvertibleErrorCode()));138        return;139      }140    }141  }142 143  OnResolved(std::move(Result));144}145 146/// Performs flags lookup by calling findSymbolInLogicalDylib and147///        returning the flags value for that symbol.148Expected<JITSymbolResolver::LookupSet>149LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {150  JITSymbolResolver::LookupSet Result;151 152  for (auto &Symbol : Symbols) {153    std::string SymName = Symbol.str();154    if (auto Sym = findSymbolInLogicalDylib(SymName)) {155      // If there's an existing def but it is not strong, then the caller is156      // responsible for it.157      if (!Sym.getFlags().isStrong())158        Result.insert(Symbol);159    } else if (auto Err = Sym.takeError())160      return std::move(Err);161    else {162      // If there is no existing definition then the caller is responsible for163      // it.164      Result.insert(Symbol);165    }166  }167 168  return std::move(Result);169}170