From d3188e39df2f8039d14ef1683a657bc8bbe681c5 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 31 Oct 2023 14:11:42 +0900 Subject: [PATCH] [LoongArch] Implement a workaround for R_LARCH_PCALA_LO12 It seems R_LARCH_PCALA_LO12 is sometimes used against JIRL even though such use case is incorrect as per the psABI. At least, `/usr/lib/loongarch64-linux-gnu/libc_nonshared.a(atexit.oS)` on `cfarm400.cfarm.net` contains such relocation. We need this patch to self-host mold on that cfarm machine. --- elf/arch-loongarch.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/elf/arch-loongarch.cc b/elf/arch-loongarch.cc index 4d565e211c..998a48dd33 100644 --- a/elf/arch-loongarch.cc +++ b/elf/arch-loongarch.cc @@ -323,7 +323,17 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) { write_k12(loc, (S + A) >> 52); break; case R_LARCH_PCALA_LO12: - write_k12(loc, S + A); + // It looks like R_LARCH_PCALA_LO12 is sometimes used for JIRL even + // though the instruction takes a 16 bit immediate rather than 12 bits. + // It is contrary to the psABI document, but GNU ld has special + // code to handle it. We accept it with a warning message. + if ((*(ul32 *)loc & 0xfc00'0000) == 0x4c00'0000) { + Warn(ctx) << *this << ": invalid use of a R_LARCH_PCALA_LO12 relocation" + << " against a JIRL instruction"; + write_k16(loc, sign_extend(S + A, 11) >> 2); + } else { + write_k12(loc, S + A); + } break; case R_LARCH_PCALA_HI20: write_j20(loc, hi20(S + A, P));