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 if (RISCVABI::isRVE(ABI))
123 EFlags |= ELF::EF_RISCV_RVE;
124
125 if (RISCVABI::isSoftFP(ABI))
127 else if (RISCVABI::isSingleFP(ABI))
129 else if (RISCVABI::isDoubleFP(ABI))
131 else
133
134 W.setELFHeaderEFlags(EFlags);
135}
136
138 AttributeSection = nullptr;
139 ArchString = InitialArchString;
140 ArchStringStack.clear();
141 // Re-seed the streamer's active ISA so the first instruction after reset
142 // still records the full ISA via "$x<ISA>", matching the behaviour set up
143 // in the constructor.
144 if (!InitialArchString.empty())
145 getStreamer().setMappingSymbolArch(InitialArchString);
146}
147
152
155 LastMappingSymbols.clear();
156 LastEMS = EMS_None;
157 MappingSymbolArch.clear();
158 LastEmittedArch.clear();
159 LastEmittedArchInSection.clear();
160 // Call target streamer reset last: it may call setMappingSymbolArch to
161 // re-seed the initial ISA after our state has been cleared.
162 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
163}
164
165void RISCVELFStreamer::emitDataMappingSymbol() {
166 if (LastEMS == EMS_Data)
167 return;
168 emitMappingSymbol("$d");
169 LastEMS = EMS_Data;
170}
171
172void RISCVELFStreamer::emitInstructionsMappingSymbol() {
173 // Emit a mapping symbol at the start of each instruction run, and whenever
174 // the active ISA has changed since the last one emitted in this section.
175 // The symbol takes the form "$x<ISA>" when MappingSymbolArch is known, or
176 // plain "$x" as a fallback. The comparison with LastEmittedArch provides
177 // deduplication: repeating .option arch with the same ISA, or re-entering a
178 // section whose last mapping symbol already matches the active ISA, emits
179 // no redundant symbol.
180 bool NeedSymbol =
181 LastEMS != EMS_Instructions || LastEmittedArch != MappingSymbolArch;
182 if (NeedSymbol) {
183 if (MappingSymbolArch.empty())
184 emitMappingSymbol("$x");
185 else
186 emitMappingSymbol("$x" + MappingSymbolArch);
187 LastEmittedArch = MappingSymbolArch;
188 }
189 LastEMS = EMS_Instructions;
190}
191
192void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
193 auto *Symbol =
194 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
195 emitLabel(Symbol);
196 Symbol->setType(ELF::STT_NOTYPE);
197 Symbol->setBinding(ELF::STB_LOCAL);
198}
199
201 MappingSymbolArch = std::string(Arch);
202}
203
205 // We have to keep track of the mapping symbol state of any sections we
206 // use. Each one should start off as EMS_None, which is provided as the
207 // default constructor by DenseMap::lookup. The last ISA suffix emitted in
208 // each section is also preserved so that re-entering a section only emits a
209 // new "$x<ISA>" symbol when the active ISA has actually changed.
210 const MCSection *Cur = getCurrentSection().first;
211 LastMappingSymbols[Cur] = LastEMS;
212 LastEmittedArchInSection[Cur] = LastEmittedArch;
213 LastEMS = LastMappingSymbols.lookup(Section);
214 auto It = LastEmittedArchInSection.find(Section);
215 LastEmittedArch = It != LastEmittedArchInSection.end() ? It->second : "";
216
217 MCELFStreamer::changeSection(Section, Subsection);
218}
219
221 const MCSubtargetInfo &STI) {
222 emitInstructionsMappingSymbol();
224}
225
227 emitDataMappingSymbol();
229}
230
231void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
232 SMLoc Loc) {
233 emitDataMappingSymbol();
234 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
235}
236
238 SMLoc Loc) {
239 emitDataMappingSymbol();
241}
242
244 std::unique_ptr<MCAsmBackend> &&MAB,
245 std::unique_ptr<MCObjectWriter> &&MOW,
246 std::unique_ptr<MCCodeEmitter> &&MCE) {
247 return new RISCVELFStreamer(C, std::move(MAB), std::move(MOW),
248 std::move(MCE));
249}
250
252 const uint32_t Feature1And) {
253 MCStreamer &OutStreamer = getStreamer();
254 MCContext &Ctx = OutStreamer.getContext();
255
256 const Triple &Triple = Ctx.getTargetTriple();
257 Align NoteAlign;
258 uint64_t DescSize;
259 if (Triple.isArch64Bit()) {
260 NoteAlign = Align(8);
261 DescSize = 16;
262 } else {
264 NoteAlign = Align(4);
265 DescSize = 12;
266 }
267
268 assert(Ctx.getObjectFileType() == MCContext::Environment::IsELF);
269 MCSection *const NoteSection =
270 Ctx.getELFSection(".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
271 OutStreamer.pushSection();
272 OutStreamer.switchSection(NoteSection);
273
274 // Emit the note header
275 OutStreamer.emitValueToAlignment(NoteAlign);
276 OutStreamer.emitIntValue(4, 4); // n_namsz
277 OutStreamer.emitIntValue(DescSize, 4); // n_descsz
278 OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); // n_type
279 OutStreamer.emitBytes(StringRef("GNU", 4)); // n_name
280
281 // Emit n_desc field
282
283 // Emit the feature_1_and property
284 OutStreamer.emitIntValue(ELF::GNU_PROPERTY_RISCV_FEATURE_1_AND, 4); // pr_type
285 OutStreamer.emitIntValue(4, 4); // pr_datasz
286 OutStreamer.emitIntValue(Feature1And, 4); // pr_data
287 OutStreamer.emitValueToAlignment(NoteAlign); // pr_padding
288
289 OutStreamer.popSection();
290}
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, uint64_t IntValue, StringRef StringValue, bool OverwriteExisting)
ELFObjectWriter & getWriter()
void reset() override
state management
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
void setAttributeItem(unsigned Attribute, uint64_t Value, bool OverwriteExisting)
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:1829
LLVM_ABI bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition Triple.cpp:1833
LLVM Value Representation.
Definition Value.h:75
@ NT_GNU_PROPERTY_TYPE_0
Definition ELF.h:1636
@ SHF_ALLOC
Definition ELF.h:1067
@ SHT_RISCV_ATTRIBUTES
Definition ELF.h:1050
@ SHT_NOTE
Definition ELF.h:971
@ STB_LOCAL
Definition ELF.h:1229
@ STT_NOTYPE
Definition ELF.h:1241
@ STO_RISCV_VARIANT_CC
Definition ELF.h:541
@ GNU_PROPERTY_RISCV_FEATURE_1_AND
Definition ELF.h:1672
@ EF_RISCV_RVE
Definition ELF.h:526
@ EF_RISCV_FLOAT_ABI_SOFT
Definition ELF.h:522
@ EF_RISCV_RVC
Definition ELF.h:520
@ EF_RISCV_TSO
Definition ELF.h:527
@ EF_RISCV_FLOAT_ABI_SINGLE
Definition ELF.h:523
@ EF_RISCV_FLOAT_ABI_DOUBLE
Definition ELF.h:524
bool isRVE(ABI TargetABI)
bool isSingleFP(ABI TargetABI)
bool isDoubleFP(ABI TargetABI)
bool isSoftFP(ABI TargetABI)
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