1 //===-- LoongArchELFObjectWriter.cpp - LoongArch ELF Writer ---*- C++ -*---===// 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/LoongArchFixupKinds.h" 10 #include "MCTargetDesc/LoongArchMCTargetDesc.h" 11 #include "llvm/BinaryFormat/ELF.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 LoongArchELFObjectWriter : public MCELFObjectTargetWriter { 22 public: 23 LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax); 24 25 ~LoongArchELFObjectWriter() override; 26 27 bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym, 28 unsigned Type) const override { 29 return EnableRelax; 30 } 31 32 protected: 33 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 34 const MCFixup &Fixup, bool IsPCRel) const override; 35 bool EnableRelax; 36 }; 37 } // end namespace 38 39 LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, 40 bool EnableRelax) 41 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH, 42 /*HasRelocationAddend=*/true), 43 EnableRelax(EnableRelax) {} 44 45 LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {} 46 47 unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx, 48 const MCValue &Target, 49 const MCFixup &Fixup, 50 bool IsPCRel) const { 51 // Determine the type of the relocation 52 unsigned Kind = Fixup.getTargetKind(); 53 54 if (Kind >= FirstLiteralRelocationKind) 55 return Kind - FirstLiteralRelocationKind; 56 57 switch (Kind) { 58 default: 59 Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); 60 return ELF::R_LARCH_NONE; 61 case FK_Data_1: 62 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 63 return ELF::R_LARCH_NONE; 64 case FK_Data_2: 65 Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported"); 66 return ELF::R_LARCH_NONE; 67 case FK_Data_4: 68 return IsPCRel ? ELF::R_LARCH_32_PCREL : ELF::R_LARCH_32; 69 case FK_Data_8: 70 return IsPCRel ? ELF::R_LARCH_64_PCREL : ELF::R_LARCH_64; 71 case LoongArch::fixup_loongarch_b16: 72 return ELF::R_LARCH_B16; 73 case LoongArch::fixup_loongarch_b21: 74 return ELF::R_LARCH_B21; 75 case LoongArch::fixup_loongarch_b26: 76 return ELF::R_LARCH_B26; 77 case LoongArch::fixup_loongarch_abs_hi20: 78 return ELF::R_LARCH_ABS_HI20; 79 case LoongArch::fixup_loongarch_abs_lo12: 80 return ELF::R_LARCH_ABS_LO12; 81 case LoongArch::fixup_loongarch_abs64_lo20: 82 return ELF::R_LARCH_ABS64_LO20; 83 case LoongArch::fixup_loongarch_abs64_hi12: 84 return ELF::R_LARCH_ABS64_HI12; 85 case LoongArch::fixup_loongarch_tls_le_hi20: 86 return ELF::R_LARCH_TLS_LE_HI20; 87 case LoongArch::fixup_loongarch_tls_le_lo12: 88 return ELF::R_LARCH_TLS_LE_LO12; 89 case LoongArch::fixup_loongarch_tls_le64_lo20: 90 return ELF::R_LARCH_TLS_LE64_LO20; 91 case LoongArch::fixup_loongarch_tls_le64_hi12: 92 return ELF::R_LARCH_TLS_LE64_HI12; 93 case LoongArch::fixup_loongarch_call36: 94 return ELF::R_LARCH_CALL36; 95 // TODO: Handle more fixup-kinds. 96 } 97 } 98 99 std::unique_ptr<MCObjectTargetWriter> 100 llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) { 101 return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit, Relax); 102 } 103