LCOV - code coverage report
Current view: top level - lib/Object - ModuleSymbolTable.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 128 135 94.8 %
Date: 2017-09-14 15:23:50 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This class represents a symbol table built from in-memory IR. It provides
      11             : // access to GlobalValues and should only be used if such access is required
      12             : // (e.g. in the LTO implementation).
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "llvm/Object/ModuleSymbolTable.h"
      17             : #include "RecordStreamer.h"
      18             : #include "llvm/ADT/STLExtras.h"
      19             : #include "llvm/ADT/SmallString.h"
      20             : #include "llvm/ADT/StringMap.h"
      21             : #include "llvm/ADT/StringRef.h"
      22             : #include "llvm/ADT/Triple.h"
      23             : #include "llvm/IR/Function.h"
      24             : #include "llvm/IR/GlobalAlias.h"
      25             : #include "llvm/IR/GlobalValue.h"
      26             : #include "llvm/IR/GlobalVariable.h"
      27             : #include "llvm/IR/Mangler.h"
      28             : #include "llvm/IR/Module.h"
      29             : #include "llvm/MC/MCAsmInfo.h"
      30             : #include "llvm/MC/MCContext.h"
      31             : #include "llvm/MC/MCDirectives.h"
      32             : #include "llvm/MC/MCInstrInfo.h"
      33             : #include "llvm/MC/MCObjectFileInfo.h"
      34             : #include "llvm/MC/MCParser/MCAsmParser.h"
      35             : #include "llvm/MC/MCParser/MCTargetAsmParser.h"
      36             : #include "llvm/MC/MCRegisterInfo.h"
      37             : #include "llvm/MC/MCSubtargetInfo.h"
      38             : #include "llvm/MC/MCSymbol.h"
      39             : #include "llvm/MC/MCTargetOptions.h"
      40             : #include "llvm/Object/SymbolicFile.h"
      41             : #include "llvm/Support/Casting.h"
      42             : #include "llvm/Support/CodeGen.h"
      43             : #include "llvm/Support/ErrorHandling.h"
      44             : #include "llvm/Support/MemoryBuffer.h"
      45             : #include "llvm/Support/SMLoc.h"
      46             : #include "llvm/Support/SourceMgr.h"
      47             : #include "llvm/Support/TargetRegistry.h"
      48             : #include "llvm/Support/raw_ostream.h"
      49             : #include <algorithm>
      50             : #include <cassert>
      51             : #include <cstdint>
      52             : #include <memory>
      53             : #include <string>
      54             : 
      55             : using namespace llvm;
      56             : using namespace object;
      57             : 
      58        2128 : void ModuleSymbolTable::addModule(Module *M) {
      59        2128 :   if (FirstMod)
      60             :     assert(FirstMod->getTargetTriple() == M->getTargetTriple());
      61             :   else
      62        2127 :     FirstMod = M;
      63             : 
      64       24550 :   for (GlobalValue &GV : M->global_values())
      65       27249 :     SymTab.push_back(&GV);
      66             : 
      67        4503 :   CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
      68        1235 :     SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
      69         247 :   });
      70        2128 : }
      71             : 
      72             : // Ensure ELF .symver aliases get the same binding as the defined symbol
      73             : // they alias with.
      74          86 : static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
      75         172 :   if (Streamer.symverAliases().empty())
      76          72 :     return;
      77             : 
      78             :   // The name in the assembler will be mangled, but the name in the IR
      79             :   // might not, so we first compute a mapping from mangled name to GV.
      80          28 :   Mangler Mang;
      81          28 :   SmallString<64> MangledName;
      82          28 :   StringMap<const GlobalValue *> MangledNameMap;
      83          35 :   auto GetMangledName = [&](const GlobalValue &GV) {
      84          70 :     if (!GV.hasName())
      85             :       return;
      86             : 
      87         140 :     MangledName.clear();
      88         105 :     MangledName.reserve(GV.getName().size() + 1);
      89          70 :     Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
      90          70 :     MangledNameMap[MangledName] = &GV;
      91          14 :   };
      92          70 :   for (const Function &F : M)
      93          28 :     GetMangledName(F);
      94          21 :   for (const GlobalVariable &GV : M.globals())
      95           7 :     GetMangledName(GV);
      96          14 :   for (const GlobalAlias &GA : M.aliases())
      97           0 :     GetMangledName(GA);
      98             : 
      99             :   // Walk all the recorded .symver aliases, and set up the binding
     100             :   // for each alias.
     101          91 :   for (auto &Symver : Streamer.symverAliases()) {
     102          49 :     const MCSymbol *Aliasee = Symver.first;
     103          49 :     MCSymbolAttr Attr = MCSA_Invalid;
     104             : 
     105             :     // First check if the aliasee binding was recorded in the asm.
     106          49 :     RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
     107          49 :     switch (state) {
     108             :     case RecordStreamer::Global:
     109             :     case RecordStreamer::DefinedGlobal:
     110             :       Attr = MCSA_Global;
     111             :       break;
     112             :     case RecordStreamer::UndefinedWeak:
     113             :     case RecordStreamer::DefinedWeak:
     114           7 :       Attr = MCSA_Weak;
     115             :       break;
     116             :     default:
     117             :       break;
     118             :     }
     119             : 
     120             :     // If we don't have a symbol attribute from assembly, then check if
     121             :     // the aliasee was defined in the IR.
     122             :     if (Attr == MCSA_Invalid) {
     123          35 :       const auto *GV = M.getNamedValue(Aliasee->getName());
     124          35 :       if (!GV) {
     125          14 :         auto MI = MangledNameMap.find(Aliasee->getName());
     126          49 :         if (MI != MangledNameMap.end())
     127           7 :           GV = MI->second;
     128             :         else
     129           7 :           continue;
     130             :       }
     131          28 :       if (GV->hasExternalLinkage())
     132             :         Attr = MCSA_Global;
     133           7 :       else if (GV->hasLocalLinkage())
     134             :         Attr = MCSA_Local;
     135             :       else if (GV->isWeakForLinker())
     136             :         Attr = MCSA_Weak;
     137             :     }
     138          14 :     if (Attr == MCSA_Invalid)
     139           0 :       continue;
     140             : 
     141             :     // Set the detected binding on each alias with this aliasee.
     142         217 :     for (auto &Alias : Symver.second)
     143          49 :       Streamer.EmitSymbolAttribute(Alias, Attr);
     144             :   }
     145             : }
     146             : 
     147        2335 : void ModuleSymbolTable::CollectAsmSymbols(
     148             :     const Module &M,
     149             :     function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
     150        4670 :   StringRef InlineAsm = M.getModuleInlineAsm();
     151        2335 :   if (InlineAsm.empty())
     152        2249 :     return;
     153             : 
     154         172 :   std::string Err;
     155         258 :   const Triple TT(M.getTargetTriple());
     156          86 :   const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
     157             :   assert(T && T->hasMCAsmParser());
     158             : 
     159         344 :   std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
     160          86 :   if (!MRI)
     161           0 :     return;
     162             : 
     163         430 :   std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
     164          86 :   if (!MAI)
     165             :     return;
     166             : 
     167             :   std::unique_ptr<MCSubtargetInfo> STI(
     168         430 :       T->createMCSubtargetInfo(TT.str(), "", ""));
     169          86 :   if (!STI)
     170             :     return;
     171             : 
     172         344 :   std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
     173          86 :   if (!MCII)
     174             :     return;
     175             : 
     176         172 :   MCObjectFileInfo MOFI;
     177         258 :   MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
     178          86 :   MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
     179         172 :   RecordStreamer Streamer(MCCtx);
     180         172 :   T->createNullTargetStreamer(Streamer);
     181             : 
     182         172 :   std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
     183         172 :   SourceMgr SrcMgr;
     184         258 :   SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
     185             :   std::unique_ptr<MCAsmParser> Parser(
     186         258 :       createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
     187             : 
     188         172 :   MCTargetOptions MCOptions;
     189             :   std::unique_ptr<MCTargetAsmParser> TAP(
     190         516 :       T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
     191          86 :   if (!TAP)
     192           0 :     return;
     193             : 
     194         172 :   Parser->setTargetParser(*TAP);
     195          86 :   if (Parser->Run(false))
     196             :     return;
     197             : 
     198          86 :   handleSymverAliases(M, Streamer);
     199             : 
     200         738 :   for (auto &KV : Streamer) {
     201         283 :     StringRef Key = KV.first();
     202         283 :     RecordStreamer::State Value = KV.second;
     203             :     // FIXME: For now we just assume that all asm symbols are executable.
     204         283 :     uint32_t Res = BasicSymbolRef::SF_Executable;
     205         283 :     switch (Value) {
     206           0 :     case RecordStreamer::NeverSeen:
     207           0 :       llvm_unreachable("NeverSeen should have been replaced earlier");
     208          71 :     case RecordStreamer::DefinedGlobal:
     209          71 :       Res |= BasicSymbolRef::SF_Global;
     210          71 :       break;
     211             :     case RecordStreamer::Defined:
     212             :       break;
     213          80 :     case RecordStreamer::Global:
     214             :     case RecordStreamer::Used:
     215          80 :       Res |= BasicSymbolRef::SF_Undefined;
     216          80 :       Res |= BasicSymbolRef::SF_Global;
     217          80 :       break;
     218          45 :     case RecordStreamer::DefinedWeak:
     219          45 :       Res |= BasicSymbolRef::SF_Weak;
     220          45 :       Res |= BasicSymbolRef::SF_Global;
     221          45 :       break;
     222           8 :     case RecordStreamer::UndefinedWeak:
     223           8 :       Res |= BasicSymbolRef::SF_Weak;
     224           8 :       Res |= BasicSymbolRef::SF_Undefined;
     225             :     }
     226         283 :     AsmSymbol(Key, BasicSymbolRef::Flags(Res));
     227             :   }
     228             : }
     229             : 
     230        8580 : void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
     231        8580 :   if (S.is<AsmSymbol *>()) {
     232         223 :     OS << S.get<AsmSymbol *>()->first;
     233             :     return;
     234             :   }
     235             : 
     236        8357 :   auto *GV = S.get<GlobalValue *>();
     237        8357 :   if (GV->hasDLLImportStorageClass())
     238           6 :     OS << "__imp_";
     239             : 
     240        8357 :   Mang.getNameWithPrefix(OS, GV, false);
     241             : }
     242             : 
     243        9508 : uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
     244        9508 :   if (S.is<AsmSymbol *>())
     245         277 :     return S.get<AsmSymbol *>()->second;
     246             : 
     247        9231 :   auto *GV = S.get<GlobalValue *>();
     248             : 
     249        9231 :   uint32_t Res = BasicSymbolRef::SF_None;
     250       18365 :   if (GV->isDeclarationForLinker())
     251             :     Res |= BasicSymbolRef::SF_Undefined;
     252       14480 :   else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
     253             :     Res |= BasicSymbolRef::SF_Hidden;
     254       12609 :   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
     255        3378 :     if (GVar->isConstant())
     256        2150 :       Res |= BasicSymbolRef::SF_Const;
     257             :   }
     258       24219 :   if (dyn_cast_or_null<Function>(GV->getBaseObject()))
     259        5757 :     Res |= BasicSymbolRef::SF_Executable;
     260       18462 :   if (isa<GlobalAlias>(GV))
     261         302 :     Res |= BasicSymbolRef::SF_Indirect;
     262       18462 :   if (GV->hasPrivateLinkage())
     263        1001 :     Res |= BasicSymbolRef::SF_FormatSpecific;
     264       15923 :   if (!GV->hasLocalLinkage())
     265        6692 :     Res |= BasicSymbolRef::SF_Global;
     266       18462 :   if (GV->hasCommonLinkage())
     267         132 :     Res |= BasicSymbolRef::SF_Common;
     268       35146 :   if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
     269       16684 :       GV->hasExternalWeakLinkage())
     270         908 :     Res |= BasicSymbolRef::SF_Weak;
     271             : 
     272       18165 :   if (GV->getName().startswith("llvm."))
     273         297 :     Res |= BasicSymbolRef::SF_FormatSpecific;
     274       12149 :   else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
     275        6430 :     if (Var->getSection() == "llvm.metadata")
     276           0 :       Res |= BasicSymbolRef::SF_FormatSpecific;
     277             :   }
     278             : 
     279             :   return Res;
     280             : }

Generated by: LCOV version 1.13