[PATCH] objcopy: add option to specify custom symbol name for binary input

Jan Beulich jbeulich@suse.com
Mon Oct 27 08:51:22 GMT 2025


On 25.10.2025 05:25, Alon Bar-Lev wrote:
> When using --input-target=binary, objcopy currently derives symbol names from
> a mangled version of the input file name.  This approach can lead to
> unpredictable results, as the generated symbols depend on the file path and
> working directory.
> 
> This patch introduces a new option:
> 
>   --input-symbol <name>    Use <name> as the base symbol name for the input file
>                            (default: derived from file name)
> 
> It allows specifying an explicit symbol name, while preserving the existing
> behavior as a fallback.
> 
> Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
> ---
>  bfd/bfd-in2.h                               | 15 ++++++++
>  bfd/bfd.c                                   | 15 ++++++++
>  bfd/binary.c                                |  7 +++-
>  binutils/doc/binutils.texi                  | 15 ++++++++
>  binutils/objcopy.c                          | 23 ++++++++----
>  binutils/testsuite/binutils-all/objcopy.exp | 39 +++++++++++++++++++++
>  6 files changed, 107 insertions(+), 7 deletions(-)

I have a total of 4 patches with the same title in my inbox. Which one is newest?
Judging from time, was this one perhaps meant to be tagged v4?

Jan

> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 5e7c6ddf1ee..313d0b66def 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -1949,6 +1949,9 @@ struct bfd
>    /* The filename the application opened the BFD with.  */
>    const char *filename;
>  
> +  /* The symbol name for the file or NULL.  */
> +  const char *filename_symbol;
> +
>    /* A pointer to the target jump table.  */
>    const struct bfd_target *xvec;
>  
> @@ -2293,6 +2296,18 @@ bfd_get_filename (const bfd *abfd)
>    return abfd->filename;
>  }
>  
> +static inline const char *
> +bfd_get_filename_symbol (const bfd *abfd)
> +{
> +  return abfd->filename_symbol;
> +}
> +
> +static inline void
> +bfd_set_filename_symbol (bfd *abfd, const char * const val)
> +{
> +  abfd->filename_symbol = val;
> +}
> +
>  static inline bool
>  bfd_get_cacheable (const bfd *abfd)
>  {
> diff --git a/bfd/bfd.c b/bfd/bfd.c
> index 858ab5ce017..8a00113a147 100644
> --- a/bfd/bfd.c
> +++ b/bfd/bfd.c
> @@ -105,6 +105,9 @@ CODE_FRAGMENT
>  .  {* The filename the application opened the BFD with.  *}
>  .  const char *filename;
>  .
> +.  {* The symbol name for the file or NULL.  *}
> +.  const char *filename_symbol;
> +.
>  .  {* A pointer to the target jump table.  *}
>  .  const struct bfd_target *xvec;
>  .
> @@ -452,6 +455,18 @@ EXTERNAL
>  .  return abfd->filename;
>  .}
>  .
> +.static inline const char *
> +.bfd_get_filename_symbol (const bfd *abfd)
> +.{
> +.  return abfd->filename_symbol;
> +.}
> +.
> +.static inline void
> +.bfd_set_filename_symbol (bfd *abfd, const char * const val)
> +.{
> +.  abfd->filename_symbol = val;
> +.}
> +.
>  .static inline bool
>  .bfd_get_cacheable (const bfd *abfd)
>  .{
> diff --git a/bfd/binary.c b/bfd/binary.c
> index 7fe47b590de..ec88f6ae71b 100644
> --- a/bfd/binary.c
> +++ b/bfd/binary.c
> @@ -122,6 +122,7 @@ static char *
>  mangle_name (bfd *abfd, char *suffix)
>  {
>    bfd_size_type size;
> +  const char *symbol;
>    char *buf;
>    char *p;
>  
> @@ -133,7 +134,11 @@ mangle_name (bfd *abfd, char *suffix)
>    if (buf == NULL)
>      return "";
>  
> -  sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix);
> +  symbol = bfd_get_filename_symbol (abfd);
> +  if (symbol == NULL)
> +    symbol = bfd_get_filename (abfd);
> +
> +  sprintf (buf, "_binary_%s_%s", symbol, suffix);
>  
>    /* Change any non-alphanumeric characters to underscores.  */
>    for (p = buf; *p; p++)
> diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
> index 89425b8a15b..5af914399a3 100644
> --- a/binutils/doc/binutils.texi
> +++ b/binutils/doc/binutils.texi
> @@ -1315,6 +1315,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
>          [@option{--keep-global-symbols=}@var{filename}]
>          [@option{--localize-symbols=}@var{filename}]
>          [@option{--weaken-symbols=}@var{filename}]
> +        [@option{--input-symbol}@var{symbolname}]
>          [@option{--add-symbol} @var{name}=[@var{section}:]@var{value}[,@var{flags}]]
>          [@option{--alt-machine-code=}@var{index}]
>          [@option{--prefix-symbols=}@var{string}]
> @@ -1554,6 +1555,20 @@ given more than once.  Note - unique symbols are not converted.
>  @itemx --weaken-symbol=@var{symbolname}
>  Make symbol @var{symbolname} weak. This option may be given more than once.
>  
> +@item --input-symbol=@var{symbolname}
> +When used with @option{--input-target=binary}, sets @var{symbolname} as the
> +base name for the symbols generated for the input file.  These symbols are:
> +
> +@example
> +_binary_@var{symbolname}_start
> +_binary_@var{symbolname}_end
> +_binary_@var{symbolname}_size
> +@end example
> +
> +By default, the binary input handler derives the base symbol name from a
> +mangled version of the input file name.  This option allows specifying it
> +explicitly.
> +
>  @item --globalize-symbol=@var{symbolname}
>  Give symbol @var{symbolname} global scoping so that it is visible
>  outside of the file in which it is defined.  This option may be given
> diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> index 9373b75d6ed..3b912563c71 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -334,6 +334,7 @@ enum command_line_switch
>    OPTION_HEAP,
>    OPTION_IMAGE_BASE,
>    OPTION_IMPURE,
> +  OPTION_INPUT_SYMBOL,
>    OPTION_INTERLEAVE_WIDTH,
>    OPTION_KEEPGLOBAL_SYMBOLS,
>    OPTION_KEEP_FILE_SYMBOLS,
> @@ -465,6 +466,7 @@ static struct option copy_options[] =
>    {"info", no_argument, 0, OPTION_FORMATS_INFO},
>    {"input-format", required_argument, 0, 'I'}, /* Obsolete */
>    {"input-target", required_argument, 0, 'I'},
> +  {"input-symbol", required_argument, 0, OPTION_INPUT_SYMBOL},
>    {"interleave", optional_argument, 0, 'i'},
>    {"interleave-width", required_argument, 0, OPTION_INTERLEAVE_WIDTH},
>    {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
> @@ -678,6 +680,8 @@ copy_usage (FILE *stream, int exit_status)
>       --globalize-symbols <file>    --globalize-symbol for all in <file>\n\
>       --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
>       --weaken-symbols <file>       -W for all symbols listed in <file>\n\
> +     --input-symbol <name>         Use <name> as the base symbol name for the input file\n\
> +                                     (default: derived from file name)\n\
>       --add-symbol <name>=[<section>:]<value>[,<flags>]  Add a symbol\n\
>       --alt-machine-code <index>    Use the target's <index>'th alternative machine\n\
>       --writable-text               Mark the output text as writable\n\
> @@ -3858,9 +3862,10 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
>  /* The top-level control.  */
>  
>  static void
> -copy_file (const char *input_filename, const char *output_filename, int ofd,
> -	   struct stat *in_stat, const char *input_target,
> -	   const char *output_target, const bfd_arch_info_type *input_arch)
> +copy_file (const char *input_filename, const char *input_symbol,
> +	   const char *output_filename, int ofd, struct stat *in_stat,
> +	   const char *input_target, const char *output_target,
> +	   const bfd_arch_info_type *input_arch)
>  {
>    bfd *ibfd;
>    char **obj_matching;
> @@ -3891,6 +3896,7 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
>        status = 1;
>        return;
>      }
> +  bfd_set_filename_symbol(ibfd, input_symbol);
>  
>    switch (do_debug_sections)
>      {
> @@ -5093,7 +5099,7 @@ strip_main (int argc, char *argv[])
>  	}
>  
>        status = 0;
> -      copy_file (argv[i], tmpname, tmpfd, &statbuf, input_target,
> +      copy_file (argv[i], NULL, tmpname, tmpfd, &statbuf, input_target,
>  		 output_target, NULL);
>        if (status == 0)
>  	{
> @@ -5341,6 +5347,7 @@ static int
>  copy_main (int argc, char *argv[])
>  {
>    char *input_filename = NULL;
> +  char *input_symbol = NULL;
>    char *output_filename = NULL;
>    char *tmpname;
>    char *input_target = NULL;
> @@ -5395,6 +5402,10 @@ copy_main (int argc, char *argv[])
>  	  input_target = optarg;
>  	  break;
>  
> +	case OPTION_INPUT_SYMBOL:
> +	  input_symbol = optarg;
> +	  break;
> +
>  	case 'O':
>  	case 'd':		/* "destination" - 'O' is preferred */
>  	  output_target = optarg;
> @@ -6197,8 +6208,8 @@ copy_main (int argc, char *argv[])
>  	     input_filename, strerror (errno));
>      }
>  
> -  copy_file (input_filename, tmpname, tmpfd, &statbuf, input_target,
> -	     output_target, input_arch);
> +  copy_file (input_filename, input_symbol, tmpname, tmpfd, &statbuf,
> +	     input_target, output_target, input_arch);
>    if (status == 0)
>      {
>        const char *oname = output_filename ? output_filename : input_filename;
> diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
> index b11b17e012c..e9469c8f324 100644
> --- a/binutils/testsuite/binutils-all/objcopy.exp
> +++ b/binutils/testsuite/binutils-all/objcopy.exp
> @@ -1602,3 +1602,42 @@ proc objcopy_tek2bin {} {
>  }
>  
>  objcopy_tek2bin
> +
> +# Test input symbol
> +
> +proc input_symbol {name file args symbol} {
> +    global OBJCOPY
> +    global NM
> +    global NMFLAGS
> +    global srcdir
> +    global subdir
> +
> +    set test "input symbol ($name)"
> +
> +    # detect a valid target, take the first supported
> +    set target [lindex [split [binutils_run $OBJCOPY "--info"] \n] 1]
> +
> +    set out tmpdir/input_symbol.o
> +    set got [binutils_run $OBJCOPY "-I binary -O $target $args $file $out"]
> +
> +    set expected [list "${symbol}_end" "${symbol}_size" "${symbol}_start"]
> +
> +    set exec_output [binutils_run $NM "-a $NMFLAGS $out"]
> +    set exec_output [prune_warnings $exec_output]
> +    set actual {}
> +    while {[regexp {^[0-9a-fA-F]+?[ ]+[TtDdA] _?binary_([0-9a-zA-Z_]+)[\r\n]+(.*)$} ${exec_output} all s rest]} {
> +	set actual [concat $actual $s]
> +	set exec_output $rest
> +    }
> +
> +    if {[lsort $expected] ne [lsort $actual]} {
> +	send_log "expected: $expected, actual: $actual\n"
> +	fail $test
> +	return
> +    }
> +
> +    pass $test
> +}
> +
> +input_symbol implicit $srcdir/$subdir/version.s "" [regsub -all {[^0-9a-zA-Z]} $srcdir/$subdir/version.s _]
> +input_symbol explicit $srcdir/$subdir/version.s "--input-symbol symbol1" symbol1



More information about the Binutils mailing list