LLVM  12.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"
15 #include "RISCVMCTargetDesc.h"
16 #include "Utils/RISCVBaseInfo.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCSectionELF.h"
21 #include "llvm/Support/LEB128.h"
23 
24 using namespace llvm;
25 
26 // This part is for ELF object output.
28  const MCSubtargetInfo &STI)
29  : RISCVTargetStreamer(S), CurrentVendor("riscv") {
31  const FeatureBitset &Features = STI.getFeatureBits();
32  auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
33  RISCVABI::ABI ABI = MAB.getTargetABI();
34  assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
35 
36  unsigned EFlags = MCA.getELFHeaderEFlags();
37 
38  if (Features[RISCV::FeatureStdExtC])
39  EFlags |= ELF::EF_RISCV_RVC;
40 
41  switch (ABI) {
43  case RISCVABI::ABI_LP64:
44  break;
48  break;
52  break;
54  EFlags |= ELF::EF_RISCV_RVE;
55  break;
57  llvm_unreachable("Improperly initialised target ABI");
58  }
59 
60  MCA.setELFHeaderEFlags(EFlags);
61 }
62 
64  return static_cast<MCELFStreamer &>(Streamer);
65 }
66 
75 
76 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
77  setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
78 }
79 
80 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
81  StringRef String) {
82  setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
83 }
84 
85 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
86  unsigned IntValue,
87  StringRef StringValue) {
88  setAttributeItems(Attribute, IntValue, StringValue,
89  /*OverwriteExisting=*/true);
90 }
91 
92 void RISCVTargetELFStreamer::finishAttributeSection() {
93  if (Contents.empty())
94  return;
95 
96  if (AttributeSection) {
97  Streamer.SwitchSection(AttributeSection);
98  } else {
100  AttributeSection = MCA.getContext().getELFSection(
101  ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0);
102  Streamer.SwitchSection(AttributeSection);
103 
105  }
106 
107  // Vendor size + Vendor name + '\0'
108  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
109 
110  // Tag + Tag Size
111  const size_t TagHeaderSize = 1 + 4;
112 
113  const size_t ContentsSize = calculateContentSize();
114 
115  Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
116  Streamer.emitBytes(CurrentVendor);
117  Streamer.emitInt8(0); // '\0'
118 
120  Streamer.emitInt32(TagHeaderSize + ContentsSize);
121 
122  // Size should have been accounted for already, now
123  // emit each field as its type (ULEB or String).
124  for (AttributeItem item : Contents) {
125  Streamer.emitULEB128IntValue(item.Tag);
126  switch (item.Type) {
127  default:
128  llvm_unreachable("Invalid attribute type");
129  case AttributeType::Numeric:
130  Streamer.emitULEB128IntValue(item.IntValue);
131  break;
132  case AttributeType::Text:
133  Streamer.emitBytes(item.StringValue);
134  Streamer.emitInt8(0); // '\0'
135  break;
136  case AttributeType::NumericAndText:
137  Streamer.emitULEB128IntValue(item.IntValue);
138  Streamer.emitBytes(item.StringValue);
139  Streamer.emitInt8(0); // '\0'
140  break;
141  }
142  }
143 
144  Contents.clear();
145 }
146 
147 size_t RISCVTargetELFStreamer::calculateContentSize() const {
148  size_t Result = 0;
149  for (AttributeItem item : Contents) {
150  switch (item.Type) {
151  case AttributeType::Hidden:
152  break;
153  case AttributeType::Numeric:
154  Result += getULEB128Size(item.Tag);
155  Result += getULEB128Size(item.IntValue);
156  break;
157  case AttributeType::Text:
158  Result += getULEB128Size(item.Tag);
159  Result += item.StringValue.size() + 1; // string + '\0'
160  break;
161  case AttributeType::NumericAndText:
162  Result += getULEB128Size(item.Tag);
163  Result += getULEB128Size(item.IntValue);
164  Result += item.StringValue.size() + 1; // string + '\0';
165  break;
166  }
167  }
168  return Result;
169 }
void setELFHeaderEFlags(unsigned Flags)
Definition: MCAssembler.h:255
RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
void emitDirectiveOptionNoPIC() override
This class represents lattice values for constants.
Definition: AllocatorList.h:23
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:69
void emitDirectiveOptionRelax() override
void emitDirectiveOptionPush() override
MCContext & getContext() const
Definition: MCAssembler.h:284
const FeatureBitset & getFeatureBits() const
void emitDirectiveOptionPop() override
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:686
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
Streaming machine code generation interface.
Definition: MCStreamer.h:196
Container class for subtarget features.
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
MCAssembler & getAssembler()
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:144
unsigned getELFHeaderEFlags() const
ELF e_header flags.
Definition: MCAssembler.h:254
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:292
MCStreamer & Streamer
Definition: MCStreamer.h:92
void emitDirectiveOptionRVC() override
void emitDirectiveOptionPIC() override
void emitDirectiveOptionNoRVC() override
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:684
Generic base class for all target subtargets.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:469
LLVM Value Representation.
Definition: Value.h:74
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
void emitDirectiveOptionNoRelax() override