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