133388ae8SLu Weining //===-- LoongArchELFObjectWriter.cpp - LoongArch ELF Writer ---*- C++ -*---===//
233388ae8SLu Weining //
333388ae8SLu Weining // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
433388ae8SLu Weining // See https://llvm.org/LICENSE.txt for license information.
533388ae8SLu Weining // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
633388ae8SLu Weining //
733388ae8SLu Weining //===----------------------------------------------------------------------===//
833388ae8SLu Weining
9c2ee21cfSwanglei #include "MCTargetDesc/LoongArchFixupKinds.h"
1033388ae8SLu Weining #include "MCTargetDesc/LoongArchMCTargetDesc.h"
11c2ee21cfSwanglei #include "llvm/BinaryFormat/ELF.h"
1233388ae8SLu Weining #include "llvm/MC/MCContext.h"
1333388ae8SLu Weining #include "llvm/MC/MCELFObjectWriter.h"
1433388ae8SLu Weining #include "llvm/MC/MCFixup.h"
1533388ae8SLu Weining #include "llvm/MC/MCObjectWriter.h"
1633388ae8SLu Weining #include "llvm/Support/ErrorHandling.h"
1733388ae8SLu Weining
1833388ae8SLu Weining using namespace llvm;
1933388ae8SLu Weining
2033388ae8SLu Weining namespace {
2133388ae8SLu Weining class LoongArchELFObjectWriter : public MCELFObjectTargetWriter {
2233388ae8SLu Weining public:
23f5bfc833SJinyang He LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool EnableRelax);
2433388ae8SLu Weining
2533388ae8SLu Weining ~LoongArchELFObjectWriter() override;
2633388ae8SLu Weining
needsRelocateWithSymbol(const MCValue & Val,const MCSymbol & Sym,unsigned Type) const27f5bfc833SJinyang He bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
28f5bfc833SJinyang He unsigned Type) const override {
29f5bfc833SJinyang He return EnableRelax;
30f5bfc833SJinyang He }
31f5bfc833SJinyang He
3233388ae8SLu Weining protected:
3333388ae8SLu Weining unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
3433388ae8SLu Weining const MCFixup &Fixup, bool IsPCRel) const override;
35f5bfc833SJinyang He bool EnableRelax;
3633388ae8SLu Weining };
37904a87acSWeining Lu } // end namespace
3833388ae8SLu Weining
LoongArchELFObjectWriter(uint8_t OSABI,bool Is64Bit,bool EnableRelax)39f5bfc833SJinyang He LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit,
40f5bfc833SJinyang He bool EnableRelax)
4133388ae8SLu Weining : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH,
42f5bfc833SJinyang He /*HasRelocationAddend=*/true),
43f5bfc833SJinyang He EnableRelax(EnableRelax) {}
4433388ae8SLu Weining
~LoongArchELFObjectWriter()4533388ae8SLu Weining LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {}
4633388ae8SLu Weining
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const4733388ae8SLu Weining unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx,
4833388ae8SLu Weining const MCValue &Target,
4933388ae8SLu Weining const MCFixup &Fixup,
5033388ae8SLu Weining bool IsPCRel) const {
5133388ae8SLu Weining // Determine the type of the relocation
5233388ae8SLu Weining unsigned Kind = Fixup.getTargetKind();
5333388ae8SLu Weining
5433388ae8SLu Weining if (Kind >= FirstLiteralRelocationKind)
5533388ae8SLu Weining return Kind - FirstLiteralRelocationKind;
5633388ae8SLu Weining
5733388ae8SLu Weining switch (Kind) {
5833388ae8SLu Weining default:
59c2ee21cfSwanglei Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
6033388ae8SLu Weining return ELF::R_LARCH_NONE;
61c2ee21cfSwanglei case FK_Data_1:
62c2ee21cfSwanglei Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
63c2ee21cfSwanglei return ELF::R_LARCH_NONE;
64c2ee21cfSwanglei case FK_Data_2:
65c2ee21cfSwanglei Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
66c2ee21cfSwanglei return ELF::R_LARCH_NONE;
67c2ee21cfSwanglei case FK_Data_4:
68036b170cSwanglei return IsPCRel ? ELF::R_LARCH_32_PCREL : ELF::R_LARCH_32;
69c2ee21cfSwanglei case FK_Data_8:
7042cb3c63SWeining Lu return IsPCRel ? ELF::R_LARCH_64_PCREL : ELF::R_LARCH_64;
71bf479547Swanglei case LoongArch::fixup_loongarch_b16:
72bf479547Swanglei return ELF::R_LARCH_B16;
73bf479547Swanglei case LoongArch::fixup_loongarch_b21:
74bf479547Swanglei return ELF::R_LARCH_B21;
75c2ee21cfSwanglei case LoongArch::fixup_loongarch_b26:
76c2ee21cfSwanglei return ELF::R_LARCH_B26;
77bf479547Swanglei case LoongArch::fixup_loongarch_abs_hi20:
78bf479547Swanglei return ELF::R_LARCH_ABS_HI20;
79bf479547Swanglei case LoongArch::fixup_loongarch_abs_lo12:
80bf479547Swanglei return ELF::R_LARCH_ABS_LO12;
81bf479547Swanglei case LoongArch::fixup_loongarch_abs64_lo20:
82bf479547Swanglei return ELF::R_LARCH_ABS64_LO20;
83bf479547Swanglei case LoongArch::fixup_loongarch_abs64_hi12:
84bf479547Swanglei return ELF::R_LARCH_ABS64_HI12;
85bf479547Swanglei case LoongArch::fixup_loongarch_tls_le_hi20:
86bf479547Swanglei return ELF::R_LARCH_TLS_LE_HI20;
87bf479547Swanglei case LoongArch::fixup_loongarch_tls_le_lo12:
88bf479547Swanglei return ELF::R_LARCH_TLS_LE_LO12;
89bf479547Swanglei case LoongArch::fixup_loongarch_tls_le64_lo20:
90bf479547Swanglei return ELF::R_LARCH_TLS_LE64_LO20;
91bf479547Swanglei case LoongArch::fixup_loongarch_tls_le64_hi12:
92bf479547Swanglei return ELF::R_LARCH_TLS_LE64_HI12;
93*2cf420d5Swanglei case LoongArch::fixup_loongarch_call36:
94*2cf420d5Swanglei return ELF::R_LARCH_CALL36;
95c2ee21cfSwanglei // TODO: Handle more fixup-kinds.
9633388ae8SLu Weining }
9733388ae8SLu Weining }
9833388ae8SLu Weining
9933388ae8SLu Weining std::unique_ptr<MCObjectTargetWriter>
createLoongArchELFObjectWriter(uint8_t OSABI,bool Is64Bit,bool Relax)100f5bfc833SJinyang He llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit, bool Relax) {
101f5bfc833SJinyang He return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit, Relax);
10233388ae8SLu Weining }
103