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