LLVM  14.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/MCCodeEmitter.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCObjectWriter.h"
22 #include "llvm/MC/MCSectionELF.h"
24 #include "llvm/MC/MCValue.h"
25 #include "llvm/Support/LEB128.h"
27 
28 using namespace llvm;
29 
30 // This part is for ELF object output.
32  const MCSubtargetInfo &STI)
33  : RISCVTargetStreamer(S), CurrentVendor("riscv") {
35  const FeatureBitset &Features = STI.getFeatureBits();
36  auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
37  RISCVABI::ABI ABI = MAB.getTargetABI();
38  assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
39 
40  unsigned EFlags = MCA.getELFHeaderEFlags();
41 
42  if (Features[RISCV::FeatureStdExtC])
43  EFlags |= ELF::EF_RISCV_RVC;
44 
45  switch (ABI) {
47  case RISCVABI::ABI_LP64:
48  break;
52  break;
56  break;
58  EFlags |= ELF::EF_RISCV_RVE;
59  break;
61  llvm_unreachable("Improperly initialised target ABI");
62  }
63 
64  MCA.setELFHeaderEFlags(EFlags);
65 }
66 
68  return static_cast<MCELFStreamer &>(Streamer);
69 }
70 
79 
80 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
81  setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
82 }
83 
84 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
85  StringRef String) {
86  setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
87 }
88 
89 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
90  unsigned IntValue,
91  StringRef StringValue) {
92  setAttributeItems(Attribute, IntValue, StringValue,
93  /*OverwriteExisting=*/true);
94 }
95 
96 void RISCVTargetELFStreamer::finishAttributeSection() {
97  if (Contents.empty())
98  return;
99 
100  if (AttributeSection) {
101  Streamer.SwitchSection(AttributeSection);
102  } else {
104  AttributeSection = MCA.getContext().getELFSection(
105  ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0);
106  Streamer.SwitchSection(AttributeSection);
107 
109  }
110 
111  // Vendor size + Vendor name + '\0'
112  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
113 
114  // Tag + Tag Size
115  const size_t TagHeaderSize = 1 + 4;
116 
117  const size_t ContentsSize = calculateContentSize();
118 
119  Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
120  Streamer.emitBytes(CurrentVendor);
121  Streamer.emitInt8(0); // '\0'
122 
124  Streamer.emitInt32(TagHeaderSize + ContentsSize);
125 
126  // Size should have been accounted for already, now
127  // emit each field as its type (ULEB or String).
128  for (AttributeItem item : Contents) {
129  Streamer.emitULEB128IntValue(item.Tag);
130  switch (item.Type) {
131  default:
132  llvm_unreachable("Invalid attribute type");
133  case AttributeType::Numeric:
134  Streamer.emitULEB128IntValue(item.IntValue);
135  break;
136  case AttributeType::Text:
137  Streamer.emitBytes(item.StringValue);
138  Streamer.emitInt8(0); // '\0'
139  break;
140  case AttributeType::NumericAndText:
141  Streamer.emitULEB128IntValue(item.IntValue);
142  Streamer.emitBytes(item.StringValue);
143  Streamer.emitInt8(0); // '\0'
144  break;
145  }
146  }
147 
148  Contents.clear();
149 }
150 
151 size_t RISCVTargetELFStreamer::calculateContentSize() const {
152  size_t Result = 0;
153  for (AttributeItem item : Contents) {
154  switch (item.Type) {
155  case AttributeType::Hidden:
156  break;
157  case AttributeType::Numeric:
158  Result += getULEB128Size(item.Tag);
159  Result += getULEB128Size(item.IntValue);
160  break;
161  case AttributeType::Text:
162  Result += getULEB128Size(item.Tag);
163  Result += item.StringValue.size() + 1; // string + '\0'
164  break;
165  case AttributeType::NumericAndText:
166  Result += getULEB128Size(item.Tag);
167  Result += getULEB128Size(item.IntValue);
168  Result += item.StringValue.size() + 1; // string + '\0';
169  break;
170  }
171  }
172  return Result;
173 }
174 
175 namespace {
176 class RISCVELFStreamer : public MCELFStreamer {
177  static std::pair<unsigned, unsigned> getRelocPairForSize(unsigned Size) {
178  switch (Size) {
179  default:
180  llvm_unreachable("unsupported fixup size");
181  case 1:
182  return std::make_pair(RISCV::fixup_riscv_add_8, RISCV::fixup_riscv_sub_8);
183  case 2:
184  return std::make_pair(RISCV::fixup_riscv_add_16,
186  case 4:
187  return std::make_pair(RISCV::fixup_riscv_add_32,
189  case 8:
190  return std::make_pair(RISCV::fixup_riscv_add_64,
192  }
193  }
194 
195  static bool requiresFixups(MCContext &C, const MCExpr *Value,
196  const MCExpr *&LHS, const MCExpr *&RHS) {
197  const auto *MBE = dyn_cast<MCBinaryExpr>(Value);
198  if (MBE == nullptr)
199  return false;
200 
201  MCValue E;
202  if (!Value->evaluateAsRelocatable(E, nullptr, nullptr))
203  return false;
204  if (E.getSymA() == nullptr || E.getSymB() == nullptr)
205  return false;
206 
207  const auto &A = E.getSymA()->getSymbol();
208  const auto &B = E.getSymB()->getSymbol();
209 
210  LHS =
212  MCConstantExpr::create(E.getConstant(), C), C);
213  RHS = E.getSymB();
214 
215  return (A.isInSection() ? A.getSection().hasInstructions()
216  : !A.getName().empty()) ||
217  (B.isInSection() ? B.getSection().hasInstructions()
218  : !B.getName().empty());
219  }
220 
221 public:
222  RISCVELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
223  std::unique_ptr<MCObjectWriter> MOW,
224  std::unique_ptr<MCCodeEmitter> MCE)
225  : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
226 
227  void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
228  const MCExpr *A, *B;
229  if (!requiresFixups(getContext(), Value, A, B))
231 
233 
234  MCDataFragment *DF = getOrCreateDataFragment();
235  flushPendingLabels(DF, DF->getContents().size());
236  MCDwarfLineEntry::make(this, getCurrentSectionOnly());
237 
238  unsigned Add, Sub;
239  std::tie(Add, Sub) = getRelocPairForSize(Size);
240 
241  DF->getFixups().push_back(MCFixup::create(
242  DF->getContents().size(), A, static_cast<MCFixupKind>(Add), Loc));
243  DF->getFixups().push_back(MCFixup::create(
244  DF->getContents().size(), B, static_cast<MCFixupKind>(Sub), Loc));
245 
246  DF->getContents().resize(DF->getContents().size() + Size, 0);
247  }
248 };
249 } // namespace
250 
251 namespace llvm {
253  std::unique_ptr<MCAsmBackend> MAB,
254  std::unique_ptr<MCObjectWriter> MOW,
255  std::unique_ptr<MCCodeEmitter> MCE,
256  bool RelaxAll) {
257  RISCVELFStreamer *S =
258  new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));
259  S->getAssembler().setRelaxAll(RelaxAll);
260  return S;
261 }
262 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::RISCVTargetELFStreamer::emitDirectiveOptionPush
void emitDirectiveOptionPush() override
Definition: RISCVELFStreamer.cpp:71
llvm::MCAssembler::getBackend
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:300
llvm::RISCVABI::ABI_LP64F
@ ABI_LP64F
Definition: RISCVBaseInfo.h:301
llvm::MCAssembler::getELFHeaderEFlags
unsigned getELFHeaderEFlags() const
ELF e_header flags.
Definition: MCAssembler.h:262
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:252
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
RISCVELFStreamer.h
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::Attribute
Definition: Attributes.h:52
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:705
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:483
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:1191
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:707
llvm::RISCVTargetELFStreamer::emitDirectiveOptionNoRelax
void emitDirectiveOptionNoRelax() override
Definition: RISCVELFStreamer.cpp:78
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
RISCVAttributes.h
llvm::RISCV::fixup_riscv_add_32
@ fixup_riscv_add_32
Definition: RISCVFixupKinds.h:91
llvm::ELF::EF_RISCV_RVC
@ EF_RISCV_RVC
Definition: ELF.h:649
llvm::RISCVABI::ABI_ILP32
@ ABI_ILP32
Definition: RISCVBaseInfo.h:296
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::RISCVTargetELFStreamer::emitDirectiveOptionPIC
void emitDirectiveOptionPIC() override
Definition: RISCVELFStreamer.cpp:73
llvm::RISCVABI::ABI_LP64
@ ABI_LP64
Definition: RISCVBaseInfo.h:300
ELF.h
llvm::MCELFStreamer
Definition: MCELFStreamer.h:24
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:292
llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE
@ EF_RISCV_FLOAT_ABI_SINGLE
Definition: ELF.h:652
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
MCContext.h
llvm::RISCVTargetELFStreamer::emitDirectiveOptionPop
void emitDirectiveOptionPop() override
Definition: RISCVELFStreamer.cpp:72
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCContext::getELFSection
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:540
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::RISCVABI::ABI_ILP32D
@ ABI_ILP32D
Definition: RISCVBaseInfo.h:298
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:111
llvm::RISCVABI::ABI_ILP32E
@ ABI_ILP32E
Definition: RISCVBaseInfo.h:299
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::RISCV::fixup_riscv_sub_8
@ fixup_riscv_sub_8
Definition: RISCVFixupKinds.h:78
llvm::MCAssembler
Definition: MCAssembler.h:60
llvm::MCTargetStreamer::Streamer
MCStreamer & Streamer
Definition: MCStreamer.h:93
llvm::ELF::SHT_RISCV_ATTRIBUTES
@ SHT_RISCV_ATTRIBUTES
Definition: ELF.h:981
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:77
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::ELF::EF_RISCV_FLOAT_ABI_DOUBLE
@ EF_RISCV_FLOAT_ABI_DOUBLE
Definition: ELF.h:653
llvm::MCAssembler::setELFHeaderEFlags
void setELFHeaderEFlags(unsigned Flags)
Definition: MCAssembler.h:263
llvm::RISCVTargetELFStreamer::emitDirectiveOptionNoRVC
void emitDirectiveOptionNoRVC() override
Definition: RISCVELFStreamer.cpp:76
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:1609
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:31
llvm::MCObjectStreamer::getAssembler
MCAssembler & getAssembler()
Definition: MCObjectStreamer.h:112
llvm::ELF::EF_RISCV_RVE
@ EF_RISCV_RVE
Definition: ELF.h:655
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:357
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:134
llvm::RISCV::fixup_riscv_sub_16
@ fixup_riscv_sub_16
Definition: RISCVFixupKinds.h:86
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::RISCVTargetELFStreamer::emitDirectiveOptionNoPIC
void emitDirectiveOptionNoPIC() override
Definition: RISCVELFStreamer.cpp:74
MCObjectWriter.h
llvm::RISCVTargetELFStreamer::getStreamer
MCELFStreamer & getStreamer()
Definition: RISCVELFStreamer.cpp:67
llvm::RISCVABI::ABI_LP64D
@ ABI_LP64D
Definition: RISCVBaseInfo.h:302
std
Definition: BitVector.h:838
llvm::RISCV::fixup_riscv_sub_32
@ fixup_riscv_sub_32
Definition: RISCVFixupKinds.h:94
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:385
llvm::RISCV::fixup_riscv_add_16
@ fixup_riscv_add_16
Definition: RISCVFixupKinds.h:83
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:183
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:161
llvm::RISCVABI::ABI_Unknown
@ ABI_Unknown
Definition: RISCVBaseInfo.h:303
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:1189
llvm::RISCVAsmBackend
Definition: RISCVAsmBackend.h:24
llvm::RISCVTargetELFStreamer::emitDirectiveOptionRVC
void emitDirectiveOptionRVC() override
Definition: RISCVELFStreamer.cpp:75
llvm::RISCVABI::ABI_ILP32F
@ ABI_ILP32F
Definition: RISCVBaseInfo.h:297
llvm::RISCVTargetStreamer
Definition: RISCVTargetStreamer.h:19
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:37
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::MCDataFragment
Fragment for data and encoded instructions.
Definition: MCFragment.h:242
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:1212
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::RISCVABI::ABI
ABI
Definition: RISCVBaseInfo.h:295