LLVM  8.0.1
RecordStreamer.cpp
Go to the documentation of this file.
1 //===-- RecordStreamer.cpp - Record asm defined and used symbols ----------===//
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 #include "RecordStreamer.h"
11 #include "llvm/IR/Mangler.h"
12 #include "llvm/IR/Module.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCSymbol.h"
15 
16 using namespace llvm;
17 
18 void RecordStreamer::markDefined(const MCSymbol &Symbol) {
19  State &S = Symbols[Symbol.getName()];
20  switch (S) {
21  case DefinedGlobal:
22  case Global:
23  S = DefinedGlobal;
24  break;
25  case NeverSeen:
26  case Defined:
27  case Used:
28  S = Defined;
29  break;
30  case DefinedWeak:
31  break;
32  case UndefinedWeak:
33  S = DefinedWeak;
34  }
35 }
36 
37 void RecordStreamer::markGlobal(const MCSymbol &Symbol,
39  State &S = Symbols[Symbol.getName()];
40  switch (S) {
41  case DefinedGlobal:
42  case Defined:
43  S = (Attribute == MCSA_Weak) ? DefinedWeak : DefinedGlobal;
44  break;
45 
46  case NeverSeen:
47  case Global:
48  case Used:
49  S = (Attribute == MCSA_Weak) ? UndefinedWeak : Global;
50  break;
51  case UndefinedWeak:
52  case DefinedWeak:
53  break;
54  }
55 }
56 
57 void RecordStreamer::markUsed(const MCSymbol &Symbol) {
58  State &S = Symbols[Symbol.getName()];
59  switch (S) {
60  case DefinedGlobal:
61  case Defined:
62  case Global:
63  case DefinedWeak:
64  case UndefinedWeak:
65  break;
66 
67  case NeverSeen:
68  case Used:
69  S = Used;
70  break;
71  }
72 }
73 
74 void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
75 
77  : MCStreamer(Context), M(M) {}
78 
80  return Symbols.begin();
81 }
82 
84 
86  const MCSubtargetInfo &STI, bool) {
87  MCStreamer::EmitInstruction(Inst, STI);
88 }
89 
91  MCStreamer::EmitLabel(Symbol);
92  markDefined(*Symbol);
93 }
94 
96  markDefined(*Symbol);
97  MCStreamer::EmitAssignment(Symbol, Value);
98 }
99 
101  MCSymbolAttr Attribute) {
102  if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
103  markGlobal(*Symbol, Attribute);
104  if (Attribute == MCSA_LazyReference)
105  markUsed(*Symbol);
106  return true;
107 }
108 
110  uint64_t Size, unsigned ByteAlignment,
111  SMLoc Loc) {
112  markDefined(*Symbol);
113 }
114 
116  unsigned ByteAlignment) {
117  markDefined(*Symbol);
118 }
119 
120 RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
121  auto SI = Symbols.find(Sym->getName());
122  if (SI == Symbols.end())
123  return NeverSeen;
124  return SI->second;
125 }
126 
128  const MCSymbol *Aliasee) {
129  SymverAliasMap[Aliasee].push_back(AliasName);
130 }
131 
134  return {SymverAliasMap.begin(), SymverAliasMap.end()};
135 }
136 
138  // Mapping from mangled name to GV.
139  StringMap<const GlobalValue *> MangledNameMap;
140  // The name in the assembler will be mangled, but the name in the IR
141  // might not, so we first compute a mapping from mangled name to GV.
142  Mangler Mang;
143  SmallString<64> MangledName;
144  for (const GlobalValue &GV : M.global_values()) {
145  if (!GV.hasName())
146  continue;
147  MangledName.clear();
148  MangledName.reserve(GV.getName().size() + 1);
149  Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
150  MangledNameMap[MangledName] = &GV;
151  }
152 
153  // Walk all the recorded .symver aliases, and set up the binding
154  // for each alias.
155  for (auto &Symver : SymverAliasMap) {
156  const MCSymbol *Aliasee = Symver.first;
157  MCSymbolAttr Attr = MCSA_Invalid;
158  bool IsDefined = false;
159 
160  // First check if the aliasee binding was recorded in the asm.
161  RecordStreamer::State state = getSymbolState(Aliasee);
162  switch (state) {
165  Attr = MCSA_Global;
166  break;
169  Attr = MCSA_Weak;
170  break;
171  default:
172  break;
173  }
174 
175  switch (state) {
179  IsDefined = true;
180  break;
185  break;
186  }
187 
188  if (Attr == MCSA_Invalid || !IsDefined) {
189  const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
190  if (!GV) {
191  auto MI = MangledNameMap.find(Aliasee->getName());
192  if (MI != MangledNameMap.end())
193  GV = MI->second;
194  }
195  if (GV) {
196  // If we don't have a symbol attribute from assembly, then check if
197  // the aliasee was defined in the IR.
198  if (Attr == MCSA_Invalid) {
199  if (GV->hasExternalLinkage())
200  Attr = MCSA_Global;
201  else if (GV->hasLocalLinkage())
202  Attr = MCSA_Local;
203  else if (GV->isWeakForLinker())
204  Attr = MCSA_Weak;
205  }
206  IsDefined = IsDefined || !GV->isDeclarationForLinker();
207  }
208  }
209 
210  // Set the detected binding on each alias with this aliasee.
211  for (auto AliasName : Symver.second) {
212  std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
213  SmallString<128> NewName;
214  if (!Split.second.empty() && !Split.second.startswith("@")) {
215  // Special processing for "@@@" according
216  // https://sourceware.org/binutils/docs/as/Symver.html
217  const char *Separator = IsDefined ? "@@" : "@";
218  AliasName =
219  (Split.first + Separator + Split.second).toStringRef(NewName);
220  }
221  MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
222  // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
223  // converted into @ or @@.
224  const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
225  if (IsDefined)
226  markDefined(*Alias);
227  // Don't use EmitAssignment override as it always marks alias as defined.
228  MCStreamer::EmitAssignment(Alias, Value);
229  if (Attr != MCSA_Invalid)
230  EmitSymbolAttribute(Alias, Attr);
231  }
232  }
233 }
bool isDeclarationForLinker() const
Definition: GlobalValue.h:524
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:39
bool hasLocalLinkage() const
Definition: GlobalValue.h:436
LLVMContext & Context
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:323
This class represents lattice values for constants.
Definition: AllocatorList.h:24
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
Not a valid directive.
Definition: MCDirectives.h:20
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
void emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) override
Record .symver aliases for later processing.
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override
Emit an assignment of Value to Symbol.
iterator find(StringRef Key)
Definition: StringMap.h:333
StringMap< State >::const_iterator const_iterator
void reserve(size_type N)
Definition: SmallVector.h:376
const_iterator end()
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:956
MCContext & getContext() const
Definition: MCStreamer.h:251
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
.local (ELF)
Definition: MCDirectives.h:35
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
Definition: MCStreamer.cpp:912
Context object for machine code objects.
Definition: MCContext.h:63
bool hasExternalLinkage() const
Definition: GlobalValue.h:422
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type. ...
Definition: Module.cpp:114
.lazy_reference (MachO)
Definition: MCDirectives.h:34
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
Definition: GlobalValue.h:370
Streaming machine code generation interface.
Definition: MCStreamer.h:189
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Definition: StringExtras.h:53
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool) override
Emit the given Instruction into the current section.
Module.h This file contains the declarations for the Module class.
MCSymbolAttr
Definition: MCDirectives.h:19
A range adaptor for a pair of iterators.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:220
void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, SMLoc Loc=SMLoc()) override
Emit the zerofill section and an optional symbol.
iterator begin()
Definition: StringMap.h:315
.type _foo,
Definition: MCDirectives.h:30
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:123
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:47
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a common symbol.
void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
LLVM Value Representation.
Definition: Value.h:73
iterator_range< const_symver_iterator > symverAliases()
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:347
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable&#39;s name.
Definition: Mangler.cpp:112
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Represents a location in source code.
Definition: SMLoc.h:24
const_iterator begin()
static void Split(std::vector< std::string > &V, StringRef S)
Splits a string of comma separated items in to a vector of strings.
iterator_range< global_value_iterator > global_values()
Definition: Module.h:685
RecordStreamer(MCContext &Context, const Module &M)
iterator end()
Definition: StringMap.h:318