Add --redefine-sym to objcopy.

This commit is contained in:
Alan Modra 2000-04-05 03:43:56 +00:00
parent c7e79b4bee
commit 57938635f5
5 changed files with 258 additions and 64 deletions

View File

@ -1,3 +1,32 @@
2000-04-05 Alan Modra <alan@linuxcare.com.au>
* binutils.texi: Remove optional `=' from long options that have
an `=' in the argument.
* objcopy.1: Here too. Remove extra space on discard-all.
* binutils.texi (objcopy): Mention --redefine-sym.
* objcopy.1: Here too.
* NEWS: And here.
* objcopy.c (parse_flags): Split off flag names from error message
gettext as they are not translated.
(copy_main): Similarly split off option name for --add-section,
--set-section-flags, --change-section-vma, --change-section-lma
error messages.
Some white space changes.
from Matthew Benjamin <matt@linuxbox.nu>
* objcopy.c (struct redefine_node): New.
(redefine_sym_list): New.
(redefine_list_append): New.
(lookup_sym_redefinition): New.
(OPTION_REDEFINE_SYM): New.
(copy_options): Add --redefine-sym option.
(copy_usage): Mention it.
(filter_symbols): Rename symbols on redefine_sym_list.
(copy_object): Call filter_symbols if redefine_sym_list != NULL.
(copy_main): Handle OPTION_REDEFINE_SYM.
2000-04-04 H.J. Lu <hjl@gnu.org>
* readelf.c (process_symbol_table): Correctly read in symbol

View File

@ -22,14 +22,16 @@ Changes in binutils 2.10:
equivalent to --change-section-address. The other --adjust-* options are now
renamed to --change-*, although --adjust-* continues to work.
* objcopy has a --redefine-sym option that lets you rename symbols.
* objcopy now takes a -j/--only-section option to copy only the specified
sections.
* dlltool now supports the IMPORTS command.
* dlltool now takes --export-all-symbols, --no-export-all-symbols,
--exclude-symbols, and --no-default-excludes options.
* objcopy now takes a -j/--only-section option to copy only the specified
sections.
Changes in binutils 2.9:
* Added windres program, which can be used to manipulate resources in WIN32

View File

@ -878,14 +878,14 @@ objcopy [ -F @var{bfdname} | --target=@var{bfdname} ]
[ --gap-fill=@var{val} ] [ --pad-to=@var{address} ]
[ --set-start=@var{val} ] [ --adjust-start=@var{incr} ]
[ --change-addresses=@var{incr} ]
[ --change-section-address=@var{section}@{=,+,-@}@var{val} ]
[ --change-section-lma=@var{section}@{=,+,-@}@var{val} ]
[ --change-section-vma=@var{section}@{=,+,-@}@var{val} ]
[ --change-section-address @var{section}@{=,+,-@}@var{val} ]
[ --change-section-lma @var{section}@{=,+,-@}@var{val} ]
[ --change-section-vma @var{section}@{=,+,-@}@var{val} ]
[ --change-warnings ] [ --no-change-warnings ]
[ --set-section-flags=@var{section}=@var{flags} ]
[ --add-section=@var{sectionname}=@var{filename} ]
[ --set-section-flags @var{section}=@var{flags} ]
[ --add-section @var{sectionname}=@var{filename} ]
[ --change-leading-char ] [ --remove-leading-char ]
[ --weaken ]
[ --redefine-sym @var{old}=@var{new} ] [ --weaken ]
[ -v | --verbose ] [ -V | --version ] [ --help ]
@var{infile} [@var{outfile}]
@end smallexample
@ -1137,6 +1137,11 @@ different conventions for symbol names. This is different from
when appropriate, regardless of the object file format of the output
file.
@item --redefine-sym @var{old}=@var{new}
Change the name of a symbol @var{old}, to @var{new}. This can be useful
when one is trying link two things together for which you have no
source, and there are name collisions.
@item --weaken
Change all global symbols in the file to be weak. This can be useful
when building an object which will be linked against other objects using

View File

@ -38,15 +38,16 @@ objcopy \- copy and translate object files
.RB "[\|" \-\-set\-start=\fIval\fR "\|]"
.RB "[\|" \-\-change\-start=\fIincr\fR "\|]"
.RB "[\|" \-\-change\-addresses=\fIincr\fR "\|]"
.RB "[\|" \-\-change\-section\-address=\fIsection{=,+,-}val\fR "\|]"
.RB "[\|" \-\-change\-section\-lma=\fIsection{=,+,-}val\fR "\|]"
.RB "[\|" \-\-change\-section\-vma=\fIsection{=,+,-}val\fR "\|]"
.RB "[\|" \-\-change\-section\-address\ \fIsection{=,+,-}val\fR "\|]"
.RB "[\|" \-\-change\-section\-lma\ \fIsection{=,+,-}val\fR "\|]"
.RB "[\|" \-\-change\-section\-vma\ \fIsection{=,+,-}val\fR "\|]"
.RB "[\|" \-\-change\-warnings\fR "\|]"
.RB "[\|" \-\-no\-change\-warnings\fR "\|]"
.RB "[\|" \-\-set\-section\-flags=\fIsection=flags\fR "\|]"
.RB "[\|" \-\-add\-section=\fIsectionname=filename\fR "\|]"
.RB "[\|" \-\-set\-section\-flags\ \fIsection=flags\fR "\|]"
.RB "[\|" \-\-add\-section\ \fIsectionname=filename\fR "\|]"
.RB "[\|" \-\-change\-leading\-char\fR "\|]"
.RB "[\|" \-\-remove\-leading\-char\fR "\|]"
.RB "[\|" \-\-redefine\-sym\ \fIold=new\fR "\|]"
.RB "[\|" \-\-weaken\fR "\|]"
.RB "[\|" \-v\ |\ \-\-verbose\fR "\|]"
.RB "[\|" \-V\ |\ \-\-version\fR "\|]"
@ -214,7 +215,7 @@ the sections; if the program expects sections to be loaded at a
certain address, and this option is used to change the sections such
that they are loaded at a different address, the program may fail.
.TP
.B \fB\-\-change\-section\-address=\fIsection{=,+,-}val\fR, \fB\-\-adjust\-section\-vma=\fIsection{=,+,-}val
.B \fB\-\-change\-section\-address\ \fIsection{=,+,-}val\fR, \fB\-\-adjust\-section\-vma\ \fIsection{=,+,-}val
Set or changes the VMA and LMA addresses of the named \fIsection\fP.
If \fI=\fP is used, the section address is set to \fIval\fP.
Otherwise, \fIval\fP is added to or subtracted from the section
@ -222,7 +223,7 @@ address. See the comments under \fB\-\-change\-addresses\fP, above. If
\fIsection\fP does not exist in the input file, a warning will be
issued, unless \fB\-\-no\-change\-warnings\fP is used.
.TP
.B \fB\-\-change\-section\-lma=\fIsection{=,+,-}val
.B \fB\-\-change\-section\-lma\ \fIsection{=,+,-}val
Set or change the LMA address of the named \fIsection\fP. If \fI=\fP is
used, the section address is set to \fIval\fP. Otherwise, \fIval\fP
is added to or subtracted from the section address. See the comments
@ -230,7 +231,7 @@ under \fB\-\-change\-addresses\fP, above. If \fIsection\fP does not exist
in the input file, a warning will be issued, unless
\fB\-\-no\-change\-warnings\fP is used.
.TP
.B \fB\-\-change\-section\-vma=\fIsection{=,+,-}val
.B \fB\-\-change\-section\-vma\ \fIsection{=,+,-}val
Set or change the VMA address of the named \fIsection\fP. If \fI=\fP is
used, the section address is set to \fIval\fP. Otherwise, \fIval\fP
is added to or subtracted from the section address. See the comments
@ -246,14 +247,14 @@ not exist, issue a warning. This is the default.
Do not issue a warning if \fB\-\-change\-section\-XXX\fP is used, even
if the named section does not exist.
.TP
.B \fB\-\-set\-section\-flags=\fIsection=flags
.B \fB\-\-set\-section\-flags\ \fIsection=flags
Set the flags for the named section. The \fIflags\fP argument is a
comma separated string of flag names. The recognized names are
\fIalloc\fP, \fIcontents\fP, \fIload\fP, \fInoload\fP, \fIreadonly\fP,
\fIcode\fP, \fIdata\fP, \fIrom\fP, \fIshare\fP, and \fIdebug\fP. Not
all flags are meaningful for all object file formats.
.TP
.B \fB\-\-add\-section=\fIsectionname=filename
.B \fB\-\-add\-section\ \fIsectionname=filename
Add a new section named \fIsectionname\fR while copying the file. The
contents of the new section are taken from the file \fIfilename\fR.
The size of the section will be the size of the file. This option
@ -281,6 +282,11 @@ with different conventions for symbol names. This is different from
\fB\-\-change\-leading\-char\fP because it always changes the symbol name
when appropriate, regardless of the object file format of the output
.TP
.B \-\-redefine\-sym\ \fIold=new
Change the name of symbol \fIold\fR to \fInew\fR. This can be useful
when one is trying link two things together for which you have no
source, and there are name collisions.
.TP
.B \-\-weaken
Change all global symbols in the file to be weak.
.TP

View File

@ -38,6 +38,14 @@ struct symlist
struct symlist *next;
};
/* A list to support redefine_sym. */
struct redefine_node
{
char *source;
char *target;
struct redefine_node *next;
};
static void copy_usage PARAMS ((FILE *, int));
static void strip_usage PARAMS ((FILE *, int));
static flagword parse_flags PARAMS ((const char *));
@ -60,6 +68,8 @@ static void copy_file
PARAMS ((const char *, const char *, const char *, const char *));
static int strip_main PARAMS ((int, char **));
static int copy_main PARAMS ((int, char **));
static const char *lookup_sym_redefinition PARAMS((const char *));
static void redefine_list_append PARAMS ((const char *, const char *));
#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
@ -172,12 +182,13 @@ static boolean change_leading_char = false;
static boolean remove_leading_char = false;
/* List of symbols to strip, keep, localize, and weaken. */
/* List of symbols to strip, keep, localize, weaken, or redefine. */
static struct symlist *strip_specific_list = NULL;
static struct symlist *keep_specific_list = NULL;
static struct symlist *localize_specific_list = NULL;
static struct symlist *weaken_specific_list = NULL;
static struct redefine_node *redefine_sym_list = NULL;
/* If this is true, we weaken global symbols (set BSF_WEAK). */
@ -202,6 +213,7 @@ static boolean weaken = false;
#define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
#define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
#define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
#define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
/* Options to handle if running as "strip". */
@ -276,6 +288,7 @@ static struct option copy_options[] =
{"version", no_argument, 0, 'V'},
{"weaken", no_argument, 0, OPTION_WEAKEN},
{"weaken-symbol", required_argument, 0, 'W'},
{"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
{0, no_argument, 0, 0}
};
@ -335,6 +348,7 @@ copy_usage (stream, exit_status)
--add-section <name>=<file> Add section <name> found in <file> to output\n\
--change-leading-char Force output format's leading character style\n\
--remove-leading-char Remove leading character from global symbols\n\
--redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
-v --verbose List all object files modified\n\
-V --version Display this program's version number\n\
-h --help Display this output\n\
@ -423,7 +437,8 @@ parse_flags (s)
strncpy (copy, s, len);
copy[len] = '\0';
non_fatal (_("unrecognized section flag `%s'"), copy);
fatal (_("supported flags: alloc, load, noload, readonly, debug, code, data, rom, share, contents"));
fatal (_("supported flags: %s"),
"alloc, load, noload, readonly, debug, code, data, rom, share, contents");
}
s = snext;
@ -549,6 +564,15 @@ filter_symbols (abfd, obfd, osyms, isyms, symcount)
const char *name = bfd_asymbol_name (sym);
int keep;
if (redefine_sym_list)
{
const char *old_name, *new_name;
old_name = bfd_asymbol_name (sym);
new_name = lookup_sym_redefinition (old_name);
name = bfd_asymbol_name (sym) = new_name;
}
if (change_leading_char
&& (bfd_get_symbol_leading_char (abfd)
!= bfd_get_symbol_leading_char (obfd))
@ -630,6 +654,64 @@ filter_symbols (abfd, obfd, osyms, isyms, symcount)
return dst_count;
}
static const char *
lookup_sym_redefinition (source)
const char *source;
{
const char *result;
struct redefine_node *list;
result = source;
for (list = redefine_sym_list; list != NULL; list = list->next)
{
if (strcmp (source, list->source) == 0)
{
result = list->target;
break;
}
}
return result;
}
/* Add a node to a symbol redefine list */
static void
redefine_list_append (source, target)
const char *source;
const char *target;
{
struct redefine_node **p;
struct redefine_node *list;
struct redefine_node *new_node;
for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
{
if (strcmp (source, list->source) == 0)
{
fatal (_("%s: Multiple redefinition of symbol \"%s\""),
"--redefine-sym",
source);
}
if (strcmp (target, list->target) == 0)
{
fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
"--redefine-sym",
target);
}
}
new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
new_node->source = strdup (source);
new_node->target = strdup (target);
new_node->next = NULL;
*p = new_node;
}
/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
Adjust *SIZE. */
@ -868,6 +950,7 @@ copy_object (ibfd, obfd)
|| convert_debugging
|| change_leading_char
|| remove_leading_char
|| redefine_sym_list
|| weaken)
{
/* Mark symbols used in output relocations so that they
@ -1720,22 +1803,27 @@ copy_main (argc, argv)
if (copy_byte < 0)
fatal (_("byte number must be non-negative"));
break;
case 'i':
interleave = atoi (optarg);
if (interleave < 1)
fatal (_("interleave must be positive"));
break;
case 'I':
case 's': /* "source" - 'I' is preferred */
input_target = optarg;
break;
case 'O':
case 'd': /* "destination" - 'O' is preferred */
output_target = optarg;
break;
case 'F':
input_target = output_target = optarg;
break;
case 'j':
p = find_section_list (optarg, true);
if (p->remove)
@ -1743,6 +1831,7 @@ copy_main (argc, argv)
p->copy = true;
sections_copied = true;
break;
case 'R':
p = find_section_list (optarg, true);
if (p->copy)
@ -1750,45 +1839,59 @@ copy_main (argc, argv)
p->remove = true;
sections_removed = true;
break;
case 'S':
strip_symbols = STRIP_ALL;
break;
case 'g':
strip_symbols = STRIP_DEBUG;
break;
case OPTION_STRIP_UNNEEDED:
strip_symbols = STRIP_UNNEEDED;
break;
case 'K':
add_specific_symbol (optarg, &keep_specific_list);
break;
case 'N':
add_specific_symbol (optarg, &strip_specific_list);
break;
case 'L':
add_specific_symbol (optarg, &localize_specific_list);
break;
case 'W':
add_specific_symbol (optarg, &weaken_specific_list);
break;
case 'p':
preserve_dates = true;
break;
case 'x':
discard_locals = LOCALS_ALL;
break;
case 'X':
discard_locals = LOCALS_START_L;
break;
case 'v':
verbose = true;
break;
case 'V':
show_version = true;
break;
case OPTION_WEAKEN:
weaken = true;
break;
case OPTION_ADD_SECTION:
{
const char *s;
@ -1801,7 +1904,7 @@ copy_main (argc, argv)
s = strchr (optarg, '=');
if (s == NULL)
fatal (_("bad format for --add-section NAME=FILENAME"));
fatal (_("bad format for %s"), "--add-section");
if (stat (s + 1, & st) < 0)
fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
@ -1834,9 +1937,11 @@ copy_main (argc, argv)
add_sections = pa;
}
break;
case OPTION_CHANGE_START:
change_start = parse_vma (optarg, "--change-start");
break;
case OPTION_CHANGE_SECTION_ADDRESS:
case OPTION_CHANGE_SECTION_LMA:
case OPTION_CHANGE_SECTION_VMA:
@ -1908,19 +2013,24 @@ copy_main (argc, argv)
}
}
break;
case OPTION_CHANGE_ADDRESSES:
change_section_address = parse_vma (optarg, "--change-addresses");
change_start = change_section_address;
break;
case OPTION_CHANGE_WARNINGS:
change_warn = true;
break;
case OPTION_CHANGE_LEADING_CHAR:
change_leading_char = true;
break;
case OPTION_DEBUGGING:
convert_debugging = true;
break;
case OPTION_GAP_FILL:
{
bfd_vma gap_fill_vma;
@ -1939,16 +2049,52 @@ copy_main (argc, argv)
gap_fill_set = true;
}
break;
case OPTION_NO_CHANGE_WARNINGS:
change_warn = false;
break;
case OPTION_PAD_TO:
pad_to = parse_vma (optarg, "--pad-to");
pad_to_set = true;
break;
case OPTION_REMOVE_LEADING_CHAR:
remove_leading_char = true;
break;
case OPTION_REDEFINE_SYM:
{
/* Push this redefinition onto redefine_symbol_list. */
int len;
const char *s;
const char *nextarg;
char *source, *target;
s = strchr (optarg, '=');
if (s == NULL)
{
fatal (_("bad format for %s"), "--redefine-sym");
}
len = s - optarg;
source = (char *) xmalloc (len + 1);
strncpy (source, optarg, len);
source[len] = '\0';
nextarg = s + 1;
len = strlen (nextarg);
target = (char *) xmalloc (len + 1);
strcpy (target, nextarg);
redefine_list_append (source, target);
free (source);
free (target);
}
break;
case OPTION_SET_SECTION_FLAGS:
{
const char *s;
@ -1957,7 +2103,7 @@ copy_main (argc, argv)
s = strchr (optarg, '=');
if (s == NULL)
fatal (_("bad format for --set-section-flags"));
fatal (_("bad format for %s"), "--set-section-flags");
len = s - optarg;
name = (char *) xmalloc (len + 1);
@ -1970,14 +2116,18 @@ copy_main (argc, argv)
p->flags = parse_flags (s + 1);
}
break;
case OPTION_SET_START:
set_start = parse_vma (optarg, "--set-start");
set_start_set = true;
break;
case 0:
break; /* we've been given a long option */
case 'h':
copy_usage (stdout, 0);
default:
copy_usage (stderr, 1);
}
@ -2046,7 +2196,8 @@ copy_main (argc, argv)
sprintf_vma (buff, p->vma_val);
/* xgettext:c-format */
non_fatal (_("Warning: --change-section-vma %s%c0x%s never used"),
non_fatal (_("%s %s%c0x%s never used"),
"--change-section-vma",
p->name,
p->change_vma == CHANGE_SET ? '=' : '+',
buff);
@ -2059,7 +2210,8 @@ copy_main (argc, argv)
sprintf_vma (buff, p->lma_val);
/* xgettext:c-format */
non_fatal (_("Warning: --change-section-lma %s%c0x%s never used"),
non_fatal (_("%s %s%c0x%s never used"),
"--change-section-lma",
p->name,
p->change_lma == CHANGE_SET ? '=' : '+',
buff);