Implement new switch --rename-section
This commit is contained in:
parent
f18ee7ef71
commit
594ef5dbd2
4 changed files with 207 additions and 51 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
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;
|
||||
if (strcmp (source, list->source) == 0)
|
||||
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,18 +877,14 @@ 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
@ -1229,7 +1236,7 @@ copy_object (ibfd, obfd)
|
|||
from the input BFD to the output BFD. This is done last to
|
||||
permit the routine to look at the filtered symbol table, which is
|
||||
important for the ECOFF code at least. */
|
||||
if (!bfd_copy_private_bfd_data (ibfd, obfd))
|
||||
if (! bfd_copy_private_bfd_data (ibfd, obfd))
|
||||
{
|
||||
non_fatal (_("%s: error copying private BFD data: %s"),
|
||||
bfd_get_filename (obfd),
|
||||
|
@ -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,7 +1500,8 @@ 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
|
||||
|| strip_symbols == STRIP_UNNEEDED
|
||||
|
@ -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");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue