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() = default; 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 case RISCV::fixup_riscv_add_8: 90 return ELF::R_RISCV_ADD8; 91 case RISCV::fixup_riscv_sub_8: 92 return ELF::R_RISCV_SUB8; 93 case RISCV::fixup_riscv_add_16: 94 return ELF::R_RISCV_ADD16; 95 case RISCV::fixup_riscv_sub_16: 96 return ELF::R_RISCV_SUB16; 97 case RISCV::fixup_riscv_add_32: 98 return ELF::R_RISCV_ADD32; 99 case RISCV::fixup_riscv_sub_32: 100 return ELF::R_RISCV_SUB32; 101 case RISCV::fixup_riscv_add_64: 102 return ELF::R_RISCV_ADD64; 103 case RISCV::fixup_riscv_sub_64: 104 return ELF::R_RISCV_SUB64; 105 } 106 } 107 108 switch (Kind) { 109 default: 110 Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); 111 return ELF::R_RISCV_NONE; 112 case FK_Data_1: 113 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 114 return ELF::R_RISCV_NONE; 115 case FK_Data_2: 116 Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported"); 117 return ELF::R_RISCV_NONE; 118 case FK_Data_4: 119 if (Expr->getKind() == MCExpr::Target && 120 cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL) 121 return ELF::R_RISCV_32_PCREL; 122 return ELF::R_RISCV_32; 123 case FK_Data_8: 124 return ELF::R_RISCV_64; 125 case RISCV::fixup_riscv_hi20: 126 return ELF::R_RISCV_HI20; 127 case RISCV::fixup_riscv_lo12_i: 128 return ELF::R_RISCV_LO12_I; 129 case RISCV::fixup_riscv_lo12_s: 130 return ELF::R_RISCV_LO12_S; 131 case RISCV::fixup_riscv_tprel_hi20: 132 return ELF::R_RISCV_TPREL_HI20; 133 case RISCV::fixup_riscv_tprel_lo12_i: 134 return ELF::R_RISCV_TPREL_LO12_I; 135 case RISCV::fixup_riscv_tprel_lo12_s: 136 return ELF::R_RISCV_TPREL_LO12_S; 137 case RISCV::fixup_riscv_tprel_add: 138 return ELF::R_RISCV_TPREL_ADD; 139 case RISCV::fixup_riscv_relax: 140 return ELF::R_RISCV_RELAX; 141 case RISCV::fixup_riscv_align: 142 return ELF::R_RISCV_ALIGN; 143 case RISCV::fixup_riscv_set_6b: 144 return ELF::R_RISCV_SET6; 145 case RISCV::fixup_riscv_sub_6b: 146 return ELF::R_RISCV_SUB6; 147 case RISCV::fixup_riscv_add_8: 148 return ELF::R_RISCV_ADD8; 149 case RISCV::fixup_riscv_set_8: 150 return ELF::R_RISCV_SET8; 151 case RISCV::fixup_riscv_sub_8: 152 return ELF::R_RISCV_SUB8; 153 case RISCV::fixup_riscv_set_16: 154 return ELF::R_RISCV_SET16; 155 case RISCV::fixup_riscv_add_16: 156 return ELF::R_RISCV_ADD16; 157 case RISCV::fixup_riscv_sub_16: 158 return ELF::R_RISCV_SUB16; 159 case RISCV::fixup_riscv_set_32: 160 return ELF::R_RISCV_SET32; 161 case RISCV::fixup_riscv_add_32: 162 return ELF::R_RISCV_ADD32; 163 case RISCV::fixup_riscv_sub_32: 164 return ELF::R_RISCV_SUB32; 165 case RISCV::fixup_riscv_add_64: 166 return ELF::R_RISCV_ADD64; 167 case RISCV::fixup_riscv_sub_64: 168 return ELF::R_RISCV_SUB64; 169 } 170 } 171 172 std::unique_ptr<MCObjectTargetWriter> 173 llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) { 174 return std::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit); 175 } 176