[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