* 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.
 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{--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}]
         [@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}).
 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
 
 
 @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.
 
 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
 @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;
 
 /* 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
   {
 /* 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_WRITABLE_TEXT,
     OPTION_PURE,
     OPTION_IMPURE,
-    OPTION_EXTRACT_SYMBOL
+    OPTION_EXTRACT_SYMBOL,
+    OPTION_REVERSE_BYTES
   };
 
 /* Options to handle if running as "strip".  */
   };
 
 /* 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},
   {"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},
   {"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\
      --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\
      --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 (!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.  */
       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;
 
          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;
        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.
 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
 
 
 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
 # Test generating S records.
 
 # We make the srec filename 8.3 compatible. Note that the header string
This page took 0.035134 seconds and 4 git commands to generate.