diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h @@ -23,12 +23,14 @@ namespace llvm { class LoongArchAsmBackend : public MCAsmBackend { + const MCSubtargetInfo &STI; uint8_t OSABI; bool Is64Bit; public: LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit) - : MCAsmBackend(support::little), OSABI(OSABI), Is64Bit(Is64Bit) {} + : MCAsmBackend(support::little), STI(STI), OSABI(OSABI), + Is64Bit(Is64Bit) {} ~LoongArchAsmBackend() override {} void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, @@ -49,6 +51,8 @@ return LoongArch::NumTargetFixupKinds; } + Optional getFixupKind(StringRef Name) const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; void relaxInstruction(MCInst &Inst, diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp @@ -22,6 +22,22 @@ using namespace llvm; +Optional LoongArchAsmBackend::getFixupKind(StringRef Name) const { + if (STI.getTargetTriple().isOSBinFormatELF()) { + auto Type = llvm::StringSwitch(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" +#undef ELF_RELOC + .Case("BFD_RELOC_NONE", ELF::R_LARCH_NONE) + .Case("BFD_RELOC_32", ELF::R_LARCH_32) + .Case("BFD_RELOC_64", ELF::R_LARCH_64) + .Default(-1u); + if (Type != -1u) + return static_cast(FirstLiteralRelocationKind + Type); + } + return None; +} + const MCFixupKindInfo & LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[] = { @@ -38,6 +54,11 @@ static_assert((array_lengthof(Infos)) == LoongArch::NumTargetFixupKinds, "Not all fixup kinds added to Infos array"); + // Fixup kinds from .reloc directive are like R_LARCH_NONE. They + // do not require any extra processing. + if (Kind >= FirstLiteralRelocationKind) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); @@ -59,6 +80,8 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) { + if (Fixup.getKind() >= FirstLiteralRelocationKind) + return true; // TODO: Determine which relocation require special processing at linking // time. return false; diff --git a/llvm/test/MC/LoongArch/Relocations/reloc-directive-err.s b/llvm/test/MC/LoongArch/Relocations/reloc-directive-err.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/LoongArch/Relocations/reloc-directive-err.s @@ -0,0 +1,6 @@ +# RUN: llvm-mc --triple=loongarch64 %s |& FileCheck --check-prefix=PRINT %s +# RUN: not llvm-mc --filetype=obj --triple=loongarch64 %s -o /dev/null |& FileCheck %s + +# PRINT: .reloc 0, R_INVALID, 0 +# CHECK: {{.*}}.s:[[# @LINE+1]]:11: error: unknown relocation name +.reloc 0, R_INVALID, 0 diff --git a/llvm/test/MC/LoongArch/Relocations/reloc-directive.s b/llvm/test/MC/LoongArch/Relocations/reloc-directive.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/LoongArch/Relocations/reloc-directive.s @@ -0,0 +1,46 @@ +# RUN: llvm-mc --triple=loongarch64 %s | FileCheck --check-prefix=PRINT %s +# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \ +# RUN: | llvm-readobj -r - | FileCheck %s + +# PRINT: .reloc 8, R_LARCH_NONE, .data +# PRINT: .reloc 4, R_LARCH_NONE, foo+4 +# PRINT: .reloc 0, R_LARCH_NONE, 8 +# PRINT: .reloc 0, R_LARCH_32, .data+2 +# PRINT: .reloc 0, R_LARCH_TLS_DTPMOD32, foo+3 +# PRINT: .reloc 0, R_LARCH_IRELATIVE, 5 +# PRINT: .reloc 0, BFD_RELOC_NONE, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_32, 9 +# PRINT-NEXT: .reloc 0, BFD_RELOC_64, 9 + +.text + ret + nop + nop + .reloc 8, R_LARCH_NONE, .data + .reloc 4, R_LARCH_NONE, foo+4 + .reloc 0, R_LARCH_NONE, 8 + + .reloc 0, R_LARCH_32, .data+2 + .reloc 0, R_LARCH_TLS_DTPMOD32, foo+3 + .reloc 0, R_LARCH_IRELATIVE, 5 + + .reloc 0, BFD_RELOC_NONE, 9 + .reloc 0, BFD_RELOC_32, 9 + .reloc 0, BFD_RELOC_64, 9 + +.data +.globl foo +foo: + .word 0 + .word 0 + .word 0 + +# CHECK: 0x8 R_LARCH_NONE .data 0x0 +# CHECK-NEXT: 0x4 R_LARCH_NONE foo 0x4 +# CHECK-NEXT: 0x0 R_LARCH_NONE - 0x8 +# CHECK-NEXT: 0x0 R_LARCH_32 .data 0x2 +# CHECK-NEXT: 0x0 R_LARCH_TLS_DTPMOD32 foo 0x3 +# CHECK-NEXT: 0x0 R_LARCH_IRELATIVE - 0x5 +# CHECK-NEXT: 0x0 R_LARCH_NONE - 0x9 +# CHECK-NEXT: 0x0 R_LARCH_32 - 0x9 +# CHECK-NEXT: 0x0 R_LARCH_64 - 0x9