Skip to content

Commit 3a3dd03

Browse files
committed
[lld][LoongArch] Fix relaxation for R_LARCH_GOT_PC_{HI20,LO12}
We could relax codes when the addends of both relocations are zero. Note: For `ld.bfd`, GOT references with non-zero addends will trigger an assert in LoongArch, but `lld` handles these cases without any errors. ``` ld.bfd: BFD (GNU Binutils) 2.44.0 assertion fail /usr/src/debug/binutils/binutils-gdb/bfd/elfnn-loongarch.c:4248 ```
1 parent 92d0924 commit 3a3dd03

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

lld/ELF/Arch/LoongArch.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -809,10 +809,13 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
809809
// address.
810810
// Meanwhile skip undefined, preemptible and STT_GNU_IFUNC symbols, because
811811
// these symbols may be resolve in runtime.
812+
// Moreover, relaxation can only occur if the addends of both relocations are
813+
// zero for GOT references.
812814
if (rHi20.type == R_LARCH_GOT_PC_HI20 &&
813-
(!rHi20.sym->isDefined() || rHi20.sym->isPreemptible ||
814-
rHi20.sym->isGnuIFunc() ||
815-
(ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section)))
815+
(!rHi20.sym || rHi20.sym != rLo12.sym || !rHi20.sym->isDefined() ||
816+
rHi20.sym->isPreemptible || rHi20.sym->isGnuIFunc() ||
817+
(ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section) ||
818+
rHi20.addend != 0 || rLo12.addend != 0))
816819
return;
817820

818821
uint64_t dest = 0;

lld/test/ELF/loongarch-relax-pc-hi20-lo12.s

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# REQUIRES: loongarch
22

3-
# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax %s -o %t.32.o
3+
# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax --defsym ELF32=1 %s -o %t.32.o
44
# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t.64.o
55

66
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.32.o -o %t.32
77
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.64.o -o %t.64
8-
# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck --check-prefixes=RELAX %s
9-
# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck --check-prefixes=RELAX %s
8+
# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck --check-prefixes=RELAX,RELAX32 %s
9+
# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck --check-prefixes=RELAX,RELAX64 %s
1010

1111
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.32.o -shared -o %t.32s
1212
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.64.o -shared -o %t.64s
@@ -25,6 +25,11 @@
2525
# RELAX-NEXT: pcaddi $a0, 4094
2626
# RELAX-NEXT: pcaddi $a0, 4093
2727

28+
# RELAX32-NEXT: pcalau12i $a0, 4
29+
# RELAX32-NEXT: ld.w $a0, $a0, 8
30+
# RELAX64-NEXT: pcalau12i $a0, 4
31+
# RELAX64-NEXT: ld.d $a0, $a0, 12
32+
2833
# NORELAX32-LABEL: <_start>:
2934
## offset exceed range of pcaddi
3035
## offset = 0x410000 - 0x10000: 0x400 pages, page offset 0
@@ -36,6 +41,8 @@
3641
# NORELAX32-NEXT: addi.w $a0, $a0, 0
3742
# NORELAX32-NEXT: pcalau12i $a0, 1024
3843
# NORELAX32-NEXT: ld.w $a0, $a0, 4
44+
# NORELAX32-NEXT: pcalau12i $a0, 1024
45+
# NORELAX32-NEXT: ld.w $a0, $a0, 8
3946

4047
# NORELAX64-LABEL: <_start>:
4148
## offset exceed range of pcaddi
@@ -48,6 +55,16 @@
4855
# NORELAX64-NEXT: addi.d $a0, $a0, 0
4956
# NORELAX64-NEXT: pcalau12i $a0, 1024
5057
# NORELAX64-NEXT: ld.d $a0, $a0, 8
58+
# NORELAX64-NEXT: pcalau12i $a0, 1024
59+
# NORELAX64-NEXT: ld.d $a0, $a0, 12
60+
61+
.macro ld dst, src1, src2
62+
.ifdef ELF32
63+
ld.w \dst, \src1, \src2
64+
.else
65+
ld.d \dst, \src1, \src2
66+
.endif
67+
.endm
5168

5269
.section .text
5370
.global _start
@@ -57,6 +74,11 @@ _start:
5774
la.pcrel $a0, sym
5875
la.got $a0, sym
5976

77+
pcalau12i $a0, %got_pc_hi20(sym+4)
78+
.reloc .-4, R_LARCH_RELAX, 0
79+
ld $a0, $a0, %got_pc_lo12(sym+4)
80+
.reloc .-4, R_LARCH_RELAX, 0
81+
6082
.section .data
6183
sym:
6284
.zero 4

0 commit comments

Comments
 (0)