LLVM  15.0.0git
RISCVELFStreamer.cpp
Go to the documentation of this file.
1 //===-- RISCVELFStreamer.cpp - RISCV 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 RISCV specific target streamer methods.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVELFStreamer.h"
14 #include "RISCVAsmBackend.h"
15 #include "RISCVBaseInfo.h"
16 #include "RISCVMCTargetDesc.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCObjectWriter.h"
23 #include "llvm/MC/MCSectionELF.h"
25 #include "llvm/MC/MCValue.h"
26 #include "llvm/Support/LEB128.h"
28 
29 using namespace llvm;
30 
31 // This part is for ELF object output.
33  const MCSubtargetInfo &STI)
34  : RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) {
36  const FeatureBitset &Features = STI.getFeatureBits();
37  auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
39  MAB.getTargetOptions().getABIName()));
40 }
41 
43  return static_cast<MCELFStreamer &>(Streamer);
44 }
45 
54 
55 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
56  setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
57 }
58 
59 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
60  StringRef String) {
61  setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
62 }
63 
64 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
65  unsigned IntValue,
66  StringRef StringValue) {
67  setAttributeItems(Attribute, IntValue, StringValue,
68  /*OverwriteExisting=*/true);
69 }
70 
71 void RISCVTargetELFStreamer::finishAttributeSection() {
72  if (Contents.empty())
73  return;
74 
75  if (AttributeSection) {
76  Streamer.switchSection(AttributeSection);
77  } else {
79  AttributeSection = MCA.getContext().getELFSection(
80  ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0);
81  Streamer.switchSection(AttributeSection);
82 
84  }
85 
86  // Vendor size + Vendor name + '\0'
87  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
88 
89  // Tag + Tag Size
90  const size_t TagHeaderSize = 1 + 4;
91 
92  const size_t ContentsSize = calculateContentSize();
93 
94  Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
95  Streamer.emitBytes(CurrentVendor);
96  Streamer.emitInt8(0); // '\0'
97 
99  Streamer.emitInt32(TagHeaderSize + ContentsSize);
100 
101  // Size should have been accounted for already, now
102  // emit each field as its type (ULEB or String).
103  for (AttributeItem item : Contents) {
104  Streamer.emitULEB128IntValue(item.Tag);
105  switch (item.Type) {
106  default:
107  llvm_unreachable("Invalid attribute type");
108  case AttributeType::Numeric:
109  Streamer.emitULEB128IntValue(item.IntValue);
110  break;
111  case AttributeType::Text:
112  Streamer.emitBytes(item.StringValue);
113  Streamer.emitInt8(0); // '\0'
114  break;
115  case AttributeType::NumericAndText:
116  Streamer.emitULEB128IntValue(item.IntValue);
117  Streamer.emitBytes(item.StringValue);
118  Streamer.emitInt8(0); // '\0'
119  break;
120  }
121  }
122 
123  Contents.clear();
124 }
125 
126 size_t RISCVTargetELFStreamer::calculateContentSize() const {
127  size_t Result = 0;
128  for (AttributeItem item : Contents) {
129  switch (item.Type) {
130  case AttributeType::Hidden:
131  break;
132  case AttributeType::Numeric:
133  Result += getULEB128Size(item.Tag);
134  Result += getULEB128Size(item.IntValue);
135  break;
136  case AttributeType::Text:
137  Result += getULEB128Size(item.Tag);
138  Result += item.StringValue.size() + 1; // string + '\0'
139  break;
140  case AttributeType::NumericAndText:
141  Result += getULEB128Size(item.Tag);
142  Result += getULEB128Size(item.IntValue);
143  Result += item.StringValue.size() + 1; // string + '\0';
144  break;
145  }
146  }
147  return Result;
148 }
149 
153  const FeatureBitset &Features = STI.getFeatureBits();
155 
156  unsigned EFlags = MCA.getELFHeaderEFlags();
157 
158  if (Features[RISCV::FeatureStdExtC])
159  EFlags |= ELF::EF_RISCV_RVC;
160 
161  switch (ABI) {
162  case RISCVABI::ABI_ILP32:
163  case RISCVABI::ABI_LP64:
164  break;
166  case RISCVABI::ABI_LP64F:
168  break;
170  case RISCVABI::ABI_LP64D:
172  break;
174  EFlags |= ELF::EF_RISCV_RVE;
175  break;
177  llvm_unreachable("Improperly initialised target ABI");
178  }
179 
180  MCA.setELFHeaderEFlags(EFlags);
181 }
182 
183 void RISCVTargetELFStreamer::reset() {
184  AttributeSection = nullptr;
185  Contents.clear();
186 }
187 
188 namespace {
189 class RISCVELFStreamer : public MCELFStreamer {
190  static std::pair<unsigned, unsigned> getRelocPairForSize(unsigned Size) {
191  switch (Size) {
192  default:
193  llvm_unreachable("unsupported fixup size");
194  case 1:
195  return std::make_pair(RISCV::fixup_riscv_add_8, RISCV::fixup_riscv_sub_8);
196  case 2:
197  return std::make_pair(RISCV::fixup_riscv_add_16,
199  case 4:
200  return std::make_pair(RISCV::fixup_riscv_add_32,
202  case 8:
203  return std::make_pair(RISCV::fixup_riscv_add_64,
205  }
206  }
207 
208  static bool requiresFixups(MCContext &C, const MCExpr *Value,
209  const MCExpr *&LHS, const MCExpr *&RHS) {
210  auto IsMetadataOrEHFrameSection = [](const MCSection &S) -> bool {
211  // Additionally check .apple_names/.apple_types. They are fixed-size and
212  // do not need fixups. llvm-dwarfdump --apple-names does not process
213  // R_RISCV_{ADD,SUB}32 in them.
214  return S.getKind().isMetadata() || S.getName() == ".eh_frame" ||
215  S.getName() == ".apple_names" || S.getName() == ".apple_types";
216  };
217 
218  const auto *MBE = dyn_cast<MCBinaryExpr>(Value);
219  if (MBE == nullptr)
220  return false;
221 
222  MCValue E;
223  if (!Value->evaluateAsRelocatable(E, nullptr, nullptr))
224  return false;
225  if (E.getSymA() == nullptr || E.getSymB() == nullptr)
226  return false;
227 
228  const auto &A = E.getSymA()->getSymbol();
229  const auto &B = E.getSymB()->getSymbol();
230 
231  LHS =
233  MCConstantExpr::create(E.getConstant(), C), C);
234  RHS = E.getSymB();
235 
236  // TODO: when available, R_RISCV_n_PCREL should be preferred.
237 
238  // Avoid pairwise relocations for symbolic difference in debug and .eh_frame
239  if (A.isInSection())
240  return !IsMetadataOrEHFrameSection(A.getSection());
241  if (B.isInSection())
242  return !IsMetadataOrEHFrameSection(B.getSection());
243  // as well as for absolute symbols.
244  return !A.getName().empty() || !B.getName().empty();
245  }
246 
247  void reset() override {
248  static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
250  }
251 
252 public:
253  RISCVELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
254  std::unique_ptr<MCObjectWriter> MOW,
255  std::unique_ptr<MCCodeEmitter> MCE)
256  : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
257 
258  void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
259  const MCExpr *A, *B;
260  if (!requiresFixups(getContext(), Value, A, B))
261  return MCELFStreamer::emitValueImpl(Value, Size, Loc);
262 
263  MCStreamer::emitValueImpl(Value, Size, Loc);
264 
265  MCDataFragment *DF = getOrCreateDataFragment();
266  flushPendingLabels(DF, DF->getContents().size());
267  MCDwarfLineEntry::make(this, getCurrentSectionOnly());
268 
269  unsigned Add, Sub;
270  std::tie(Add, Sub) = getRelocPairForSize(Size);
271 
272  DF->getFixups().push_back(MCFixup::create(
273  DF->getContents().size(), A, static_cast<MCFixupKind>(Add), Loc));
274  DF->getFixups().push_back(MCFixup::create(
275  DF->getContents().size(), B, static_cast<MCFixupKind>(Sub), Loc));
276 
277  DF->getContents().resize(DF->getContents().size() + Size, 0);
278  }
279 };
280 } // namespace
281 
282 namespace llvm {
284  std::unique_ptr<MCAsmBackend> MAB,
285  std::unique_ptr<MCObjectWriter> MOW,
286  std::unique_ptr<MCCodeEmitter> MCE,
287  bool RelaxAll) {
288  RISCVELFStreamer *S =
289  new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));
290  S->getAssembler().setRelaxAll(RelaxAll);
291  return S;
292 }
293 } // namespace llvm
llvm::RISCVTargetELFStreamer::emitDirectiveOptionPush
void emitDirectiveOptionPush() override
Definition: RISCVELFStreamer.cpp:46
llvm::MCAssembler::getBackend
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:329
llvm::RISCVABI::ABI_LP64F
@ ABI_LP64F
Definition: RISCVBaseInfo.h:354
llvm::MCAssembler::getELFHeaderEFlags
unsigned getELFHeaderEFlags() const
ELF e_header flags.
Definition: MCAssembler.h:276
ABI
Generic address nodes are lowered to some combination of target independent and machine specific ABI
Definition: Relocation.txt:34
llvm::createRISCVELFStreamer
MCELFStreamer * createRISCVELFStreamer(MCContext &C, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > MOW, std::unique_ptr< MCCodeEmitter > MCE, bool RelaxAll)
Definition: RISCVELFStreamer.cpp:283
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
RISCVELFStreamer.h
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:76
llvm::Attribute
Definition: Attributes.h:65
MCCodeEmitter.h
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
MCSectionELF.h
llvm::MCStreamer::emitInt8
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:736
llvm::MCFixup::create
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
llvm::MCBinaryExpr::Add
@ Add
Addition.
Definition: MCExpr.h:484
MCAssembler.h
llvm::RISCV::fixup_riscv_sub_64
@ fixup_riscv_sub_64
Definition: RISCVFixupKinds.h:100
llvm::MCStreamer::emitValueImpl
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
Definition: MCStreamer.cpp:1204
llvm::getULEB128Size
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19
llvm::MCStreamer::emitInt32
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:738
llvm::RISCVTargetELFStreamer::emitDirectiveOptionNoRelax
void emitDirectiveOptionNoRelax() override
Definition: RISCVELFStreamer.cpp:53
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
RISCVAttributes.h
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::RISCV::fixup_riscv_add_32
@ fixup_riscv_add_32
Definition: RISCVFixupKinds.h:91
llvm::MCELFStreamer::reset
void reset() override
state management
Definition: MCELFStreamer.h:40
llvm::RISCVTargetELFStreamer::finish
void finish() override
Definition: RISCVELFStreamer.cpp:150
llvm::RISCVABI::ABI_ILP32
@ ABI_ILP32
Definition: RISCVBaseInfo.h:349
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::RISCVTargetELFStreamer::emitDirectiveOptionPIC
void emitDirectiveOptionPIC() override
Definition: RISCVELFStreamer.cpp:48
llvm::RISCVABI::ABI_LP64
@ ABI_LP64
Definition: RISCVBaseInfo.h:353
ELF.h
llvm::MCELFStreamer
Definition: MCELFStreamer.h:31
MCAsmBackend.h
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MCAssembler::getContext
MCContext & getContext() const
Definition: MCAssembler.h:321
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::MCSubtargetInfo::getTargetTriple
const Triple & getTargetTriple() const
Definition: MCSubtargetInfo.h:108
MCContext.h
llvm::RISCVTargetELFStreamer::emitDirectiveOptionPop
void emitDirectiveOptionPop() override
Definition: RISCVELFStreamer.cpp:47
llvm::MCStreamer::switchSection
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Definition: MCStreamer.cpp:1225
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCContext::getELFSection
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:563
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::RISCVABI::ABI_ILP32D
@ ABI_ILP32D
Definition: RISCVBaseInfo.h:351
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
llvm::RISCVABI::ABI_ILP32E
@ ABI_ILP32E
Definition: RISCVBaseInfo.h:352
RISCVMCTargetDesc.h
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::ELFAttrs::Format_Version
@ Format_Version
Definition: ELFAttributes.h:33
RISCVAsmBackend.h
llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE
@ EF_RISCV_FLOAT_ABI_DOUBLE
Definition: ELF.h:667
llvm::RISCV::fixup_riscv_sub_8
@ fixup_riscv_sub_8
Definition: RISCVFixupKinds.h:78
llvm::MCAssembler
Definition: MCAssembler.h:73
llvm::MCTargetStreamer::Streamer
MCStreamer & Streamer
Definition: MCStreamer.h:95
LEB128.h
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::RISCVTargetELFStreamer::emitDirectiveOptionRelax
void emitDirectiveOptionRelax() override
Definition: RISCVELFStreamer.cpp:52
llvm::MCBinaryExpr::create
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:183
llvm::MCAssembler::setELFHeaderEFlags
void setELFHeaderEFlags(unsigned Flags)
Definition: MCAssembler.h:277
llvm::RISCVTargetELFStreamer::emitDirectiveOptionNoRVC
void emitDirectiveOptionNoRVC() override
Definition: RISCVELFStreamer.cpp:51
llvm::move
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:1675
llvm::RISCV::fixup_riscv_add_8
@ fixup_riscv_add_8
Definition: RISCVFixupKinds.h:75
llvm::RISCVTargetELFStreamer::RISCVTargetELFStreamer
RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
Definition: RISCVELFStreamer.cpp:32
llvm::MCObjectStreamer::getAssembler
MCAssembler & getAssembler()
Definition: MCObjectStreamer.h:128
llvm::MCELFStreamer::emitValueImpl
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.
Definition: MCELFStreamer.cpp:358
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MCDwarfLineEntry::make
static void make(MCStreamer *MCOS, MCSection *Section)
Definition: MCDwarf.cpp:91
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::RISCV::fixup_riscv_sub_16
@ fixup_riscv_sub_16
Definition: RISCVFixupKinds.h:86
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::RISCVTargetStreamer::finish
void finish() override
Definition: RISCVTargetStreamer.cpp:24
llvm::RISCVTargetELFStreamer::emitDirectiveOptionNoPIC
void emitDirectiveOptionNoPIC() override
Definition: RISCVELFStreamer.cpp:49
llvm::RISCVTargetStreamer::setTargetABI
void setTargetABI(RISCVABI::ABI ABI)
Definition: RISCVTargetStreamer.cpp:42
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
MCObjectWriter.h
llvm::RISCVTargetELFStreamer::getStreamer
MCELFStreamer & getStreamer()
Definition: RISCVELFStreamer.cpp:42
llvm::RISCVABI::ABI_LP64D
@ ABI_LP64D
Definition: RISCVBaseInfo.h:355
std
Definition: BitVector.h:851
llvm::RISCV::fixup_riscv_sub_32
@ fixup_riscv_sub_32
Definition: RISCVFixupKinds.h:94
llvm::ELF::EF_RISCV_RVE
@ EF_RISCV_RVE
Definition: ELF.h:669
llvm::RISCVABI::computeTargetABI
ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, StringRef ABIName)
Definition: RISCVBaseInfo.cpp:37
llvm::RISCV::fixup_riscv_add_64
@ fixup_riscv_add_64
Definition: RISCVFixupKinds.h:97
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
llvm::RISCV::fixup_riscv_add_16
@ fixup_riscv_add_16
Definition: RISCVFixupKinds.h:83
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:185
MCValue.h
RISCVBaseInfo.h
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
llvm::MCStreamer::emitULEB128IntValue
void emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
Definition: MCStreamer.cpp:162
llvm::ELF::SHT_RISCV_ATTRIBUTES
@ SHT_RISCV_ATTRIBUTES
Definition: ELF.h:1023
llvm::RISCVABI::ABI_Unknown
@ ABI_Unknown
Definition: RISCVBaseInfo.h:356
llvm::ELFAttrs::File
@ File
Definition: ELFAttributes.h:26
llvm::MCStreamer::emitBytes
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Definition: MCStreamer.cpp:1202
llvm::RISCVAsmBackend
Definition: RISCVAsmBackend.h:24
llvm::RISCVTargetELFStreamer::emitDirectiveOptionRVC
void emitDirectiveOptionRVC() override
Definition: RISCVELFStreamer.cpp:50
llvm::RISCVABI::ABI_ILP32F
@ ABI_ILP32F
Definition: RISCVBaseInfo.h:350
llvm::RISCVTargetStreamer
Definition: RISCVTargetStreamer.h:20
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:36
llvm::MCDataFragment
Fragment for data and encoded instructions.
Definition: MCFragment.h:241
llvm::ELF::EF_RISCV_RVC
@ EF_RISCV_RVC
Definition: ELF.h:663
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::RISCVTargetStreamer::getTargetABI
RISCVABI::ABI getTargetABI() const
Definition: RISCVTargetStreamer.h:44
llvm::RISCVABI::ABI
ABI
Definition: RISCVBaseInfo.h:348
llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE
@ EF_RISCV_FLOAT_ABI_SINGLE
Definition: ELF.h:666