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/RISCVMCTargetDesc.h" 11 #include "llvm/MC/MCELFObjectWriter.h" 12 #include "llvm/MC/MCFixup.h" 13 #include "llvm/MC/MCObjectWriter.h" 14 #include "llvm/Support/ErrorHandling.h" 15 16 using namespace llvm; 17 18 namespace { 19 class RISCVELFObjectWriter : public MCELFObjectTargetWriter { 20 public: 21 RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit); 22 23 ~RISCVELFObjectWriter() override; 24 25 // Return true if the given relocation must be with a symbol rather than 26 // section plus offset. 27 bool needsRelocateWithSymbol(const MCSymbol &Sym, 28 unsigned Type) const override { 29 // TODO: this is very conservative, update once RISC-V psABI requirements 30 // are clarified. 31 return true; 32 } 33 34 protected: 35 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 36 const MCFixup &Fixup, bool IsPCRel) const override; 37 }; 38 } 39 40 RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) 41 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV, 42 /*HasRelocationAddend*/ true) {} 43 44 RISCVELFObjectWriter::~RISCVELFObjectWriter() {} 45 46 unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, 47 const MCValue &Target, 48 const MCFixup &Fixup, 49 bool IsPCRel) const { 50 // Determine the type of the relocation 51 switch ((unsigned)Fixup.getKind()) { 52 default: 53 llvm_unreachable("invalid fixup kind!"); 54 case FK_Data_4: 55 return ELF::R_RISCV_32; 56 case FK_Data_8: 57 return ELF::R_RISCV_64; 58 case FK_Data_Add_1: 59 return ELF::R_RISCV_ADD8; 60 case FK_Data_Add_2: 61 return ELF::R_RISCV_ADD16; 62 case FK_Data_Add_4: 63 return ELF::R_RISCV_ADD32; 64 case FK_Data_Add_8: 65 return ELF::R_RISCV_ADD64; 66 case FK_Data_Sub_1: 67 return ELF::R_RISCV_SUB8; 68 case FK_Data_Sub_2: 69 return ELF::R_RISCV_SUB16; 70 case FK_Data_Sub_4: 71 return ELF::R_RISCV_SUB32; 72 case FK_Data_Sub_8: 73 return ELF::R_RISCV_SUB64; 74 case RISCV::fixup_riscv_hi20: 75 return ELF::R_RISCV_HI20; 76 case RISCV::fixup_riscv_lo12_i: 77 return ELF::R_RISCV_LO12_I; 78 case RISCV::fixup_riscv_lo12_s: 79 return ELF::R_RISCV_LO12_S; 80 case RISCV::fixup_riscv_pcrel_hi20: 81 return ELF::R_RISCV_PCREL_HI20; 82 case RISCV::fixup_riscv_pcrel_lo12_i: 83 return ELF::R_RISCV_PCREL_LO12_I; 84 case RISCV::fixup_riscv_pcrel_lo12_s: 85 return ELF::R_RISCV_PCREL_LO12_S; 86 case RISCV::fixup_riscv_got_hi20: 87 return ELF::R_RISCV_GOT_HI20; 88 case RISCV::fixup_riscv_tprel_hi20: 89 return ELF::R_RISCV_TPREL_HI20; 90 case RISCV::fixup_riscv_tprel_lo12_i: 91 return ELF::R_RISCV_TPREL_LO12_I; 92 case RISCV::fixup_riscv_tprel_lo12_s: 93 return ELF::R_RISCV_TPREL_LO12_S; 94 case RISCV::fixup_riscv_tprel_add: 95 return ELF::R_RISCV_TPREL_ADD; 96 case RISCV::fixup_riscv_tls_got_hi20: 97 return ELF::R_RISCV_TLS_GOT_HI20; 98 case RISCV::fixup_riscv_tls_gd_hi20: 99 return ELF::R_RISCV_TLS_GD_HI20; 100 case RISCV::fixup_riscv_jal: 101 return ELF::R_RISCV_JAL; 102 case RISCV::fixup_riscv_branch: 103 return ELF::R_RISCV_BRANCH; 104 case RISCV::fixup_riscv_rvc_jump: 105 return ELF::R_RISCV_RVC_JUMP; 106 case RISCV::fixup_riscv_rvc_branch: 107 return ELF::R_RISCV_RVC_BRANCH; 108 case RISCV::fixup_riscv_call: 109 return ELF::R_RISCV_CALL; 110 case RISCV::fixup_riscv_call_plt: 111 return ELF::R_RISCV_CALL_PLT; 112 case RISCV::fixup_riscv_relax: 113 return ELF::R_RISCV_RELAX; 114 case RISCV::fixup_riscv_align: 115 return ELF::R_RISCV_ALIGN; 116 } 117 } 118 119 std::unique_ptr<MCObjectTargetWriter> 120 llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) { 121 return llvm::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit); 122 } 123