diff --git a/0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch b/0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch new file mode 100644 index 0000000000000000000000000000000000000000..103400d6442966c1aac21b362de6bb69a3b5521f --- /dev/null +++ b/0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch @@ -0,0 +1,764 @@ +From 2b870b1f213f2d645f4fa685371fbefea09b2969 Mon Sep 17 00:00:00 2001 +From: Lu Weining +Date: Mon, 25 Dec 2023 17:40:48 +0800 +Subject: [PATCH 1/6] [lld][LoongArch] Support the R_LARCH_CALL36 relocation + type (#73346) + +R_LARCH_CALL36 was designed for function call on medium code model where +the 2 instructions (pcaddu18i + jirl) must be adjacent. This is expected +to replace current medium code model implementation, i.e. +R_LARCH_PCALA_{HI20,LO12} on pcalau12i + jirl. + +See https://github.com/loongson/la-abi-specs/pull/3 for more details. + +(cherry picked from commit 88548df0fc08364bd03148c936e36f0bb07dde8a) +--- + lld/ELF/Arch/LoongArch.cpp | 20 ++++++++++ + lld/test/ELF/loongarch-call36.s | 69 +++++++++++++++++++++++++++++++++ + 2 files changed, 89 insertions(+) + create mode 100644 lld/test/ELF/loongarch-call36.s + +diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp +index 160fab4aeba9..72d9c6838e31 100644 +--- a/lld/ELF/Arch/LoongArch.cpp ++++ b/lld/ELF/Arch/LoongArch.cpp +@@ -479,6 +479,7 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, + case R_LARCH_B16: + case R_LARCH_B21: + case R_LARCH_B26: ++ case R_LARCH_CALL36: + return R_PLT_PC; + case R_LARCH_GOT_PC_HI20: + case R_LARCH_GOT64_PC_LO20: +@@ -607,6 +608,25 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, + write32le(loc, setD10k16(read32le(loc), val >> 2)); + return; + ++ case R_LARCH_CALL36: { ++ // This relocation is designed for adjancent pcaddu18i+jirl pairs that ++ // are patched in one time. Because of sign extension of these insns' ++ // immediate fields, the relocation range is [-128G - 0x20000, +128G - ++ // 0x20000) (of course must be 4-byte aligned). ++ if (((int64_t)val + 0x20000) != llvm::SignExtend64(val + 0x20000, 38)) ++ reportRangeError(loc, rel, Twine(val), llvm::minIntN(38) - 0x20000, ++ llvm::maxIntN(38) - 0x20000); ++ checkAlignment(loc, val, 4, rel); ++ // Since jirl performs sign extension on the offset immediate, adds (1<<17) ++ // to original val to get the correct hi20. ++ uint32_t hi20 = extractBits(val + (1 << 17), 37, 18); ++ // Despite the name, the lower part is actually 18 bits with 4-byte aligned. ++ uint32_t lo16 = extractBits(val, 17, 2); ++ write32le(loc, setJ20(read32le(loc), hi20)); ++ write32le(loc + 4, setK16(read32le(loc + 4), lo16)); ++ return; ++ } ++ + // Relocs intended for `addi`, `ld` or `st`. + case R_LARCH_PCALA_LO12: + // We have to again inspect the insn word to handle the R_LARCH_PCALA_LO12 +diff --git a/lld/test/ELF/loongarch-call36.s b/lld/test/ELF/loongarch-call36.s +new file mode 100644 +index 000000000000..2d25a2ac64ed +--- /dev/null ++++ b/lld/test/ELF/loongarch-call36.s +@@ -0,0 +1,69 @@ ++# REQUIRES: loongarch ++ ++# RUN: rm -rf %t && split-file %s %t ++# RUN: llvm-mc --filetype=obj --triple=loongarch64-unknown-elf %t/a.s -o %t/a.o ++ ++# RUN: ld.lld %t/a.o --section-start=.text=0x20010 --section-start=.sec.foo=0x60020 -o %t/exe1 ++# RUN: llvm-objdump --no-show-raw-insn -d %t/exe1 | FileCheck --match-full-lines %s --check-prefix=EXE1 ++## hi20 = target - pc + (1 << 17) >> 18 = 0x60020 - 0x20010 + 0x20000 >> 18 = 1 ++## lo18 = target - pc & (1 << 18) - 1 = 0x60020 - 0x20010 & 0x3ffff = 16 ++# EXE1: 20010: pcaddu18i $t0, 1 ++# EXE1-NEXT: 20014: jirl $zero, $t0, 16 ++ ++# RUN: ld.lld %t/a.o --section-start=.text=0x20010 --section-start=.sec.foo=0x40020 -o %t/exe2 ++# RUN: llvm-objdump --no-show-raw-insn -d %t/exe2 | FileCheck --match-full-lines %s --check-prefix=EXE2 ++## hi20 = target - pc + (1 << 17) >> 18 = 0x40020 - 0x20010 + 0x20000 >> 18 = 1 ++## lo18 = target - pc & (1 << 18) - 1 = 0x40020 - 0x20010 & 0x3ffff = -131056 ++# EXE2: 20010: pcaddu18i $t0, 1 ++# EXE2-NEXT: 20014: jirl $zero, $t0, -131056 ++ ++# RUN: ld.lld %t/a.o -shared -T %t/a.t -o %t/a.so ++# RUN: llvm-readelf -x .got.plt %t/a.so | FileCheck --check-prefix=GOTPLT %s ++# RUN: llvm-objdump -d --no-show-raw-insn %t/a.so | FileCheck --check-prefix=SO %s ++## PLT should be present in this case. ++# SO: Disassembly of section .plt: ++# SO: <.plt>: ++## foo@plt: ++# SO: 1234520: pcaddu12i $t3, 64{{$}} ++# SO-NEXT: ld.d $t3, $t3, 544{{$}} ++# SO-NEXT: jirl $t1, $t3, 0 ++# SO-NEXT: nop ++ ++# SO: Disassembly of section .text: ++# SO: <_start>: ++## hi20 = foo@plt - pc + (1 << 17) >> 18 = 0x1234520 - 0x1274670 + 0x20000 >> 18 = -1 ++## lo18 = foo@plt - pc & (1 << 18) - 1 = 0x1234520 - 0x1274670 & 0x3ffff = -336 ++# SO-NEXT: pcaddu18i $t0, -1{{$}} ++# SO-NEXT: jirl $zero, $t0, -336{{$}} ++ ++# GOTPLT: section '.got.plt': ++# GOTPLT-NEXT: 0x01274730 00000000 00000000 00000000 00000000 ++# GOTPLT-NEXT: 0x01274740 00452301 00000000 ++ ++# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x2000020000 -o /dev/null 2>&1 | \ ++# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-RANGE %s ++# ERROR-RANGE: error: [[FILE]]:(.text+0x0): relocation R_LARCH_CALL36 out of range: 137438953472 is not in [-137439084544, 137438822399]; references 'foo' ++ ++## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. ++# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ ++# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s ++# ERROR-ALIGN: error: [[FILE]]:(.text+0x0): improper alignment for relocation R_LARCH_CALL36: 0x20001 is not aligned to 4 bytes ++ ++#--- a.t ++SECTIONS { ++ .plt 0x1234500: { *(.plt) } ++ .text 0x1274670: { *(.text) } ++} ++ ++#--- a.s ++.text ++.global _start ++_start: ++ .reloc ., R_LARCH_CALL36, foo ++ pcaddu18i $t0, 0 ++ jirl $zero, $t0, 0 ++ ++.section .sec.foo,"ax" ++.global foo ++foo: ++ ret +-- +2.20.1 + + +From 6accc3e17550f87c2e5154fdee4056e21f680542 Mon Sep 17 00:00:00 2001 +From: Weining Lu +Date: Mon, 25 Dec 2023 18:28:19 +0800 +Subject: [PATCH 2/6] [lld][test][LoongArch] Remove the test for R_LARCH_CALL36 + range checking + +Several buildbots report: +ld.lld: error: failed to open /dev/null: Cannot allocate memory + +For example: +- https://lab.llvm.org/buildbot/#/builders/184/builds/8842 +- https://lab.llvm.org/buildbot/#/builders/247/builds/12559 + +(cherry picked from commit 0fbc728dba97149e530cfb7f2ada0283c398a7ce) +--- + lld/test/ELF/loongarch-call36.s | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/lld/test/ELF/loongarch-call36.s b/lld/test/ELF/loongarch-call36.s +index 2d25a2ac64ed..0a00adacbd6a 100644 +--- a/lld/test/ELF/loongarch-call36.s ++++ b/lld/test/ELF/loongarch-call36.s +@@ -40,10 +40,6 @@ + # GOTPLT-NEXT: 0x01274730 00000000 00000000 00000000 00000000 + # GOTPLT-NEXT: 0x01274740 00452301 00000000 + +-# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x2000020000 -o /dev/null 2>&1 | \ +-# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-RANGE %s +-# ERROR-RANGE: error: [[FILE]]:(.text+0x0): relocation R_LARCH_CALL36 out of range: 137438953472 is not in [-137439084544, 137438822399]; references 'foo' +- + ## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. + # RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ + # RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s +-- +2.20.1 + + +From be0c0cd979b6f4e2d778ca16d96a3e465a3ac4dc Mon Sep 17 00:00:00 2001 +From: Weining Lu +Date: Mon, 25 Dec 2023 22:41:09 +0800 +Subject: [PATCH 3/6] Revert "[lld][test][LoongArch] Remove the test for + R_LARCH_CALL36 range checking" + +This reverts commit 0fbc728dba97149e530cfb7f2ada0283c398a7ce. + +In 88548df0fc08, both the .sec.foo and .tex sections used the same +section flags, hence sharing one segment, pushing the output file +size too large. This breaks on many buildbots. + +Now assign section .sec.foo different flags ("awx") from .text ("ax") +so that both sections get their own segment. + +(cherry picked from commit 6452395561eaae59e38f1df84f5413dffdb9169f) +--- + lld/test/ELF/loongarch-call36.s | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lld/test/ELF/loongarch-call36.s b/lld/test/ELF/loongarch-call36.s +index 0a00adacbd6a..b593fdf1f604 100644 +--- a/lld/test/ELF/loongarch-call36.s ++++ b/lld/test/ELF/loongarch-call36.s +@@ -40,6 +40,10 @@ + # GOTPLT-NEXT: 0x01274730 00000000 00000000 00000000 00000000 + # GOTPLT-NEXT: 0x01274740 00452301 00000000 + ++# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x2000020000 -o /dev/null 2>&1 | \ ++# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-RANGE %s ++# ERROR-RANGE: error: [[FILE]]:(.text+0x0): relocation R_LARCH_CALL36 out of range: 137438953472 is not in [-137439084544, 137438822399]; references 'foo' ++ + ## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. + # RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ + # RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s +@@ -59,7 +63,7 @@ _start: + pcaddu18i $t0, 0 + jirl $zero, $t0, 0 + +-.section .sec.foo,"ax" ++.section .sec.foo,"awx" + .global foo + foo: + ret +-- +2.20.1 + + +From cf0d9db4664d59e163d53c62ae1de663092ab2d2 Mon Sep 17 00:00:00 2001 +From: Weining Lu +Date: Fri, 10 Nov 2023 13:37:55 +0800 +Subject: [PATCH 4/6] [lld][ELF] Add a corner testcase for + elf::getLoongArchPageDelta + +If `page(dest) - page(pc)` is 0xfffffffffff000, i.e. page(pc) is next +to page(dest), and lo12(dest) > 0x7ff, correct %pc64_lo12 and %pc64_hi12 +should be both -1 (which can be checked with binutils) but they are both +0 on lld. This patch adds such a test showing lld's incorrect behaviour +and following patch will fix this issue. + +(cherry picked from commit e752b58e0d26fc08bca6b2a4e56b05af7f8d8d66) +--- + lld/test/ELF/loongarch-pc-aligned.s | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s +index 9df3492d1877..f6ac56e5261d 100644 +--- a/lld/test/ELF/loongarch-pc-aligned.s ++++ b/lld/test/ELF/loongarch-pc-aligned.s +@@ -260,6 +260,19 @@ + # EXTREME15-NEXT: lu32i.d $t0, -349526 + # EXTREME15-NEXT: lu52i.d $t0, $t0, -1093 + ++## FIXME: Correct %pc64_lo20 should be 0xfffff (-1) and %pc64_hi12 should be 0xfff (-1), but current values are: ++## page delta = 0x0000000000000000, page offset = 0x888 ++## %pc_lo12 = 0x888 = -1912 ++## %pc_hi20 = 0x00000 = 0 ++## %pc64_lo20 = 0x00000 = 0 ++## %pc64_hi12 = 0x00000 = 0 ++# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16 ++# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16 ++# EXTREME16: addi.d $t0, $zero, -1912 ++# EXTREME16-NEXT: pcalau12i $t1, 0 ++# EXTREME16-NEXT: lu32i.d $t0, 0 ++# EXTREME16-NEXT: lu52i.d $t0, $t0, 0 ++ + #--- a.s + .rodata + x: +-- +2.20.1 + + +From 11d61b028f306d5ace2b09154781575e88b118cb Mon Sep 17 00:00:00 2001 +From: Weining Lu +Date: Sat, 25 Nov 2023 15:44:05 +0800 +Subject: [PATCH 5/6] [lld][LoongArch] Add a another corner testcase for + elf::getLoongArchPageDelta + +Similar to e752b58e0d26. + +(cherry picked from commit 84a20989c6f72d0f7d04c9981d51c7838e95855c) +--- + lld/ELF/Arch/LoongArch.cpp | 1 - + lld/test/ELF/loongarch-pc-aligned.s | 13 +++++++++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp +index 72d9c6838e31..516d02bb9e3f 100644 +--- a/lld/ELF/Arch/LoongArch.cpp ++++ b/lld/ELF/Arch/LoongArch.cpp +@@ -168,7 +168,6 @@ uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) { + result -= 0x10000'0000; + else if (!negativeA && negativeB) + result += 0x10000'0000; +- + return result; + } + +diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s +index f6ac56e5261d..e7950400a5c8 100644 +--- a/lld/test/ELF/loongarch-pc-aligned.s ++++ b/lld/test/ELF/loongarch-pc-aligned.s +@@ -273,6 +273,19 @@ + # EXTREME16-NEXT: lu32i.d $t0, 0 + # EXTREME16-NEXT: lu52i.d $t0, $t0, 0 + ++## FIXME: Correct %pc64_lo20 should be 0x00000 (0) and %pc64_hi12 should be 0x000 (0), but current values are: ++## page delta = 0xffffffff80000000, page offset = 0x888 ++## %pc_lo12 = 0x888 = -1912 ++## %pc_hi20 = 0x80000 = -524288 ++## %pc64_lo20 = 0xfffff = -1 ++## %pc64_hi12 = 0xfff = -1 ++# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17 ++# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17 ++# EXTREME17: addi.d $t0, $zero, -1912 ++# EXTREME17-NEXT: pcalau12i $t1, -524288 ++# EXTREME17-NEXT: lu32i.d $t0, -1 ++# EXTREME17-NEXT: lu52i.d $t0, $t0, -1 ++ + #--- a.s + .rodata + x: +-- +2.20.1 + + +From 1ea127e041629ae2df9b9cf6a85e25b6276d4a99 Mon Sep 17 00:00:00 2001 +From: Lu Weining +Date: Wed, 10 Jan 2024 18:03:52 +0800 +Subject: [PATCH 6/6] [lld][LoongArch] Handle extreme code model relocs + according to psABI v2.30 (#73387) + +psABI v2.30 requires the extreme code model instructions sequence +(pcalau12i+addi.d+lu32i.d+lu52i.d) to be adjacent. + +See https://github.com/llvm/llvm-project/pull/71907 and +https://github.com/loongson-community/discussions/issues/17 for details. + +(cherry picked from commit 38394a3d0b8b9a1fdc444bdebeba17a19250997d) +--- + lld/ELF/Arch/LoongArch.cpp | 110 +++++++--------------------- + lld/ELF/InputSection.cpp | 10 +-- + lld/ELF/Target.h | 2 +- + lld/test/ELF/loongarch-pc-aligned.s | 109 ++++++++++++++------------- + 4 files changed, 93 insertions(+), 138 deletions(-) + +diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp +index 516d02bb9e3f..19147a0f6df6 100644 +--- a/lld/ELF/Arch/LoongArch.cpp ++++ b/lld/ELF/Arch/LoongArch.cpp +@@ -85,89 +85,33 @@ static uint64_t getLoongArchPage(uint64_t p) { + static uint32_t lo12(uint32_t val) { return val & 0xfff; } + + // Calculate the adjusted page delta between dest and PC. +-uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) { +- // Consider the large code model access pattern, of which the smaller code +- // models' access patterns are a subset: +- // +- // pcalau12i U, %foo_hi20(sym) ; b in [-0x80000, 0x7ffff] +- // addi.d T, zero, %foo_lo12(sym) ; a in [-0x800, 0x7ff] +- // lu32i.d T, %foo64_lo20(sym) ; c in [-0x80000, 0x7ffff] +- // lu52i.d T, T, %foo64_hi12(sym) ; d in [-0x800, 0x7ff] +- // {ldx,stx,add}.* dest, U, T +- // +- // Let page(pc) = 0xRRR'QQQQQ'PPPPP'000 and dest = 0xZZZ'YYYYY'XXXXX'AAA, +- // with RQ, P, ZY, X and A representing the respective bitfields as unsigned +- // integers. We have: +- // +- // page(dest) = 0xZZZ'YYYYY'XXXXX'000 +- // - page(pc) = 0xRRR'QQQQQ'PPPPP'000 +- // ---------------------------------- +- // 0xddd'ccccc'bbbbb'000 +- // +- // Now consider the above pattern's actual effects: +- // +- // page(pc) 0xRRR'QQQQQ'PPPPP'000 +- // pcalau12i + 0xiii'iiiii'bbbbb'000 +- // addi + 0xjjj'jjjjj'kkkkk'AAA +- // lu32i.d & lu52i.d + 0xddd'ccccc'00000'000 +- // -------------------------------------------------- +- // dest = U + T +- // = ((RQ<<32) + (P<<12) + i + (b<<12)) + (j + k + A + (cd<<32)) +- // = (((RQ+cd)<<32) + i + j) + (((P+b)<<12) + k) + A +- // = (ZY<<32) + (X<<12) + A +- // +- // ZY<<32 = (RQ<<32)+(cd<<32)+i+j, X<<12 = (P<<12)+(b<<12)+k +- // cd<<32 = (ZY<<32)-(RQ<<32)-i-j, b<<12 = (X<<12)-(P<<12)-k +- // +- // where i and k are terms representing the effect of b's and A's sign +- // extension respectively. +- // +- // i = signed b < 0 ? -0x10000'0000 : 0 +- // k = signed A < 0 ? -0x1000 : 0 +- // +- // The j term is a bit complex: it represents the higher half of +- // sign-extended bits from A that are effectively lost if i == 0 but k != 0, +- // due to overwriting by lu32i.d & lu52i.d. +- // +- // j = signed A < 0 && signed b >= 0 ? 0x10000'0000 : 0 +- // +- // The actual effect of the instruction sequence before the final addition, +- // i.e. our desired result value, is thus: +- // +- // result = (cd<<32) + (b<<12) +- // = (ZY<<32)-(RQ<<32)-i-j + (X<<12)-(P<<12)-k +- // = ((ZY<<32)+(X<<12)) - ((RQ<<32)+(P<<12)) - i - j - k +- // = page(dest) - page(pc) - i - j - k +- // +- // when signed A >= 0 && signed b >= 0: +- // +- // i = j = k = 0 +- // result = page(dest) - page(pc) +- // +- // when signed A >= 0 && signed b < 0: +- // +- // i = -0x10000'0000, j = k = 0 +- // result = page(dest) - page(pc) + 0x10000'0000 +- // +- // when signed A < 0 && signed b >= 0: +- // +- // i = 0, j = 0x10000'0000, k = -0x1000 +- // result = page(dest) - page(pc) - 0x10000'0000 + 0x1000 +- // +- // when signed A < 0 && signed b < 0: +- // +- // i = -0x10000'0000, j = 0, k = -0x1000 +- // result = page(dest) - page(pc) + 0x1000 +- uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc); +- bool negativeA = lo12(dest) > 0x7ff; +- bool negativeB = (result & 0x8000'0000) != 0; +- +- if (negativeA) +- result += 0x1000; +- if (negativeA && !negativeB) +- result -= 0x10000'0000; +- else if (!negativeA && negativeB) +- result += 0x10000'0000; ++uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type) { ++ // Note that if the sequence being relocated is `pcalau12i + addi.d + lu32i.d ++ // + lu52i.d`, they must be adjancent so that we can infer the PC of ++ // `pcalau12i` when calculating the page delta for the other two instructions ++ // (lu32i.d and lu52i.d). Compensate all the sign-extensions is a bit ++ // complicated. Just use psABI recommended algorithm. ++ uint64_t pcalau12i_pc; ++ switch (type) { ++ case R_LARCH_PCALA64_LO20: ++ case R_LARCH_GOT64_PC_LO20: ++ case R_LARCH_TLS_IE64_PC_LO20: ++ pcalau12i_pc = pc - 8; ++ break; ++ case R_LARCH_PCALA64_HI12: ++ case R_LARCH_GOT64_PC_HI12: ++ case R_LARCH_TLS_IE64_PC_HI12: ++ pcalau12i_pc = pc - 12; ++ break; ++ default: ++ pcalau12i_pc = pc; ++ break; ++ } ++ uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pcalau12i_pc); ++ if (dest & 0x800) ++ result += 0x1000 - 0x1'0000'0000; ++ if (result & 0x8000'0000) ++ result += 0x1'0000'0000; + return result; + } + +diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp +index b178d82407e3..44444b62251d 100644 +--- a/lld/ELF/InputSection.cpp ++++ b/lld/ELF/InputSection.cpp +@@ -712,8 +712,8 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, + return sym.getGotVA() + a - p; + case R_LOONGARCH_GOT_PAGE_PC: + if (sym.hasFlag(NEEDS_TLSGD)) +- return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p); +- return getLoongArchPageDelta(sym.getGotVA() + a, p); ++ return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p, type); ++ return getLoongArchPageDelta(sym.getGotVA() + a, p, type); + case R_MIPS_GOTREL: + return sym.getVA(a) - in.mipsGot->getGp(file); + case R_MIPS_GOT_GP: +@@ -763,7 +763,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, + return 0; + } + case R_LOONGARCH_PAGE_PC: +- return getLoongArchPageDelta(sym.getVA(a), p); ++ return getLoongArchPageDelta(sym.getVA(a), p, type); + case R_PC: + case R_ARM_PCA: { + uint64_t dest; +@@ -798,7 +798,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, + case R_PPC64_CALL_PLT: + return sym.getPltVA() + a - p; + case R_LOONGARCH_PLT_PAGE_PC: +- return getLoongArchPageDelta(sym.getPltVA() + a, p); ++ return getLoongArchPageDelta(sym.getPltVA() + a, p, type); + case R_PLT_GOTPLT: + return sym.getPltVA() + a - in.gotPlt->getVA(); + case R_PPC32_PLTREL: +@@ -860,7 +860,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, + case R_TLSGD_PC: + return in.got->getGlobalDynAddr(sym) + a - p; + case R_LOONGARCH_TLSGD_PAGE_PC: +- return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p); ++ return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p, type); + case R_TLSLD_GOTPLT: + return in.got->getVA() + in.got->getTlsIndexOff() + a - in.gotPlt->getVA(); + case R_TLSLD_GOT: +diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h +index bf831afa1793..aeabe47f92a1 100644 +--- a/lld/ELF/Target.h ++++ b/lld/ELF/Target.h +@@ -229,7 +229,7 @@ void addPPC64SaveRestore(); + uint64_t getPPC64TocBase(); + uint64_t getAArch64Page(uint64_t expr); + template void writeARMCmseImportLib(); +-uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc); ++uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type); + void riscvFinalizeRelax(int passes); + void mergeRISCVAttributesSections(); + void addArmInputSectionMappingSymbols(); +diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s +index e7950400a5c8..0405961e5f74 100644 +--- a/lld/test/ELF/loongarch-pc-aligned.s ++++ b/lld/test/ELF/loongarch-pc-aligned.s +@@ -75,8 +75,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x4443333334567111 --section-start=.text=0x0000000012345678 -o %t/extreme0 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme0 | FileCheck %s --check-prefix=EXTREME0 +-# EXTREME0: addi.d $t0, $zero, 273 +-# EXTREME0-NEXT: pcalau12i $t1, 139810 ++# EXTREME0: pcalau12i $t1, 139810 ++# EXTREME0-NEXT: addi.d $t0, $zero, 273 + # EXTREME0-NEXT: lu32i.d $t0, 209715 + # EXTREME0-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -87,8 +87,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x4443333334567888 --section-start=.text=0x0000000012345678 -o %t/extreme1 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme1 | FileCheck %s --check-prefix=EXTREME1 +-# EXTREME1: addi.d $t0, $zero, -1912 +-# EXTREME1-NEXT: pcalau12i $t1, 139811 ++# EXTREME1: pcalau12i $t1, 139811 ++# EXTREME1-NEXT: addi.d $t0, $zero, -1912 + # EXTREME1-NEXT: lu32i.d $t0, 209714 + # EXTREME1-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -99,8 +99,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x44433333abcde111 --section-start=.text=0x0000000012345678 -o %t/extreme2 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme2 | FileCheck %s --check-prefix=EXTREME2 +-# EXTREME2: addi.d $t0, $zero, 273 +-# EXTREME2-NEXT: pcalau12i $t1, -419431 ++# EXTREME2: pcalau12i $t1, -419431 ++# EXTREME2-NEXT: addi.d $t0, $zero, 273 + # EXTREME2-NEXT: lu32i.d $t0, 209716 + # EXTREME2-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -111,8 +111,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x44433333abcde888 --section-start=.text=0x0000000012345678 -o %t/extreme3 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme3 | FileCheck %s --check-prefix=EXTREME3 +-# EXTREME3: addi.d $t0, $zero, -1912 +-# EXTREME3-NEXT: pcalau12i $t1, -419430 ++# EXTREME3: pcalau12i $t1, -419430 ++# EXTREME3-NEXT: addi.d $t0, $zero, -1912 + # EXTREME3-NEXT: lu32i.d $t0, 209715 + # EXTREME3-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -123,8 +123,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaa34567111 --section-start=.text=0x0000000012345678 -o %t/extreme4 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme4 | FileCheck %s --check-prefix=EXTREME4 +-# EXTREME4: addi.d $t0, $zero, 273 +-# EXTREME4-NEXT: pcalau12i $t1, 139810 ++# EXTREME4: pcalau12i $t1, 139810 ++# EXTREME4-NEXT: addi.d $t0, $zero, 273 + # EXTREME4-NEXT: lu32i.d $t0, -349526 + # EXTREME4-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -135,8 +135,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaa34567888 --section-start=.text=0x0000000012345678 -o %t/extreme5 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme5 | FileCheck %s --check-prefix=EXTREME5 +-# EXTREME5: addi.d $t0, $zero, -1912 +-# EXTREME5-NEXT: pcalau12i $t1, 139811 ++# EXTREME5: pcalau12i $t1, 139811 ++# EXTREME5-NEXT: addi.d $t0, $zero, -1912 + # EXTREME5-NEXT: lu32i.d $t0, -349527 + # EXTREME5-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -147,8 +147,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaaabcde111 --section-start=.text=0x0000000012345678 -o %t/extreme6 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme6 | FileCheck %s --check-prefix=EXTREME6 +-# EXTREME6: addi.d $t0, $zero, 273 +-# EXTREME6-NEXT: pcalau12i $t1, -419431 ++# EXTREME6: pcalau12i $t1, -419431 ++# EXTREME6-NEXT: addi.d $t0, $zero, 273 + # EXTREME6-NEXT: lu32i.d $t0, -349525 + # EXTREME6-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -159,8 +159,8 @@ + ## %pc64_hi12 = 0x444 = 1092 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x444aaaaaabcde888 --section-start=.text=0x0000000012345678 -o %t/extreme7 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme7 | FileCheck %s --check-prefix=EXTREME7 +-# EXTREME7: addi.d $t0, $zero, -1912 +-# EXTREME7-NEXT: pcalau12i $t1, -419430 ++# EXTREME7: pcalau12i $t1, -419430 ++# EXTREME7-NEXT: addi.d $t0, $zero, -1912 + # EXTREME7-NEXT: lu32i.d $t0, -349526 + # EXTREME7-NEXT: lu52i.d $t0, $t0, 1092 + +@@ -171,8 +171,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb3333334567111 --section-start=.text=0x0000000012345678 -o %t/extreme8 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme8 | FileCheck %s --check-prefix=EXTREME8 +-# EXTREME8: addi.d $t0, $zero, 273 +-# EXTREME8-NEXT: pcalau12i $t1, 139810 ++# EXTREME8: pcalau12i $t1, 139810 ++# EXTREME8-NEXT: addi.d $t0, $zero, 273 + # EXTREME8-NEXT: lu32i.d $t0, 209715 + # EXTREME8-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -183,8 +183,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb3333334567888 --section-start=.text=0x0000000012345678 -o %t/extreme9 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme9 | FileCheck %s --check-prefix=EXTREME9 +-# EXTREME9: addi.d $t0, $zero, -1912 +-# EXTREME9-NEXT: pcalau12i $t1, 139811 ++# EXTREME9: pcalau12i $t1, 139811 ++# EXTREME9-NEXT: addi.d $t0, $zero, -1912 + # EXTREME9-NEXT: lu32i.d $t0, 209714 + # EXTREME9-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -195,8 +195,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb33333abcde111 --section-start=.text=0x0000000012345678 -o %t/extreme10 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme10 | FileCheck %s --check-prefix=EXTREME10 +-# EXTREME10: addi.d $t0, $zero, 273 +-# EXTREME10-NEXT: pcalau12i $t1, -419431 ++# EXTREME10: pcalau12i $t1, -419431 ++# EXTREME10-NEXT: addi.d $t0, $zero, 273 + # EXTREME10-NEXT: lu32i.d $t0, 209716 + # EXTREME10-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -207,8 +207,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbb33333abcde888 --section-start=.text=0x0000000012345678 -o %t/extreme11 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme11 | FileCheck %s --check-prefix=EXTREME11 +-# EXTREME11: addi.d $t0, $zero, -1912 +-# EXTREME11-NEXT: pcalau12i $t1, -419430 ++# EXTREME11: pcalau12i $t1, -419430 ++# EXTREME11-NEXT: addi.d $t0, $zero, -1912 + # EXTREME11-NEXT: lu32i.d $t0, 209715 + # EXTREME11-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -219,8 +219,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaa34567111 --section-start=.text=0x0000000012345678 -o %t/extreme12 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme12 | FileCheck %s --check-prefix=EXTREME12 +-# EXTREME12: addi.d $t0, $zero, 273 +-# EXTREME12-NEXT: pcalau12i $t1, 139810 ++# EXTREME12: pcalau12i $t1, 139810 ++# EXTREME12-NEXT: addi.d $t0, $zero, 273 + # EXTREME12-NEXT: lu32i.d $t0, -349526 + # EXTREME12-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -231,8 +231,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaa34567888 --section-start=.text=0x0000000012345678 -o %t/extreme13 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme13 | FileCheck %s --check-prefix=EXTREME13 +-# EXTREME13: addi.d $t0, $zero, -1912 +-# EXTREME13-NEXT: pcalau12i $t1, 139811 ++# EXTREME13: pcalau12i $t1, 139811 ++# EXTREME13-NEXT: addi.d $t0, $zero, -1912 + # EXTREME13-NEXT: lu32i.d $t0, -349527 + # EXTREME13-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -243,8 +243,8 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaaabcde111 --section-start=.text=0x0000000012345678 -o %t/extreme14 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme14 | FileCheck %s --check-prefix=EXTREME14 +-# EXTREME14: addi.d $t0, $zero, 273 +-# EXTREME14-NEXT: pcalau12i $t1, -419431 ++# EXTREME14: pcalau12i $t1, -419431 ++# EXTREME14-NEXT: addi.d $t0, $zero, 273 + # EXTREME14-NEXT: lu32i.d $t0, -349525 + # EXTREME14-NEXT: lu52i.d $t0, $t0, -1093 + +@@ -255,36 +255,47 @@ + ## %pc64_hi12 = 0xbbb = -1093 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0xbbbaaaaaabcde888 --section-start=.text=0x0000000012345678 -o %t/extreme15 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme15 | FileCheck %s --check-prefix=EXTREME15 +-# EXTREME15: addi.d $t0, $zero, -1912 +-# EXTREME15-NEXT: pcalau12i $t1, -419430 ++# EXTREME15: pcalau12i $t1, -419430 ++# EXTREME15-NEXT: addi.d $t0, $zero, -1912 + # EXTREME15-NEXT: lu32i.d $t0, -349526 + # EXTREME15-NEXT: lu52i.d $t0, $t0, -1093 + +-## FIXME: Correct %pc64_lo20 should be 0xfffff (-1) and %pc64_hi12 should be 0xfff (-1), but current values are: +-## page delta = 0x0000000000000000, page offset = 0x888 ++## page delta = 0xffffffff00000000, page offset = 0x888 + ## %pc_lo12 = 0x888 = -1912 + ## %pc_hi20 = 0x00000 = 0 +-## %pc64_lo20 = 0x00000 = 0 +-## %pc64_hi12 = 0x00000 = 0 ++## %pc64_lo20 = 0xfffff = -1 ++## %pc64_hi12 = 0xfff = -1 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16 +-# EXTREME16: addi.d $t0, $zero, -1912 +-# EXTREME16-NEXT: pcalau12i $t1, 0 +-# EXTREME16-NEXT: lu32i.d $t0, 0 +-# EXTREME16-NEXT: lu52i.d $t0, $t0, 0 ++# EXTREME16: pcalau12i $t1, 0 ++# EXTREME16-NEXT: addi.d $t0, $zero, -1912 ++# EXTREME16-NEXT: lu32i.d $t0, -1 ++# EXTREME16-NEXT: lu52i.d $t0, $t0, -1 + +-## FIXME: Correct %pc64_lo20 should be 0x00000 (0) and %pc64_hi12 should be 0x000 (0), but current values are: +-## page delta = 0xffffffff80000000, page offset = 0x888 ++## page delta = 0x0000000080000000, page offset = 0x888 + ## %pc_lo12 = 0x888 = -1912 + ## %pc_hi20 = 0x80000 = -524288 +-## %pc64_lo20 = 0xfffff = -1 +-## %pc64_hi12 = 0xfff = -1 ++## %pc64_lo20 = 0xfffff = 0 ++## %pc64_hi12 = 0xfff = 0 + # RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17 + # RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17 +-# EXTREME17: addi.d $t0, $zero, -1912 +-# EXTREME17-NEXT: pcalau12i $t1, -524288 +-# EXTREME17-NEXT: lu32i.d $t0, -1 +-# EXTREME17-NEXT: lu52i.d $t0, $t0, -1 ++# EXTREME17: pcalau12i $t1, -524288 ++# EXTREME17-NEXT: addi.d $t0, $zero, -1912 ++# EXTREME17-NEXT: lu32i.d $t0, 0 ++# EXTREME17-NEXT: lu52i.d $t0, $t0, 0 ++ ++## A case that pcalau12i, lu32i.d and lu52i.d are in different pages. ++## page delta = 0x0000000080000000, page offset = 0x123 ++## %pc_lo12 = 0x111 = 273 ++## %pc_hi20 = 0x80000 = -524288 ++## %pc64_lo20 = 0x00001 = 1 ++## %pc64_hi12 = 0x000 = 0 ++# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x80000111 --section-start=.text=0xff8 -o %t/extreme18 ++# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme18 | FileCheck %s --check-prefix=EXTREME18 ++# EXTREME18: pcalau12i $t1, -524288 ++# EXTREME18-NEXT: addi.d $t0, $zero, 273 ++# EXTREME18-NEXT: lu32i.d $t0, 1 ++# EXTREME18-NEXT: lu52i.d $t0, $t0, 0 + + #--- a.s + .rodata +@@ -303,7 +314,7 @@ x: + .text + .global _start + _start: +- addi.d $t0, $zero, %pc_lo12(x) + pcalau12i $t1, %pc_hi20(x) ++ addi.d $t0, $zero, %pc_lo12(x) + lu32i.d $t0, %pc64_lo20(x) + lu52i.d $t0, $t0, %pc64_hi12(x) +-- +2.20.1 + diff --git a/lld.spec b/lld.spec index a9a221a2fc88b268a3657e660abbe8674a8423e2..183330cb1ad45cb273c68223014e3569c9c5ab00 100644 --- a/lld.spec +++ b/lld.spec @@ -38,7 +38,7 @@ Name: %{pkg_name} Version: %{maj_ver}.%{min_ver}.%{patch_ver} -Release: 5 +Release: 6 Summary: The LLVM Linker License: NCSA @@ -51,6 +51,7 @@ Patch3: 0003-Backport-ELF-RISCV-Implement-emit-relocs-with-relaxation.patch Patch4: 0004-Backport-lld-ELF-Support-relax-R_LARCH_ALIGN.patch Patch5: 0005-Backport-lld-LoongArch-Support-the-R_LARCH_-ADD-SUB-_ULEB128-relocation-types.patch Patch6: 0006-Add-BiSheng-Autotuner-support-for-LLVM-compiler.patch +Patch7: 0007-Backport-LoongArch-add-support-for-call36-and-extreme-relocs.patch BuildRequires: clang BuildRequires: cmake @@ -145,6 +146,9 @@ rm %{buildroot}%{install_includedir}/mach-o/compact_unwind_encoding.h %{install_libdir}/liblld*.so.* %changelog +* Mon Sep 23 2024 zhanglimin - 17.0.6-6 +- [LoongArch] Backport the support for call36 and extreme model relocs. + * Tue Jul 30 2024 liyunfei - 17.0.6-5 - Disable toolchain_clang build for BiSheng Autotuner support temporary.