Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
35294 views
//===-- RISCVELFStreamer.cpp - RISC-V ELF Target Streamer Methods ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file provides RISC-V specific target streamer methods.9//10//===----------------------------------------------------------------------===//1112#include "RISCVELFStreamer.h"13#include "RISCVAsmBackend.h"14#include "RISCVBaseInfo.h"15#include "RISCVMCTargetDesc.h"16#include "llvm/BinaryFormat/ELF.h"17#include "llvm/MC/MCAsmBackend.h"18#include "llvm/MC/MCAssembler.h"19#include "llvm/MC/MCCodeEmitter.h"20#include "llvm/MC/MCContext.h"21#include "llvm/MC/MCObjectWriter.h"22#include "llvm/MC/MCSectionELF.h"23#include "llvm/MC/MCSubtargetInfo.h"24#include "llvm/MC/MCValue.h"25#include "llvm/Support/LEB128.h"26#include "llvm/Support/RISCVAttributes.h"2728using namespace llvm;2930// This part is for ELF object output.31RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,32const MCSubtargetInfo &STI)33: RISCVTargetStreamer(S), CurrentVendor("riscv") {34MCAssembler &MCA = getStreamer().getAssembler();35const FeatureBitset &Features = STI.getFeatureBits();36auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());37setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,38MAB.getTargetOptions().getABIName()));39setFlagsFromFeatures(STI);40// `j label` in `.option norelax; j label; .option relax; ...; label:` needs a41// relocation to ensure the jump target is correct after linking. This is due42// to a limitation that shouldForceRelocation has to make the decision upfront43// without knowing a possibly future .option relax. When RISCVAsmParser is used,44// its ParseInstruction may call setForceRelocs as well.45if (STI.hasFeature(RISCV::FeatureRelax))46static_cast<RISCVAsmBackend &>(MAB).setForceRelocs();47}4849RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {50return static_cast<RISCVELFStreamer &>(Streamer);51}5253void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}54void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}55void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}56void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}57void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}58void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}59void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}60void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}6162void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {63getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);64}6566void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,67StringRef String) {68getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);69}7071void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,72unsigned IntValue,73StringRef StringValue) {74getStreamer().setAttributeItems(Attribute, IntValue, StringValue,75/*OverwriteExisting=*/true);76}7778void RISCVTargetELFStreamer::finishAttributeSection() {79RISCVELFStreamer &S = getStreamer();80if (S.Contents.empty())81return;8283S.emitAttributesSection(CurrentVendor, ".riscv.attributes",84ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);85}8687void RISCVTargetELFStreamer::finish() {88RISCVTargetStreamer::finish();89ELFObjectWriter &W = getStreamer().getWriter();90RISCVABI::ABI ABI = getTargetABI();9192unsigned EFlags = W.getELFHeaderEFlags();9394if (hasRVC())95EFlags |= ELF::EF_RISCV_RVC;96if (hasTSO())97EFlags |= ELF::EF_RISCV_TSO;9899switch (ABI) {100case RISCVABI::ABI_ILP32:101case RISCVABI::ABI_LP64:102break;103case RISCVABI::ABI_ILP32F:104case RISCVABI::ABI_LP64F:105EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;106break;107case RISCVABI::ABI_ILP32D:108case RISCVABI::ABI_LP64D:109EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;110break;111case RISCVABI::ABI_ILP32E:112case RISCVABI::ABI_LP64E:113EFlags |= ELF::EF_RISCV_RVE;114break;115case RISCVABI::ABI_Unknown:116llvm_unreachable("Improperly initialised target ABI");117}118119W.setELFHeaderEFlags(EFlags);120}121122void RISCVTargetELFStreamer::reset() {123AttributeSection = nullptr;124}125126void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {127getStreamer().getAssembler().registerSymbol(Symbol);128cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);129}130131void RISCVELFStreamer::reset() {132static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();133MCELFStreamer::reset();134LastMappingSymbols.clear();135LastEMS = EMS_None;136}137138void RISCVELFStreamer::emitDataMappingSymbol() {139if (LastEMS == EMS_Data)140return;141emitMappingSymbol("$d");142LastEMS = EMS_Data;143}144145void RISCVELFStreamer::emitInstructionsMappingSymbol() {146if (LastEMS == EMS_Instructions)147return;148emitMappingSymbol("$x");149LastEMS = EMS_Instructions;150}151152void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {153auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));154emitLabel(Symbol);155Symbol->setType(ELF::STT_NOTYPE);156Symbol->setBinding(ELF::STB_LOCAL);157}158159void RISCVELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {160// We have to keep track of the mapping symbol state of any sections we161// use. Each one should start off as EMS_None, which is provided as the162// default constructor by DenseMap::lookup.163LastMappingSymbols[getPreviousSection().first] = LastEMS;164LastEMS = LastMappingSymbols.lookup(Section);165166MCELFStreamer::changeSection(Section, Subsection);167}168169void RISCVELFStreamer::emitInstruction(const MCInst &Inst,170const MCSubtargetInfo &STI) {171emitInstructionsMappingSymbol();172MCELFStreamer::emitInstruction(Inst, STI);173}174175void RISCVELFStreamer::emitBytes(StringRef Data) {176emitDataMappingSymbol();177MCELFStreamer::emitBytes(Data);178}179180void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,181SMLoc Loc) {182emitDataMappingSymbol();183MCELFStreamer::emitFill(NumBytes, FillValue, Loc);184}185186void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,187SMLoc Loc) {188emitDataMappingSymbol();189MCELFStreamer::emitValueImpl(Value, Size, Loc);190}191192namespace llvm {193MCELFStreamer *createRISCVELFStreamer(MCContext &C,194std::unique_ptr<MCAsmBackend> MAB,195std::unique_ptr<MCObjectWriter> MOW,196std::unique_ptr<MCCodeEmitter> MCE) {197RISCVELFStreamer *S =198new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));199return S;200}201} // namespace llvm202203204