[PATCH v2] [RFC][ld] Introduce static bundle object support
Jan Beulich
jbeulich@suse.com
Fri Oct 17 11:49:58 GMT 2025
On 10.10.2025 14:23, Eyal Itkin wrote:
> Note: This patch is a draft for review.
>
> Introduce a new "Static Bundle Object" which is a
> relocatable object that supports symbol visibility
> and finalization of local relocations. This format
> is aimed to be incorporated within static archives
> so to replace the current static archives of plain
> object code files that are used to form static
> libraries.
>
> The full discussion about the format is available in the
> generic-abi group that is responsible for the ELF standard:
> https://groups.google.com/g/generic-abi/c/sT25-xfX9yc
>
> Some questions I had about the process itself:
> 1. The patch is architecture dependent given that
> relocations support is found in both bfd/elflink.c AND
> in some arch-specific files (such as bfd/elf64-x86-64.c).
> Hence, what is the standard way for marking some archs as
> not yet supported? And what is the recommended process for
> adding said support (especially given need to test it)?
Add a flag to struct bfd_target?
You say "some questions", but there is on "1.".
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -3227,7 +3227,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> bool converted_reloc;
> bool need_copy_reloc_in_pie;
> bool no_copyreloc_p;
> + bool skip_reloc_registration;
>
> + skip_reloc_registration = 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 +3288,15 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> h, sec, relocation,
> unresolved_reloc, warned, ignored);
> st_size = h->size;
> + skip_reloc_registration = !info->static_bundle || !h->forced_local;
> +
> + struct bfd_section *input_sec_out = input_section->output_section;
> + struct bfd_section *sym_sec_out = sec ? sec->output_section : NULL;
> +
> + /* A relocatable can not finalize a cross-section relocation. */
> + if (sym_sec_out != NULL
> + && sym_sec_out->index != input_sec_out->index)
> + skip_reloc_registration = true;
> }
>
> if (sec != NULL && discarded_section (sec))
> @@ -3310,7 +3321,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> continue;
> }
>
> - if (bfd_link_relocatable (info))
> + if (bfd_link_relocatable (info) && skip_reloc_registration)
Considering especially this use, I find the variable name rather misleading.
> @@ -5117,6 +5128,13 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> }
> }
>
> + /* Skip the applied relocation if based on local relocation. */
> + if (bfd_link_relocatable (info) && !skip_reloc_registration)
> + {
> + wrel--;
> + continue;
> + }
> +
> if (wrel != rel)
> *wrel = *rel;
> }
This is where the name fits, just in the inverted sense as it looks. You
skip registration when the variable is false.
> @@ -5409,7 +5427,8 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
> if (h->got.offset != (bfd_vma) -1
> && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h)->tls_type)
> && elf_x86_hash_entry (h)->tls_type != GOT_TLS_IE
> - && !local_undefweak)
> + && !local_undefweak
> + && !(bfd_link_relocatable (info) && info->static_bundle))
Here and elsewhere - why both checks? You disallow --finalize-locals without
-r in the linker, afaics.
> --- a/bfd/elflink.c
> +++ b/bfd/elflink.c
> @@ -803,9 +803,9 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
> (*bed->elf_backend_hide_symbol) (info, h, true);
> }
>
> - /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
> - and executables. */
> - if (!bfd_link_relocatable (info)
> + /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects,
> + executables and static bundles. */
> + if (!(bfd_link_relocatable (info) && info->static_bundle)
> && h->dynindx != -1
> && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
> || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
Is this all-or-nothing approach really going to help longer term? I could
imagine people wanting to "finalize" just some of the symbols.
> @@ -5680,7 +5685,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
> goto error_free_vers;
> }
> }
> - else if (h->dynindx != -1)
> + else if (h->dynindx != -1
> + || (bfd_link_relocatable (info) && info->static_bundle))
> /* If the symbol already has a dynamic index, but
> visibility says it should not be visible, turn it into
> a local symbol. */
Comments like this likely will want updating. Here the talking about a
"dynamic index" is at best misleading when it comes to a relocatable link.
> --- /dev/null
> +++ b/ld/testsuite/ld-static-bundle/bundle1.c
Do the testcase sources really need to be C ones? That way testing of cross
builds is liable to skip those tests, for there not being any cross compiler
available for the target.
> @@ -0,0 +1,15 @@
> +/* This is part of the static bundle ld test. This file becomes part
> + of a static library implemented using a static bundle. */
> +
> +/* This function is defined by another file in the static bundle. */
> +extern int helper_get_value();
> +
> +/* This function returns the library specific values. This is the
> + only publicly exposed function in this library. */
> +
> +__attribute__((visibility("default"))) __attribute__((used))
> +int
> +lib_get_value ()
> +{
> + return helper_get_value ();
> +}
> \ No newline at end of file
Please make sure all new files end in a newline.
> --- /dev/null
> +++ b/ld/testsuite/ld-static-bundle/static-bundle.exp
> @@ -0,0 +1,181 @@
> +# Expect script for ld-static-bundle tests
>
> +# Copyright (C) 1994-2025 Free Software Foundation, Inc.
>
> +#
>
> +# This file is part of the GNU Binutils.
>
> +#
>
> +# This program is free software; you can redistribute it and/or modify
Something's pretty odd throughout this file, possibly related to odd newlines
you may be using.
Jan
More information about the Binutils
mailing list