* objcopy.c (reverse_bytes): New variable.
authorNick Clifton <nickc@redhat.com>
Mon, 23 Apr 2007 10:59:07 +0000 (10:59 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 23 Apr 2007 10:59:07 +0000 (10:59 +0000)
  (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.

binutils/ChangeLog
binutils/doc/binutils.texi
binutils/objcopy.c
binutils/testsuite/ChangeLog
binutils/testsuite/binutils-all/objcopy.exp

index d18d20d4d41056ca7a8608e3dcf3124bc17bda30..bd622fb565a3cf9c9ca355aa5d29416f6bdaecb6 100644 (file)
@@ -1,3 +1,13 @@
+2007-04-20  Nathan Froyd  <froydnj@codesourcery.com>
+           Phil Edwards  <phil@codesourcery.com>
+           Thomas de Lellis <tdel@windriver.com>
+
+       * 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.
+
 2007-04-20  Nick Clifton  <nickc@redhat.com>
 
        * rclex.l: Allow underscores at the start of identifiers.
index 04fdcc674c89056e7842063644348ac8a9f20457..ec18bc8f8683472c5e091048fa54371da890b378 100644 (file)
@@ -987,6 +987,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
         [@option{--add-section} @var{sectionname}=@var{filename}]
         [@option{--rename-section} @var{oldname}=@var{newname}[,@var{flags}]]
         [@option{--change-leading-char}] [@option{--remove-leading-char}]
+        [@option{--reverse-bytes=}@var{num}]
         [@option{--srec-len=}@var{ival}] [@option{--srec-forceS3}]
         [@option{--redefine-sym} @var{old}=@var{new}]
         [@option{--redefine-syms=}@var{filename}]
@@ -1052,6 +1053,7 @@ Note---@command{objcopy} is not able to change the endianness of its input
 files.  If the input format has an endianness (some formats do not),
 @command{objcopy} can only copy the inputs into file formats that have the
 same endianness or which have no endianness (e.g., @samp{srec}).
+(However, see the @option{--reverse-bytes} option.)
 
 @c man end
 
@@ -1342,6 +1344,30 @@ different conventions for symbol names.  This is different from
 when appropriate, regardless of the object file format of the output
 file.
 
+@item --reverse-bytes=@var{num}
+Reverse the bytes in a section with output contents.  A section length must
+be evenly divisible by the value given in order for the swap to be able to
+take place. Reversing takes place before the interleaving is performed.
+
+This option is used typically in generating ROM images for problematic
+target systems.  For example, on some target boards, the 32-bit words
+fetched from 8-bit ROMs are re-assembled in little-endian byte order
+regardless of the CPU byte order.  Depending on the programming model, the
+endianness of the ROM may need to be modified.
+
+Consider a simple file with a section containing the following eight
+bytes:  @code{12345678}.
+
+Using @samp{--reverse-bytes=2} for the above example, the bytes in the
+output file would be ordered @code{21436587}.
+
+Using @samp{--reverse-bytes=4} for the above example, the bytes in the
+output file would be ordered @code{43218765}.
+
+By using @samp{--reverse-bytes=2} for the above example, followed by
+@samp{--reverse-bytes=4} on the output file, the bytes in the second
+output file would be ordered @code{34127856}.
+
 @item --srec-len=@var{ival}
 Meaningful only for srec output.  Set the maximum length of the Srecords
 being produced to @var{ival}.  This length covers both address, data and
index d02b3e0e0b46c9eca35e65a2282c321cb992c287..92ccbbe2e623b2b4240b2c84ea2f0dde616761b7 100644 (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;
index 3dfd768c5aa4713d6c4dfa0f4525dbaa1112c1e0..7fb53d75254507ea2e74d7f0ae93a4141621a6ef 100644 (file)
@@ -1,3 +1,9 @@
+2007-04-20  Nathan Froyd  <froydnj@codesourcery.com>
+           Phil Edwards  <phil@codesourcery.com>
+           Thomas de Lellis <tdel@windriver.com>
+
+       * binutils-all/objcopy.exp: Add test for --reverse-bytes.
+
 2007-04-21  Richard Earnshaw  <rearnsha@arm.com>
 
        * binutils-all/readelf.exp (regexp_diff): Delete.
index cc56b4f14596246fd5bde35d916bb09ce70bb23c..510f6cedbe57d2bc3fba54ee70ed1a4de9c8203f 100644 (file)
@@ -113,6 +113,40 @@ proc objcopy_test {testname srcfile} {
 
 objcopy_test "simple copy" bintest.s
 
+# Test reversing bytes in a section.
+
+set reversed ${tempfile}-reversed
+set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -j .data --reverse-bytes=4 $tempfile $reversed"]
+
+if ![string match "" $got] then {
+    fail "objcopy --reverse-bytes"
+} else {
+    if [is_remote host] {
+        remote_upload host ${reversed} tmpdir/copy-reversed.o
+        set reversed tmpdir/copy-reversed.o
+    }
+
+    set origdata [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s -j .data $tempfile"]
+    set revdata [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s -j .data $reversed"]
+
+    set want "^ \[0-9\]+ (\[0-9\]+)"
+    set found_orig [regexp -lineanchor $want $origdata -> origdata]
+    set found_rev [regexp -lineanchor $want $revdata -> revdata]
+
+    if {$found_orig == 0 || $found_rev == 0} then {
+        fail "objcopy --reverse-bytes"
+    } else {
+        scan $origdata "%2x%2x%2x%2x" b1 b2 b3 b4
+        scan $revdata "%2x%2x%2x%2x" c4 c3 c2 c1
+
+        if {$b1 == $c1 && $b2 == $c2 && $b3 == $c3 && $b4 == $c4} then {
+            pass "objcopy --reverse-bytes"
+        } else {
+            fail "objcopy --reverse-bytes"
+        }
+    }
+}
+
 # Test generating S records.
 
 # We make the srec filename 8.3 compatible. Note that the header string