[PATCH] RISC-V: Also output undefined symbols as dynamic symbols

Nelson Chu nelson.chu1990@gmail.com
Wed May 13 15:10:18 GMT 2026


On Mon, May 11, 2026 at 12:28 PM Vivian Wang <wangruikang@iscas.ac.cn> wrote:
>
> Consider this program, which refers to an undefined symbol foo:
>
>   int foo(void);
>   int main() { foo(); }
>
> If linking with --unresolved-symbols=ignore-in-object-file, what should
> happen is the symbol foo is left undefined and left for the dynamic
> linker to resolve. (See commit 4295841be439 ("RISC-V: Go PLT for
> CALL/JUMP/RVC_JUMP if `h->plt.offset' isn't -1").) Instead, with
> binutils 2.46:
>
> 1. With -no-pie, ld generates an auipc/jalr call to address 0, crashing
>    at runtime instead of generating an undefined symbol message.
>
> 2. With -pie, ld generates this bogus error message (-fPIC does not
>    change this, and R_RISCV_CALL_PLT is correct here) and stops, failing
>    to produce an executable:
>
>      ld: relocation R_RISCV_CALL_PLT against `foo' which may bind
>      externally can not be used when making a shared object; recompile
>      with -fPIC
>
> Bisection leads to commit 9e10fcf71c11 ("RISC-V: Fix the assert fail
> when linking discarded sections under -pie for got"), which stopped
> outputting dynamic symbols for non-undefweak symbols. Therefore, in
> order to fix the issue, also output undefined symbols as dynamic
> symbols.

So do you think we should also stop output dynamic symbols for
undefined symbols?  umm maybe you are right, I am not sure.  Just
curious, it seems other targets don't need to handle
bfd_link_hash_undefined in the following codes, so why and what's the
difference between riscv and others?  I think we might miss some
codes, rather than the codes here, just guess.

Thanks
Nelson

> Fixes test case ld-elf/dwarf.exp, specifically dwarf3, where the bogus
> error prevents the second "undefined reference" error from appearing. No
> regressions found for the ld tests on riscv64.
>
> bfd/:
>
>         * elfnn-riscv.c (allocate_dynrelocs): Also output undefined
>         symbols as dynamic symbols
>
> Fixes: 9e10fcf71c11 ("RISC-V: Fix the assert fail when linking discarded sections under -pie for got")
> ---
> This is my first patch to binutils. Please advise if I'm doing something wrong. Thanks.
>
> Vivian "dramforever" Wang
> ---
>  bfd/elfnn-riscv.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index eb3d7926c..d66c42b78 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -1439,10 +1439,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
>            && h->plt.refcount > 0)
>      {
>        /* Make sure this symbol is output as a dynamic symbol.
> -        Undefined weak syms won't yet be marked as dynamic.  */
> +        Undefined and undefweak syms won't yet be marked as dynamic.  */
>        if (h->dynindx == -1
>           && !h->forced_local
> -         && h->root.type == bfd_link_hash_undefweak
> +         && (h->root.type == bfd_link_hash_undefweak
> +             || h->root.type == bfd_link_hash_undefined)
>           && !bfd_elf_link_record_dynamic_symbol (info, h))
>         return false;
>
> @@ -1500,11 +1501,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
>        int tls_type = riscv_elf_hash_entry (h)->tls_type;
>
>        /* Make sure this symbol is output as a dynamic symbol.
> -        Undefined weak syms won't yet be marked as dynamic.  */
> +        Undefined and undefweak syms won't yet be marked as dynamic.  */
>        if (dyn
>           && h->dynindx == -1
>           && !h->forced_local
> -         && h->root.type == bfd_link_hash_undefweak
> +         && (h->root.type == bfd_link_hash_undefweak
> +             || h->root.type == bfd_link_hash_undefined)
>           && !bfd_elf_link_record_dynamic_symbol (info, h))
>         return false;
>
> @@ -1611,10 +1613,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
>                       || h->root.type == bfd_link_hash_undefined))))
>         {
>           /* Make sure this symbol is output as a dynamic symbol.
> -            Undefined weak syms won't yet be marked as dynamic.  */
> +            Undefined and undefweak syms won't yet be marked as dynamic.  */
>           if (h->dynindx == -1
>               && !h->forced_local
> -             && h->root.type == bfd_link_hash_undefweak
> +             && (h->root.type == bfd_link_hash_undefweak
> +                 || h->root.type == bfd_link_hash_undefined)
>               && !bfd_elf_link_record_dynamic_symbol (info, h))
>             return false;
>
> --
> 2.53.0
>


More information about the Binutils mailing list