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
18using namespace llvm;
19
20namespace {
21class LoongArchELFObjectWriter : public MCELFObjectTargetWriter {
22public:
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
32protected:
33 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
34 const MCFixup &Fixup, bool IsPCRel) const override;
35 bool EnableRelax;
36};
37} // end namespace
38
39LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit,
40 bool EnableRelax)
41 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH,
42 /*HasRelocationAddend=*/true),
43 EnableRelax(EnableRelax) {}
44
45LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {}
46
47unsigned 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(L: Fixup.getLoc(), Msg: "Unsupported relocation type");
60 return ELF::R_LARCH_NONE;
61 case FK_Data_1:
62 Ctx.reportError(L: Fixup.getLoc(), Msg: "1-byte data relocations not supported");
63 return ELF::R_LARCH_NONE;
64 case FK_Data_2:
65 Ctx.reportError(L: Fixup.getLoc(), Msg: "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
99std::unique_ptr<MCObjectTargetWriter>
100llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) {
101 return std::make_unique<LoongArchELFObjectWriter>(args&: OSABI, args&: Is64Bit, args&: Relax);
102}
103