Home | History | Annotate | Line # | Download | only in MCTargetDesc
      1 //===-- RISCVELFObjectWriter.cpp - RISCV ELF Writer -----------------------===//
      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 #include "MCTargetDesc/RISCVFixupKinds.h"
     10 #include "MCTargetDesc/RISCVMCExpr.h"
     11 #include "MCTargetDesc/RISCVMCTargetDesc.h"
     12 #include "llvm/MC/MCContext.h"
     13 #include "llvm/MC/MCELFObjectWriter.h"
     14 #include "llvm/MC/MCFixup.h"
     15 #include "llvm/MC/MCObjectWriter.h"
     16 #include "llvm/Support/ErrorHandling.h"
     17 
     18 using namespace llvm;
     19 
     20 namespace {
     21 class RISCVELFObjectWriter : public MCELFObjectTargetWriter {
     22 public:
     23   RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit);
     24 
     25   ~RISCVELFObjectWriter() override;
     26 
     27   // Return true if the given relocation must be with a symbol rather than
     28   // section plus offset.
     29   bool needsRelocateWithSymbol(const MCSymbol &Sym,
     30                                unsigned Type) const override {
     31     // TODO: this is very conservative, update once RISC-V psABI requirements
     32     //       are clarified.
     33     return true;
     34   }
     35 
     36 protected:
     37   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
     38                         const MCFixup &Fixup, bool IsPCRel) const override;
     39 };
     40 }
     41 
     42 RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
     43     : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV,
     44                               /*HasRelocationAddend*/ true) {}
     45 
     46 RISCVELFObjectWriter::~RISCVELFObjectWriter() {}
     47 
     48 unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
     49                                             const MCValue &Target,
     50                                             const MCFixup &Fixup,
     51                                             bool IsPCRel) const {
     52   const MCExpr *Expr = Fixup.getValue();
     53   // Determine the type of the relocation
     54   unsigned Kind = Fixup.getTargetKind();
     55   if (Kind >= FirstLiteralRelocationKind)
     56     return Kind - FirstLiteralRelocationKind;
     57   if (IsPCRel) {
     58     switch (Kind) {
     59     default:
     60       Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
     61       return ELF::R_RISCV_NONE;
     62     case FK_Data_4:
     63     case FK_PCRel_4:
     64       return ELF::R_RISCV_32_PCREL;
     65     case RISCV::fixup_riscv_pcrel_hi20:
     66       return ELF::R_RISCV_PCREL_HI20;
     67     case RISCV::fixup_riscv_pcrel_lo12_i:
     68       return ELF::R_RISCV_PCREL_LO12_I;
     69     case RISCV::fixup_riscv_pcrel_lo12_s:
     70       return ELF::R_RISCV_PCREL_LO12_S;
     71     case RISCV::fixup_riscv_got_hi20:
     72       return ELF::R_RISCV_GOT_HI20;
     73     case RISCV::fixup_riscv_tls_got_hi20:
     74       return ELF::R_RISCV_TLS_GOT_HI20;
     75     case RISCV::fixup_riscv_tls_gd_hi20:
     76       return ELF::R_RISCV_TLS_GD_HI20;
     77     case RISCV::fixup_riscv_jal:
     78       return ELF::R_RISCV_JAL;
     79     case RISCV::fixup_riscv_branch:
     80       return ELF::R_RISCV_BRANCH;
     81     case RISCV::fixup_riscv_rvc_jump:
     82       return ELF::R_RISCV_RVC_JUMP;
     83     case RISCV::fixup_riscv_rvc_branch:
     84       return ELF::R_RISCV_RVC_BRANCH;
     85     case RISCV::fixup_riscv_call:
     86       return ELF::R_RISCV_CALL;
     87     case RISCV::fixup_riscv_call_plt:
     88       return ELF::R_RISCV_CALL_PLT;
     89     }
     90   }
     91 
     92   switch (Kind) {
     93   default:
     94     Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
     95     return ELF::R_RISCV_NONE;
     96   case FK_Data_1:
     97     Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
     98     return ELF::R_RISCV_NONE;
     99   case FK_Data_2:
    100     Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
    101     return ELF::R_RISCV_NONE;
    102   case FK_Data_4:
    103     if (Expr->getKind() == MCExpr::Target &&
    104         cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)
    105       return ELF::R_RISCV_32_PCREL;
    106     return ELF::R_RISCV_32;
    107   case FK_Data_8:
    108     return ELF::R_RISCV_64;
    109   case FK_Data_Add_1:
    110     return ELF::R_RISCV_ADD8;
    111   case FK_Data_Add_2:
    112     return ELF::R_RISCV_ADD16;
    113   case FK_Data_Add_4:
    114     return ELF::R_RISCV_ADD32;
    115   case FK_Data_Add_8:
    116     return ELF::R_RISCV_ADD64;
    117   case FK_Data_Add_6b:
    118     return ELF::R_RISCV_SET6;
    119   case FK_Data_Sub_1:
    120     return ELF::R_RISCV_SUB8;
    121   case FK_Data_Sub_2:
    122     return ELF::R_RISCV_SUB16;
    123   case FK_Data_Sub_4:
    124     return ELF::R_RISCV_SUB32;
    125   case FK_Data_Sub_8:
    126     return ELF::R_RISCV_SUB64;
    127   case FK_Data_Sub_6b:
    128     return ELF::R_RISCV_SUB6;
    129   case RISCV::fixup_riscv_hi20:
    130     return ELF::R_RISCV_HI20;
    131   case RISCV::fixup_riscv_lo12_i:
    132     return ELF::R_RISCV_LO12_I;
    133   case RISCV::fixup_riscv_lo12_s:
    134     return ELF::R_RISCV_LO12_S;
    135   case RISCV::fixup_riscv_tprel_hi20:
    136     return ELF::R_RISCV_TPREL_HI20;
    137   case RISCV::fixup_riscv_tprel_lo12_i:
    138     return ELF::R_RISCV_TPREL_LO12_I;
    139   case RISCV::fixup_riscv_tprel_lo12_s:
    140     return ELF::R_RISCV_TPREL_LO12_S;
    141   case RISCV::fixup_riscv_tprel_add:
    142     return ELF::R_RISCV_TPREL_ADD;
    143   case RISCV::fixup_riscv_relax:
    144     return ELF::R_RISCV_RELAX;
    145   case RISCV::fixup_riscv_align:
    146     return ELF::R_RISCV_ALIGN;
    147   }
    148 }
    149 
    150 std::unique_ptr<MCObjectTargetWriter>
    151 llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
    152   return std::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit);
    153 }
    154