LLVM 24.0.0git
RISCVELFStreamer.cpp
Go to the documentation of this file.
1//===-- RISCVELFStreamer.cpp - RISC-V ELF Target Streamer Methods ---------===//
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// This file provides RISC-V specific target streamer methods.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVELFStreamer.h"
14#include "RISCVBaseInfo.h"
15#include "RISCVMCTargetDesc.h"
18#include "llvm/MC/MCAssembler.h"
20#include "llvm/MC/MCContext.h"
23
24using namespace llvm;
25
26// This part is for ELF object output.
32
34 std::unique_ptr<MCAsmBackend> MAB,
35 std::unique_ptr<MCObjectWriter> MOW,
36 std::unique_ptr<MCCodeEmitter> MCE)
37 : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
38
42
45
46 // Compute the initial ISA string. This serves two purposes:
47 // 1. Deduplication: subsequent .option arch/rvc/norvc directives compare
48 // against ArchString to avoid propagating redundant ISA updates.
49 // 2. Initial symbol: seed the streamer's active ISA so a "$x<ArchString>"
50 // mapping symbol is emitted before the first instruction, recording
51 // the full ISA in the object even when no .option directive is present.
53 InitialArchString = (*ParseResult)->toString();
54 setArchString(InitialArchString);
55 } else {
56 consumeError(ParseResult.takeError());
57 }
58}
59
61 if (Arch == ArchString)
62 return;
63 ArchString = std::string(Arch);
65}
66
68 ArchStringStack.push_back(ArchString);
69}
70
72 if (!ArchStringStack.empty())
73 setArchString(ArchStringStack.pop_back_val());
74}
75
84
85void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
86 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
87}
88
89void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
91 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
92}
93
94void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
95 unsigned IntValue,
96 StringRef StringValue) {
97 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
98 /*OverwriteExisting=*/true);
99}
100
102 RISCVELFStreamer &S = getStreamer();
103 if (S.Contents.empty())
104 return;
105
106 S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
107 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
108}
109
114
115 unsigned EFlags = W.getELFHeaderEFlags();
116
117 if (hasRVC())
118 EFlags |= ELF::EF_RISCV_RVC;
119 if (hasTSO())
120 EFlags |= ELF::EF_RISCV_TSO;
121
122 switch (ABI) {
127 break;
133 break;
139 break;
144 EFlags |= ELF::EF_RISCV_RVE;
145 break;
147 break;
148 }
149
150 W.setELFHeaderEFlags(EFlags);
151}
152
154 AttributeSection = nullptr;
155 ArchString = InitialArchString;
156 ArchStringStack.clear();
157 // Re-seed the streamer's active ISA so the first instruction after reset
158 // still records the full ISA via "$x<ISA>", matching the behaviour set up
159 // in the constructor.
160 if (!InitialArchString.empty())
161 getStreamer().setMappingSymbolArch(InitialArchString);
162}
163
168
171 LastMappingSymbols.clear();
172 LastEMS = EMS_None;
173 MappingSymbolArch.clear();
174 LastEmittedArch.clear();
175 LastEmittedArchInSection.clear();
176 // Call target streamer reset last: it may call setMappingSymbolArch to
177 // re-seed the initial ISA after our state has been cleared.
178 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
179}
180
181void RISCVELFStreamer::emitDataMappingSymbol() {
182 if (LastEMS == EMS_Data)
183 return;
184 emitMappingSymbol("$d");
185 LastEMS = EMS_Data;
186}
187
188void RISCVELFStreamer::emitInstructionsMappingSymbol() {
189 // Emit a mapping symbol at the start of each instruction run, and whenever
190 // the active ISA has changed since the last one emitted in this section.
191 // The symbol takes the form "$x<ISA>" when MappingSymbolArch is known, or
192 // plain "$x" as a fallback. The comparison with LastEmittedArch provides
193 // deduplication: repeating .option arch with the same ISA, or re-entering a
194 // section whose last mapping symbol already matches the active ISA, emits
195 // no redundant symbol.
196 bool NeedSymbol =
197 LastEMS != EMS_Instructions || LastEmittedArch != MappingSymbolArch;
198 if (NeedSymbol) {
199 if (MappingSymbolArch.empty())
200 emitMappingSymbol("$x");
201 else
202 emitMappingSymbol("$x" + MappingSymbolArch);
203 LastEmittedArch = MappingSymbolArch;
204 }
205 LastEMS = EMS_Instructions;
206}
207
208void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
209 auto *Symbol =
210 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
211 emitLabel(Symbol);
212 Symbol->setType(ELF::STT_NOTYPE);
213 Symbol->setBinding(ELF::STB_LOCAL);
214}
215
217 MappingSymbolArch = std::string(Arch);
218}
219
221 // We have to keep track of the mapping symbol state of any sections we
222 // use. Each one should start off as EMS_None, which is provided as the
223 // default constructor by DenseMap::lookup. The last ISA suffix emitted in
224 // each section is also preserved so that re-entering a section only emits a
225 // new "$x<ISA>" symbol when the active ISA has actually changed.
226 const MCSection *Cur = getCurrentSection().first;
227 LastMappingSymbols[Cur] = LastEMS;
228 LastEmittedArchInSection[Cur] = LastEmittedArch;
229 LastEMS = LastMappingSymbols.lookup(Section);
230 auto It = LastEmittedArchInSection.find(Section);
231 LastEmittedArch = It != LastEmittedArchInSection.end() ? It->second : "";
232
233 MCELFStreamer::changeSection(Section, Subsection);
234}
235
237 const MCSubtargetInfo &STI) {
238 emitInstructionsMappingSymbol();
240}
241
243 emitDataMappingSymbol();
245}
246
247void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
248 SMLoc Loc) {
249 emitDataMappingSymbol();
250 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
251}
252
254 SMLoc Loc) {
255 emitDataMappingSymbol();
257}
258
260 std::unique_ptr<MCAsmBackend> &&MAB,
261 std::unique_ptr<MCObjectWriter> &&MOW,
262 std::unique_ptr<MCCodeEmitter> &&MCE) {
263 return new RISCVELFStreamer(C, std::move(MAB), std::move(MOW),
264 std::move(MCE));
265}
266
268 const uint32_t Feature1And) {
269 MCStreamer &OutStreamer = getStreamer();
270 MCContext &Ctx = OutStreamer.getContext();
271
272 const Triple &Triple = Ctx.getTargetTriple();
273 Align NoteAlign;
274 uint64_t DescSize;
275 if (Triple.isArch64Bit()) {
276 NoteAlign = Align(8);
277 DescSize = 16;
278 } else {
280 NoteAlign = Align(4);
281 DescSize = 12;
282 }
283
284 assert(Ctx.getObjectFileType() == MCContext::Environment::IsELF);
285 MCSection *const NoteSection =
286 Ctx.getELFSection(".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
287 OutStreamer.pushSection();
288 OutStreamer.switchSection(NoteSection);
289
290 // Emit the note header
291 OutStreamer.emitValueToAlignment(NoteAlign);
292 OutStreamer.emitIntValue(4, 4); // n_namsz
293 OutStreamer.emitIntValue(DescSize, 4); // n_descsz
294 OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); // n_type
295 OutStreamer.emitBytes(StringRef("GNU", 4)); // n_name
296
297 // Emit n_desc field
298
299 // Emit the feature_1_and property
300 OutStreamer.emitIntValue(ELF::GNU_PROPERTY_RISCV_FEATURE_1_AND, 4); // pr_type
301 OutStreamer.emitIntValue(4, 4); // pr_datasz
302 OutStreamer.emitIntValue(Feature1And, 4); // pr_data
303 OutStreamer.emitValueToAlignment(NoteAlign); // pr_padding
304
305 OutStreamer.popSection();
306}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI bool registerSymbol(const MCSymbol &Symbol)
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI MCSymbol * createLocalSymbol(StringRef Name)
Create a local, non-temporary symbol like an ELF mapping symbol.
SmallVector< AttributeItem, 64 > Contents
void emitAttributesSection(StringRef Vendor, const Twine &Section, unsigned Type, MCSection *&AttributeSection)
void changeSection(MCSection *Section, uint32_t Subsection=0) override
This is called by popSection and switchSection, if the current section changes.
void setAttributeItems(unsigned Attribute, unsigned IntValue, StringRef StringValue, bool OverwriteExisting)
ELFObjectWriter & getWriter()
void setAttributeItem(unsigned Attribute, unsigned Value, bool OverwriteExisting)
void reset() override
state management
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc=SMLoc()) override
Emit Size bytes worth of the value specified by FillValue.
MCAssembler & getAssembler()
void emitBytes(StringRef Data) override
Emit the bytes in Data into the output.
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc()) override
Emit the expression Value into the output as a native integer of the given Size bytes.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:580
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual bool popSection()
Restore the current and previous section from the section stack.
MCContext & getContext() const
Definition MCStreamer.h:326
virtual void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
MCTargetStreamer * getTargetStreamer()
Definition MCStreamer.h:336
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
void pushSection()
Save the current and previous section on the section stack.
Definition MCStreamer.h:460
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
MCSectionSubPair getCurrentSection() const
Return the current section that the streamer is emitting code to.
Definition MCStreamer.h:433
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
MCStreamer & Streamer
Definition MCStreamer.h:97
This class represents success/failure for parsing-like operations that find it important to chain tog...
void setMappingSymbolArch(StringRef Arch)
void changeSection(MCSection *Section, uint32_t Subsection) override
This is called by popSection and switchSection, if the current section changes.
void emitBytes(StringRef Data) override
Emit the bytes in Data into the output.
RISCVELFStreamer(MCContext &C, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > MOW, std::unique_ptr< MCCodeEmitter > MCE)
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc) override
Emit Size bytes worth of the value specified by FillValue.
void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override
Emit the expression Value into the output as a native integer of the given Size bytes.
void setArchString(StringRef Arch) override
void setFlagsFromFeatures(const MCSubtargetInfo &STI) override
void emitNoteGnuPropertySection(const uint32_t Feature1And)
void emitDirectiveOptionNoExact() override
RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
void emitDirectiveVariantCC(MCSymbol &Symbol) override
RISCVELFStreamer & getStreamer()
void emitDirectiveOptionNoRelax() override
RISCVABI::ABI getTargetABI() const
virtual void setFlagsFromFeatures(const MCSubtargetInfo &STI)
Represents a location in source code.
Definition SMLoc.h:22
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition Triple.cpp:1827
LLVM_ABI bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition Triple.cpp:1831
LLVM Value Representation.
Definition Value.h:75
@ NT_GNU_PROPERTY_TYPE_0
Definition ELF.h:1828
@ SHF_ALLOC
Definition ELF.h:1259
@ SHT_RISCV_ATTRIBUTES
Definition ELF.h:1242
@ SHT_NOTE
Definition ELF.h:1163
@ STB_LOCAL
Definition ELF.h:1421
@ STT_NOTYPE
Definition ELF.h:1433
@ STO_RISCV_VARIANT_CC
Definition ELF.h:733
@ GNU_PROPERTY_RISCV_FEATURE_1_AND
Definition ELF.h:1864
@ EF_RISCV_RVE
Definition ELF.h:718
@ EF_RISCV_RVC
Definition ELF.h:712
@ EF_RISCV_TSO
Definition ELF.h:719
@ EF_RISCV_FLOAT_ABI_SINGLE
Definition ELF.h:715
@ EF_RISCV_FLOAT_ABI_DOUBLE
Definition ELF.h:716
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
This is an optimization pass for GlobalISel generic memory operations.
MCStreamer * createRISCVELFStreamer(const Triple &, MCContext &C, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&MOW, std::unique_ptr< MCCodeEmitter > &&MCE)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39