mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 12:23:31 +08:00
Add ability for objcopy to insert new symbols into a binary.
PR binutils/19104 binutils * objcopy.c (command_line_switch): Add OPTION_ADD_SYMBOL. (copy_options): Add add-symbol. (copy_usage): Likewise. (parse_symflags): New function. (need_sym_before): New function. (create_new_symbol): New function. (filter_symbols): Add code to insert new symbols. (copy_main): Process OPTION_ADD_SYMBOL. * doc/binutils.texi: Document new feature. * NEWS: Add note about the new feature. tests * binutils-all/add-symbol.d: New test. * binutils-all/objcopy.exp: Run the new test.
This commit is contained in:

committed by
Nick Clifton

parent
1283d92f0e
commit
2b35fb28f3
@ -1,3 +1,17 @@
|
|||||||
|
2015-10-21 Ronald Hoogenbllon <rhoogenboom@irdeto.com>
|
||||||
|
|
||||||
|
PR binutils/19104
|
||||||
|
* objcopy.c (command_line_switch): Add OPTION_ADD_SYMBOL.
|
||||||
|
(copy_options): Add add-symbol.
|
||||||
|
(copy_usage): Likewise.
|
||||||
|
(parse_symflags): New function.
|
||||||
|
(need_sym_before): New function.
|
||||||
|
(create_new_symbol): New function.
|
||||||
|
(filter_symbols): Add code to insert new symbols.
|
||||||
|
(copy_main): Process OPTION_ADD_SYMBOL.
|
||||||
|
* doc/binutils.texi: Document new feature.
|
||||||
|
* NEWS: Add note about the new feature.
|
||||||
|
|
||||||
2015-10-18 Paul Pluzhnikov <ppluzhnikov@google.com>
|
2015-10-18 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
PR binutils/19147
|
PR binutils/19147
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
|
||||||
|
* Add option to objcopy to insert new symbols into a file:
|
||||||
|
--add-symbol <name>=[<section>:]<value>[,<flags>]
|
||||||
|
|
||||||
* Add support for the ARC EM/HS, and ARC600/700 architectures.
|
* Add support for the ARC EM/HS, and ARC600/700 architectures.
|
||||||
|
|
||||||
* Extend objcopy --compress-debug-sections option to support
|
* Extend objcopy --compress-debug-sections option to support
|
||||||
|
@ -1106,6 +1106,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
|
|||||||
[@option{--localize-symbols=}@var{filename}]
|
[@option{--localize-symbols=}@var{filename}]
|
||||||
[@option{--globalize-symbols=}@var{filename}]
|
[@option{--globalize-symbols=}@var{filename}]
|
||||||
[@option{--weaken-symbols=}@var{filename}]
|
[@option{--weaken-symbols=}@var{filename}]
|
||||||
|
[@option{--add-symbol} @var{name}=[@var{section}:]@var{value}[,@var{flags}]
|
||||||
[@option{--alt-machine-code=}@var{index}]
|
[@option{--alt-machine-code=}@var{index}]
|
||||||
[@option{--prefix-symbols=}@var{string}]
|
[@option{--prefix-symbols=}@var{string}]
|
||||||
[@option{--prefix-sections=}@var{string}]
|
[@option{--prefix-sections=}@var{string}]
|
||||||
@ -1504,6 +1505,18 @@ command line. In this case, pass the original section name to
|
|||||||
@option{--update-section}, and the original and new section names to
|
@option{--update-section}, and the original and new section names to
|
||||||
@option{--rename-section}.
|
@option{--rename-section}.
|
||||||
|
|
||||||
|
@item --add-symbol @var{name}=[@var{section}:]@var{value}[,@var{flags}]
|
||||||
|
Add a new symbol named @var{name} while copying the file. This option may be
|
||||||
|
specified multiple times. If the @var{section} is given, the symbol will be
|
||||||
|
associated with and relative to that section, otherwise it will be an ABS
|
||||||
|
symbol. Specifying an undefined section will result in a fatal error. There
|
||||||
|
is no check for the value, it will be taken as specified. Symbol flags can
|
||||||
|
be specified and not all flags will be meaningful for all object file
|
||||||
|
formats. By default, the symbol will be global. The special flag
|
||||||
|
'before=@var{othersym}' will insert the new symbol in front of the specified
|
||||||
|
@var{othersym}, otherwise the symbol(s) will be added at the end of the
|
||||||
|
symbol table in the order they appear.
|
||||||
|
|
||||||
@item --rename-section @var{oldname}=@var{newname}[,@var{flags}]
|
@item --rename-section @var{oldname}=@var{newname}[,@var{flags}]
|
||||||
Rename a section from @var{oldname} to @var{newname}, optionally
|
Rename a section from @var{oldname} to @var{newname}, optionally
|
||||||
changing the section's flags to @var{flags} in the process. This has
|
changing the section's flags to @var{flags} in the process. This has
|
||||||
|
@ -50,7 +50,7 @@ static short pe_minor_subsystem_version = -1;
|
|||||||
|
|
||||||
struct is_specified_symbol_predicate_data
|
struct is_specified_symbol_predicate_data
|
||||||
{
|
{
|
||||||
const char *name;
|
const char * name;
|
||||||
bfd_boolean found;
|
bfd_boolean found;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,6 +62,16 @@ struct redefine_node
|
|||||||
struct redefine_node *next;
|
struct redefine_node *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct addsym_node
|
||||||
|
{
|
||||||
|
struct addsym_node *next;
|
||||||
|
char * symdef;
|
||||||
|
long symval;
|
||||||
|
flagword flags;
|
||||||
|
char * section;
|
||||||
|
char * othersym;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct section_rename
|
typedef struct section_rename
|
||||||
{
|
{
|
||||||
const char * old_name;
|
const char * old_name;
|
||||||
@ -88,26 +98,26 @@ static int deterministic = -1; /* Enable deterministic archives. */
|
|||||||
static int status = 0; /* Exit status. */
|
static int status = 0; /* Exit status. */
|
||||||
|
|
||||||
enum strip_action
|
enum strip_action
|
||||||
{
|
{
|
||||||
STRIP_UNDEF,
|
STRIP_UNDEF,
|
||||||
STRIP_NONE, /* Don't strip. */
|
STRIP_NONE, /* Don't strip. */
|
||||||
STRIP_DEBUG, /* Strip all debugger symbols. */
|
STRIP_DEBUG, /* Strip all debugger symbols. */
|
||||||
STRIP_UNNEEDED, /* Strip unnecessary symbols. */
|
STRIP_UNNEEDED, /* Strip unnecessary symbols. */
|
||||||
STRIP_NONDEBUG, /* Strip everything but debug info. */
|
STRIP_NONDEBUG, /* Strip everything but debug info. */
|
||||||
STRIP_DWO, /* Strip all DWO info. */
|
STRIP_DWO, /* Strip all DWO info. */
|
||||||
STRIP_NONDWO, /* Strip everything but DWO info. */
|
STRIP_NONDWO, /* Strip everything but DWO info. */
|
||||||
STRIP_ALL /* Strip all symbols. */
|
STRIP_ALL /* Strip all symbols. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Which symbols to remove. */
|
/* Which symbols to remove. */
|
||||||
static enum strip_action strip_symbols = STRIP_UNDEF;
|
static enum strip_action strip_symbols = STRIP_UNDEF;
|
||||||
|
|
||||||
enum locals_action
|
enum locals_action
|
||||||
{
|
{
|
||||||
LOCALS_UNDEF,
|
LOCALS_UNDEF,
|
||||||
LOCALS_START_L, /* Discard locals starting with L. */
|
LOCALS_START_L, /* Discard locals starting with L. */
|
||||||
LOCALS_ALL /* Discard all locals. */
|
LOCALS_ALL /* Discard all locals. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Which local symbols to remove. Overrides STRIP_ALL. */
|
/* Which local symbols to remove. Overrides STRIP_ALL. */
|
||||||
static enum locals_action discard_locals;
|
static enum locals_action discard_locals;
|
||||||
@ -232,6 +242,8 @@ static htab_t globalize_specific_htab = NULL;
|
|||||||
static htab_t keepglobal_specific_htab = NULL;
|
static htab_t keepglobal_specific_htab = NULL;
|
||||||
static htab_t weaken_specific_htab = NULL;
|
static htab_t weaken_specific_htab = NULL;
|
||||||
static struct redefine_node *redefine_sym_list = NULL;
|
static struct redefine_node *redefine_sym_list = NULL;
|
||||||
|
static struct addsym_node *add_sym_list = NULL, **add_sym_tail = &add_sym_list;
|
||||||
|
static int add_symbols = 0;
|
||||||
|
|
||||||
/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
|
/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
|
||||||
static bfd_boolean weaken = FALSE;
|
static bfd_boolean weaken = FALSE;
|
||||||
@ -254,11 +266,11 @@ static int reverse_bytes = 0;
|
|||||||
/* For Coff objects, we may want to allow or disallow long section names,
|
/* For Coff objects, we may want to allow or disallow long section names,
|
||||||
or preserve them where found in the inputs. Debug info relies on them. */
|
or preserve them where found in the inputs. Debug info relies on them. */
|
||||||
enum long_section_name_handling
|
enum long_section_name_handling
|
||||||
{
|
{
|
||||||
DISABLE,
|
DISABLE,
|
||||||
ENABLE,
|
ENABLE,
|
||||||
KEEP
|
KEEP
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The default long section handling mode is to preserve them.
|
/* The default long section handling mode is to preserve them.
|
||||||
This is also the only behaviour for 'strip'. */
|
This is also the only behaviour for 'strip'. */
|
||||||
@ -266,68 +278,69 @@ static enum long_section_name_handling long_section_names = KEEP;
|
|||||||
|
|
||||||
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
|
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
|
||||||
enum command_line_switch
|
enum command_line_switch
|
||||||
{
|
{
|
||||||
OPTION_ADD_SECTION=150,
|
OPTION_ADD_SECTION=150,
|
||||||
OPTION_UPDATE_SECTION,
|
OPTION_ADD_GNU_DEBUGLINK,
|
||||||
OPTION_DUMP_SECTION,
|
OPTION_ADD_SYMBOL,
|
||||||
OPTION_CHANGE_ADDRESSES,
|
OPTION_ALT_MACH_CODE,
|
||||||
OPTION_CHANGE_LEADING_CHAR,
|
OPTION_CHANGE_ADDRESSES,
|
||||||
OPTION_CHANGE_START,
|
OPTION_CHANGE_LEADING_CHAR,
|
||||||
OPTION_CHANGE_SECTION_ADDRESS,
|
OPTION_CHANGE_SECTION_ADDRESS,
|
||||||
OPTION_CHANGE_SECTION_LMA,
|
OPTION_CHANGE_SECTION_LMA,
|
||||||
OPTION_CHANGE_SECTION_VMA,
|
OPTION_CHANGE_SECTION_VMA,
|
||||||
OPTION_CHANGE_WARNINGS,
|
OPTION_CHANGE_START,
|
||||||
OPTION_COMPRESS_DEBUG_SECTIONS,
|
OPTION_CHANGE_WARNINGS,
|
||||||
OPTION_DEBUGGING,
|
OPTION_COMPRESS_DEBUG_SECTIONS,
|
||||||
OPTION_DECOMPRESS_DEBUG_SECTIONS,
|
OPTION_DEBUGGING,
|
||||||
OPTION_GAP_FILL,
|
OPTION_DECOMPRESS_DEBUG_SECTIONS,
|
||||||
OPTION_NO_CHANGE_WARNINGS,
|
OPTION_DUMP_SECTION,
|
||||||
OPTION_PAD_TO,
|
OPTION_EXTRACT_DWO,
|
||||||
OPTION_REMOVE_LEADING_CHAR,
|
OPTION_EXTRACT_SYMBOL,
|
||||||
OPTION_SET_SECTION_FLAGS,
|
OPTION_FILE_ALIGNMENT,
|
||||||
OPTION_SET_START,
|
OPTION_FORMATS_INFO,
|
||||||
OPTION_STRIP_UNNEEDED,
|
OPTION_GAP_FILL,
|
||||||
OPTION_WEAKEN,
|
OPTION_GLOBALIZE_SYMBOL,
|
||||||
OPTION_REDEFINE_SYM,
|
OPTION_GLOBALIZE_SYMBOLS,
|
||||||
OPTION_REDEFINE_SYMS,
|
OPTION_HEAP,
|
||||||
OPTION_SREC_LEN,
|
OPTION_IMAGE_BASE,
|
||||||
OPTION_SREC_FORCES3,
|
OPTION_IMPURE,
|
||||||
OPTION_STRIP_SYMBOLS,
|
OPTION_INTERLEAVE_WIDTH,
|
||||||
OPTION_STRIP_UNNEEDED_SYMBOL,
|
OPTION_KEEPGLOBAL_SYMBOLS,
|
||||||
OPTION_STRIP_UNNEEDED_SYMBOLS,
|
OPTION_KEEP_FILE_SYMBOLS,
|
||||||
OPTION_KEEP_SYMBOLS,
|
OPTION_KEEP_SYMBOLS,
|
||||||
OPTION_LOCALIZE_HIDDEN,
|
OPTION_LOCALIZE_HIDDEN,
|
||||||
OPTION_LOCALIZE_SYMBOLS,
|
OPTION_LOCALIZE_SYMBOLS,
|
||||||
OPTION_LONG_SECTION_NAMES,
|
OPTION_LONG_SECTION_NAMES,
|
||||||
OPTION_GLOBALIZE_SYMBOL,
|
OPTION_NO_CHANGE_WARNINGS,
|
||||||
OPTION_GLOBALIZE_SYMBOLS,
|
OPTION_ONLY_KEEP_DEBUG,
|
||||||
OPTION_KEEPGLOBAL_SYMBOLS,
|
OPTION_PAD_TO,
|
||||||
OPTION_WEAKEN_SYMBOLS,
|
OPTION_PREFIX_ALLOC_SECTIONS,
|
||||||
OPTION_RENAME_SECTION,
|
OPTION_PREFIX_SECTIONS,
|
||||||
OPTION_ALT_MACH_CODE,
|
OPTION_PREFIX_SYMBOLS,
|
||||||
OPTION_PREFIX_SYMBOLS,
|
OPTION_PURE,
|
||||||
OPTION_PREFIX_SECTIONS,
|
OPTION_READONLY_TEXT,
|
||||||
OPTION_PREFIX_ALLOC_SECTIONS,
|
OPTION_REDEFINE_SYM,
|
||||||
OPTION_FORMATS_INFO,
|
OPTION_REDEFINE_SYMS,
|
||||||
OPTION_ADD_GNU_DEBUGLINK,
|
OPTION_REMOVE_LEADING_CHAR,
|
||||||
OPTION_ONLY_KEEP_DEBUG,
|
OPTION_RENAME_SECTION,
|
||||||
OPTION_KEEP_FILE_SYMBOLS,
|
OPTION_REVERSE_BYTES,
|
||||||
OPTION_READONLY_TEXT,
|
OPTION_SECTION_ALIGNMENT,
|
||||||
OPTION_WRITABLE_TEXT,
|
OPTION_SET_SECTION_FLAGS,
|
||||||
OPTION_PURE,
|
OPTION_SET_START,
|
||||||
OPTION_IMPURE,
|
OPTION_SREC_FORCES3,
|
||||||
OPTION_EXTRACT_SYMBOL,
|
OPTION_SREC_LEN,
|
||||||
OPTION_REVERSE_BYTES,
|
OPTION_STACK,
|
||||||
OPTION_FILE_ALIGNMENT,
|
OPTION_STRIP_DWO,
|
||||||
OPTION_HEAP,
|
OPTION_STRIP_SYMBOLS,
|
||||||
OPTION_IMAGE_BASE,
|
OPTION_STRIP_UNNEEDED,
|
||||||
OPTION_SECTION_ALIGNMENT,
|
OPTION_STRIP_UNNEEDED_SYMBOL,
|
||||||
OPTION_STACK,
|
OPTION_STRIP_UNNEEDED_SYMBOLS,
|
||||||
OPTION_INTERLEAVE_WIDTH,
|
OPTION_SUBSYSTEM,
|
||||||
OPTION_SUBSYSTEM,
|
OPTION_UPDATE_SECTION,
|
||||||
OPTION_EXTRACT_DWO,
|
OPTION_WEAKEN,
|
||||||
OPTION_STRIP_DWO
|
OPTION_WEAKEN_SYMBOLS,
|
||||||
};
|
OPTION_WRITABLE_TEXT
|
||||||
|
};
|
||||||
|
|
||||||
/* Options to handle if running as "strip". */
|
/* Options to handle if running as "strip". */
|
||||||
|
|
||||||
@ -345,16 +358,16 @@ static struct option strip_options[] =
|
|||||||
{"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
|
{"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
|
||||||
{"keep-symbol", required_argument, 0, 'K'},
|
{"keep-symbol", required_argument, 0, 'K'},
|
||||||
{"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
|
{"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
|
||||||
|
{"output-file", required_argument, 0, 'o'},
|
||||||
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
|
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
|
||||||
{"output-target", required_argument, 0, 'O'},
|
{"output-target", required_argument, 0, 'O'},
|
||||||
{"output-file", required_argument, 0, 'o'},
|
|
||||||
{"preserve-dates", no_argument, 0, 'p'},
|
{"preserve-dates", no_argument, 0, 'p'},
|
||||||
{"remove-section", required_argument, 0, 'R'},
|
{"remove-section", required_argument, 0, 'R'},
|
||||||
{"strip-all", no_argument, 0, 's'},
|
{"strip-all", no_argument, 0, 's'},
|
||||||
{"strip-debug", no_argument, 0, 'S'},
|
{"strip-debug", no_argument, 0, 'S'},
|
||||||
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
|
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
|
||||||
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
|
|
||||||
{"strip-symbol", required_argument, 0, 'N'},
|
{"strip-symbol", required_argument, 0, 'N'},
|
||||||
|
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
|
||||||
{"target", required_argument, 0, 'F'},
|
{"target", required_argument, 0, 'F'},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", no_argument, 0, 'V'},
|
||||||
@ -368,10 +381,10 @@ static struct option copy_options[] =
|
|||||||
{
|
{
|
||||||
{"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
|
{"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
|
||||||
{"add-section", required_argument, 0, OPTION_ADD_SECTION},
|
{"add-section", required_argument, 0, OPTION_ADD_SECTION},
|
||||||
{"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
|
{"add-symbol", required_argument, 0, OPTION_ADD_SYMBOL},
|
||||||
|
{"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
|
||||||
{"adjust-start", required_argument, 0, OPTION_CHANGE_START},
|
{"adjust-start", required_argument, 0, OPTION_CHANGE_START},
|
||||||
{"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
|
{"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
|
||||||
{"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
|
|
||||||
{"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
|
{"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
|
||||||
{"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
|
{"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
|
||||||
{"binary-architecture", required_argument, 0, 'B'},
|
{"binary-architecture", required_argument, 0, 'B'},
|
||||||
@ -393,11 +406,14 @@ static struct option copy_options[] =
|
|||||||
{"enable-deterministic-archives", no_argument, 0, 'D'},
|
{"enable-deterministic-archives", no_argument, 0, 'D'},
|
||||||
{"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
|
{"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
|
||||||
{"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
|
{"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
|
||||||
|
{"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
|
||||||
{"format", required_argument, 0, 'F'}, /* Obsolete */
|
{"format", required_argument, 0, 'F'}, /* Obsolete */
|
||||||
{"gap-fill", required_argument, 0, OPTION_GAP_FILL},
|
{"gap-fill", required_argument, 0, OPTION_GAP_FILL},
|
||||||
{"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
|
{"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
|
||||||
{"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
|
{"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
|
||||||
|
{"heap", required_argument, 0, OPTION_HEAP},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
|
||||||
{"impure", no_argument, 0, OPTION_IMPURE},
|
{"impure", no_argument, 0, OPTION_IMPURE},
|
||||||
{"info", no_argument, 0, OPTION_FORMATS_INFO},
|
{"info", no_argument, 0, OPTION_FORMATS_INFO},
|
||||||
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
|
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
|
||||||
@ -420,9 +436,9 @@ static struct option copy_options[] =
|
|||||||
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
|
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
|
||||||
{"output-target", required_argument, 0, 'O'},
|
{"output-target", required_argument, 0, 'O'},
|
||||||
{"pad-to", required_argument, 0, OPTION_PAD_TO},
|
{"pad-to", required_argument, 0, OPTION_PAD_TO},
|
||||||
{"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
|
|
||||||
{"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
|
|
||||||
{"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
|
{"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
|
||||||
|
{"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
|
||||||
|
{"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
|
||||||
{"preserve-dates", no_argument, 0, 'p'},
|
{"preserve-dates", no_argument, 0, 'p'},
|
||||||
{"pure", no_argument, 0, OPTION_PURE},
|
{"pure", no_argument, 0, OPTION_PURE},
|
||||||
{"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
|
{"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
|
||||||
@ -432,19 +448,23 @@ static struct option copy_options[] =
|
|||||||
{"remove-section", required_argument, 0, 'R'},
|
{"remove-section", required_argument, 0, 'R'},
|
||||||
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
|
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
|
||||||
{"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
|
{"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
|
||||||
|
{"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
|
||||||
{"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
|
{"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
|
||||||
{"set-start", required_argument, 0, OPTION_SET_START},
|
{"set-start", required_argument, 0, OPTION_SET_START},
|
||||||
{"srec-len", required_argument, 0, OPTION_SREC_LEN},
|
|
||||||
{"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
|
{"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
|
||||||
|
{"srec-len", required_argument, 0, OPTION_SREC_LEN},
|
||||||
|
{"stack", required_argument, 0, OPTION_STACK},
|
||||||
{"strip-all", no_argument, 0, 'S'},
|
{"strip-all", no_argument, 0, 'S'},
|
||||||
{"strip-debug", no_argument, 0, 'g'},
|
{"strip-debug", no_argument, 0, 'g'},
|
||||||
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
|
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
|
||||||
|
{"strip-symbol", required_argument, 0, 'N'},
|
||||||
|
{"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
|
||||||
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
|
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
|
||||||
{"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
|
{"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
|
||||||
{"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
|
{"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
|
||||||
{"strip-symbol", required_argument, 0, 'N'},
|
{"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
|
||||||
{"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
|
|
||||||
{"target", required_argument, 0, 'F'},
|
{"target", required_argument, 0, 'F'},
|
||||||
|
{"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", no_argument, 0, 'V'},
|
||||||
{"weaken", no_argument, 0, OPTION_WEAKEN},
|
{"weaken", no_argument, 0, OPTION_WEAKEN},
|
||||||
@ -452,12 +472,6 @@ static struct option copy_options[] =
|
|||||||
{"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
|
{"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
|
||||||
{"wildcard", no_argument, 0, 'w'},
|
{"wildcard", no_argument, 0, 'w'},
|
||||||
{"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
|
{"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
|
||||||
{"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
|
|
||||||
{"heap", required_argument, 0, OPTION_HEAP},
|
|
||||||
{"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
|
|
||||||
{"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
|
|
||||||
{"stack", required_argument, 0, OPTION_STACK},
|
|
||||||
{"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
|
|
||||||
{0, no_argument, 0, 0}
|
{0, no_argument, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -585,6 +599,7 @@ copy_usage (FILE *stream, int exit_status)
|
|||||||
--globalize-symbols <file> --globalize-symbol for all in <file>\n\
|
--globalize-symbols <file> --globalize-symbol for all in <file>\n\
|
||||||
--keep-global-symbols <file> -G for all symbols listed 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\
|
--weaken-symbols <file> -W for all symbols listed in <file>\n\
|
||||||
|
--add-symbol <name>=[<section>:]<value>[,<flags>] Add a symbol\n\
|
||||||
--alt-machine-code <index> Use the target's <index>'th alternative machine\n\
|
--alt-machine-code <index> Use the target's <index>'th alternative machine\n\
|
||||||
--writable-text Mark the output text as writable\n\
|
--writable-text Mark the output text as writable\n\
|
||||||
--readonly-text Make the output text write protected\n\
|
--readonly-text Make the output text write protected\n\
|
||||||
@ -727,6 +742,78 @@ parse_flags (const char *s)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse symbol flags into a flagword, with a fatal error if the
|
||||||
|
string can't be parsed. */
|
||||||
|
|
||||||
|
static flagword
|
||||||
|
parse_symflags (const char *s, char **other)
|
||||||
|
{
|
||||||
|
flagword ret;
|
||||||
|
const char *snext;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
ret = BSF_NO_FLAGS;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
snext = strchr (s, ',');
|
||||||
|
if (snext == NULL)
|
||||||
|
len = strlen (s);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = snext - s;
|
||||||
|
++snext;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PARSE_FLAG(fname,fval) \
|
||||||
|
else if (len == (int) sizeof fname - 1 && strncasecmp (fname, s, len) == 0) \
|
||||||
|
ret |= fval
|
||||||
|
|
||||||
|
#define PARSE_OTHER(fname,fval) \
|
||||||
|
else if (len >= (int) sizeof fname && strncasecmp (fname, s, sizeof fname - 1) == 0) \
|
||||||
|
fval = strndup (s + sizeof fname - 1, len - sizeof fname + 1)
|
||||||
|
|
||||||
|
if (0) ;
|
||||||
|
PARSE_FLAG ("local", BSF_LOCAL);
|
||||||
|
PARSE_FLAG ("global", BSF_GLOBAL);
|
||||||
|
PARSE_FLAG ("export", BSF_EXPORT);
|
||||||
|
PARSE_FLAG ("debug", BSF_DEBUGGING);
|
||||||
|
PARSE_FLAG ("function", BSF_FUNCTION);
|
||||||
|
PARSE_FLAG ("weak", BSF_WEAK);
|
||||||
|
PARSE_FLAG ("section", BSF_SECTION_SYM);
|
||||||
|
PARSE_FLAG ("constructor", BSF_CONSTRUCTOR);
|
||||||
|
PARSE_FLAG ("warning", BSF_WARNING);
|
||||||
|
PARSE_FLAG ("indirect", BSF_INDIRECT);
|
||||||
|
PARSE_FLAG ("file", BSF_FILE);
|
||||||
|
PARSE_FLAG ("object", BSF_OBJECT);
|
||||||
|
PARSE_FLAG ("synthetic", BSF_SYNTHETIC);
|
||||||
|
PARSE_FLAG ("indirect-function", BSF_GNU_INDIRECT_FUNCTION | BSF_FUNCTION);
|
||||||
|
PARSE_FLAG ("unique-object", BSF_GNU_UNIQUE | BSF_OBJECT);
|
||||||
|
PARSE_OTHER ("before=", *other);
|
||||||
|
|
||||||
|
#undef PARSE_FLAG
|
||||||
|
#undef PARSE_OTHER
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *copy;
|
||||||
|
|
||||||
|
copy = (char *) xmalloc (len + 1);
|
||||||
|
strncpy (copy, s, len);
|
||||||
|
copy[len] = '\0';
|
||||||
|
non_fatal (_("unrecognized symbol flag `%s'"), copy);
|
||||||
|
fatal (_("supported flags: %s"),
|
||||||
|
"local, global, export, debug, function, weak, section, "
|
||||||
|
"constructor, warning, indirect, file, object, synthetic, "
|
||||||
|
"indirect-function, unique-object, before=<othersym>");
|
||||||
|
}
|
||||||
|
|
||||||
|
s = snext;
|
||||||
|
}
|
||||||
|
while (s != NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find and optionally add an entry in the change_sections list.
|
/* Find and optionally add an entry in the change_sections list.
|
||||||
|
|
||||||
We need to be careful in how we match section names because of the support
|
We need to be careful in how we match section names because of the support
|
||||||
@ -1213,6 +1300,49 @@ is_hidden_symbol (asymbol *sym)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
need_sym_before (struct addsym_node **node, const char *sym)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
struct addsym_node *ptr = add_sym_list;
|
||||||
|
|
||||||
|
/* 'othersym' symbols are at the front of the list. */
|
||||||
|
for (count = 0; count < add_symbols; count++)
|
||||||
|
{
|
||||||
|
if (!ptr->othersym)
|
||||||
|
break;
|
||||||
|
else if (strcmp (ptr->othersym, sym) == 0)
|
||||||
|
{
|
||||||
|
free (ptr->othersym);
|
||||||
|
ptr->othersym = ""; /* Empty name is hopefully never a valid symbol name. */
|
||||||
|
*node = ptr;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
ptr = ptr->next;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static asymbol *
|
||||||
|
create_new_symbol (struct addsym_node *ptr, bfd *obfd)
|
||||||
|
{
|
||||||
|
asymbol *sym = bfd_make_empty_symbol(obfd);
|
||||||
|
|
||||||
|
bfd_asymbol_name(sym) = ptr->symdef;
|
||||||
|
sym->value = ptr->symval;
|
||||||
|
sym->flags = ptr->flags;
|
||||||
|
if (ptr->section)
|
||||||
|
{
|
||||||
|
asection *sec = bfd_get_section_by_name (obfd, ptr->section);
|
||||||
|
if (!sec)
|
||||||
|
fatal (_("Section %s not found"), ptr->section);
|
||||||
|
sym->section = sec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sym->section = bfd_abs_section_ptr;
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
/* Choose which symbol entries to copy; put the result in OSYMS.
|
/* Choose which symbol entries to copy; put the result in OSYMS.
|
||||||
We don't copy in place, because that confuses the relocs.
|
We don't copy in place, because that confuses the relocs.
|
||||||
Return the number of symbols to print. */
|
Return the number of symbols to print. */
|
||||||
@ -1238,6 +1368,14 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||||||
|
|
||||||
undefined = bfd_is_und_section (bfd_get_section (sym));
|
undefined = bfd_is_und_section (bfd_get_section (sym));
|
||||||
|
|
||||||
|
if (add_sym_list)
|
||||||
|
{
|
||||||
|
struct addsym_node *ptr;
|
||||||
|
|
||||||
|
if (need_sym_before (&ptr, name))
|
||||||
|
to[dst_count++] = create_new_symbol (ptr, obfd);
|
||||||
|
}
|
||||||
|
|
||||||
if (redefine_sym_list)
|
if (redefine_sym_list)
|
||||||
{
|
{
|
||||||
char *old_name, *new_name;
|
char *old_name, *new_name;
|
||||||
@ -1394,6 +1532,23 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||||||
to[dst_count++] = sym;
|
to[dst_count++] = sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (add_sym_list)
|
||||||
|
{
|
||||||
|
struct addsym_node *ptr = add_sym_list;
|
||||||
|
|
||||||
|
for (src_count = 0; src_count < add_symbols; src_count++)
|
||||||
|
{
|
||||||
|
if (ptr->othersym)
|
||||||
|
{
|
||||||
|
if (strcmp (ptr->othersym, ""))
|
||||||
|
fatal (_("'before=%s' not found"), ptr->othersym);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to[dst_count++] = create_new_symbol (ptr, obfd);
|
||||||
|
|
||||||
|
ptr = ptr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
to[dst_count] = NULL;
|
to[dst_count] = NULL;
|
||||||
|
|
||||||
@ -2179,7 +2334,8 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
|
|||||||
|| change_leading_char
|
|| change_leading_char
|
||||||
|| remove_leading_char
|
|| remove_leading_char
|
||||||
|| redefine_sym_list
|
|| redefine_sym_list
|
||||||
|| weaken)
|
|| weaken
|
||||||
|
|| add_symbols)
|
||||||
{
|
{
|
||||||
/* Mark symbols used in output relocations so that they
|
/* Mark symbols used in output relocations so that they
|
||||||
are kept, even if they are local labels or static symbols.
|
are kept, even if they are local labels or static symbols.
|
||||||
@ -2193,7 +2349,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
|
|||||||
bfd_map_over_sections (ibfd,
|
bfd_map_over_sections (ibfd,
|
||||||
mark_symbols_used_in_relocations,
|
mark_symbols_used_in_relocations,
|
||||||
isympp);
|
isympp);
|
||||||
osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
|
osympp = (asymbol **) xmalloc ((symcount + add_symbols + 1) * sizeof (asymbol *));
|
||||||
symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
|
symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3920,6 +4076,53 @@ copy_main (int argc, char *argv[])
|
|||||||
"--dump-section");
|
"--dump-section");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPTION_ADD_SYMBOL:
|
||||||
|
{
|
||||||
|
char *s, *t;
|
||||||
|
struct addsym_node *newsym = xmalloc (sizeof *newsym);
|
||||||
|
|
||||||
|
newsym->next = NULL;
|
||||||
|
s = strchr (optarg, '=');
|
||||||
|
if (s == NULL)
|
||||||
|
fatal (_("bad format for %s"), "--add-symbol");
|
||||||
|
t = strchr (s + 1, ':');
|
||||||
|
|
||||||
|
newsym->symdef = strndup (optarg, s - optarg);
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
newsym->section = strndup (s + 1, t - (s + 1));
|
||||||
|
newsym->symval = strtol (t + 1, NULL, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newsym->section = NULL;
|
||||||
|
newsym->symval = strtol (s + 1, NULL, 0);
|
||||||
|
t = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = strchr (t + 1, ',');
|
||||||
|
if (t)
|
||||||
|
newsym->flags = parse_symflags (t+1, &newsym->othersym);
|
||||||
|
else
|
||||||
|
newsym->flags = BSF_GLOBAL;
|
||||||
|
|
||||||
|
/* Keep 'othersym' symbols at the front of the list. */
|
||||||
|
if (newsym->othersym)
|
||||||
|
{
|
||||||
|
newsym->next = add_sym_list;
|
||||||
|
if (!add_sym_list)
|
||||||
|
add_sym_tail = &newsym->next;
|
||||||
|
add_sym_list = newsym;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*add_sym_tail = newsym;
|
||||||
|
add_sym_tail = &newsym->next;
|
||||||
|
}
|
||||||
|
add_symbols++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case OPTION_CHANGE_START:
|
case OPTION_CHANGE_START:
|
||||||
change_start = parse_vma (optarg, "--change-start");
|
change_start = parse_vma (optarg, "--change-start");
|
||||||
break;
|
break;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2015-10-21 Ronald Hoogenbllon <rhoogenboom@irdeto.com>
|
||||||
|
|
||||||
|
PR binutils/19104
|
||||||
|
* binutils-all/add-symbol.d: New test.
|
||||||
|
* binutils-all/objcopy.exp: Run the new test.
|
||||||
|
|
||||||
2015-10-15 Alan Modra <amodra@gmail.com>
|
2015-10-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* binutils-all/objcopy.exp: Delete trailing whitespace. Use
|
* binutils-all/objcopy.exp: Delete trailing whitespace. Use
|
||||||
|
16
binutils/testsuite/binutils-all/add-symbol.d
Normal file
16
binutils/testsuite/binutils-all/add-symbol.d
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#PROG: objcopy
|
||||||
|
#name: objcopy add-symbol
|
||||||
|
#source: symbols.s
|
||||||
|
#objcopy: --add-symbol NEW=0x1234 --add-symbol NEW_DATA=.data:0x4321,local
|
||||||
|
#objdump: --syms
|
||||||
|
# MIPS targets swap the order of the symbols in the output.
|
||||||
|
#not-target: mips-*-* tx39-*-*
|
||||||
|
|
||||||
|
.*: +file format .*
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
#...
|
||||||
|
0+04321 l[ ]+.data[ ]+0+00 NEW_DATA
|
||||||
|
#...
|
||||||
|
0+01234 g[ ]+\*ABS\*[ ]+0+00 NEW
|
||||||
|
#pass
|
@ -1097,6 +1097,7 @@ if [is_elf_format] {
|
|||||||
run_dump_test "testranges-ia64"
|
run_dump_test "testranges-ia64"
|
||||||
|
|
||||||
run_dump_test "add-section"
|
run_dump_test "add-section"
|
||||||
|
run_dump_test "add-symbol"
|
||||||
run_dump_test "add-empty-section"
|
run_dump_test "add-empty-section"
|
||||||
|
|
||||||
run_dump_test "exclude-1a"
|
run_dump_test "exclude-1a"
|
||||||
|
Reference in New Issue
Block a user