[PATCH 2/2] RISC-V: Don't generate R_RISCV_RELATIVE if symbol referenced section is SH_ABS

Fangrui Song maskray@sourceware.org
Thu Aug 21 05:42:07 GMT 2025


On Wed, Aug 20, 2025 at 9:33 PM Nelson Chu <nelson@rivosinc.com> wrote:
>
> It's werid if it's absolute symbol but have a relative reloc for got entry
> under pie.  So don't generate relative reloc if symbol referenced section is
> SH_ABS.  However, x86 allows the absolute symbol defined in linker script has
> a relative reloc, not sure if risc-v needs this or not.
> ---
>  bfd/elfnn-riscv.c                                 | 3 ++-
>  ld/testsuite/ld-riscv-elf/absolute-no-relative.d  | 9 +++++++++
>  ld/testsuite/ld-riscv-elf/absolute-no-relative.ld | 6 ++++++
>  ld/testsuite/ld-riscv-elf/absolute-no-relative.s  | 8 ++++++++
>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp        | 1 +
>  5 files changed, 26 insertions(+), 1 deletion(-)
>  create mode 100644 ld/testsuite/ld-riscv-elf/absolute-no-relative.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/absolute-no-relative.ld
>  create mode 100644 ld/testsuite/ld-riscv-elf/absolute-no-relative.s
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 6ff64325f85..aac061fb43d 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -2880,7 +2880,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
>                       if (h->dynindx == -1
>                           && !h->forced_local
>                           && h->root.type != bfd_link_hash_undefweak
> -                         && bfd_link_pic (info))
> +                         && bfd_link_pic (info)
> +                         && !bfd_is_abs_section(h->root.u.def.section))
>                         relative_got = true;
>
>                       bfd_put_NN (output_bfd, relocation,
> diff --git a/ld/testsuite/ld-riscv-elf/absolute-no-relative.d b/ld/testsuite/ld-riscv-elf/absolute-no-relative.d
> new file mode 100644
> index 00000000000..6699ac1d0ef
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/absolute-no-relative.d
> @@ -0,0 +1,9 @@
> +#source: absolute-no-relative.s
> +#as:
> +#ld: -Tabsolute-no-relative.ld -pie
> +#readelf: -Wr
> +
> +Relocation section '.rela.dyn' at .*
> +[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
> +0+[    ]+0+[   ]+R_RISCV_NONE[         ]+0
> +0+[    ]+0+[   ]+R_RISCV_NONE[         ]+0
> diff --git a/ld/testsuite/ld-riscv-elf/absolute-no-relative.ld b/ld/testsuite/ld-riscv-elf/absolute-no-relative.ld
> new file mode 100644
> index 00000000000..34bbcba7e73
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/absolute-no-relative.ld
> @@ -0,0 +1,6 @@
> +ENTRY(_start)
> +SECTIONS {
> +       __symbol_abs__ = 0x1234;
> +       .text 0x10000 : { *(.text*)}
> +       .got  0x20000 : { *(.got*) }
> +}
> diff --git a/ld/testsuite/ld-riscv-elf/absolute-no-relative.s b/ld/testsuite/ld-riscv-elf/absolute-no-relative.s
> new file mode 100644
> index 00000000000..4515661cfd5
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/absolute-no-relative.s
> @@ -0,0 +1,8 @@
> +.text
> +.global _start
> +_start:
> +lga    x1, symbol_abs
> +lga    x1, __symbol_abs__
> +
> +.global symbol_abs
> +.set symbol_abs, 0x100
> diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> index bae1105cad6..b0d510ac8da 100644
> --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> @@ -338,4 +338,5 @@ if [istarget "riscv*-*-*"] {
>      }
>      run_dump_test "tls"
>      run_dump_test "tlsbin"
> +    run_dump_test "absolute-no-relative"
>  }
> --
> 2.39.5 (Apple Git-154)
>

Reviewed-by: Fangrui Song <maskray@sourceware.org>

I haven't checked, but I suspect that the condition `h->root.type !=
bfd_link_hash_undefweak` should be generalized to undefined.
In a   -pie -z undefs  or -pie --noinhibit-exec    link, an undefined
non-weak symbol should be treated as an absolute value as well.
-z undefs suppresses the "undefined symbol" error.


More information about the Binutils mailing list