binutils-gdb/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a-emit-relocs.d
Nelson Chu 81c353cb9c RISC-V: PR27180, Update relocation for riscv_zero_pcrel_hi_reloc.
When pcrel access overflow, the riscv_zero_pcrel_hi_reloc may convert pcrel
relocation to absolutly access if possible at the relocate stage.  We used to
encode the target address into r_sym of R_RISCV_HI20 if it is converted from
R_RISCV_PCREL_HI20.  But that may cause segfault if --emit-relocs is set,
since r_sym becomes an address rather than a symbol index.  Although the
relocate result is correct, it does not meet the definition, so may cause
unexpected behaviors.

This patch encodes the target address into r_addend, rather than r_sym, if
riscv_zero_pcrel_hi_reloc converts the relocation.  Besdies, since the
corresponding pcrel_lo relocation are also changed to absolutly access,
we should also update them to R_RISCV_LO12_I/S.

bfd/
	PR 27180
	* elfnn-riscv.c (riscv_pcrel_hi_reloc): New boolean `absolute', to
	inform corresponding pcrel_lo that the pcrel_hi relocation was already
	converted to hi20 relocation.
	(riscv_record_pcrel_hi_reloc): Likewise, record `absolute'.
	(riscv_pcrel_lo_reloc): Removed `const' for Elf_Internal_Rela *reloc,
	since we may need to convert it from pcrel_lo to lo relocation.
	(riscv_record_pcrel_lo_reloc): Likewise.  Convert pcrel_lo to lo
	relocation if corresponding pcrel_hi was converted to hi relocation.
	(riscv_zero_pcrel_hi_reloc): Encode target absolute address into
	r_addend rather than r_sym.  Clear the `addr' to avoid duplicate
	relocate in the perform_relocation.
	(riscv_elf_relocate_section): Updated.
ld/
	PR 27180
	* testsuite/ld-riscv-elf/pcrel-lo-addend-3a-emit-relocs.d: New testcase.
	Segfault without applying this patch.
	* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
2024-06-28 13:36:49 +08:00

27 lines
932 B
Makefile

#source: pcrel-lo-addend-3a.s
#as: -march=rv64i -mabi=lp64 -mno-relax
#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld --emit-relocs
#objdump: -dr
#...
Disassembly of section .text:
0+900000000 <_start>:
.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x2
.*:[ ]+R_RISCV_HI20[ ]+\*ABS\*\+0x2000
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,0\(a5\) # 2000 <ll>
.*:[ ]+R_RISCV_LO12_I[ ]+\*ABS\*\+0x2000
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,4\(a5\)
.*:[ ]+R_RISCV_LO12_I[ ]+\*ABS\*\+0x2004
.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x2
.*:[ ]+R_RISCV_HI20[ ]+\*ABS\*\+0x2004
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,4\(a5\) # 2004 <ll\+0x4>
.*:[ ]+R_RISCV_LO12_I[ ]+\*ABS\*\+0x2004
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,8\(a5\)
.*:[ ]+R_RISCV_LO12_I[ ]+\*ABS\*\+0x2008
.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x1
.*:[ ]+R_RISCV_HI20[ ]+\*ABS\*\+0x1008
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,8\(a5\) # 1008 <_GLOBAL_OFFSET_TABLE_\+0x8>
.*:[ ]+R_RISCV_LO12_I[ ]+\*ABS\*\+0x1008
#pass