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