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 // `j label` in `.option norelax; j label; .option relax; ...; label:` needs a 38 // relocation to ensure the jump target is correct after linking. This is due 39 // to a limitation that shouldForceRelocation has to make the decision upfront 40 // without knowing a possibly future .option relax. When RISCVAsmParser is used, 41 // its ParseInstruction may call setForceRelocs as well. 42 if (STI.hasFeature(RISCV::FeatureRelax)) 43 static_cast<RISCVAsmBackend &>(MAB).setForceRelocs(); 44 } 45 46 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { 47 return static_cast<RISCVELFStreamer &>(Streamer); 48 } 49 50 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {} 51 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {} 52 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {} 53 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {} 54 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} 55 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} 56 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} 57 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} 58 59 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 60 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); 61 } 62 63 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, 64 StringRef String) { 65 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); 66 } 67 68 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 69 unsigned IntValue, 70 StringRef StringValue) { 71 getStreamer().setAttributeItems(Attribute, IntValue, StringValue, 72 /*OverwriteExisting=*/true); 73 } 74 75 void RISCVTargetELFStreamer::finishAttributeSection() { 76 RISCVELFStreamer &S = getStreamer(); 77 if (S.Contents.empty()) 78 return; 79 80 S.emitAttributesSection(CurrentVendor, ".riscv.attributes", 81 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection); 82 } 83 84 void RISCVTargetELFStreamer::finish() { 85 RISCVTargetStreamer::finish(); 86 ELFObjectWriter &W = getStreamer().getWriter(); 87 RISCVABI::ABI ABI = getTargetABI(); 88 89 unsigned EFlags = W.getELFHeaderEFlags(); 90 91 if (hasRVC()) 92 EFlags |= ELF::EF_RISCV_RVC; 93 if (hasTSO()) 94 EFlags |= ELF::EF_RISCV_TSO; 95 96 switch (ABI) { 97 case RISCVABI::ABI_ILP32: 98 case RISCVABI::ABI_LP64: 99 break; 100 case RISCVABI::ABI_ILP32F: 101 case RISCVABI::ABI_LP64F: 102 EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; 103 break; 104 case RISCVABI::ABI_ILP32D: 105 case RISCVABI::ABI_LP64D: 106 EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; 107 break; 108 case RISCVABI::ABI_ILP32E: 109 case RISCVABI::ABI_LP64E: 110 EFlags |= ELF::EF_RISCV_RVE; 111 break; 112 case RISCVABI::ABI_Unknown: 113 llvm_unreachable("Improperly initialised target ABI"); 114 } 115 116 W.setELFHeaderEFlags(EFlags); 117 } 118 119 void RISCVTargetELFStreamer::reset() { 120 AttributeSection = nullptr; 121 } 122 123 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { 124 getStreamer().getAssembler().registerSymbol(Symbol); 125 cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC); 126 } 127 128 void RISCVELFStreamer::reset() { 129 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset(); 130 MCELFStreamer::reset(); 131 LastMappingSymbols.clear(); 132 LastEMS = EMS_None; 133 } 134 135 void RISCVELFStreamer::emitDataMappingSymbol() { 136 if (LastEMS == EMS_Data) 137 return; 138 emitMappingSymbol("$d"); 139 LastEMS = EMS_Data; 140 } 141 142 void RISCVELFStreamer::emitInstructionsMappingSymbol() { 143 if (LastEMS == EMS_Instructions) 144 return; 145 emitMappingSymbol("$x"); 146 LastEMS = EMS_Instructions; 147 } 148 149 void RISCVELFStreamer::emitMappingSymbol(StringRef Name) { 150 auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name)); 151 emitLabel(Symbol); 152 Symbol->setType(ELF::STT_NOTYPE); 153 Symbol->setBinding(ELF::STB_LOCAL); 154 } 155 156 void RISCVELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) { 157 // We have to keep track of the mapping symbol state of any sections we 158 // use. Each one should start off as EMS_None, which is provided as the 159 // default constructor by DenseMap::lookup. 160 LastMappingSymbols[getPreviousSection().first] = LastEMS; 161 LastEMS = LastMappingSymbols.lookup(Section); 162 163 MCELFStreamer::changeSection(Section, Subsection); 164 } 165 166 void RISCVELFStreamer::emitInstruction(const MCInst &Inst, 167 const MCSubtargetInfo &STI) { 168 emitInstructionsMappingSymbol(); 169 MCELFStreamer::emitInstruction(Inst, STI); 170 } 171 172 void RISCVELFStreamer::emitBytes(StringRef Data) { 173 emitDataMappingSymbol(); 174 MCELFStreamer::emitBytes(Data); 175 } 176 177 void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, 178 SMLoc Loc) { 179 emitDataMappingSymbol(); 180 MCELFStreamer::emitFill(NumBytes, FillValue, Loc); 181 } 182 183 void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, 184 SMLoc Loc) { 185 emitDataMappingSymbol(); 186 MCELFStreamer::emitValueImpl(Value, Size, Loc); 187 } 188 189 namespace llvm { 190 MCELFStreamer *createRISCVELFStreamer(MCContext &C, 191 std::unique_ptr<MCAsmBackend> MAB, 192 std::unique_ptr<MCObjectWriter> MOW, 193 std::unique_ptr<MCCodeEmitter> MCE) { 194 RISCVELFStreamer *S = 195 new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)); 196 return S; 197 } 198 } // namespace llvm 199