LLVM 20.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
79 return Symbols.begin();
80}
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
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}
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
bool hasExternalLinkage() const
Definition: GlobalValue.h:511
bool hasLocalLinkage() const
Definition: GlobalValue.h:528
bool isDeclarationForLinker() const
Definition: GlobalValue.h:618
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
Definition: GlobalValue.h:458
Context object for machine code objects.
Definition: MCContext.h:83
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:213
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:36
Streaming machine code generation interface.
Definition: MCStreamer.h:213
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
MCContext & getContext() const
Definition: MCStreamer.h:300
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:414
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:393
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
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:120
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type.
Definition: Module.cpp:135
iterator_range< global_value_iterator > global_values()
Definition: Module.cpp:415
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)
Definition: SmallVector.h:676
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
iterator end()
Definition: StringMap.h:220
iterator begin()
Definition: StringMap.h:219
iterator find(StringRef Key)
Definition: StringMap.h:233
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
LLVM Value Representation.
Definition: Value.h:74
A range adaptor for a pair of iterators.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:38
@ MCSA_LazyReference
.lazy_reference (MachO)
Definition: MCDirectives.h:37
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39