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