1 //===-- RISCVELFStreamer.cpp - RISC-V 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 RISC-V 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/MCELFObjectWriter.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 25 using namespace llvm; 26 27 // This part is for ELF object output. 28 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, 29 const MCSubtargetInfo &STI) 30 : RISCVTargetStreamer(S), CurrentVendor("riscv") { 31 MCAssembler &MCA = getStreamer().getAssembler(); 32 const FeatureBitset &Features = STI.getFeatureBits(); 33 auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend()); 34 setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features, 35 MAB.getTargetOptions().getABIName())); 36 setFlagsFromFeatures(STI); 37 } 38 39 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { 40 return static_cast<RISCVELFStreamer &>(Streamer); 41 } 42 43 void RISCVTargetELFStreamer::emitDirectiveOptionExact() {} 44 void RISCVTargetELFStreamer::emitDirectiveOptionNoExact() {} 45 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {} 46 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {} 47 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {} 48 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {} 49 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} 50 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} 51 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} 52 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} 53 54 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 55 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); 56 } 57 58 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, 59 StringRef String) { 60 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); 61 } 62 63 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 64 unsigned IntValue, 65 StringRef StringValue) { 66 getStreamer().setAttributeItems(Attribute, IntValue, StringValue, 67 /*OverwriteExisting=*/true); 68 } 69 70 void RISCVTargetELFStreamer::finishAttributeSection() { 71 RISCVELFStreamer &S = getStreamer(); 72 if (S.Contents.empty()) 73 return; 74 75 S.emitAttributesSection(CurrentVendor, ".riscv.attributes", 76 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection); 77 } 78 79 void RISCVTargetELFStreamer::finish() { 80 RISCVTargetStreamer::finish(); 81 ELFObjectWriter &W = getStreamer().getWriter(); 82 RISCVABI::ABI ABI = getTargetABI(); 83 84 unsigned EFlags = W.getELFHeaderEFlags(); 85 86 if (hasRVC()) 87 EFlags |= ELF::EF_RISCV_RVC; 88 if (hasTSO()) 89 EFlags |= ELF::EF_RISCV_TSO; 90 91 switch (ABI) { 92 case RISCVABI::ABI_ILP32: 93 case RISCVABI::ABI_LP64: 94 break; 95 case RISCVABI::ABI_ILP32F: 96 case RISCVABI::ABI_LP64F: 97 EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; 98 break; 99 case RISCVABI::ABI_ILP32D: 100 case RISCVABI::ABI_LP64D: 101 EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; 102 break; 103 case RISCVABI::ABI_ILP32E: 104 case RISCVABI::ABI_LP64E: 105 EFlags |= ELF::EF_RISCV_RVE; 106 break; 107 case RISCVABI::ABI_Unknown: 108 llvm_unreachable("Improperly initialised target ABI"); 109 } 110 111 W.setELFHeaderEFlags(EFlags); 112 } 113 114 void RISCVTargetELFStreamer::reset() { 115 AttributeSection = nullptr; 116 } 117 118 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { 119 getStreamer().getAssembler().registerSymbol(Symbol); 120 cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC); 121 } 122 123 void RISCVELFStreamer::reset() { 124 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset(); 125 MCELFStreamer::reset(); 126 LastMappingSymbols.clear(); 127 LastEMS = EMS_None; 128 } 129 130 void RISCVELFStreamer::emitDataMappingSymbol() { 131 if (LastEMS == EMS_Data) 132 return; 133 emitMappingSymbol("$d"); 134 LastEMS = EMS_Data; 135 } 136 137 void RISCVELFStreamer::emitInstructionsMappingSymbol() { 138 if (LastEMS == EMS_Instructions) 139 return; 140 emitMappingSymbol("$x"); 141 LastEMS = EMS_Instructions; 142 } 143 144 void RISCVELFStreamer::emitMappingSymbol(StringRef Name) { 145 auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name)); 146 emitLabel(Symbol); 147 Symbol->setType(ELF::STT_NOTYPE); 148 Symbol->setBinding(ELF::STB_LOCAL); 149 } 150 151 void RISCVELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) { 152 // We have to keep track of the mapping symbol state of any sections we 153 // use. Each one should start off as EMS_None, which is provided as the 154 // default constructor by DenseMap::lookup. 155 LastMappingSymbols[getPreviousSection().first] = LastEMS; 156 LastEMS = LastMappingSymbols.lookup(Section); 157 158 MCELFStreamer::changeSection(Section, Subsection); 159 } 160 161 void RISCVELFStreamer::emitInstruction(const MCInst &Inst, 162 const MCSubtargetInfo &STI) { 163 emitInstructionsMappingSymbol(); 164 MCELFStreamer::emitInstruction(Inst, STI); 165 } 166 167 void RISCVELFStreamer::emitBytes(StringRef Data) { 168 emitDataMappingSymbol(); 169 MCELFStreamer::emitBytes(Data); 170 } 171 172 void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, 173 SMLoc Loc) { 174 emitDataMappingSymbol(); 175 MCELFStreamer::emitFill(NumBytes, FillValue, Loc); 176 } 177 178 void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, 179 SMLoc Loc) { 180 emitDataMappingSymbol(); 181 MCELFStreamer::emitValueImpl(Value, Size, Loc); 182 } 183 184 MCStreamer *llvm::createRISCVELFStreamer(const Triple &, MCContext &C, 185 std::unique_ptr<MCAsmBackend> &&MAB, 186 std::unique_ptr<MCObjectWriter> &&MOW, 187 std::unique_ptr<MCCodeEmitter> &&MCE) { 188 return new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), 189 std::move(MCE)); 190 } 191