Implement new switch --rename-section

This commit is contained in:
Nick Clifton 2001-07-31 13:49:39 +00:00
parent f18ee7ef71
commit 594ef5dbd2
4 changed files with 207 additions and 51 deletions

View file

@ -1,3 +1,19 @@
2001-07-31 Nick Clifton <nickc@cambridge.redhat.com>
* objcopy.c: Fix formatting.
(section_rename): New structure.
(OPTION_RENAME_SECTION): New switch.
(copy_usage): Document new switch.
(add_section_rename): New function: Add a node to the section
rename list.
(find_section_rename): New function: Find the new name and
flags for a section.
(setup_section): Call find_section_name to determine the name
of the output section.
(copy_main): Handle OPTION_RENAME_SECTION.
* binutils.texi: Document new switch.
* NEWS: Mention new switch.
2001-07-30 Nick Clifton <nickc@cambridge.redhat.com>
* README: Rename bug-gnu-utils@gcc.org to bug-binutils@gcc.org.

View file

@ -1,5 +1,7 @@
-*- text -*-
* objcopy: Add --rename-section to change section names.
* readelf: Support added for DWARF 2.1 extensions. Support added for
displaying the contents of .debug.macinfo sections.

View file

@ -941,6 +941,7 @@ objcopy [ -F @var{bfdname} | --target=@var{bfdname} ]
[ --change-warnings ] [ --no-change-warnings ]
[ --set-section-flags @var{section}=@var{flags} ]
[ --add-section @var{sectionname}=@var{filename} ]
[ --rename-section @var{oldname}=@var{newname}[,@var{flags}] ]
[ --change-leading-char ] [ --remove-leading-char ]
[ --srec-len=@var{ival} ] [ --srec-forceS3 ]
[ --redefine-sym @var{old}=@var{new} ] [ --weaken ]
@ -1210,6 +1211,24 @@ contents of the new section are taken from the file @var{filename}. The
size of the section will be the size of the file. This option only
works on file formats which can support sections with arbitrary names.
@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
the advantage over usng a linker script to perform the rename in that
the output stays as an object file and does not become a linked
executable.
This option is particularly helpful when the input format is binary,
since this will always create a section called .data. If for example,
you wanted instead to create a section called .rodata containing binary
data you could use the following command line to achieve it:
@smallexample
objcopy -I binary -O <output_format> -B <architecture> \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
<input_binary_file> <output_object_file>
@end smallexample
@item --change-leading-char
Some object file formats use special characters at the start of
symbols. The most common such character is underscore, which compilers

View file

@ -48,6 +48,18 @@ struct redefine_node
struct redefine_node *next;
};
typedef struct section_rename
{
const char * old_name;
const char * new_name;
flagword flags;
struct section_rename * next;
}
section_rename;
/* List of sections to be renamed. */
static section_rename * section_rename_list;
static void copy_usage PARAMS ((FILE *, int));
static void strip_usage PARAMS ((FILE *, int));
static flagword parse_flags PARAMS ((const char *));
@ -73,6 +85,8 @@ 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 *));
static const char * find_section_rename PARAMS ((bfd *, sec_ptr, flagword *));
static void add_section_rename PARAMS ((const char *, const char *, flagword));
#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
@ -134,7 +148,11 @@ struct section_list
};
static struct section_list *change_sections;
/* True if some sections are to be removed. */
static boolean sections_removed;
/* True if only some sections are to be copied. */
static boolean sections_copied;
/* Changes to the start address. */
@ -154,7 +172,6 @@ static boolean pad_to_set = false;
static bfd_vma pad_to;
/* List of sections to add. */
struct section_add
{
/* Next section to add. */
@ -171,23 +188,20 @@ struct section_add
asection *section;
};
/* List of sections to add to the output BFD. */
static struct section_add *add_sections;
/* Whether to convert debugging information. */
static boolean convert_debugging = false;
/* Whether to change the leading character in symbol names. */
static boolean change_leading_char = false;
/* Whether to remove the leading character from global symbol names. */
static boolean remove_leading_char = false;
/* List of symbols to strip, keep, localize, keep-global, weaken,
or redefine. */
static struct symlist *strip_specific_list = NULL;
static struct symlist *keep_specific_list = NULL;
static struct symlist *localize_specific_list = NULL;
@ -196,7 +210,6 @@ 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). */
static boolean weaken = false;
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
@ -226,6 +239,7 @@ static boolean weaken = false;
#define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1)
#define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1)
#define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)
#define OPTION_RENAME_SECTION (OPTION_WEAKEN_SYMBOLS + 1)
/* Options to handle if running as "strip". */
@ -292,6 +306,7 @@ static struct option copy_options[] =
{"keep-global-symbol", required_argument, 0, 'G'},
{"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
{"remove-section", required_argument, 0, 'R'},
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
{"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
{"set-start", required_argument, 0, OPTION_SET_START},
{"strip-all", no_argument, 0, 'S'},
@ -334,6 +349,7 @@ extern boolean S3Forced;
/* Defined in bfd/binary.c. Used to set architecture of input binary files. */
extern enum bfd_architecture bfd_external_binary_architecture;
static void
copy_usage (stream, exit_status)
FILE *stream;
@ -381,6 +397,7 @@ copy_usage (stream, exit_status)
--set-section-flags <name>=<flags>\n\
Set section <name>'s properties to <flags>\n\
--add-section <name>=<file> Add section <name> found in <file> to output\n\
--rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\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\
@ -666,10 +683,9 @@ is_specified_symbol (name, list)
struct symlist *tmp_list;
for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
{
if (strcmp (name, tmp_list->name) == 0)
return true;
}
return false;
}
@ -832,27 +848,22 @@ filter_symbols (abfd, obfd, osyms, isyms, symcount)
return dst_count;
}
/* Find the redefined name of symbol SOURCE. */
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;
return list->target;
return source;
}
/* Add a node to a symbol redefine list */
/* Add a node to a symbol redefine list. */
static void
redefine_list_append (source, target)
@ -866,19 +877,15 @@ redefine_list_append (source, target)
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));
@ -889,7 +896,6 @@ redefine_list_append (source, target)
*p = new_node;
}
/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
Adjust *SIZE. */
@ -902,6 +908,7 @@ filter_bytes (memhunk, size)
for (; from < end; from += interleave)
*to++ = *from;
if (*size % interleave > (bfd_size_type) copy_byte)
*size = (*size / interleave) + 1;
else
@ -951,7 +958,7 @@ copy_object (ibfd, obfd)
& bfd_applicable_file_flags (obfd))))
RETURN_NONFATAL (bfd_get_filename (ibfd));
/* Copy architecture of input file to output file */
/* Copy architecture of input file to output file. */
if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
bfd_get_mach (ibfd)))
non_fatal (_("Warning: Output file cannot represent architecture %s"),
@ -1107,8 +1114,8 @@ copy_object (ibfd, obfd)
}
}
/* Symbol filtering must happen after the output sections have
been created, but before their contents are set. */
/* Symbol filtering must happen after the output sections
have been created, but before their contents are set. */
dhandle = NULL;
symsize = bfd_get_symtab_upper_bound (ibfd);
if (symsize < 0)
@ -1189,7 +1196,6 @@ copy_object (ibfd, obfd)
int c, i;
/* Fill in the gaps. */
if (max_gap > 8192)
max_gap = 8192;
buf = (bfd_byte *) xmalloc (max_gap);
@ -1205,6 +1211,7 @@ copy_object (ibfd, obfd)
left = gaps[i];
off = bfd_section_size (obfd, osections[i]) - left;
while (left > 0)
{
bfd_size_type now;
@ -1273,6 +1280,7 @@ copy_archive (ibfd, obfd, output_target)
list = NULL;
this_element = bfd_openr_next_archived_file (ibfd, NULL);
while (!status && this_element != (bfd *) NULL)
{
/* Create an output file for this member. */
@ -1286,6 +1294,7 @@ copy_archive (ibfd, obfd, output_target)
if (preserve_dates)
{
stat_status = bfd_stat_arch_elt (this_element, &buf);
if (stat_status != 0)
non_fatal (_("internal stat error on %s"),
bfd_get_filename (this_element));
@ -1360,7 +1369,6 @@ copy_file (input_filename, output_filename, input_target, output_target)
/* To allow us to do "strip *" without dying on the first
non-object file, failures are nonfatal. */
ibfd = bfd_openr (input_filename, input_target);
if (ibfd == NULL)
RETURN_NONFATAL (input_filename);
@ -1415,8 +1423,68 @@ copy_file (input_filename, output_filename, input_target, output_target)
}
}
/* Create a section in OBFD with the same name and attributes
as ISECTION in IBFD. */
/* Add a name to the section renaming list. */
static void
add_section_rename (old_name, new_name, flags)
const char * old_name;
const char * new_name;
flagword flags;
{
section_rename * rename;
/* Check for conflicts first. */
for (rename = section_rename_list; rename != NULL; rename = rename->next)
if (strcmp (rename->old_name, old_name) == 0)
{
/* Silently ignore duplicate definitions. */
if (strcmp (rename->new_name, new_name) == 0
&& rename->flags == flags)
return;
fatal (_("Multiple renames of section %s"), old_name);
}
rename = (section_rename *) xmalloc (sizeof (* rename));
rename->old_name = old_name;
rename->new_name = new_name;
rename->flags = flags;
rename->next = section_rename_list;
section_rename_list = rename;
}
/* Check the section rename list for a new name of the input section
ISECTION. Return the new name if one is found.
Also set RETURNED_FLAGS to the flags to be used for this section. */
static const char *
find_section_rename (ibfd, isection, returned_flags)
bfd * ibfd ATTRIBUTE_UNUSED;
sec_ptr isection;
flagword * returned_flags;
{
const char * old_name = bfd_section_name (ibfd, isection);
section_rename * rename;
/* Default to using the flags of the input section. */
* returned_flags = bfd_get_section_flags (ibfd, isection);
for (rename = section_rename_list; rename != NULL; rename = rename->next)
if (strcmp (rename->old_name, old_name) == 0)
{
if (rename->flags != (flagword) -1)
* returned_flags = rename->flags;
return rename->new_name;
}
return old_name;
}
/* Create a section in OBFD with the same
name and attributes as ISECTION in IBFD. */
static void
setup_section (ibfd, isection, obfdarg)
@ -1432,6 +1500,7 @@ setup_section (ibfd, isection, obfdarg)
bfd_vma lma;
flagword flags;
const char *err;
const char * name;
if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
&& (strip_symbols == STRIP_DEBUG
@ -1450,7 +1519,10 @@ setup_section (ibfd, isection, obfdarg)
if (sections_copied && (p == NULL || ! p->copy))
return;
osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
/* Get the, possibly new, name of the output section. */
name = find_section_rename (ibfd, isection, & flags);
osection = bfd_make_section_anyway (obfd, name);
if (osection == NULL)
{
@ -1507,7 +1579,6 @@ setup_section (ibfd, isection, obfdarg)
goto loser;
}
flags = bfd_get_section_flags (ibfd, isection);
if (p != NULL && p->set_flags)
flags = p->flags | (flags & SEC_HAS_CONTENTS);
if (!bfd_set_section_flags (obfd, osection, flags))
@ -1530,7 +1601,7 @@ setup_section (ibfd, isection, obfdarg)
goto loser;
}
/* All went well */
/* All went well. */
return;
loser:
@ -1559,8 +1630,8 @@ copy_section (ibfd, isection, obfdarg)
bfd_size_type size;
long relsize;
/* If we have already failed earlier on, do not keep on generating
complaints now. */
/* If we have already failed earlier on,
do not keep on generating complaints now. */
if (status != 0)
return;
@ -1901,7 +1972,8 @@ strip_main (argc, argv)
show_version = true;
break;
case 0:
break; /* we've been given a long option */
/* We've been given a long option. */
break;
case 'h':
strip_usage (stdout, 0);
default:
@ -2268,9 +2340,7 @@ copy_main (argc, argv)
s = strchr (optarg, '=');
if (s == NULL)
{
fatal (_("bad format for %s"), "--redefine-sym");
}
len = s - optarg;
source = (char *) xmalloc (len + 1);
@ -2311,6 +2381,54 @@ copy_main (argc, argv)
}
break;
case OPTION_RENAME_SECTION:
{
flagword flags;
const char * s;
char * old_name;
char * new_name;
unsigned int len;
s = strchr (optarg, '=');
if (s == NULL)
fatal (_("bad format for %s"), "--rename-section");
len = s - optarg;
if (len == 0)
fatal (_("no old name is %s"), "--rename-section");
old_name = (char *) xmalloc (len + 1);
strncpy (old_name, optarg, len);
old_name[len] = 0;
s = strchr (optarg + len, ',');
if (s)
{
unsigned int new_len;
flags = parse_flags (s + 1);
new_len = s - (optarg + len);
if (new_len == 0)
fatal (_("no new name in %s"), "--rename-section");
new_name = (char *) xmalloc (new_len + 1);
strncpy (new_name, optarg + len, new_len);
new_name [new_len] = 0;
}
else
{
s = optarg + len;
len = strlen (s);
if (len == 0)
fatal (_("no new name in %s"), "--rename-section");
new_name = (char *) xmalloc (len + 1);
strcpy (new_name, s);
flags = -1;
}
add_section_rename (old_name, new_name, flags);
}
break;
case OPTION_SET_START:
set_start = parse_vma (optarg, "--set-start");
set_start_set = true;
@ -2419,6 +2537,7 @@ copy_main (argc, argv)
else
{
copy_file (input_filename, output_filename, input_target, output_target);
if (status == 0 && preserve_dates)
set_times (output_filename, &statbuf);
}