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 "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 auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
33 StringRef ABIName = MAB.getTargetOptions().getABIName();
34 // We have to recompute the ABI rather than casting STI to RISCVSubtarget
35 // since MC tools like llvm-mc call this when STI is MCSubtargetInfo instead.
36 // Using RISCVSubtarget requires a TargetMachine, which the MC-only tools
37 // deliberately don't link.
38 // TODO: Might be cleaner to have callers set the ABI instead of computing
39 // it twice which introduces a chance of it being out of sync.
40 if (auto ABIOrErr = RISCVABI::computeTargetABI(STI, ABIName)) {
41 setTargetABI(*ABIOrErr);
42 } else {
43 // Do not warn here and instead silently fall back to the default ABI:
44 // either RISCVSubtarget::initializeSubtargetDependencies() or
45 // RISCVAsmParser::onBeginOfFile() will print the message with proper
46 // contexts. Reporting here would just duplicate that diagnostic.
47 consumeError(ABIOrErr.takeError());
49 }
51
52 // Compute the initial ISA string. This serves two purposes:
53 // 1. Deduplication: subsequent .option arch/rvc/norvc directives compare
54 // against ArchString to avoid propagating redundant ISA updates.
55 // 2. Initial symbol: seed the streamer's active ISA so a "$x<ArchString>"
56 // mapping symbol is emitted before the first instruction, recording
57 // the full ISA in the object even when no .option directive is present.
59 InitialArchString = (*ParseResult)->toString();
60 ArchString = InitialArchString;
62 }
63}
64
66 std::unique_ptr<MCAsmBackend> MAB,
67 std::unique_ptr<MCObjectWriter> MOW,
68 std::unique_ptr<MCCodeEmitter> MCE)
69 : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
70
74
76 if (Arch == ArchString)
77 return;
78 ArchString = std::string(Arch);
80}
81
83 ArchStringStack.push_back(ArchString);
84}
85
87 if (!ArchStringStack.empty())
88 setArchString(ArchStringStack.pop_back_val());
89}
90
99
100void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
101 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
102}
103
104void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
106 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
107}
108
109void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
110 unsigned IntValue,
111 StringRef StringValue) {
112 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
113 /*OverwriteExisting=*/true);
114}
115
117 RISCVELFStreamer &S = getStreamer();
118 if (S.Contents.empty())
119 return;
120
121 S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
122 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
123}
124
129
130 unsigned EFlags = W.getELFHeaderEFlags();
131
132 if (hasRVC())
133 EFlags |= ELF::EF_RISCV_RVC;
134 if (hasTSO())
135 EFlags |= ELF::EF_RISCV_TSO;
136
137 switch (ABI) {
142 break;
148 break;
154 break;
159 EFlags |= ELF::EF_RISCV_RVE;
160 break;
162 llvm_unreachable("Improperly initialised target ABI");
163 }
164
165 W.setELFHeaderEFlags(EFlags);
166}
167
169 AttributeSection = nullptr;
170 ArchString = InitialArchString;
171 ArchStringStack.clear();
172 // Re-seed the streamer's active ISA so the first instruction after reset
173 // still records the full ISA via "$x<ISA>", matching the behaviour set up
174 // in the constructor.
175 if (!InitialArchString.empty())
176 getStreamer().setMappingSymbolArch(InitialArchString);
177}
178
183
186 LastMappingSymbols.clear();
187 LastEMS = EMS_None;
188 MappingSymbolArch.clear();
189 LastEmittedArch.clear();
190 LastEmittedArchInSection.clear();
191 // Call target streamer reset last: it may call setMappingSymbolArch to
192 // re-seed the initial ISA after our state has been cleared.
193 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
194}
195
196void RISCVELFStreamer::emitDataMappingSymbol() {
197 if (LastEMS == EMS_Data)
198 return;
199 emitMappingSymbol("$d");
200 LastEMS = EMS_Data;
201}
202
203void RISCVELFStreamer::emitInstructionsMappingSymbol() {
204 // Emit a mapping symbol at the start of each instruction run, and whenever
205 // the active ISA has changed since the last one emitted in this section.
206 // The symbol takes the form "$x<ISA>" when MappingSymbolArch is known, or
207 // plain "$x" as a fallback. The comparison with LastEmittedArch provides
208 // deduplication: repeating .option arch with the same ISA, or re-entering a
209 // section whose last mapping symbol already matches the active ISA, emits
210 // no redundant symbol.
211 bool NeedSymbol =
212 LastEMS != EMS_Instructions || LastEmittedArch != MappingSymbolArch;
213 if (NeedSymbol) {
214 if (MappingSymbolArch.empty())
215 emitMappingSymbol("$x");
216 else
217 emitMappingSymbol("$x" + MappingSymbolArch);
218 LastEmittedArch = MappingSymbolArch;
219 }
220 LastEMS = EMS_Instructions;
221}
222
223void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
224 auto *Symbol =
225 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
226 emitLabel(Symbol);
227 Symbol->setType(ELF::STT_NOTYPE);
228 Symbol->setBinding(ELF::STB_LOCAL);
229}
230
232 MappingSymbolArch = std::string(Arch);
233}
234
236 // We have to keep track of the mapping symbol state of any sections we
237 // use. Each one should start off as EMS_None, which is provided as the
238 // default constructor by DenseMap::lookup. The last ISA suffix emitted in
239 // each section is also preserved so that re-entering a section only emits a
240 // new "$x<ISA>" symbol when the active ISA has actually changed.
241 const MCSection *Prev = getPreviousSection().first;
242 LastMappingSymbols[Prev] = LastEMS;
243 LastEmittedArchInSection[Prev] = LastEmittedArch;
244 LastEMS = LastMappingSymbols.lookup(Section);
245 auto It = LastEmittedArchInSection.find(Section);
246 LastEmittedArch = It != LastEmittedArchInSection.end() ? It->second : "";
247
248 MCELFStreamer::changeSection(Section, Subsection);
249}
250
252 const MCSubtargetInfo &STI) {
253 emitInstructionsMappingSymbol();
255}
256
258 emitDataMappingSymbol();
260}
261
262void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
263 SMLoc Loc) {
264 emitDataMappingSymbol();
265 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
266}
267
269 SMLoc Loc) {
270 emitDataMappingSymbol();
272}
273
275 std::unique_ptr<MCAsmBackend> &&MAB,
276 std::unique_ptr<MCObjectWriter> &&MOW,
277 std::unique_ptr<MCCodeEmitter> &&MCE) {
278 return new RISCVELFStreamer(C, std::move(MAB), std::move(MOW),
279 std::move(MCE));
280}
281
283 const uint32_t Feature1And) {
284 MCStreamer &OutStreamer = getStreamer();
285 MCContext &Ctx = OutStreamer.getContext();
286
287 const Triple &Triple = Ctx.getTargetTriple();
288 Align NoteAlign;
289 uint64_t DescSize;
290 if (Triple.isArch64Bit()) {
291 NoteAlign = Align(8);
292 DescSize = 16;
293 } else {
295 NoteAlign = Align(4);
296 DescSize = 12;
297 }
298
299 assert(Ctx.getObjectFileType() == MCContext::Environment::IsELF);
300 MCSection *const NoteSection =
301 Ctx.getELFSection(".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
302 OutStreamer.pushSection();
303 OutStreamer.switchSection(NoteSection);
304
305 // Emit the note header
306 OutStreamer.emitValueToAlignment(NoteAlign);
307 OutStreamer.emitIntValue(4, 4); // n_namsz
308 OutStreamer.emitIntValue(DescSize, 4); // n_descsz
309 OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); // n_type
310 OutStreamer.emitBytes(StringRef("GNU", 4)); // n_name
311
312 // Emit n_desc field
313
314 // Emit the feature_1_and property
315 OutStreamer.emitIntValue(ELF::GNU_PROPERTY_RISCV_FEATURE_1_AND, 4); // pr_type
316 OutStreamer.emitIntValue(4, 4); // pr_datasz
317 OutStreamer.emitIntValue(Feature1And, 4); // pr_data
318 OutStreamer.emitValueToAlignment(NoteAlign); // pr_padding
319
320 OutStreamer.popSection();
321}
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
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:580
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:443
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.
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 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
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
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ NT_GNU_PROPERTY_TYPE_0
Definition ELF.h:1822
@ SHF_ALLOC
Definition ELF.h:1259
@ SHT_RISCV_ATTRIBUTES
Definition ELF.h:1242
@ SHT_NOTE
Definition ELF.h:1163
@ STB_LOCAL
Definition ELF.h:1415
@ STT_NOTYPE
Definition ELF.h:1427
@ STO_RISCV_VARIANT_CC
Definition ELF.h:733
@ GNU_PROPERTY_RISCV_FEATURE_1_AND
Definition ELF.h:1858
@ 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
Expected< ABI > computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
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)
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
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
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