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/Casting.h" 27 #include "llvm/Support/LEB128.h" 28 #include "llvm/Support/RISCVAttributes.h" 29 30 using namespace llvm; 31 32 // This part is for ELF object output. 33 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, 34 const MCSubtargetInfo &STI) 35 : RISCVTargetStreamer(S), CurrentVendor("riscv") { 36 MCAssembler &MCA = getStreamer().getAssembler(); 37 const FeatureBitset &Features = STI.getFeatureBits(); 38 auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend()); 39 RISCVABI::ABI ABI = MAB.getTargetABI(); 40 assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI"); 41 42 unsigned EFlags = MCA.getELFHeaderEFlags(); 43 44 if (Features[RISCV::FeatureStdExtC]) 45 EFlags |= ELF::EF_RISCV_RVC; 46 47 switch (ABI) { 48 case RISCVABI::ABI_ILP32: 49 case RISCVABI::ABI_LP64: 50 break; 51 case RISCVABI::ABI_ILP32F: 52 case RISCVABI::ABI_LP64F: 53 EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; 54 break; 55 case RISCVABI::ABI_ILP32D: 56 case RISCVABI::ABI_LP64D: 57 EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; 58 break; 59 case RISCVABI::ABI_ILP32E: 60 EFlags |= ELF::EF_RISCV_RVE; 61 break; 62 case RISCVABI::ABI_Unknown: 63 llvm_unreachable("Improperly initialised target ABI"); 64 } 65 66 MCA.setELFHeaderEFlags(EFlags); 67 } 68 69 MCELFStreamer &RISCVTargetELFStreamer::getStreamer() { 70 return static_cast<MCELFStreamer &>(Streamer); 71 } 72 73 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {} 74 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {} 75 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {} 76 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {} 77 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} 78 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} 79 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} 80 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} 81 82 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 83 setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); 84 } 85 86 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, 87 StringRef String) { 88 setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); 89 } 90 91 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 92 unsigned IntValue, 93 StringRef StringValue) { 94 setAttributeItems(Attribute, IntValue, StringValue, 95 /*OverwriteExisting=*/true); 96 } 97 98 void RISCVTargetELFStreamer::finishAttributeSection() { 99 if (Contents.empty()) 100 return; 101 102 if (AttributeSection) { 103 Streamer.SwitchSection(AttributeSection); 104 } else { 105 MCAssembler &MCA = getStreamer().getAssembler(); 106 AttributeSection = MCA.getContext().getELFSection( 107 ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0); 108 Streamer.SwitchSection(AttributeSection); 109 110 Streamer.emitInt8(ELFAttrs::Format_Version); 111 } 112 113 // Vendor size + Vendor name + '\0' 114 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 115 116 // Tag + Tag Size 117 const size_t TagHeaderSize = 1 + 4; 118 119 const size_t ContentsSize = calculateContentSize(); 120 121 Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize); 122 Streamer.emitBytes(CurrentVendor); 123 Streamer.emitInt8(0); // '\0' 124 125 Streamer.emitInt8(ELFAttrs::File); 126 Streamer.emitInt32(TagHeaderSize + ContentsSize); 127 128 // Size should have been accounted for already, now 129 // emit each field as its type (ULEB or String). 130 for (AttributeItem item : Contents) { 131 Streamer.emitULEB128IntValue(item.Tag); 132 switch (item.Type) { 133 default: 134 llvm_unreachable("Invalid attribute type"); 135 case AttributeType::Numeric: 136 Streamer.emitULEB128IntValue(item.IntValue); 137 break; 138 case AttributeType::Text: 139 Streamer.emitBytes(item.StringValue); 140 Streamer.emitInt8(0); // '\0' 141 break; 142 case AttributeType::NumericAndText: 143 Streamer.emitULEB128IntValue(item.IntValue); 144 Streamer.emitBytes(item.StringValue); 145 Streamer.emitInt8(0); // '\0' 146 break; 147 } 148 } 149 150 Contents.clear(); 151 } 152 153 size_t RISCVTargetELFStreamer::calculateContentSize() const { 154 size_t Result = 0; 155 for (AttributeItem item : Contents) { 156 switch (item.Type) { 157 case AttributeType::Hidden: 158 break; 159 case AttributeType::Numeric: 160 Result += getULEB128Size(item.Tag); 161 Result += getULEB128Size(item.IntValue); 162 break; 163 case AttributeType::Text: 164 Result += getULEB128Size(item.Tag); 165 Result += item.StringValue.size() + 1; // string + '\0' 166 break; 167 case AttributeType::NumericAndText: 168 Result += getULEB128Size(item.Tag); 169 Result += getULEB128Size(item.IntValue); 170 Result += item.StringValue.size() + 1; // string + '\0'; 171 break; 172 } 173 } 174 return Result; 175 } 176 177 namespace { 178 class RISCVELFStreamer : public MCELFStreamer { 179 static std::pair<unsigned, unsigned> getRelocPairForSize(unsigned Size) { 180 switch (Size) { 181 default: 182 llvm_unreachable("unsupported fixup size"); 183 case 1: 184 return std::make_pair(RISCV::fixup_riscv_add_8, RISCV::fixup_riscv_sub_8); 185 case 2: 186 return std::make_pair(RISCV::fixup_riscv_add_16, 187 RISCV::fixup_riscv_sub_16); 188 case 4: 189 return std::make_pair(RISCV::fixup_riscv_add_32, 190 RISCV::fixup_riscv_sub_32); 191 case 8: 192 return std::make_pair(RISCV::fixup_riscv_add_64, 193 RISCV::fixup_riscv_sub_64); 194 } 195 } 196 197 static bool requiresFixups(MCContext &C, const MCExpr *Value, 198 const MCExpr *&LHS, const MCExpr *&RHS) { 199 const auto *MBE = dyn_cast<MCBinaryExpr>(Value); 200 if (MBE == nullptr) 201 return false; 202 203 MCValue E; 204 if (!Value->evaluateAsRelocatable(E, nullptr, nullptr)) 205 return false; 206 if (E.getSymA() == nullptr || E.getSymB() == nullptr) 207 return false; 208 209 const auto &A = E.getSymA()->getSymbol(); 210 const auto &B = E.getSymB()->getSymbol(); 211 212 LHS = 213 MCBinaryExpr::create(MCBinaryExpr::Add, MCSymbolRefExpr::create(&A, C), 214 MCConstantExpr::create(E.getConstant(), C), C); 215 RHS = E.getSymB(); 216 217 return (A.isInSection() ? A.getSection().hasInstructions() 218 : !A.getName().empty()) || 219 (B.isInSection() ? B.getSection().hasInstructions() 220 : !B.getName().empty()); 221 } 222 223 public: 224 RISCVELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB, 225 std::unique_ptr<MCObjectWriter> MOW, 226 std::unique_ptr<MCCodeEmitter> MCE) 227 : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {} 228 229 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { 230 const MCExpr *A, *B; 231 if (!requiresFixups(getContext(), Value, A, B)) 232 return MCELFStreamer::emitValueImpl(Value, Size, Loc); 233 234 MCStreamer::emitValueImpl(Value, Size, Loc); 235 236 MCDataFragment *DF = getOrCreateDataFragment(); 237 flushPendingLabels(DF, DF->getContents().size()); 238 MCDwarfLineEntry::make(this, getCurrentSectionOnly()); 239 240 unsigned Add, Sub; 241 std::tie(Add, Sub) = getRelocPairForSize(Size); 242 243 DF->getFixups().push_back(MCFixup::create( 244 DF->getContents().size(), A, static_cast<MCFixupKind>(Add), Loc)); 245 DF->getFixups().push_back(MCFixup::create( 246 DF->getContents().size(), B, static_cast<MCFixupKind>(Sub), Loc)); 247 248 DF->getContents().resize(DF->getContents().size() + Size, 0); 249 } 250 }; 251 } // namespace 252 253 namespace llvm { 254 MCELFStreamer *createRISCVELFStreamer(MCContext &C, 255 std::unique_ptr<MCAsmBackend> MAB, 256 std::unique_ptr<MCObjectWriter> MOW, 257 std::unique_ptr<MCCodeEmitter> MCE, 258 bool RelaxAll) { 259 RISCVELFStreamer *S = 260 new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)); 261 S->getAssembler().setRelaxAll(RelaxAll); 262 return S; 263 } 264 } // namespace llvm 265