Skip to content

Commit 6590ec8

Browse files
xry111lzshhxx
authored andcommitted
LoongArch: Adapt R_LARCH_{PCALA,GOT,TLS_IE,TLS_DESC}64_* handling per psABI v2.30
In LoongArch psABI v2.30, an offset (-8 for LO20 and -12 for HI12) should be applied on PC for these reloc types to avoid wrong relocation when the instruction sequence crosses a page boundary. The lld linker has already adapted the change. Make it for the bfd linker too. Link: https://github.com/loongson/la-abi-specs/releases/v2.30 Link: loongson-community/discussions#17 Link: llvm/llvm-project#73387 Signed-off-by: Xi Ruoyao <[email protected]>
1 parent 5e35a3a commit 6590ec8

File tree

4 files changed

+42
-13
lines changed

4 files changed

+42
-13
lines changed

bfd/elfnn-loongarch.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,7 +2529,7 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
25292529
({ \
25302530
bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
25312531
relocation = (relocation & ~(bfd_vma)0xfff) \
2532-
- (pc & ~(bfd_vma)0xfff); \
2532+
- ((pc) & ~(bfd_vma)0xfff); \
25332533
if (__lo > 0x7ff) \
25342534
relocation += (0x1000 - 0x100000000); \
25352535
if (relocation & 0x80000000) \
@@ -3534,14 +3534,16 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
35343534
}
35353535
break;
35363536

3537-
case R_LARCH_PCALA64_LO20:
35383537
case R_LARCH_PCALA64_HI12:
3538+
pc -= 4;
3539+
/* Fall through. */
3540+
case R_LARCH_PCALA64_LO20:
35393541
if (h && h->plt.offset != MINUS_ONE)
35403542
relocation = sec_addr (plt) + h->plt.offset;
35413543
else
35423544
relocation += rel->r_addend;
35433545

3544-
RELOCATE_CALC_PC64_HI32 (relocation, pc);
3546+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
35453547

35463548
break;
35473549

@@ -3668,9 +3670,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
36683670
relocation = got_off + sec_addr (got);
36693671
}
36703672

3671-
if (r_type == R_LARCH_GOT64_PC_HI12
3672-
|| r_type == R_LARCH_GOT64_PC_LO20)
3673-
RELOCATE_CALC_PC64_HI32 (relocation, pc);
3673+
if (r_type == R_LARCH_GOT64_PC_HI12)
3674+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3675+
else if (r_type == R_LARCH_GOT64_PC_LO20)
3676+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
36743677

36753678
break;
36763679

@@ -3871,13 +3874,14 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
38713874
/* Use both TLS_GD and TLS_DESC. */
38723875
if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
38733876
relocation += 2 * GOT_ENTRY_SIZE;
3874-
}
38753877

3876-
if (r_type == R_LARCH_TLS_DESC64_PC_LO20
3877-
|| r_type == R_LARCH_TLS_DESC64_PC_HI12)
3878-
RELOCATE_CALC_PC64_HI32 (relocation, pc);
3878+
if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
3879+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3880+
else if (r_type == R_LARCH_TLS_DESC64_PC_HI12)
3881+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
38793882

38803883
break;
3884+
}
38813885

38823886
case R_LARCH_TLS_DESC_LD:
38833887
case R_LARCH_TLS_DESC_CALL:
@@ -3906,9 +3910,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
39063910
else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
39073911
relocation += 2 * GOT_ENTRY_SIZE;
39083912

3909-
if (r_type == R_LARCH_TLS_IE64_PC_LO20
3910-
|| r_type == R_LARCH_TLS_IE64_PC_HI12)
3911-
RELOCATE_CALC_PC64_HI32 (relocation, pc);
3913+
if (r_type == R_LARCH_TLS_IE64_PC_LO20)
3914+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3915+
else if (r_type == R_LARCH_TLS_IE64_PC_HI12)
3916+
RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
39123917

39133918
break;
39143919

ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ if [istarget "loongarch64-*-*"] {
3333
run_dump_test "disas-jirl"
3434
run_dump_test "local-ifunc-reloc"
3535
run_dump_test "anno-sym"
36+
run_dump_test "pcala64"
3637
}
3738

3839
if [istarget "loongarch32-*-*"] {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ld: -Ttext=0x180000ff8 -Tdata=0x1000000000
2+
#objdump: -d
3+
4+
.*:[ ]+file format .*
5+
6+
7+
Disassembly of section .text:
8+
9+
0000000180000ff8 <_start>:
10+
[ ]+180000ff8:[ ]+1b000004[ ]+pcalau12i[ ]+\$a0,[ ]+-524288
11+
[ ]+180000ffc:[ ]+02c0000c[ ]+li.d[ ]+\$t0,[ ]+0
12+
[ ]+180001000:[ ]+160001ec[ ]+lu32i.d[ ]+\$t0,[ ]+15
13+
[ ]+180001004:[ ]+0300018c[ ]+lu52i.d[ ]+\$t0,[ ]+\$t0,[ ]+0
14+
[ ]+180001008:[ ]+0010b084[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$t0
15+
[ ]+18000100c:[ ]+4c000020[ ]+ret
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.text
2+
.globl _start
3+
_start:
4+
la.pcrel $a0, $t0, sym
5+
jr $ra
6+
.data
7+
sym:
8+
.dword 0

0 commit comments

Comments
 (0)