LLVM 23.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 "RISCVAsmBackend.h"
15#include "RISCVBaseInfo.h"
16#include "RISCVMCTargetDesc.h"
19#include "llvm/MC/MCAssembler.h"
21#include "llvm/MC/MCContext.h"
24
25using namespace llvm;
26
27// This part is for ELF object output.
29 const MCSubtargetInfo &STI)
30 : RISCVTargetStreamer(S), CurrentVendor("riscv") {
32 const FeatureBitset &Features = STI.getFeatureBits();
33 auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
35 MAB.getTargetOptions().getABIName()));
37
38 // Compute the initial ISA string. This serves two purposes:
39 // 1. Deduplication: subsequent .option arch/rvc/norvc directives compare
40 // against ArchString to avoid propagating redundant ISA updates.
41 // 2. Initial symbol: seed the streamer's active ISA so a "$x<ArchString>"
42 // mapping symbol is emitted before the first instruction, recording
43 // the full ISA in the object even when no .option directive is present.
45 STI.hasFeature(RISCV::Feature64Bit), Features)) {
46 InitialArchString = (*ParseResult)->toString();
47 ArchString = InitialArchString;
49 }
50}
51
53 std::unique_ptr<MCAsmBackend> MAB,
54 std::unique_ptr<MCObjectWriter> MOW,
55 std::unique_ptr<MCCodeEmitter> MCE)
56 : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
57
61
63 if (Arch == ArchString)
64 return;
65 ArchString = std::string(Arch);
67}
68
70 ArchStringStack.push_back(ArchString);
71}
72
74 if (!ArchStringStack.empty())
75 setArchString(ArchStringStack.pop_back_val());
76}
77
86
87void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
88 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
89}
90
91void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
93 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
94}
95
96void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
97 unsigned IntValue,
98 StringRef StringValue) {
99 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
100 /*OverwriteExisting=*/true);
101}
102
104 RISCVELFStreamer &S = getStreamer();
105 if (S.Contents.empty())
106 return;
107
108 S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
109 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
110}
111
116
117 unsigned EFlags = W.getELFHeaderEFlags();
118
119 if (hasRVC())
120 EFlags |= ELF::EF_RISCV_RVC;
121 if (hasTSO())
122 EFlags |= ELF::EF_RISCV_TSO;
123
124 switch (ABI) {
127 break;
131 break;
135 break;
138 EFlags |= ELF::EF_RISCV_RVE;
139 break;
141 llvm_unreachable("Improperly initialised target ABI");
142 }
143
144 W.setELFHeaderEFlags(EFlags);
145}
146
148 AttributeSection = nullptr;
149 ArchString = InitialArchString;
150 ArchStringStack.clear();
151 // Re-seed the streamer's active ISA so the first instruction after reset
152 // still records the full ISA via "$x<ISA>", matching the behaviour set up
153 // in the constructor.
154 if (!InitialArchString.empty())
155 getStreamer().setMappingSymbolArch(InitialArchString);
156}
157
162
165 LastMappingSymbols.clear();
166 LastEMS = EMS_None;
167 MappingSymbolArch.clear();
168 LastEmittedArch.clear();
169 LastEmittedArchInSection.clear();
170 // Call target streamer reset last: it may call setMappingSymbolArch to
171 // re-seed the initial ISA after our state has been cleared.
172 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
173}
174
175void RISCVELFStreamer::emitDataMappingSymbol() {
176 if (LastEMS == EMS_Data)
177 return;
178 emitMappingSymbol("$d");
179 LastEMS = EMS_Data;
180}
181
182void RISCVELFStreamer::emitInstructionsMappingSymbol() {
183 // Emit a mapping symbol at the start of each instruction run, and whenever
184 // the active ISA has changed since the last one emitted in this section.
185 // The symbol takes the form "$x<ISA>" when MappingSymbolArch is known, or
186 // plain "$x" as a fallback. The comparison with LastEmittedArch provides
187 // deduplication: repeating .option arch with the same ISA, or re-entering a
188 // section whose last mapping symbol already matches the active ISA, emits
189 // no redundant symbol.
190 bool NeedSymbol =
191 LastEMS != EMS_Instructions || LastEmittedArch != MappingSymbolArch;
192 if (NeedSymbol) {
193 if (MappingSymbolArch.empty())
194 emitMappingSymbol("$x");
195 else
196 emitMappingSymbol("$x" + MappingSymbolArch);
197 LastEmittedArch = MappingSymbolArch;
198 }
199 LastEMS = EMS_Instructions;
200}
201
202void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
203 auto *Symbol =
204 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
205 emitLabel(Symbol);
206 Symbol->setType(ELF::STT_NOTYPE);
207 Symbol->setBinding(ELF::STB_LOCAL);
208}
209
211 MappingSymbolArch = std::string(Arch);
212}
213
215 // We have to keep track of the mapping symbol state of any sections we
216 // use. Each one should start off as EMS_None, which is provided as the
217 // default constructor by DenseMap::lookup. The last ISA suffix emitted in
218 // each section is also preserved so that re-entering a section only emits a
219 // new "$x<ISA>" symbol when the active ISA has actually changed.
220 const MCSection *Prev = getPreviousSection().first;
221 LastMappingSymbols[Prev] = LastEMS;
222 LastEmittedArchInSection[Prev] = LastEmittedArch;
223 LastEMS = LastMappingSymbols.lookup(Section);
224 auto It = LastEmittedArchInSection.find(Section);
225 LastEmittedArch = It != LastEmittedArchInSection.end() ? It->second : "";
226
227 MCELFStreamer::changeSection(Section, Subsection);
228}
229
231 const MCSubtargetInfo &STI) {
232 emitInstructionsMappingSymbol();
234}
235
237 emitDataMappingSymbol();
239}
240
241void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
242 SMLoc Loc) {
243 emitDataMappingSymbol();
244 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
245}
246
248 SMLoc Loc) {
249 emitDataMappingSymbol();
251}
252
254 std::unique_ptr<MCAsmBackend> &&MAB,
255 std::unique_ptr<MCObjectWriter> &&MOW,
256 std::unique_ptr<MCCodeEmitter> &&MCE) {
257 return new RISCVELFStreamer(C, std::move(MAB), std::move(MOW),
258 std::move(MCE));
259}
260
262 const uint32_t Feature1And) {
263 MCStreamer &OutStreamer = getStreamer();
264 MCContext &Ctx = OutStreamer.getContext();
265
266 const Triple &Triple = Ctx.getTargetTriple();
267 Align NoteAlign;
268 uint64_t DescSize;
269 if (Triple.isArch64Bit()) {
270 NoteAlign = Align(8);
271 DescSize = 16;
272 } else {
274 NoteAlign = Align(4);
275 DescSize = 12;
276 }
277
278 assert(Ctx.getObjectFileType() == MCContext::Environment::IsELF);
279 MCSection *const NoteSection =
280 Ctx.getELFSection(".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
281 OutStreamer.pushSection();
282 OutStreamer.switchSection(NoteSection);
283
284 // Emit the note header
285 OutStreamer.emitValueToAlignment(NoteAlign);
286 OutStreamer.emitIntValue(4, 4); // n_namsz
287 OutStreamer.emitIntValue(DescSize, 4); // n_descsz
288 OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); // n_type
289 OutStreamer.emitBytes(StringRef("GNU", 4)); // n_name
290
291 // Emit n_desc field
292
293 // Emit the feature_1_and property
294 OutStreamer.emitIntValue(ELF::GNU_PROPERTY_RISCV_FEATURE_1_AND, 4); // pr_type
295 OutStreamer.emitIntValue(4, 4); // pr_datasz
296 OutStreamer.emitIntValue(Feature1And, 4); // pr_data
297 OutStreamer.emitValueToAlignment(NoteAlign); // pr_padding
298
299 OutStreamer.popSection();
300}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
Container class for subtarget features.
MCAsmBackend & getBackend() const
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:569
Streaming machine code generation interface.
Definition MCStreamer.h:222
MCSectionSubPair getPreviousSection() const
Return the previous section that the streamer is emitting code to.
Definition MCStreamer.h:433
virtual bool popSection()
Restore the current and previous section from the section stack.
MCContext & getContext() const
Definition MCStreamer.h:323
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:333
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:450
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
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 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
void setFlagsFromFeatures(const MCSubtargetInfo &STI)
void setTargetABI(RISCVABI::ABI ABI)
Represents a location in source code.
Definition SMLoc.h:22
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition Triple.cpp:2029
LLVM_ABI bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition Triple.cpp:2033
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ NT_GNU_PROPERTY_TYPE_0
Definition ELF.h:1811
@ SHF_ALLOC
Definition ELF.h:1249
@ SHT_RISCV_ATTRIBUTES
Definition ELF.h:1232
@ SHT_NOTE
Definition ELF.h:1154
@ STB_LOCAL
Definition ELF.h:1405
@ STT_NOTYPE
Definition ELF.h:1417
@ STO_RISCV_VARIANT_CC
Definition ELF.h:731
@ GNU_PROPERTY_RISCV_FEATURE_1_AND
Definition ELF.h:1847
@ EF_RISCV_RVE
Definition ELF.h:716
@ EF_RISCV_RVC
Definition ELF.h:710
@ EF_RISCV_TSO
Definition ELF.h:717
@ EF_RISCV_FLOAT_ABI_SINGLE
Definition ELF.h:713
@ EF_RISCV_FLOAT_ABI_DOUBLE
Definition ELF.h:714
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)
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)
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
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:1917
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39