https://sourceware.org/bugzilla/show_bug.cgi?id=33556
Bug ID: 33556
Summary: [RISC-V] Incorrect relaxation for call to weak
absolute symbol at 0
Product: binutils
Version: 2.45
Status: UNCONFIRMED
Severity: minor
Priority: P2
Component: binutils
Assignee: unassigned at sourceware dot org
Reporter: davidegrayson at gmail dot com
Target Milestone: ---
I found a case where the GNU linker performs an erroneous RISCV-V relaxation.
It changes the 8-byte R_RISCV_CALL_PLT into a 4-byte R_RISCV_JAL, which only
works if the relocation is within 1 MB of the target, but it should not
do that because the relocation is at address 0x10000000 and the target is 0.
This incorrect relaxation prevents the linker from producing correct code
and results in the error:
(.text+0x0): relocation truncated to fit: R_RISCV_JAL against `*UND*'
Here is the code that reproduces this:
==== weird.asm ====
.text
.global _start
_start:
.weak _foo
call _foo
_foo = 0
==== pc64k.ld ====
MEMORY {
ROM (r): ORIGIN = 0x10000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
}
ENTRY(_start)
SECTIONS {
.text : { *(.text .text.*) } >ROM
.data : { *(.data .data.*) } >RAM
.bss (NOLOAD) : { *(.bss .bss.*) } >RAM
}
==== build.sh ====
riscv64-unknown-elf-as -mabi=ilp32 -march=rv32i weird.asm -o weird.o
riscv64-unknown-elf-ld -melf32lriscv --relax --gc-sections -Tpc64k.ld weird.o
-o weird.elf
====
Several things make the bug go away:
- Changing the value of _foo to 1.
- Removing the MEMORY directives from the linker script.
- Removing the ".weak" directive.
- Removing the "_foo = 0" line, which defines _foo as an absolute symbol.
I haven't looked at the GNU linker code very much so I don't have any ideas
about why this is happening.
--
You are receiving this mail because:
You are on the CC list for the bug.