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 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { 43 return static_cast<RISCVELFStreamer &>(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 if (Features[RISCV::FeatureStdExtZtso]) 161 EFlags |= ELF::EF_RISCV_TSO; 162 163 switch (ABI) { 164 case RISCVABI::ABI_ILP32: 165 case RISCVABI::ABI_LP64: 166 break; 167 case RISCVABI::ABI_ILP32F: 168 case RISCVABI::ABI_LP64F: 169 EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; 170 break; 171 case RISCVABI::ABI_ILP32D: 172 case RISCVABI::ABI_LP64D: 173 EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; 174 break; 175 case RISCVABI::ABI_ILP32E: 176 EFlags |= ELF::EF_RISCV_RVE; 177 break; 178 case RISCVABI::ABI_Unknown: 179 llvm_unreachable("Improperly initialised target ABI"); 180 } 181 182 MCA.setELFHeaderEFlags(EFlags); 183 } 184 185 void RISCVTargetELFStreamer::reset() { 186 AttributeSection = nullptr; 187 Contents.clear(); 188 } 189 190 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { 191 getStreamer().getAssembler().registerSymbol(Symbol); 192 cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC); 193 } 194 195 std::pair<unsigned, unsigned> 196 RISCVELFStreamer::getRelocPairForSize(unsigned Size) { 197 switch (Size) { 198 default: 199 llvm_unreachable("unsupported fixup size"); 200 case 1: 201 return std::make_pair(RISCV::fixup_riscv_add_8, RISCV::fixup_riscv_sub_8); 202 case 2: 203 return std::make_pair(RISCV::fixup_riscv_add_16, RISCV::fixup_riscv_sub_16); 204 case 4: 205 return std::make_pair(RISCV::fixup_riscv_add_32, RISCV::fixup_riscv_sub_32); 206 case 8: 207 return std::make_pair(RISCV::fixup_riscv_add_64, RISCV::fixup_riscv_sub_64); 208 } 209 } 210 211 bool RISCVELFStreamer::requiresFixups(MCContext &C, const MCExpr *Value, 212 const MCExpr *&LHS, const MCExpr *&RHS) { 213 const auto *MBE = dyn_cast<MCBinaryExpr>(Value); 214 if (MBE == nullptr) 215 return false; 216 217 MCValue E; 218 if (!Value->evaluateAsRelocatable(E, nullptr, nullptr)) 219 return false; 220 if (E.getSymA() == nullptr || E.getSymB() == nullptr) 221 return false; 222 223 const auto &A = E.getSymA()->getSymbol(); 224 const auto &B = E.getSymB()->getSymbol(); 225 226 LHS = MCBinaryExpr::create(MCBinaryExpr::Add, MCSymbolRefExpr::create(&A, C), 227 MCConstantExpr::create(E.getConstant(), C), C); 228 RHS = E.getSymB(); 229 230 // If either symbol is in a text section, we need to delay the relocation 231 // evaluation as relaxation may alter the size of the symbol. 232 // 233 // Unfortunately, we cannot identify if the symbol was built with relaxation 234 // as we do not track the state per symbol or section. However, BFD will 235 // always emit the relocation and so we follow suit which avoids the need to 236 // track that information. 237 if (A.isInSection() && A.getSection().getKind().isText()) 238 return true; 239 if (B.isInSection() && B.getSection().getKind().isText()) 240 return true; 241 242 // If A is undefined and B is defined, we should emit ADD/SUB for A-B. 243 // Unfortunately, A may be defined later, but this requiresFixups call has to 244 // eagerly make a decision. For now, emit ADD/SUB unless A is .L*. This 245 // heuristic handles many temporary label differences for .debug_* and 246 // .apple_types sections. 247 // 248 // TODO Implement delayed relocation decision. 249 if (!A.isInSection() && !A.isTemporary() && B.isInSection()) 250 return true; 251 252 // Support cross-section symbolic differences ... 253 return A.isInSection() && B.isInSection() && 254 A.getSection().getName() != B.getSection().getName(); 255 } 256 257 void RISCVELFStreamer::reset() { 258 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset(); 259 MCELFStreamer::reset(); 260 } 261 262 void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, 263 SMLoc Loc) { 264 const MCExpr *A, *B; 265 if (!requiresFixups(getContext(), Value, A, B)) 266 return MCELFStreamer::emitValueImpl(Value, Size, Loc); 267 268 MCStreamer::emitValueImpl(Value, Size, Loc); 269 270 MCDataFragment *DF = getOrCreateDataFragment(); 271 flushPendingLabels(DF, DF->getContents().size()); 272 MCDwarfLineEntry::make(this, getCurrentSectionOnly()); 273 274 unsigned Add, Sub; 275 std::tie(Add, Sub) = getRelocPairForSize(Size); 276 277 DF->getFixups().push_back(MCFixup::create( 278 DF->getContents().size(), A, static_cast<MCFixupKind>(Add), Loc)); 279 DF->getFixups().push_back(MCFixup::create( 280 DF->getContents().size(), B, static_cast<MCFixupKind>(Sub), Loc)); 281 282 DF->getContents().resize(DF->getContents().size() + Size, 0); 283 } 284 285 namespace llvm { 286 MCELFStreamer *createRISCVELFStreamer(MCContext &C, 287 std::unique_ptr<MCAsmBackend> MAB, 288 std::unique_ptr<MCObjectWriter> MOW, 289 std::unique_ptr<MCCodeEmitter> MCE, 290 bool RelaxAll) { 291 RISCVELFStreamer *S = 292 new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)); 293 S->getAssembler().setRelaxAll(RelaxAll); 294 return S; 295 } 296 } // namespace llvm 297