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"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCValue.h"
26 #include "llvm/Support/LEB128.h"
27 #include "llvm/Support/RISCVAttributes.h"
28 
29 using namespace llvm;
30 
31 // This part is for ELF object output.
32 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
33                                                const MCSubtargetInfo &STI)
34     : RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) {
35   MCAssembler &MCA = getStreamer().getAssembler();
36   const FeatureBitset &Features = STI.getFeatureBits();
37   auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
38   setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
39                                           MAB.getTargetOptions().getABIName()));
40 }
41 
42 MCELFStreamer &RISCVTargetELFStreamer::getStreamer() {
43   return static_cast<MCELFStreamer &>(Streamer);
44 }
45 
46 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
47 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
48 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
49 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
50 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
51 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
52 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
53 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
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 {
78     MCAssembler &MCA = getStreamer().getAssembler();
79     AttributeSection = MCA.getContext().getELFSection(
80         ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0);
81     Streamer.switchSection(AttributeSection);
82 
83     Streamer.emitInt8(ELFAttrs::Format_Version);
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 
98   Streamer.emitInt8(ELFAttrs::File);
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 
150 void RISCVTargetELFStreamer::finish() {
151   RISCVTargetStreamer::finish();
152   MCAssembler &MCA = getStreamer().getAssembler();
153   const FeatureBitset &Features = STI.getFeatureBits();
154   RISCVABI::ABI ABI = getTargetABI();
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;
165   case RISCVABI::ABI_ILP32F:
166   case RISCVABI::ABI_LP64F:
167     EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
168     break;
169   case RISCVABI::ABI_ILP32D:
170   case RISCVABI::ABI_LP64D:
171     EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
172     break;
173   case RISCVABI::ABI_ILP32E:
174     EFlags |= ELF::EF_RISCV_RVE;
175     break;
176   case RISCVABI::ABI_Unknown:
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,
198                             RISCV::fixup_riscv_sub_16);
199     case 4:
200       return std::make_pair(RISCV::fixup_riscv_add_32,
201                             RISCV::fixup_riscv_sub_32);
202     case 8:
203       return std::make_pair(RISCV::fixup_riscv_add_64,
204                             RISCV::fixup_riscv_sub_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 =
232         MCBinaryExpr::create(MCBinaryExpr::Add, MCSymbolRefExpr::create(&A, C),
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();
249     MCELFStreamer::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 {
283 MCELFStreamer *createRISCVELFStreamer(MCContext &C,
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
294