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

H.J. Lu hjl.tools@gmail.com
Fri Oct 24 23:21:17 GMT 2025


On Sat, Oct 25, 2025 at 7:19 AM Alon Bar-Lev <alon.barlev@gmail.com> 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 +++++++++++++++++------
>  5 files changed, 68 insertions(+), 7 deletions(-)
>
> 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;
> --
> 2.43.0
>

Tests are missing.

-- 
H.J.


More information about the Binutils mailing list