LLVM 22.0.0git
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
15using namespace llvm;
16
17void 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
36void RecordStreamer::markGlobal(const MCSymbol &Symbol,
38 State &S = Symbols[Symbol.getName()];
39 switch (S) {
40 case DefinedGlobal:
41 case Defined:
43 break;
44
45 case NeverSeen:
46 case Global:
47 case Used:
49 break;
50 case UndefinedWeak:
51 case DefinedWeak:
52 break;
53 }
54}
55
56void 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
73void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
74
76 : MCStreamer(Context), M(M) {}
77
81
83
86 markDefined(*Symbol);
87}
88
90 markDefined(*Symbol);
92}
93
97 markGlobal(*Symbol, Attribute);
99 markUsed(*Symbol);
100 return true;
101}
102
104 uint64_t Size, Align ByteAlignment,
105 SMLoc Loc) {
106 markDefined(*Symbol);
107}
108
110 Align ByteAlignment) {
111 markDefined(*Symbol);
112}
113
114RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
115 auto SI = Symbols.find(Sym->getName());
116 if (SI == Symbols.end())
117 return NeverSeen;
118 return SI->second;
119}
120
122 StringRef Name,
123 bool KeepOriginalSym) {
124 SymverAliasMap[OriginalSym].push_back(Name);
125}
126
129 return {SymverAliasMap.begin(), SymverAliasMap.end()};
130}
131
133 // Mapping from mangled name to GV.
134 StringMap<const GlobalValue *> MangledNameMap;
135 // The name in the assembler will be mangled, but the name in the IR
136 // might not, so we first compute a mapping from mangled name to GV.
137 Mangler Mang;
138 SmallString<64> MangledName;
139 for (const GlobalValue &GV : M.global_values()) {
140 if (!GV.hasName())
141 continue;
142 MangledName.clear();
143 MangledName.reserve(GV.getName().size() + 1);
144 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
145 MangledNameMap[MangledName] = &GV;
146 }
147
148 // Walk all the recorded .symver aliases, and set up the binding
149 // for each alias.
150 for (auto &Symver : SymverAliasMap) {
151 const MCSymbol *Aliasee = Symver.first;
153 bool IsDefined = false;
154
155 // First check if the aliasee binding was recorded in the asm.
156 RecordStreamer::State state = getSymbolState(Aliasee);
157 switch (state) {
160 Attr = MCSA_Global;
161 break;
164 Attr = MCSA_Weak;
165 break;
166 default:
167 break;
168 }
169
170 switch (state) {
174 IsDefined = true;
175 break;
180 break;
181 }
182
183 if (Attr == MCSA_Invalid || !IsDefined) {
184 const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
185 if (!GV) {
186 auto MI = MangledNameMap.find(Aliasee->getName());
187 if (MI != MangledNameMap.end())
188 GV = MI->second;
189 }
190 if (GV) {
191 // If we don't have a symbol attribute from assembly, then check if
192 // the aliasee was defined in the IR.
193 if (Attr == MCSA_Invalid) {
194 if (GV->hasExternalLinkage())
195 Attr = MCSA_Global;
196 else if (GV->hasLocalLinkage())
197 Attr = MCSA_Local;
198 else if (GV->isWeakForLinker())
199 Attr = MCSA_Weak;
200 }
201 IsDefined = IsDefined || !GV->isDeclarationForLinker();
202 }
203 }
204
205 // Set the detected binding on each alias with this aliasee.
206 for (auto AliasName : Symver.second) {
207 std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
208 SmallString<128> NewName;
209 if (!Split.second.empty() && !Split.second.starts_with("@")) {
210 // Special processing for "@@@" according
211 // https://sourceware.org/binutils/docs/as/Symver.html
212 const char *Separator = IsDefined ? "@@" : "@";
213 AliasName =
214 (Split.first + Separator + Split.second).toStringRef(NewName);
215 }
216 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
217 // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
218 // converted into @ or @@.
219 const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
220 if (IsDefined)
221 markDefined(*Alias);
222 // Don't use EmitAssignment override as it always marks alias as defined.
224 if (Attr != MCSA_Invalid)
225 emitSymbolAttribute(Alias, Attr);
226 }
227 }
228}
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:69
bool hasExternalLinkage() const
bool hasLocalLinkage() const
bool isDeclarationForLinker() const
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:496
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
MCContext & getContext() const
Definition MCStreamer.h:314
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCStreamer(MCContext &Ctx)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition Mangler.cpp:121
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment, SMLoc Loc=SMLoc()) override
Emit the zerofill section and an optional symbol.
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override
Emit a common symbol.
void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym) override
Record .symver aliases for later processing.
void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override
Emit an assignment of Value to Symbol.
iterator_range< const_symver_iterator > symverAliases()
StringMap< State >::const_iterator const_iterator
const_iterator end()
RecordStreamer(MCContext &Context, const Module &M)
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
const_iterator begin()
Represents a location in source code.
Definition SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void reserve(size_type N)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:133
iterator end()
Definition StringMap.h:224
iterator find(StringRef Key)
Definition StringMap.h:235
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
LLVM Value Representation.
Definition Value.h:75
A range adaptor for a pair of iterators.
This is an optimization pass for GlobalISel generic memory operations.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
@ MCSA_Local
.local (ELF)
@ MCSA_LazyReference
.lazy_reference (MachO)
@ MCSA_Weak
.weak
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_Invalid
Not a valid directive.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39