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/MC/MCValue.h" 17 #include "llvm/Support/ErrorHandling.h" 18 19 using namespace llvm; 20 21 namespace { 22 class LoongArchELFObjectWriter : public MCELFObjectTargetWriter { 23 public: 24 LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax); 25 26 ~LoongArchELFObjectWriter() override; 27 28 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override { 29 return EnableRelax; 30 } 31 32 protected: 33 unsigned getRelocType(const MCFixup &, const MCValue &, 34 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(const MCFixup &Fixup, 48 const MCValue &Target, 49 bool IsPCRel) const { 50 switch (Target.getSpecifier()) { 51 case ELF::R_LARCH_TLS_LE_HI20: 52 case ELF::R_LARCH_TLS_IE_PC_HI20: 53 case ELF::R_LARCH_TLS_IE_HI20: 54 case ELF::R_LARCH_TLS_LD_PC_HI20: 55 case ELF::R_LARCH_TLS_LD_HI20: 56 case ELF::R_LARCH_TLS_GD_PC_HI20: 57 case ELF::R_LARCH_TLS_GD_HI20: 58 case ELF::R_LARCH_TLS_DESC_PC_HI20: 59 case ELF::R_LARCH_TLS_DESC_HI20: 60 case ELF::R_LARCH_TLS_LE_HI20_R: 61 case ELF::R_LARCH_TLS_LD_PCREL20_S2: 62 case ELF::R_LARCH_TLS_GD_PCREL20_S2: 63 case ELF::R_LARCH_TLS_DESC_PCREL20_S2: 64 if (auto *SA = Target.getAddSym()) 65 cast<MCSymbolELF>(SA)->setType(ELF::STT_TLS); 66 break; 67 default: 68 break; 69 } 70 71 auto Kind = Fixup.getKind(); 72 if (mc::isRelocation(Fixup.getKind())) 73 return Kind; 74 switch (Kind) { 75 default: 76 reportError(Fixup.getLoc(), "Unsupported relocation type"); 77 return ELF::R_LARCH_NONE; 78 case FK_Data_1: 79 reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 80 return ELF::R_LARCH_NONE; 81 case FK_Data_2: 82 reportError(Fixup.getLoc(), "2-byte data relocations not supported"); 83 return ELF::R_LARCH_NONE; 84 case FK_Data_4: 85 return IsPCRel ? ELF::R_LARCH_32_PCREL : ELF::R_LARCH_32; 86 case FK_Data_8: 87 return IsPCRel ? ELF::R_LARCH_64_PCREL : ELF::R_LARCH_64; 88 case LoongArch::fixup_loongarch_b16: 89 return ELF::R_LARCH_B16; 90 case LoongArch::fixup_loongarch_b21: 91 return ELF::R_LARCH_B21; 92 case LoongArch::fixup_loongarch_b26: 93 return ELF::R_LARCH_B26; 94 case LoongArch::fixup_loongarch_abs_hi20: 95 return ELF::R_LARCH_ABS_HI20; 96 case LoongArch::fixup_loongarch_abs_lo12: 97 return ELF::R_LARCH_ABS_LO12; 98 case LoongArch::fixup_loongarch_abs64_lo20: 99 return ELF::R_LARCH_ABS64_LO20; 100 case LoongArch::fixup_loongarch_abs64_hi12: 101 return ELF::R_LARCH_ABS64_HI12; 102 } 103 } 104 105 std::unique_ptr<MCObjectTargetWriter> 106 llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) { 107 return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit, Relax); 108 } 109