[PATCH] strip: Treat slim GCC/LLVM IR objects the same

Alan Modra amodra@gmail.com
Thu Aug 14 21:24:06 GMT 2025


On Tue, Aug 12, 2025 at 12:27:45PM -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.
> 
> bfd/
> 
> 	PR binutils/33271
> 	* plugin.c (bfd_plugin_object_p): Set the lto_type field to
> 	lto_slim_ir_object for slim LLVM IR object.

Is there a reason why you don't do this in bfd_set_lto_type?

> binutils/
> 
> 	PR binutils/33271
> 	* objcopy.c (copy_archive): Always copy slim IR object as unknown
> 	object.
> 	(copy_file): Likewise.

This part shouldn't be needed now.

> 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/plugin.c                             | 19 ++++++++++++-
>  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, 42 insertions(+), 26 deletions(-)
> 
> diff --git a/bfd/plugin.c b/bfd/plugin.c
> index 733e7f0f322..19f2c8ae534 100644
> --- a/bfd/plugin.c
> +++ b/bfd/plugin.c
> @@ -772,7 +772,24 @@ bfd_plugin_object_p (bfd *abfd)
>    if (abfd->plugin_format == bfd_plugin_unknown && !load_plugin (abfd))
>      return NULL;
>  
> -  return abfd->plugin_format == bfd_plugin_yes ? _bfd_no_cleanup : NULL;
> +  if (abfd->plugin_format == bfd_plugin_yes)
> +    {
> +      /* Check slim LLVM IR object whose first 4 bytes: 'B', 'C', 0xc0,
> +	 0xde.  */
> +      bfd_byte llvm_ir_magic[4];
> +      if (abfd->lto_type == lto_non_object
> +	  && 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)
> +	abfd->lto_type = lto_slim_ir_object;
> +
> +      return _bfd_no_cleanup;
> +    }
> +  else
> +    return NULL;
>  }
>  
>  /* Copy any private info we understand from the input bfd
> diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> index 654d2b9b44a..d53f085c1c7 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -3771,10 +3771,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)
> -	  || bfd_plugin_target_p (this_element->xvec))
> +      /* Copy slim LTO IR file as unknown object.  */
> +      if (this_element->lto_type == lto_slim_ir_object)
>  	ok_object = false;
>        else
>  #endif
> @@ -4042,9 +4040,9 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
>   	}
>  
>  #if BFD_SUPPORTS_PLUGINS
> -      if (bfd_plugin_target_p (ibfd->xvec))
> +      if (ibfd->lto_type == lto_slim_ir_object)
>  	{
> -	  /* Copy LTO IR file as unknown file.  */
> +	  /* Copy slim LTO IR file as unknown file.  */
>  	  if (!copy_unknown_file (ibfd, obfd, in_stat->st_size,
>  				  in_stat->st_mode))
>  	    status = 1;
> 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