Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
35293 views
//===-- RISCVELFObjectWriter.cpp - RISC-V ELF Writer ----------------------===//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//===----------------------------------------------------------------------===//78#include "MCTargetDesc/RISCVFixupKinds.h"9#include "MCTargetDesc/RISCVMCExpr.h"10#include "MCTargetDesc/RISCVMCTargetDesc.h"11#include "llvm/MC/MCContext.h"12#include "llvm/MC/MCELFObjectWriter.h"13#include "llvm/MC/MCFixup.h"14#include "llvm/MC/MCObjectWriter.h"15#include "llvm/MC/MCValue.h"16#include "llvm/Support/ErrorHandling.h"1718using namespace llvm;1920namespace {21class RISCVELFObjectWriter : public MCELFObjectTargetWriter {22public:23RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit);2425~RISCVELFObjectWriter() override;2627// Return true if the given relocation must be with a symbol rather than28// section plus offset.29bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,30unsigned Type) const override {31// TODO: this is very conservative, update once RISC-V psABI requirements32// are clarified.33return true;34}3536protected:37unsigned getRelocType(MCContext &Ctx, const MCValue &Target,38const MCFixup &Fixup, bool IsPCRel) const override;39};40}4142RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)43: MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV,44/*HasRelocationAddend*/ true) {}4546RISCVELFObjectWriter::~RISCVELFObjectWriter() = default;4748unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,49const MCValue &Target,50const MCFixup &Fixup,51bool IsPCRel) const {52const MCExpr *Expr = Fixup.getValue();53// Determine the type of the relocation54unsigned Kind = Fixup.getTargetKind();55if (Kind >= FirstLiteralRelocationKind)56return Kind - FirstLiteralRelocationKind;57if (IsPCRel) {58switch (Kind) {59default:60Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");61return ELF::R_RISCV_NONE;62case FK_Data_4:63case FK_PCRel_4:64return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT65? ELF::R_RISCV_PLT3266: ELF::R_RISCV_32_PCREL;67case RISCV::fixup_riscv_pcrel_hi20:68return ELF::R_RISCV_PCREL_HI20;69case RISCV::fixup_riscv_pcrel_lo12_i:70return ELF::R_RISCV_PCREL_LO12_I;71case RISCV::fixup_riscv_pcrel_lo12_s:72return ELF::R_RISCV_PCREL_LO12_S;73case RISCV::fixup_riscv_got_hi20:74return ELF::R_RISCV_GOT_HI20;75case RISCV::fixup_riscv_tls_got_hi20:76return ELF::R_RISCV_TLS_GOT_HI20;77case RISCV::fixup_riscv_tls_gd_hi20:78return ELF::R_RISCV_TLS_GD_HI20;79case RISCV::fixup_riscv_tlsdesc_hi20:80return ELF::R_RISCV_TLSDESC_HI20;81case RISCV::fixup_riscv_tlsdesc_load_lo12:82return ELF::R_RISCV_TLSDESC_LOAD_LO12;83case RISCV::fixup_riscv_tlsdesc_add_lo12:84return ELF::R_RISCV_TLSDESC_ADD_LO12;85case RISCV::fixup_riscv_tlsdesc_call:86return ELF::R_RISCV_TLSDESC_CALL;87case RISCV::fixup_riscv_jal:88return ELF::R_RISCV_JAL;89case RISCV::fixup_riscv_branch:90return ELF::R_RISCV_BRANCH;91case RISCV::fixup_riscv_rvc_jump:92return ELF::R_RISCV_RVC_JUMP;93case RISCV::fixup_riscv_rvc_branch:94return ELF::R_RISCV_RVC_BRANCH;95case RISCV::fixup_riscv_call:96return ELF::R_RISCV_CALL_PLT;97case RISCV::fixup_riscv_call_plt:98return ELF::R_RISCV_CALL_PLT;99}100}101102switch (Kind) {103default:104Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");105return ELF::R_RISCV_NONE;106case RISCV::fixup_riscv_tlsdesc_load_lo12:107return ELF::R_RISCV_TLSDESC_LOAD_LO12;108case RISCV::fixup_riscv_tlsdesc_add_lo12:109return ELF::R_RISCV_TLSDESC_ADD_LO12;110case RISCV::fixup_riscv_tlsdesc_call:111return ELF::R_RISCV_TLSDESC_CALL;112113case FK_Data_1:114Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");115return ELF::R_RISCV_NONE;116case FK_Data_2:117Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");118return ELF::R_RISCV_NONE;119case FK_Data_4:120if (Expr->getKind() == MCExpr::Target &&121cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)122return ELF::R_RISCV_32_PCREL;123if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL)124return ELF::R_RISCV_GOT32_PCREL;125return ELF::R_RISCV_32;126case FK_Data_8:127return ELF::R_RISCV_64;128case RISCV::fixup_riscv_hi20:129return ELF::R_RISCV_HI20;130case RISCV::fixup_riscv_lo12_i:131return ELF::R_RISCV_LO12_I;132case RISCV::fixup_riscv_lo12_s:133return ELF::R_RISCV_LO12_S;134case RISCV::fixup_riscv_tprel_hi20:135return ELF::R_RISCV_TPREL_HI20;136case RISCV::fixup_riscv_tprel_lo12_i:137return ELF::R_RISCV_TPREL_LO12_I;138case RISCV::fixup_riscv_tprel_lo12_s:139return ELF::R_RISCV_TPREL_LO12_S;140case RISCV::fixup_riscv_tprel_add:141return ELF::R_RISCV_TPREL_ADD;142case RISCV::fixup_riscv_relax:143return ELF::R_RISCV_RELAX;144case RISCV::fixup_riscv_align:145return ELF::R_RISCV_ALIGN;146}147}148149std::unique_ptr<MCObjectTargetWriter>150llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) {151return std::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit);152}153154155