//===-- RISCVELFStreamer.cpp - RISC-V ELF Target Streamer Methods ---------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file provides RISC-V specific target streamer methods. // //===----------------------------------------------------------------------===// #include "RISCVELFStreamer.h" #include "RISCVAsmBackend.h" #include "RISCVBaseInfo.h" #include "RISCVMCTargetDesc.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/RISCVAttributes.h" using namespace llvm; // This part is for ELF object output. RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) : RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) { MCAssembler &MCA = getStreamer().getAssembler(); const FeatureBitset &Features = STI.getFeatureBits(); auto &MAB = static_cast(MCA.getBackend()); setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features, MAB.getTargetOptions().getABIName())); } RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { return static_cast(Streamer); } void RISCVTargetELFStreamer::emitDirectiveOptionPush() {} void RISCVTargetELFStreamer::emitDirectiveOptionPop() {} void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {} void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); } void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, StringRef String) { getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); } void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) { getStreamer().setAttributeItems(Attribute, IntValue, StringValue, /*OverwriteExisting=*/true); } void RISCVTargetELFStreamer::finishAttributeSection() { RISCVELFStreamer &S = getStreamer(); if (S.Contents.empty()) return; S.emitAttributesSection(CurrentVendor, ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, AttributeSection); } void RISCVTargetELFStreamer::finish() { RISCVTargetStreamer::finish(); MCAssembler &MCA = getStreamer().getAssembler(); const FeatureBitset &Features = STI.getFeatureBits(); RISCVABI::ABI ABI = getTargetABI(); unsigned EFlags = MCA.getELFHeaderEFlags(); if (Features[RISCV::FeatureStdExtC]) EFlags |= ELF::EF_RISCV_RVC; if (Features[RISCV::FeatureStdExtZtso]) EFlags |= ELF::EF_RISCV_TSO; switch (ABI) { case RISCVABI::ABI_ILP32: case RISCVABI::ABI_LP64: break; case RISCVABI::ABI_ILP32F: case RISCVABI::ABI_LP64F: EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; break; case RISCVABI::ABI_ILP32D: case RISCVABI::ABI_LP64D: EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; break; case RISCVABI::ABI_ILP32E: case RISCVABI::ABI_LP64E: EFlags |= ELF::EF_RISCV_RVE; break; case RISCVABI::ABI_Unknown: llvm_unreachable("Improperly initialised target ABI"); } MCA.setELFHeaderEFlags(EFlags); } void RISCVTargetELFStreamer::reset() { AttributeSection = nullptr; } void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { getStreamer().getAssembler().registerSymbol(Symbol); cast(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC); } void RISCVELFStreamer::reset() { static_cast(getTargetStreamer())->reset(); MCELFStreamer::reset(); } namespace llvm { MCELFStreamer *createRISCVELFStreamer(MCContext &C, std::unique_ptr MAB, std::unique_ptr MOW, std::unique_ptr MCE, bool RelaxAll) { RISCVELFStreamer *S = new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)); S->getAssembler().setRelaxAll(RelaxAll); return S; } } // namespace llvm