LLVM 18.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
85 const MCSubtargetInfo &STI) {
87}
88
91 markDefined(*Symbol);
92}
93
95 markDefined(*Symbol);
97}
98
102 markGlobal(*Symbol, Attribute);
104 markUsed(*Symbol);
105 return true;
106}
107
109 uint64_t Size, Align ByteAlignment,
110 SMLoc Loc) {
111 markDefined(*Symbol);
112}
113
115 Align ByteAlignment) {
116 markDefined(*Symbol);
117}
118
119RecordStreamer::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
128 bool KeepOriginalSym) {
129 SymverAliasMap[OriginalSym].push_back(Name);
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;
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.
229 if (Attr != MCSA_Invalid)
230 emitSymbolAttribute(Alias, Attr);
231 }
232 }
233}
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:468
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
LLVMContext & Context
bool hasExternalLinkage() const
Definition: GlobalValue.h:506
bool hasLocalLinkage() const
Definition: GlobalValue.h:523
bool isDeclarationForLinker() const
Definition: GlobalValue.h:614
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
Definition: GlobalValue.h:453
Context object for machine code objects.
Definition: MCContext.h:76
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:201
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
Streaming machine code generation interface.
Definition: MCStreamer.h:212
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCContext & getContext() const
Definition: MCStreamer.h:297
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:424
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:389
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:206
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:119
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:110
iterator_range< global_value_iterator > global_values()
Definition: Module.cpp:419
void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment, SMLoc Loc=SMLoc()) override
Emit the zerofill section and an optional symbol.
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
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:667
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:112
iterator end()
Definition: StringMap.h:205
iterator begin()
Definition: StringMap.h:204
iterator find(StringRef Key)
Definition: StringMap.h:218
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