[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