[PATCH v3 2/2] [ld] Allow relocation finalization for ld -r
Jan Beulich
jbeulich@suse.com
Fri Nov 7 11:43:12 GMT 2025
On 17.10.2025 19:50, Eyal Itkin wrote:
> Introduce the "--finalize-locals" CLI flag, which will
> be supported only for relocatables (ld -r).
>
> When provided, relocations that are associated with
> local symbols, and that support finalization, will
> undergo a finalization step. This change aligns the
> ET_REL creation to support the same finalization
> semantics as that of the shared library (ET_DYN). In
> essence, if the symbols are local, and support finalize,
> there is no need to keep these relocations in the binary.
>
> This added support will enable users to properly strip
> the output of "ld -r --localize-hidden --finalize-locals",
> as the symbols will no longer be tied to unneeded relocations.
>
> The full discussion about the format is available in
> the generic-abi group that is responsible for the ELF
> standard. Specifically, the summarized architecture can
> be found here:
> https://groups.google.com/g/generic-abi/c/sT25-xfX9yc/m/J9SIthF4BgAJ
>
> Signed-off-by: Eyal Itkin <eyal.itkin@gmail.com>
> ---
> bfd/elf64-x86-64.c | 54 +++++++++++++++++++++++++-
> include/bfdlink.h | 3 ++
> ld/ld.h | 3 ++
> ld/ldlex.h | 1 +
> ld/lexsup.c | 9 +++++
> ld/testsuite/ld-elf/finalize_locals.s | 23 +++++++++++
> ld/testsuite/ld-elf/finalize_locals1.d | 12 ++++++
> ld/testsuite/ld-elf/finalize_locals2.d | 13 +++++++
> ld/testsuite/ld-elf/finalize_locals3.d | 3 ++
> 9 files changed, 120 insertions(+), 1 deletion(-)
> create mode 100644 ld/testsuite/ld-elf/finalize_locals.s
> create mode 100644 ld/testsuite/ld-elf/finalize_locals1.d
> create mode 100644 ld/testsuite/ld-elf/finalize_locals2.d
> create mode 100644 ld/testsuite/ld-elf/finalize_locals3.d
Please consider using - in place of _ in the names of new files. On most
keyboards that's easier to type. Underscores really should only be used
when dashes have some special meaning. (Applies to patch 1 as well.)
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -3158,6 +3158,47 @@ elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
> return address - static_tls_size - htab->tls_sec->vma;
> }
>
> +/* Check if a given symbol-related relocation can be finalized. */
> +
> +static int
> +elf_x86_64_can_finalize_reloc (Elf_Internal_Rela *rel,
> + asection *input_section,
> + asection *output_section)
The function returning a boolean result, its return type wants to be bool.
> +{
> + struct bfd_section *input_sec_out;
> + struct bfd_section *sym_sec_out;
> + unsigned int r_type;
> +
> + if (output_section == NULL)
> + return 0;
Can output_section really be NULL here?
> + input_sec_out = input_section->output_section;
> + sym_sec_out = output_section->output_section;
> +
> + /* Relocation must not cross section boundaries. */
> + if (sym_sec_out->index != input_sec_out->index)
> + return 0;
> +
> + r_type = ELF32_R_TYPE (rel->r_info);
> +
> + /* Some relocation types can not be finalized. */
> + switch (r_type)
> + {
> + default:
> + break;
> + case R_X86_64_GOTPCREL:
> + case R_X86_64_GOTPCRELX:
> + case R_X86_64_REX_GOTPCRELX:
> + case R_X86_64_CODE_4_GOTPCRELX:
> + case R_X86_64_CODE_5_GOTPCRELX:
> + case R_X86_64_CODE_6_GOTPCRELX:
> + case R_X86_64_GOTPCREL64:
> + return 0;
What about relocations involving the PLT? Or about anything related to
TLS? I wonder whether you rather want to white-list relocations that
are suitable.
> @@ -3227,7 +3268,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> bool converted_reloc;
> bool need_copy_reloc_in_pie;
> bool no_copyreloc_p;
> + bool reloc_skip_symbol;
>
> + reloc_skip_symbol = true;
> r_type = ELF32_R_TYPE (rel->r_info);
> if (r_type == (int) R_X86_64_GNU_VTINHERIT
> || r_type == (int) R_X86_64_GNU_VTENTRY)
> @@ -3286,6 +3329,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> h, sec, relocation,
> unresolved_reloc, warned, ignored);
> st_size = h->size;
> + if (info->finalize_locals && h->forced_local
> + && elf_x86_64_can_finalize_reloc (rel, input_section, sec))
> + reloc_skip_symbol = false;
Why would this need limiting to "forced" locals?
> @@ -3310,7 +3356,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> continue;
> }
>
> - if (bfd_link_relocatable (info))
> + if (bfd_link_relocatable (info) && reloc_skip_symbol)
> {
> if (wrel != rel)
> *wrel = *rel;
I continue to find this confusing: You check a variable with "skip" in
its name just to do something when the implication is that something
wants skipping.
> --- a/include/bfdlink.h
> +++ b/include/bfdlink.h
> @@ -489,6 +489,9 @@ struct bfd_link_info
> /* TRUE if supports localizing hidden symbols. */
> unsigned int localize_hidden: 1;
>
> + /* TRUE if supports finalizing local symbols. */
> + unsigned int finalize_locals: 1;
Same question as for the other patch: Why "supports"?
> --- a/ld/ld.h
> +++ b/ld/ld.h
> @@ -335,6 +335,9 @@ typedef struct
>
> /* If set, localize hidden symbols. */
> bool localize_hidden;
> +
> + /* If set, finalize locale symbols. */
> + bool finalize_locals;
> } ld_config_type;
And again - where is this used?
> --- a/ld/lexsup.c
> +++ b/ld/lexsup.c
> @@ -210,6 +210,8 @@ static const struct ld_option ld_options[] =
> 'r', NULL, N_("Generate relocatable output"), TWO_DASHES },
> { {"localize-hidden", no_argument, NULL, OPTION_LOCALIZE_HIDDEN},
> '\0', NULL, N_("Localize hidden relocatable symbols"), TWO_DASHES },
> + { {"finalize-locals", no_argument, NULL, OPTION_FINALIZE_LOCALS},
> + '\0', NULL, N_("Attempt to finalize local relocatable symbols"), TWO_DASHES },
Also for patch 1: New command line options will want documenting.
Jan
More information about the Binutils
mailing list