ModuleSymbolTable.cpp revision 327952
1321369Sdim//===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===//
2311116Sdim//
3311116Sdim//                     The LLVM Compiler Infrastructure
4311116Sdim//
5311116Sdim// This file is distributed under the University of Illinois Open Source
6311116Sdim// License. See LICENSE.TXT for details.
7311116Sdim//
8311116Sdim//===----------------------------------------------------------------------===//
9311116Sdim//
10311116Sdim// This class represents a symbol table built from in-memory IR. It provides
11311116Sdim// access to GlobalValues and should only be used if such access is required
12311116Sdim// (e.g. in the LTO implementation).
13311116Sdim//
14311116Sdim//===----------------------------------------------------------------------===//
15311116Sdim
16321369Sdim#include "llvm/Object/ModuleSymbolTable.h"
17311116Sdim#include "RecordStreamer.h"
18311116Sdim#include "llvm/ADT/STLExtras.h"
19321369Sdim#include "llvm/ADT/SmallString.h"
20321369Sdim#include "llvm/ADT/StringMap.h"
21321369Sdim#include "llvm/ADT/StringRef.h"
22321369Sdim#include "llvm/ADT/Triple.h"
23321369Sdim#include "llvm/IR/Function.h"
24321369Sdim#include "llvm/IR/GlobalAlias.h"
25321369Sdim#include "llvm/IR/GlobalValue.h"
26321369Sdim#include "llvm/IR/GlobalVariable.h"
27311116Sdim#include "llvm/IR/Mangler.h"
28311116Sdim#include "llvm/IR/Module.h"
29311116Sdim#include "llvm/MC/MCAsmInfo.h"
30311116Sdim#include "llvm/MC/MCContext.h"
31321369Sdim#include "llvm/MC/MCDirectives.h"
32311116Sdim#include "llvm/MC/MCInstrInfo.h"
33311116Sdim#include "llvm/MC/MCObjectFileInfo.h"
34311116Sdim#include "llvm/MC/MCParser/MCAsmParser.h"
35311116Sdim#include "llvm/MC/MCParser/MCTargetAsmParser.h"
36311116Sdim#include "llvm/MC/MCRegisterInfo.h"
37311116Sdim#include "llvm/MC/MCSubtargetInfo.h"
38321369Sdim#include "llvm/MC/MCSymbol.h"
39321369Sdim#include "llvm/MC/MCTargetOptions.h"
40321369Sdim#include "llvm/Object/SymbolicFile.h"
41321369Sdim#include "llvm/Support/Casting.h"
42321369Sdim#include "llvm/Support/CodeGen.h"
43321369Sdim#include "llvm/Support/ErrorHandling.h"
44311116Sdim#include "llvm/Support/MemoryBuffer.h"
45321369Sdim#include "llvm/Support/SMLoc.h"
46311116Sdim#include "llvm/Support/SourceMgr.h"
47311116Sdim#include "llvm/Support/TargetRegistry.h"
48311116Sdim#include "llvm/Support/raw_ostream.h"
49321369Sdim#include <algorithm>
50321369Sdim#include <cassert>
51321369Sdim#include <cstdint>
52321369Sdim#include <memory>
53321369Sdim#include <string>
54321369Sdim
55311116Sdimusing namespace llvm;
56311116Sdimusing namespace object;
57311116Sdim
58311116Sdimvoid ModuleSymbolTable::addModule(Module *M) {
59311116Sdim  if (FirstMod)
60311116Sdim    assert(FirstMod->getTargetTriple() == M->getTargetTriple());
61311116Sdim  else
62311116Sdim    FirstMod = M;
63311116Sdim
64321369Sdim  for (GlobalValue &GV : M->global_values())
65311116Sdim    SymTab.push_back(&GV);
66311116Sdim
67321369Sdim  CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
68321369Sdim    SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
69321369Sdim  });
70311116Sdim}
71311116Sdim
72321369Sdim// Ensure ELF .symver aliases get the same binding as the defined symbol
73321369Sdim// they alias with.
74321369Sdimstatic void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
75321369Sdim  if (Streamer.symverAliases().empty())
76321369Sdim    return;
77321369Sdim
78321369Sdim  // The name in the assembler will be mangled, but the name in the IR
79321369Sdim  // might not, so we first compute a mapping from mangled name to GV.
80321369Sdim  Mangler Mang;
81321369Sdim  SmallString<64> MangledName;
82321369Sdim  StringMap<const GlobalValue *> MangledNameMap;
83321369Sdim  auto GetMangledName = [&](const GlobalValue &GV) {
84321369Sdim    if (!GV.hasName())
85321369Sdim      return;
86321369Sdim
87321369Sdim    MangledName.clear();
88321369Sdim    MangledName.reserve(GV.getName().size() + 1);
89321369Sdim    Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
90321369Sdim    MangledNameMap[MangledName] = &GV;
91321369Sdim  };
92321369Sdim  for (const Function &F : M)
93321369Sdim    GetMangledName(F);
94321369Sdim  for (const GlobalVariable &GV : M.globals())
95321369Sdim    GetMangledName(GV);
96321369Sdim  for (const GlobalAlias &GA : M.aliases())
97321369Sdim    GetMangledName(GA);
98321369Sdim
99321369Sdim  // Walk all the recorded .symver aliases, and set up the binding
100321369Sdim  // for each alias.
101321369Sdim  for (auto &Symver : Streamer.symverAliases()) {
102321369Sdim    const MCSymbol *Aliasee = Symver.first;
103321369Sdim    MCSymbolAttr Attr = MCSA_Invalid;
104321369Sdim
105321369Sdim    // First check if the aliasee binding was recorded in the asm.
106321369Sdim    RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
107321369Sdim    switch (state) {
108321369Sdim    case RecordStreamer::Global:
109321369Sdim    case RecordStreamer::DefinedGlobal:
110321369Sdim      Attr = MCSA_Global;
111321369Sdim      break;
112321369Sdim    case RecordStreamer::UndefinedWeak:
113321369Sdim    case RecordStreamer::DefinedWeak:
114321369Sdim      Attr = MCSA_Weak;
115321369Sdim      break;
116321369Sdim    default:
117321369Sdim      break;
118321369Sdim    }
119321369Sdim
120321369Sdim    // If we don't have a symbol attribute from assembly, then check if
121321369Sdim    // the aliasee was defined in the IR.
122321369Sdim    if (Attr == MCSA_Invalid) {
123321369Sdim      const auto *GV = M.getNamedValue(Aliasee->getName());
124321369Sdim      if (!GV) {
125321369Sdim        auto MI = MangledNameMap.find(Aliasee->getName());
126321369Sdim        if (MI != MangledNameMap.end())
127321369Sdim          GV = MI->second;
128321369Sdim        else
129321369Sdim          continue;
130321369Sdim      }
131321369Sdim      if (GV->hasExternalLinkage())
132321369Sdim        Attr = MCSA_Global;
133321369Sdim      else if (GV->hasLocalLinkage())
134321369Sdim        Attr = MCSA_Local;
135321369Sdim      else if (GV->isWeakForLinker())
136321369Sdim        Attr = MCSA_Weak;
137321369Sdim    }
138321369Sdim    if (Attr == MCSA_Invalid)
139321369Sdim      continue;
140321369Sdim
141321369Sdim    // Set the detected binding on each alias with this aliasee.
142321369Sdim    for (auto &Alias : Symver.second)
143321369Sdim      Streamer.EmitSymbolAttribute(Alias, Attr);
144321369Sdim  }
145321369Sdim}
146321369Sdim
147311116Sdimvoid ModuleSymbolTable::CollectAsmSymbols(
148321369Sdim    const Module &M,
149311116Sdim    function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
150321369Sdim  StringRef InlineAsm = M.getModuleInlineAsm();
151311116Sdim  if (InlineAsm.empty())
152311116Sdim    return;
153311116Sdim
154311116Sdim  std::string Err;
155321369Sdim  const Triple TT(M.getTargetTriple());
156311116Sdim  const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
157311116Sdim  assert(T && T->hasMCAsmParser());
158311116Sdim
159311116Sdim  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
160311116Sdim  if (!MRI)
161311116Sdim    return;
162311116Sdim
163311116Sdim  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
164311116Sdim  if (!MAI)
165311116Sdim    return;
166311116Sdim
167311116Sdim  std::unique_ptr<MCSubtargetInfo> STI(
168311116Sdim      T->createMCSubtargetInfo(TT.str(), "", ""));
169311116Sdim  if (!STI)
170311116Sdim    return;
171311116Sdim
172311116Sdim  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
173311116Sdim  if (!MCII)
174311116Sdim    return;
175311116Sdim
176311116Sdim  MCObjectFileInfo MOFI;
177311116Sdim  MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
178327952Sdim  MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
179311116Sdim  RecordStreamer Streamer(MCCtx);
180311116Sdim  T->createNullTargetStreamer(Streamer);
181311116Sdim
182311116Sdim  std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
183311116Sdim  SourceMgr SrcMgr;
184311116Sdim  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
185311116Sdim  std::unique_ptr<MCAsmParser> Parser(
186311116Sdim      createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
187311116Sdim
188311116Sdim  MCTargetOptions MCOptions;
189311116Sdim  std::unique_ptr<MCTargetAsmParser> TAP(
190311116Sdim      T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
191311116Sdim  if (!TAP)
192311116Sdim    return;
193311116Sdim
194311116Sdim  Parser->setTargetParser(*TAP);
195311116Sdim  if (Parser->Run(false))
196311116Sdim    return;
197311116Sdim
198321369Sdim  handleSymverAliases(M, Streamer);
199321369Sdim
200311116Sdim  for (auto &KV : Streamer) {
201311116Sdim    StringRef Key = KV.first();
202311116Sdim    RecordStreamer::State Value = KV.second;
203311116Sdim    // FIXME: For now we just assume that all asm symbols are executable.
204311116Sdim    uint32_t Res = BasicSymbolRef::SF_Executable;
205311116Sdim    switch (Value) {
206311116Sdim    case RecordStreamer::NeverSeen:
207311116Sdim      llvm_unreachable("NeverSeen should have been replaced earlier");
208311116Sdim    case RecordStreamer::DefinedGlobal:
209311116Sdim      Res |= BasicSymbolRef::SF_Global;
210311116Sdim      break;
211311116Sdim    case RecordStreamer::Defined:
212311116Sdim      break;
213311116Sdim    case RecordStreamer::Global:
214311116Sdim    case RecordStreamer::Used:
215311116Sdim      Res |= BasicSymbolRef::SF_Undefined;
216311116Sdim      Res |= BasicSymbolRef::SF_Global;
217311116Sdim      break;
218311116Sdim    case RecordStreamer::DefinedWeak:
219311116Sdim      Res |= BasicSymbolRef::SF_Weak;
220311116Sdim      Res |= BasicSymbolRef::SF_Global;
221311116Sdim      break;
222311116Sdim    case RecordStreamer::UndefinedWeak:
223311116Sdim      Res |= BasicSymbolRef::SF_Weak;
224311116Sdim      Res |= BasicSymbolRef::SF_Undefined;
225311116Sdim    }
226311116Sdim    AsmSymbol(Key, BasicSymbolRef::Flags(Res));
227311116Sdim  }
228311116Sdim}
229311116Sdim
230311116Sdimvoid ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
231311116Sdim  if (S.is<AsmSymbol *>()) {
232311116Sdim    OS << S.get<AsmSymbol *>()->first;
233311116Sdim    return;
234311116Sdim  }
235311116Sdim
236311116Sdim  auto *GV = S.get<GlobalValue *>();
237311116Sdim  if (GV->hasDLLImportStorageClass())
238311116Sdim    OS << "__imp_";
239311116Sdim
240311116Sdim  Mang.getNameWithPrefix(OS, GV, false);
241311116Sdim}
242311116Sdim
243311116Sdimuint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
244311116Sdim  if (S.is<AsmSymbol *>())
245311116Sdim    return S.get<AsmSymbol *>()->second;
246311116Sdim
247311116Sdim  auto *GV = S.get<GlobalValue *>();
248311116Sdim
249311116Sdim  uint32_t Res = BasicSymbolRef::SF_None;
250311116Sdim  if (GV->isDeclarationForLinker())
251311116Sdim    Res |= BasicSymbolRef::SF_Undefined;
252311116Sdim  else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
253311116Sdim    Res |= BasicSymbolRef::SF_Hidden;
254311116Sdim  if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
255311116Sdim    if (GVar->isConstant())
256311116Sdim      Res |= BasicSymbolRef::SF_Const;
257311116Sdim  }
258311116Sdim  if (dyn_cast_or_null<Function>(GV->getBaseObject()))
259311116Sdim    Res |= BasicSymbolRef::SF_Executable;
260311116Sdim  if (isa<GlobalAlias>(GV))
261311116Sdim    Res |= BasicSymbolRef::SF_Indirect;
262311116Sdim  if (GV->hasPrivateLinkage())
263311116Sdim    Res |= BasicSymbolRef::SF_FormatSpecific;
264311116Sdim  if (!GV->hasLocalLinkage())
265311116Sdim    Res |= BasicSymbolRef::SF_Global;
266311116Sdim  if (GV->hasCommonLinkage())
267311116Sdim    Res |= BasicSymbolRef::SF_Common;
268311116Sdim  if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
269311116Sdim      GV->hasExternalWeakLinkage())
270311116Sdim    Res |= BasicSymbolRef::SF_Weak;
271311116Sdim
272311116Sdim  if (GV->getName().startswith("llvm."))
273311116Sdim    Res |= BasicSymbolRef::SF_FormatSpecific;
274311116Sdim  else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
275311116Sdim    if (Var->getSection() == "llvm.metadata")
276311116Sdim      Res |= BasicSymbolRef::SF_FormatSpecific;
277311116Sdim  }
278311116Sdim
279311116Sdim  return Res;
280311116Sdim}
281