[PATCH 1/3] ld/ELF: Move -z dynamic-undefined-weak flag handling to elf.em
H.J. Lu
hjl.tools@gmail.com
Wed Jul 16 18:21:59 GMT 2025
On Wed, Jul 16, 2025 at 9:05 AM Hakan Candar <hakan@envs.net> wrote:
>
> The -z [no]dynamic-undefined-weak flag was previously handled through
> emulparams scripts, only wired into select backends like x86 and PPC.
>
> This patch moves its handling into elf.em so that it applies uniformly
> across all ELF backends, removing the need for per-target boilerplate.
>
> This change does not alter behavior for targets that already used the
> flag, but enables proper support on targets that previously ignored or
> warned on it (e.g., AArch64, RISC-V, MIPS).
>
> ld/
> * emultempl/elf.em: Add -z dynamic-undefined-weak flag handling.
> * emulparams/dynamic_undefined_weak.sh: Delete.
> * emulparams/elf32_x86_64.sh: Remove source line.
> * emulparams/elf32ppccommon.sh: Likewise.
> * emulparams/elf_i386.sh: Likewise.
> * emulparams/elf_i386_be.sh: Likewise.
> * emulparams/elf_i386_ldso.sh: Likewise.
> * emulparams/elf_i386_vxworks.sh: Likewise.
> * emulparams/elf_iamcu.sh: Likewise.
> * emulparams/elf_x86_64.sh: Likewise.
> * ld.texi: Clarify that '-z dynamic-undefined-weak' is now accepted
> for all ELF targets, though some backends may not fully support it.
> * lexsup.c (elf_shlib_list_options): Document '-z dynamic-undefined-weak'
> and '-z nodynamic-undefined-weak' options in help output.
> * NEWS: Mention the new, centralized behaviour.
>
> ld/testsuite/
> * ld-undefined/weak-undef.exp: Enable validation of
> undefined symbol retention for AArch64, RISC-V, and MIPS by
> setting appropriate assembler flags.
>
> Signed-off-by: Hakan Candar <hakan@envs.net>
> ---
> ld/NEWS | 7 ++++
> ld/emulparams/dynamic_undefined_weak.sh | 15 ---------
> ld/emulparams/elf32_x86_64.sh | 1 -
> ld/emulparams/elf32ppccommon.sh | 1 -
> ld/emulparams/elf_i386.sh | 1 -
> ld/emulparams/elf_i386_be.sh | 1 -
> ld/emulparams/elf_i386_ldso.sh | 1 -
> ld/emulparams/elf_i386_vxworks.sh | 1 -
> ld/emulparams/elf_iamcu.sh | 1 -
> ld/emulparams/elf_x86_64.sh | 1 -
> ld/emultempl/elf.em | 7 ++++
> ld/ld.texi | 7 ++--
> ld/lexsup.c | 3 ++
> ld/testsuite/ld-undefined/weak-fundef.s | 3 ++
> ld/testsuite/ld-undefined/weak-undef.exp | 42 ++++++++++--------------
> 15 files changed, 42 insertions(+), 50 deletions(-)
> delete mode 100644 ld/emulparams/dynamic_undefined_weak.sh
>
> diff --git a/ld/NEWS b/ld/NEWS
> index 217c5b7b0d3..dcb8511fc04 100644
> --- a/ld/NEWS
> +++ b/ld/NEWS
> @@ -2,6 +2,13 @@
>
> Changes in 2.45:
>
> +* The -z [no]dynamic-undefined-weak option is now handled centrally in the
> + ELF emulation code and is accepted on all ELF targets. This removes the
> + need for per-target wiring.
> +
> + Some backends may not yet fully respect this centralized
> + logic due to backend-specific conditionals.
> +
> * On s390 64-bit (s390x), generate SFrame stack trace information (.sframe)
> for the linker generated .plt section. Enabled by default. Can be disabled
> using linker option --no-ld-generated-unwind-info.
> diff --git a/ld/emulparams/dynamic_undefined_weak.sh b/ld/emulparams/dynamic_undefined_weak.sh
> deleted file mode 100644
> index 21393d40d26..00000000000
> --- a/ld/emulparams/dynamic_undefined_weak.sh
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -PARSE_AND_LIST_OPTIONS_DYNAMIC_UNDEFINED_WEAK='
> - fprintf (file, _("\
> - -z dynamic-undefined-weak Make undefined weak symbols dynamic\n\
> - -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic\n"));
> -'
> -
> -PARSE_AND_LIST_ARGS_CASE_Z_DYNAMIC_UNDEFINED_WEAK='
> - else if (strcmp (optarg, "dynamic-undefined-weak") == 0)
> - link_info.dynamic_undefined_weak = true;
> - else if (strcmp (optarg, "nodynamic-undefined-weak") == 0)
> - link_info.dynamic_undefined_weak = false;
> -'
> -
> -PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_DYNAMIC_UNDEFINED_WEAK"
> -PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_DYNAMIC_UNDEFINED_WEAK"
> diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh
> index 6a92eec129d..1a027732239 100644
> --- a/ld/emulparams/elf32_x86_64.sh
> +++ b/ld/emulparams/elf32_x86_64.sh
> @@ -1,6 +1,5 @@
> source_sh ${srcdir}/emulparams/plt_unwind.sh
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/reloc_overflow.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> source_sh ${srcdir}/emulparams/cet.sh
> diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh
> index da892988f5d..f3ca889a37b 100644
> --- a/ld/emulparams/elf32ppccommon.sh
> +++ b/ld/emulparams/elf32ppccommon.sh
> @@ -1,6 +1,5 @@
> # The PLT-agnostic parts of a generic 32-bit ELF PowerPC target. Included by:
> # elf32ppc.sh elf32ppcvxworks.sh elf64ppc.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
>
> TEMPLATE_NAME=elf
> GENERATE_SHLIB_SCRIPT=yes
> diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh
> index 6f698bb0b06..e7ef5185bd4 100644
> --- a/ld/emulparams/elf_i386.sh
> +++ b/ld/emulparams/elf_i386.sh
> @@ -1,6 +1,5 @@
> source_sh ${srcdir}/emulparams/plt_unwind.sh
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> source_sh ${srcdir}/emulparams/cet.sh
> source_sh ${srcdir}/emulparams/x86-report-relative.sh
> diff --git a/ld/emulparams/elf_i386_be.sh b/ld/emulparams/elf_i386_be.sh
> index dbe68e99e63..a03770f9aff 100644
> --- a/ld/emulparams/elf_i386_be.sh
> +++ b/ld/emulparams/elf_i386_be.sh
> @@ -1,5 +1,4 @@
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> SCRIPT_NAME=elf
> OUTPUT_FORMAT="elf32-i386"
> diff --git a/ld/emulparams/elf_i386_ldso.sh b/ld/emulparams/elf_i386_ldso.sh
> index 081de5f8e71..4917a65f80c 100644
> --- a/ld/emulparams/elf_i386_ldso.sh
> +++ b/ld/emulparams/elf_i386_ldso.sh
> @@ -1,6 +1,5 @@
> source_sh ${srcdir}/emulparams/plt_unwind.sh
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> SCRIPT_NAME=elf
> OUTPUT_FORMAT="elf32-i386"
> diff --git a/ld/emulparams/elf_i386_vxworks.sh b/ld/emulparams/elf_i386_vxworks.sh
> index 40c809263d1..4645967a81f 100644
> --- a/ld/emulparams/elf_i386_vxworks.sh
> +++ b/ld/emulparams/elf_i386_vxworks.sh
> @@ -13,5 +13,4 @@ GENERATE_PIE_SCRIPT=yes
> NO_SMALL_DATA=yes
> source_sh ${srcdir}/emulparams/vxworks.sh
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> diff --git a/ld/emulparams/elf_iamcu.sh b/ld/emulparams/elf_iamcu.sh
> index c1582235eda..ccd74a2ba05 100644
> --- a/ld/emulparams/elf_iamcu.sh
> +++ b/ld/emulparams/elf_iamcu.sh
> @@ -1,6 +1,5 @@
> source_sh ${srcdir}/emulparams/plt_unwind.sh
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> SCRIPT_NAME=elf
> OUTPUT_FORMAT="elf32-iamcu"
> diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh
> index 92449745c7a..ac779591f01 100644
> --- a/ld/emulparams/elf_x86_64.sh
> +++ b/ld/emulparams/elf_x86_64.sh
> @@ -1,6 +1,5 @@
> source_sh ${srcdir}/emulparams/plt_unwind.sh
> source_sh ${srcdir}/emulparams/extern_protected_data.sh
> -source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh
> source_sh ${srcdir}/emulparams/reloc_overflow.sh
> source_sh ${srcdir}/emulparams/call_nop.sh
> source_sh ${srcdir}/emulparams/cet.sh
> diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
> index 431205fe644..5e87a294fbc 100644
> --- a/ld/emultempl/elf.em
> +++ b/ld/emultempl/elf.em
> @@ -1115,6 +1115,13 @@ fragment <<EOF
> link_info.textrel_check = textrel_check_none;
> EOF
>
> +fragment <<EOF
> + else if (strcmp (optarg, "dynamic-undefined-weak") == 0)
> + link_info.dynamic_undefined_weak = true;
> + else if (strcmp (optarg, "nodynamic-undefined-weak") == 0)
> + link_info.dynamic_undefined_weak = false;
> +EOF
> +
> if test -n "$PARSE_AND_LIST_ARGS_CASE_Z" ; then
> fragment <<EOF
> $PARSE_AND_LIST_ARGS_CASE_Z
> diff --git a/ld/ld.texi b/ld/ld.texi
> index 413335ad765..ffdb4d97412 100644
> --- a/ld/ld.texi
> +++ b/ld/ld.texi
> @@ -1438,8 +1438,11 @@ if they are referenced from a regular object file and not forced local
> by symbol visibility or versioning. Do not make them dynamic if
> @samp{nodynamic-undefined-weak}. If neither option is given, a target
> may default to either option being in force, or make some other
> -selection of undefined weak symbols dynamic. Not all targets support
> -these options.
> +selection of undefined weak symbols dynamic.
> +
> +These options are available for all ELF targets, but some backends may
> +not yet fully implement consistent handling of undefined symbol retention.
> +This is considered a backend bug, not lack of support.
>
> @item execstack
> Marks the object as requiring executable stack.
> diff --git a/ld/lexsup.c b/ld/lexsup.c
> index bde20465835..5f0c040e352 100644
> --- a/ld/lexsup.c
> +++ b/ld/lexsup.c
> @@ -2267,6 +2267,9 @@ elf_shlib_list_options (FILE *file)
> fprintf (file, _("\
> -z nomemory-seal Don't mark oject to be memory sealed (default)\n"));
> #endif
> + fprintf (file, _("\
> + -z dynamic-undefined-weak Make undefined weak symbols dynamic\n\
> + -z nodynamic-undefined-weak Do not make undefined weak symbols dynamic\n"));
Please add "(default)" to the default option.
> }
>
> static void
> diff --git a/ld/testsuite/ld-undefined/weak-fundef.s b/ld/testsuite/ld-undefined/weak-fundef.s
> index de8f641b6c2..79af8052473 100644
> --- a/ld/testsuite/ld-undefined/weak-fundef.s
> +++ b/ld/testsuite/ld-undefined/weak-fundef.s
> @@ -15,3 +15,6 @@
> bl undef_weak_fun,%r2
> nop
> .endif
> + .ifdef JAL
> + jal undef_weak_fun
> + .endif
> diff --git a/ld/testsuite/ld-undefined/weak-undef.exp b/ld/testsuite/ld-undefined/weak-undef.exp
> index 071fbebb927..2d6f8f2c573 100644
> --- a/ld/testsuite/ld-undefined/weak-undef.exp
> +++ b/ld/testsuite/ld-undefined/weak-undef.exp
> @@ -103,13 +103,15 @@ set testname "weak undefined function symbols in shared lib"
>
> set asflags ""
> switch -glob $target_triplet {
> - aarch64* -
> + aarch64* { set asflags "--defsym BL=1" }
> arm* -
> powerpc64* { set asflags "--defsym BL=1" }
> powerpc* { set asflags "--defsym BLPLT=1" }
> hppa* { set asflags "--defsym HPPA=1" }
> i\[3-7\]86* -
> x86_64* { set asflags "--defsym CALLPLT=1" }
> + riscv* { set asflags "--defsym CALLPLT=1" }
> + mips* { set asflags "--defsym JAL=1 -KPIC" }
> }
>
> if { $asflags == "" || ![is_elf_format] || ![check_shared_lib_support]} then {
> @@ -123,34 +125,24 @@ if { $asflags == "" || ![is_elf_format] || ![check_shared_lib_support]} then {
> set testname "weak undefined function symbols in dynamic exe"
> undef_weak_exe $testname "--no-as-needed" 1
>
> - # Find -z options supported by the default emulation
> - set emul [get_target_emul]
> - set cmd [list "$ld --help 2>&1 | sed -e '1,/^$emul:/d;/^\[^ \]*:/,\$d'"]
> - set status [remote_exec host [concat sh -c $cmd]]
> - if { [lindex $status 0] != 0 } {
> - verbose -log "$cmd exited with status [lindex $status 0]"
> - }
> - set emulopt [lindex $status 1]
> -
> - if { [string first "dynamic-undefined-weak" $emulopt] >= 0 } {
> - # -z dynamic-undefined-weak is supported. Let's see if it works.
> + # All ELF targets support -z dynamic-undefined-weak
> + # Let's see if it works.
>
> - set testname "weak undefined functions in shared lib, no dyn undef weak"
> - undef_weak_so $testname "--shared -z nodynamic-undefined-weak" 0
> + set testname "weak undefined functions in shared lib, no dyn undef weak"
> + undef_weak_so $testname "--shared -z nodynamic-undefined-weak" 0
>
> - set testname "weak undefined functions in shared lib, dyn undef weak"
> - undef_weak_so $testname "--shared -z dynamic-undefined-weak" 1
> + set testname "weak undefined functions in shared lib, dyn undef weak"
> + undef_weak_so $testname "--shared -z dynamic-undefined-weak" 1
>
> - set testname "weak undefined functions in dynamic exe, no dyn undef weak"
> - undef_weak_exe $testname "-z nodynamic-undefined-weak" 0
> + set testname "weak undefined functions in dynamic exe, no dyn undef weak"
> + undef_weak_exe $testname "-z nodynamic-undefined-weak" 0
>
> - set testname "weak undefined functions in dynamic exe, dyn undef weak"
> - undef_weak_exe $testname "-z dynamic-undefined-weak" 1
> + set testname "weak undefined functions in dynamic exe, dyn undef weak"
> + undef_weak_exe $testname "-z dynamic-undefined-weak" 1
>
> - set testname "weak undefined functions in pie, no dyn undef weak"
> - undef_weak_exe $testname "-pie -z nodynamic-undefined-weak" 0
> + set testname "weak undefined functions in pie, no dyn undef weak"
> + undef_weak_exe $testname "-pie -z nodynamic-undefined-weak" 0
>
> - set testname "weak undefined functions in pie, dyn undef weak"
> - undef_weak_exe $testname "-pie -z dynamic-undefined-weak" 1
> - }
> + set testname "weak undefined functions in pie, dyn undef weak"
> + undef_weak_exe $testname "-pie -z dynamic-undefined-weak" 1
> }
> --
> 2.47.0
>
--
H.J.
More information about the Binutils
mailing list