[PATCH v2] strip: Treat slim GCC/LLVM IR objects the same
Alan Modra
amodra@gmail.com
Thu Aug 14 23:06:58 GMT 2025
On Thu, Aug 14, 2025 at 03:27:54PM -0700, H.J. Lu wrote:
> Slim LLVM IR object is a standalone file whose first 4 bytes are 'B',
> 'C', 0xc0, 0xde. GCC IR object is regular ELF object with sections
> whose names start with .gnu.lto_.* or .gnu.debuglto_.*. GCC IR object
> uses a .gnu.lto_.lto.<some_hash> section to encode the LTO bytecode
> information:
>
> struct lto_section
> {
> int16_t major_version;
> int16_t minor_version;
> unsigned char slim_object;
>
> /* Flags is a private field that is not defined publicly. */
> uint16_t flags;
> };
>
> In slim GCC IR object, the slim_object field is non-zero. Strip should
> treat slim GCC/LLVM IR objects the same. Since strip won't change slim
> LLVM IR objects, it should leave slim GCC IR object unchanged even when
> asked to remove all IR objects:
>
> 1. Set the lto_type field to lto_slim_ir_object for slim LLVM IR object.
> 2. Always copy slim IR object as unknown object.
OK. Please also move lto_sections_removed from file scope.
> bfd/
>
> PR binutils/33271
> * format.c (bfd_set_lto_type): Set the lto_type field to
> lto_slim_ir_object for slim LLVM IR object.
>
> binutils/
>
> PR binutils/33271
> * objcopy.c (copy_archive): Always copy slim IR object as unknown
> object.
> (copy_file): Likewise.
>
> ld/
>
> PR binutils/33271
> * testsuite/ld-plugin/lto-binutils.exp: Don't check if fat IR is
> available when running slim IR tests.
> * testsuite/ld-plugin/strip-1a-s-all.nd: Expect full symbol list.
>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> ---
> bfd/format.c | 66 +++++++++++++++---------
> binutils/objcopy.c | 10 ++--
> ld/testsuite/ld-plugin/lto-binutils.exp | 34 ++++++------
> ld/testsuite/ld-plugin/strip-1a-s-all.nd | 5 +-
> 4 files changed, 65 insertions(+), 50 deletions(-)
>
> diff --git a/bfd/format.c b/bfd/format.c
> index 25feb5266df..b74c6240f23 100644
> --- a/bfd/format.c
> +++ b/bfd/format.c
> @@ -376,33 +376,49 @@ bfd_set_lto_type (bfd *abfd ATTRIBUTE_UNUSED)
> | (bfd_get_flavour (abfd) == bfd_target_elf_flavour
> ? EXEC_P : 0))) == 0)
> {
> - asection *sec;
> + asection *sec = abfd->sections;
> enum bfd_lto_object_type type = lto_non_ir_object;
> - struct lto_section lsection = { 0, 0, 0, 0 };
> - /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode information
> - section. */
> - for (sec = abfd->sections; sec != NULL; sec = sec->next)
> - if (strcmp (sec->name, GNU_OBJECT_ONLY_SECTION_NAME) == 0)
> - {
> - type = lto_mixed_object;
> - abfd->object_only_section = sec;
> - break;
> - }
> - else if (strcmp (sec->name, ".llvm.lto") == 0)
> - {
> - type = lto_fat_ir_object;
> - break;
> - }
> - else if (lsection.major_version == 0
> - && startswith (sec->name, ".gnu.lto_.lto.")
> - && bfd_get_section_contents (abfd, sec, &lsection, 0,
> - sizeof (struct lto_section)))
> - {
> - if (lsection.slim_object)
> - type = lto_slim_ir_object;
> - else
> - type = lto_fat_ir_object;
> + if (sec == NULL)
> + {
> + /* If there are no sections, check for slim LLVM IR object whose
> + first 4 bytes are: 'B', 'C', 0xc0, 0xde. */
> + bfd_byte llvm_ir_magic[4];
> + if (bfd_seek (abfd, 0, SEEK_SET) == 0
> + && bfd_read (llvm_ir_magic, 4, abfd) == 4
> + && llvm_ir_magic[0] == 'B'
> + && llvm_ir_magic[1] == 'C'
> + && llvm_ir_magic[2] == 0xc0
> + && llvm_ir_magic[3] == 0xde)
> + type = lto_slim_ir_object;
> + }
> + else
> + {
> + struct lto_section lsection = { 0, 0, 0, 0 };
> + /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode
> + information section. */
> + for (; sec != NULL; sec = sec->next)
> + if (strcmp (sec->name, GNU_OBJECT_ONLY_SECTION_NAME) == 0)
> + {
> + type = lto_mixed_object;
> + abfd->object_only_section = sec;
> + break;
> + }
> + else if (strcmp (sec->name, ".llvm.lto") == 0)
> + {
> + type = lto_fat_ir_object;
> + break;
> + }
> + else if (lsection.major_version == 0
> + && startswith (sec->name, ".gnu.lto_.lto.")
> + && bfd_get_section_contents (abfd, sec, &lsection, 0,
> + sizeof (struct lto_section)))
> + {
> + if (lsection.slim_object)
> + type = lto_slim_ir_object;
> + else
> + type = lto_fat_ir_object;
> }
> + }
>
> abfd->lto_type = type;
> }
> diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> index bc07176799a..cb894ca9262 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -3765,9 +3765,8 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
> }
>
> #if BFD_SUPPORTS_PLUGINS
> - /* Copy LTO IR file as unknown object. */
> - if (!lto_sections_removed
> - && this_element->lto_type == lto_slim_ir_object)
> + /* Copy slim LTO IR file as unknown object. */
> + if (this_element->lto_type == lto_slim_ir_object)
> ok_object = false;
> #endif
> if (ok_object)
> @@ -4066,9 +4065,8 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
> }
>
> #if BFD_SUPPORTS_PLUGINS
> - /* Copy LTO IR file as unknown object. */
> - if (!lto_sections_removed
> - && ibfd->lto_type == lto_slim_ir_object)
> + /* Copy slim LTO IR file as unknown file. */
> + if (ibfd->lto_type == lto_slim_ir_object)
> ok_object = false;
> #endif
> if (ok_object
> diff --git a/ld/testsuite/ld-plugin/lto-binutils.exp b/ld/testsuite/ld-plugin/lto-binutils.exp
> index 4970e2282cb..1e156e4fc78 100644
> --- a/ld/testsuite/ld-plugin/lto-binutils.exp
> +++ b/ld/testsuite/ld-plugin/lto-binutils.exp
> @@ -254,24 +254,22 @@ run_lto_binutils_test [list \
> ] \
> ]
>
> -if { [check_lto_fat_available] } {
> - run_lto_binutils_test [list \
> - [list \
> - "strip" \
> - "-R .gnu.*lto_* -N __gnu_lto_v1" \
> - "strip-1a.o" \
> - "strip-1a-s-all.o" \
> - {{nm -n strip-1a-s-all.nd}} \
> - ] \
> - [list \
> - "strip" \
> - "-R .gnu.*lto_* -N __gnu_lto_v1" \
> - "libstrip-1a.a" \
> - "libstrip-1a-s-all.a" \
> - {{nm -n strip-1a-s-all.nd}} \
> - ] \
> - ]
> -}
> +run_lto_binutils_test [list \
> + [list \
> + "strip" \
> + "-R .gnu.*lto_* -N __gnu_lto_v1" \
> + "strip-1a.o" \
> + "strip-1a-s-all.o" \
> + {{nm -n strip-1a-s-all.nd}} \
> + ] \
> + [list \
> + "strip" \
> + "-R .gnu.*lto_* -N __gnu_lto_v1" \
> + "libstrip-1a.a" \
> + "libstrip-1a-s-all.a" \
> + {{nm -n strip-1a-s-all.nd}} \
> + ] \
> +]
>
> run_cc_link_tests [list \
> [list \
> diff --git a/ld/testsuite/ld-plugin/strip-1a-s-all.nd b/ld/testsuite/ld-plugin/strip-1a-s-all.nd
> index 612ba6a39b1..52265c2eb3d 100644
> --- a/ld/testsuite/ld-plugin/strip-1a-s-all.nd
> +++ b/ld/testsuite/ld-plugin/strip-1a-s-all.nd
> @@ -1,3 +1,6 @@
> #...
> -[0-9a-f]* C _?__gnu_lto_slim
> + + U foo2
> + + U foo3
> +0+ T foo1
> +0+ T main
> #pass
> --
> 2.50.1
--
Alan Modra
More information about the Binutils
mailing list