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:
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>
|
||||
|
||||
PR binutils/19147
|
||||
|
@ -1,5 +1,8 @@
|
||||
-*- 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.
|
||||
|
||||
* 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{--globalize-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{--prefix-symbols=}@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{--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}]
|
||||
Rename a section from @var{oldname} to @var{newname}, optionally
|
||||
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
|
||||
{
|
||||
const char *name;
|
||||
const char * name;
|
||||
bfd_boolean found;
|
||||
};
|
||||
|
||||
@ -62,6 +62,16 @@ struct redefine_node
|
||||
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
|
||||
{
|
||||
const char * old_name;
|
||||
@ -88,26 +98,26 @@ static int deterministic = -1; /* Enable deterministic archives. */
|
||||
static int status = 0; /* Exit status. */
|
||||
|
||||
enum strip_action
|
||||
{
|
||||
STRIP_UNDEF,
|
||||
STRIP_NONE, /* Don't strip. */
|
||||
STRIP_DEBUG, /* Strip all debugger symbols. */
|
||||
STRIP_UNNEEDED, /* Strip unnecessary symbols. */
|
||||
STRIP_NONDEBUG, /* Strip everything but debug info. */
|
||||
STRIP_DWO, /* Strip all DWO info. */
|
||||
STRIP_NONDWO, /* Strip everything but DWO info. */
|
||||
STRIP_ALL /* Strip all symbols. */
|
||||
};
|
||||
{
|
||||
STRIP_UNDEF,
|
||||
STRIP_NONE, /* Don't strip. */
|
||||
STRIP_DEBUG, /* Strip all debugger symbols. */
|
||||
STRIP_UNNEEDED, /* Strip unnecessary symbols. */
|
||||
STRIP_NONDEBUG, /* Strip everything but debug info. */
|
||||
STRIP_DWO, /* Strip all DWO info. */
|
||||
STRIP_NONDWO, /* Strip everything but DWO info. */
|
||||
STRIP_ALL /* Strip all symbols. */
|
||||
};
|
||||
|
||||
/* Which symbols to remove. */
|
||||
static enum strip_action strip_symbols = STRIP_UNDEF;
|
||||
|
||||
enum locals_action
|
||||
{
|
||||
LOCALS_UNDEF,
|
||||
LOCALS_START_L, /* Discard locals starting with L. */
|
||||
LOCALS_ALL /* Discard all locals. */
|
||||
};
|
||||
{
|
||||
LOCALS_UNDEF,
|
||||
LOCALS_START_L, /* Discard locals starting with L. */
|
||||
LOCALS_ALL /* Discard all locals. */
|
||||
};
|
||||
|
||||
/* Which local symbols to remove. Overrides STRIP_ALL. */
|
||||
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 weaken_specific_htab = 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). */
|
||||
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,
|
||||
or preserve them where found in the inputs. Debug info relies on them. */
|
||||
enum long_section_name_handling
|
||||
{
|
||||
DISABLE,
|
||||
ENABLE,
|
||||
KEEP
|
||||
};
|
||||
{
|
||||
DISABLE,
|
||||
ENABLE,
|
||||
KEEP
|
||||
};
|
||||
|
||||
/* The default long section handling mode is to preserve them.
|
||||
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. */
|
||||
enum command_line_switch
|
||||
{
|
||||
OPTION_ADD_SECTION=150,
|
||||
OPTION_UPDATE_SECTION,
|
||||
OPTION_DUMP_SECTION,
|
||||
OPTION_CHANGE_ADDRESSES,
|
||||
OPTION_CHANGE_LEADING_CHAR,
|
||||
OPTION_CHANGE_START,
|
||||
OPTION_CHANGE_SECTION_ADDRESS,
|
||||
OPTION_CHANGE_SECTION_LMA,
|
||||
OPTION_CHANGE_SECTION_VMA,
|
||||
OPTION_CHANGE_WARNINGS,
|
||||
OPTION_COMPRESS_DEBUG_SECTIONS,
|
||||
OPTION_DEBUGGING,
|
||||
OPTION_DECOMPRESS_DEBUG_SECTIONS,
|
||||
OPTION_GAP_FILL,
|
||||
OPTION_NO_CHANGE_WARNINGS,
|
||||
OPTION_PAD_TO,
|
||||
OPTION_REMOVE_LEADING_CHAR,
|
||||
OPTION_SET_SECTION_FLAGS,
|
||||
OPTION_SET_START,
|
||||
OPTION_STRIP_UNNEEDED,
|
||||
OPTION_WEAKEN,
|
||||
OPTION_REDEFINE_SYM,
|
||||
OPTION_REDEFINE_SYMS,
|
||||
OPTION_SREC_LEN,
|
||||
OPTION_SREC_FORCES3,
|
||||
OPTION_STRIP_SYMBOLS,
|
||||
OPTION_STRIP_UNNEEDED_SYMBOL,
|
||||
OPTION_STRIP_UNNEEDED_SYMBOLS,
|
||||
OPTION_KEEP_SYMBOLS,
|
||||
OPTION_LOCALIZE_HIDDEN,
|
||||
OPTION_LOCALIZE_SYMBOLS,
|
||||
OPTION_LONG_SECTION_NAMES,
|
||||
OPTION_GLOBALIZE_SYMBOL,
|
||||
OPTION_GLOBALIZE_SYMBOLS,
|
||||
OPTION_KEEPGLOBAL_SYMBOLS,
|
||||
OPTION_WEAKEN_SYMBOLS,
|
||||
OPTION_RENAME_SECTION,
|
||||
OPTION_ALT_MACH_CODE,
|
||||
OPTION_PREFIX_SYMBOLS,
|
||||
OPTION_PREFIX_SECTIONS,
|
||||
OPTION_PREFIX_ALLOC_SECTIONS,
|
||||
OPTION_FORMATS_INFO,
|
||||
OPTION_ADD_GNU_DEBUGLINK,
|
||||
OPTION_ONLY_KEEP_DEBUG,
|
||||
OPTION_KEEP_FILE_SYMBOLS,
|
||||
OPTION_READONLY_TEXT,
|
||||
OPTION_WRITABLE_TEXT,
|
||||
OPTION_PURE,
|
||||
OPTION_IMPURE,
|
||||
OPTION_EXTRACT_SYMBOL,
|
||||
OPTION_REVERSE_BYTES,
|
||||
OPTION_FILE_ALIGNMENT,
|
||||
OPTION_HEAP,
|
||||
OPTION_IMAGE_BASE,
|
||||
OPTION_SECTION_ALIGNMENT,
|
||||
OPTION_STACK,
|
||||
OPTION_INTERLEAVE_WIDTH,
|
||||
OPTION_SUBSYSTEM,
|
||||
OPTION_EXTRACT_DWO,
|
||||
OPTION_STRIP_DWO
|
||||
};
|
||||
{
|
||||
OPTION_ADD_SECTION=150,
|
||||
OPTION_ADD_GNU_DEBUGLINK,
|
||||
OPTION_ADD_SYMBOL,
|
||||
OPTION_ALT_MACH_CODE,
|
||||
OPTION_CHANGE_ADDRESSES,
|
||||
OPTION_CHANGE_LEADING_CHAR,
|
||||
OPTION_CHANGE_SECTION_ADDRESS,
|
||||
OPTION_CHANGE_SECTION_LMA,
|
||||
OPTION_CHANGE_SECTION_VMA,
|
||||
OPTION_CHANGE_START,
|
||||
OPTION_CHANGE_WARNINGS,
|
||||
OPTION_COMPRESS_DEBUG_SECTIONS,
|
||||
OPTION_DEBUGGING,
|
||||
OPTION_DECOMPRESS_DEBUG_SECTIONS,
|
||||
OPTION_DUMP_SECTION,
|
||||
OPTION_EXTRACT_DWO,
|
||||
OPTION_EXTRACT_SYMBOL,
|
||||
OPTION_FILE_ALIGNMENT,
|
||||
OPTION_FORMATS_INFO,
|
||||
OPTION_GAP_FILL,
|
||||
OPTION_GLOBALIZE_SYMBOL,
|
||||
OPTION_GLOBALIZE_SYMBOLS,
|
||||
OPTION_HEAP,
|
||||
OPTION_IMAGE_BASE,
|
||||
OPTION_IMPURE,
|
||||
OPTION_INTERLEAVE_WIDTH,
|
||||
OPTION_KEEPGLOBAL_SYMBOLS,
|
||||
OPTION_KEEP_FILE_SYMBOLS,
|
||||
OPTION_KEEP_SYMBOLS,
|
||||
OPTION_LOCALIZE_HIDDEN,
|
||||
OPTION_LOCALIZE_SYMBOLS,
|
||||
OPTION_LONG_SECTION_NAMES,
|
||||
OPTION_NO_CHANGE_WARNINGS,
|
||||
OPTION_ONLY_KEEP_DEBUG,
|
||||
OPTION_PAD_TO,
|
||||
OPTION_PREFIX_ALLOC_SECTIONS,
|
||||
OPTION_PREFIX_SECTIONS,
|
||||
OPTION_PREFIX_SYMBOLS,
|
||||
OPTION_PURE,
|
||||
OPTION_READONLY_TEXT,
|
||||
OPTION_REDEFINE_SYM,
|
||||
OPTION_REDEFINE_SYMS,
|
||||
OPTION_REMOVE_LEADING_CHAR,
|
||||
OPTION_RENAME_SECTION,
|
||||
OPTION_REVERSE_BYTES,
|
||||
OPTION_SECTION_ALIGNMENT,
|
||||
OPTION_SET_SECTION_FLAGS,
|
||||
OPTION_SET_START,
|
||||
OPTION_SREC_FORCES3,
|
||||
OPTION_SREC_LEN,
|
||||
OPTION_STACK,
|
||||
OPTION_STRIP_DWO,
|
||||
OPTION_STRIP_SYMBOLS,
|
||||
OPTION_STRIP_UNNEEDED,
|
||||
OPTION_STRIP_UNNEEDED_SYMBOL,
|
||||
OPTION_STRIP_UNNEEDED_SYMBOLS,
|
||||
OPTION_SUBSYSTEM,
|
||||
OPTION_UPDATE_SECTION,
|
||||
OPTION_WEAKEN,
|
||||
OPTION_WEAKEN_SYMBOLS,
|
||||
OPTION_WRITABLE_TEXT
|
||||
};
|
||||
|
||||
/* 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-symbol", required_argument, 0, 'K'},
|
||||
{"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
|
||||
{"output-file", required_argument, 0, 'o'},
|
||||
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
|
||||
{"output-target", required_argument, 0, 'O'},
|
||||
{"output-file", required_argument, 0, 'o'},
|
||||
{"preserve-dates", no_argument, 0, 'p'},
|
||||
{"remove-section", required_argument, 0, 'R'},
|
||||
{"strip-all", no_argument, 0, 's'},
|
||||
{"strip-debug", no_argument, 0, 'S'},
|
||||
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
|
||||
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
|
||||
{"strip-symbol", required_argument, 0, 'N'},
|
||||
{"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
|
||||
{"target", required_argument, 0, 'F'},
|
||||
{"verbose", 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-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-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},
|
||||
{"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
|
||||
{"binary-architecture", required_argument, 0, 'B'},
|
||||
@ -393,11 +406,14 @@ static struct option copy_options[] =
|
||||
{"enable-deterministic-archives", no_argument, 0, 'D'},
|
||||
{"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
|
||||
{"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
|
||||
{"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
|
||||
{"format", required_argument, 0, 'F'}, /* Obsolete */
|
||||
{"gap-fill", required_argument, 0, OPTION_GAP_FILL},
|
||||
{"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
|
||||
{"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
|
||||
{"heap", required_argument, 0, OPTION_HEAP},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
|
||||
{"impure", no_argument, 0, OPTION_IMPURE},
|
||||
{"info", no_argument, 0, OPTION_FORMATS_INFO},
|
||||
{"input-format", required_argument, 0, 'I'}, /* Obsolete */
|
||||
@ -420,9 +436,9 @@ static struct option copy_options[] =
|
||||
{"output-format", required_argument, 0, 'O'}, /* Obsolete */
|
||||
{"output-target", required_argument, 0, 'O'},
|
||||
{"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-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
|
||||
{"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
|
||||
{"preserve-dates", no_argument, 0, 'p'},
|
||||
{"pure", no_argument, 0, OPTION_PURE},
|
||||
{"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
|
||||
@ -432,19 +448,23 @@ static struct option copy_options[] =
|
||||
{"remove-section", required_argument, 0, 'R'},
|
||||
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
|
||||
{"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-start", required_argument, 0, OPTION_SET_START},
|
||||
{"srec-len", required_argument, 0, OPTION_SREC_LEN},
|
||||
{"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-debug", no_argument, 0, 'g'},
|
||||
{"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-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
|
||||
{"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
|
||||
{"strip-symbol", required_argument, 0, 'N'},
|
||||
{"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
|
||||
{"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
|
||||
{"target", required_argument, 0, 'F'},
|
||||
{"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"weaken", no_argument, 0, OPTION_WEAKEN},
|
||||
@ -452,12 +472,6 @@ static struct option copy_options[] =
|
||||
{"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
|
||||
{"wildcard", no_argument, 0, 'w'},
|
||||
{"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}
|
||||
};
|
||||
|
||||
@ -585,6 +599,7 @@ 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\
|
||||
--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\
|
||||
--readonly-text Make the output text write protected\n\
|
||||
@ -727,6 +742,78 @@ parse_flags (const char *s)
|
||||
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.
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
We don't copy in place, because that confuses the relocs.
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
char *old_name, *new_name;
|
||||
@ -1394,6 +1532,23 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
||||
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;
|
||||
|
||||
@ -2179,7 +2334,8 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
|
||||
|| change_leading_char
|
||||
|| remove_leading_char
|
||||
|| redefine_sym_list
|
||||
|| weaken)
|
||||
|| weaken
|
||||
|| add_symbols)
|
||||
{
|
||||
/* Mark symbols used in output relocations so that they
|
||||
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,
|
||||
mark_symbols_used_in_relocations,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -3920,6 +4076,53 @@ copy_main (int argc, char *argv[])
|
||||
"--dump-section");
|
||||
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:
|
||||
change_start = parse_vma (optarg, "--change-start");
|
||||
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>
|
||||
|
||||
* 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 "add-section"
|
||||
run_dump_test "add-symbol"
|
||||
run_dump_test "add-empty-section"
|
||||
|
||||
run_dump_test "exclude-1a"
|
||||
|
Loading…
x
Reference in New Issue
Block a user