* objcopy.c (reverse_bytes): New variable.

(command_line_switch, copy_main):  Add OPTION_REVERSE_ENDIAN.
  (copy_options, copy_usage):  Add "reverse-bytes" entry.
  (copy_section):  Reverse bytes within output sections.
* doc/binutils.texi:  Document new objcopy option.
* testsuite/binutils-all/objcopy.exp: Add test for --reverse-bytes.
This commit is contained in:
Nick Clifton
2007-04-23 10:59:07 +00:00
parent 9a2e615a9f
commit 9e48b4c6ec
5 changed files with 125 additions and 1 deletions

View File

@@ -218,6 +218,11 @@ static char *prefix_alloc_sections_string = 0;
/* True if --extract-symbol was passed on the command line. */
static bfd_boolean extract_symbol = FALSE;
/* If `reverse_bytes' is nonzero, then reverse the order of every chunk
of <reverse_bytes> bytes within each output section. */
static int reverse_bytes = 0;
/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
enum command_line_switch
{
@@ -265,7 +270,8 @@ enum command_line_switch
OPTION_WRITABLE_TEXT,
OPTION_PURE,
OPTION_IMPURE,
OPTION_EXTRACT_SYMBOL
OPTION_EXTRACT_SYMBOL,
OPTION_REVERSE_BYTES
};
/* Options to handle if running as "strip". */
@@ -358,6 +364,7 @@ static struct option copy_options[] =
{"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
{"remove-section", required_argument, 0, 'R'},
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
{"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
{"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},
@@ -471,6 +478,7 @@ copy_usage (FILE *stream, int exit_status)
--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\
--reverse-bytes=<num> Reverse <num> bytes at a time, in output sections with content\n\
--redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
--redefine-syms <file> --redefine-sym for all symbol pairs \n\
listed in <file>\n\
@@ -2383,6 +2391,32 @@ copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
RETURN_NONFATAL (bfd_get_filename (ibfd));
if (reverse_bytes)
{
/* We don't handle leftover bytes (too many possible behaviors,
and we don't know what the user wants). The section length
must be a multiple of the number of bytes to swap. */
if ((size % reverse_bytes) == 0)
{
unsigned long i, j;
bfd_byte b;
for (i = 0; i < size; i += reverse_bytes)
for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
{
bfd_byte *m = (bfd_byte *) memhunk;
b = m[i + j];
m[i + j] = m[(i + reverse_bytes) - (j + 1)];
m[(i + reverse_bytes) - (j + 1)] = b;
}
}
else
/* User must pad the section up in order to do this. */
fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
bfd_section_name (ibfd, isection), reverse_bytes);
}
if (copy_byte >= 0)
{
/* Keep only every `copy_byte'th byte in MEMHUNK. */
@@ -3256,6 +3290,20 @@ copy_main (int argc, char *argv[])
extract_symbol = TRUE;
break;
case OPTION_REVERSE_BYTES:
{
int prev = reverse_bytes;
reverse_bytes = atoi (optarg);
if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
fatal (_("number of bytes to reverse must be positive and even"));
if (prev && prev != reverse_bytes)
non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
prev);
break;
}
case 0:
/* We've been given a long option. */
break;