* objcopy.c: Add --interleave-width option to allow interleaving
authorNick Clifton <nickc@redhat.com>
Fri, 10 Sep 2010 12:11:28 +0000 (12:11 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 10 Sep 2010 12:11:28 +0000 (12:11 +0000)
        of more than one byte at a time.
        (copy_width): New variable.
        (copy_options): Add --interleave-width.
        (copy_section): When interleaving copy in units of copy_width
        bytes.
        (copy_main): Parse the new option.
        * doc/binutils: Document the new option.
        * NEWS: Mention the new feature.

        * binutils-all/objcopy.exp: Add test of new --interleave-width
        option.

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

index b62e9e0..dbbe42e 100644 (file)
@@ -1,3 +1,15 @@
+2010-09-10  Ben Gardiner  <bengardiner@nanometrics.ca>
+
+       * objcopy.c: Add --interleave-width option to allow interleaving
+       of more than one byte at a time.
+       (copy_width): New variable.
+       (copy_options): Add --interleave-width.
+       (copy_section): When interleaving copy in units of copy_width
+       bytes.
+       (copy_main): Parse the new option.
+       * doc/binutils: Document the new option.
+       * NEWS: Mention the new feature.
+
 2010-09-09  Jakub Jelinek  <jakub@redhat.com>
 
        * dwarf.c (decode_location_expression): Fix data adjustment
index 720df35..8e3c4bb 100644 (file)
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add --interleave-width option to objcopy to allowing copying a range of
+  bytes from the input to the output with the --interleave option.
+
 * Add support for the TMS320C6000 (TI C6X) processor family.
 
 * Readelf can now display ARM unwind tables (.ARM.exidx / .ARM.extab) using
index 0f0d8ee..82c3a67 100644 (file)
@@ -1017,7 +1017,8 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
         [@option{-x}|@option{--discard-all}]
         [@option{-X}|@option{--discard-locals}]
         [@option{-b} @var{byte}|@option{--byte=}@var{byte}]
-        [@option{-i} @var{interleave}|@option{--interleave=}@var{interleave}]
+        [@option{-i} [@var{breadth}]|@option{--interleave}[=@var{breadth}]]
+        [@option{--interleave-width=}@var{width}]
         [@option{-j} @var{sectionname}|@option{--only-section=}@var{sectionname}]
         [@option{-R} @var{sectionname}|@option{--remove-section=}@var{sectionname}]
         [@option{-p}|@option{--preserve-dates}]
@@ -1239,19 +1240,42 @@ Do not copy compiler-generated local symbols.
 
 @item -b @var{byte}
 @itemx --byte=@var{byte}
-Keep only every @var{byte}th byte of the input file (header data is not
-affected).  @var{byte} can be in the range from 0 to @var{interleave}-1,
-where @var{interleave} is given by the @option{-i} or @option{--interleave}
-option, or the default of 4.  This option is useful for creating files
-to program @sc{rom}.  It is typically used with an @code{srec} output
-target.
-
-@item -i @var{interleave}
-@itemx --interleave=@var{interleave}
-Only copy one out of every @var{interleave} bytes.  Select which byte to
-copy with the @option{-b} or @option{--byte} option.  The default is 4.
-@command{objcopy} ignores this option if you do not specify either @option{-b} or
-@option{--byte}.
+If interleaving has been enabled via the @option{--interleave} option
+then start the range of bytes to keep at the @var{byte}th byte.
+@var{byte} can be in the range from 0 to @var{breadth}-1, where
+@var{breadth} is the value given by the @option{--interleave} option.
+
+@item -i [@var{breadth}]
+@itemx --interleave[=@var{breadth}]
+Only copy a range out of every @var{breadth} bytes.  (Header data is
+not affected).  Select which byte in the range begins the copy with
+the @option{--byte} option.  Select the width of the range with the
+@option{--interleave-width} option.
+
+This option is useful for creating files to program @sc{rom}.  It is
+typically used with an @code{srec} output target.  Note that
+@command{objcopy} will complain if you do not specify the
+@option{--byte} option as well.
+
+The default interleave breadth is 4, so with @option{--byte} set to 0,
+@command{objcopy} would copy the first byte out of every four bytes
+from the input to the output.
+
+@item --interleave-width=@var{width}
+When used with the @option{--interleave} option, copy @var{width}
+bytes at a time.  The start of the range of bytes to be copied is set
+by the @option{--byte} option, and the extent of the range is set with
+the @option{--interleave} option.
+
+The default value for this option is 1.  The value of @var{width} plus
+the @var{byte} value set by the @option{--byte} option must not exceed
+the interleave breadth set by the @option{--interleave} option.
+
+This option can be used to create images for two 16-bit flashes interleaved
+in a 32-bit bus by passing @option{-b 0 -i 4 --interleave-width=2}
+and @option{-b 2 -i 4 --interleave-width=2} to two @command{objcopy}
+commands.  If the input was '12345678' then the outputs would be
+'1256' and '3478' respectively.
 
 @item -p
 @itemx --preserve-dates
index 87a23ef..84b9feb 100644 (file)
@@ -80,9 +80,10 @@ static section_rename *section_rename_list;
 static asymbol **isympp = NULL;        /* Input symbols.  */
 static asymbol **osympp = NULL;        /* Output symbols that survive stripping.  */
 
-/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes.  */
+/* If `copy_byte' >= 0, copy 'copy_width' byte(s) of every `interleave' bytes.  */
 static int copy_byte = -1;
-static int interleave = 4;
+static int interleave = 0; /* Initialised to 4 in copy_main().  */
+static int copy_width = 1;
 
 static bfd_boolean verbose;            /* Print file and target names.  */
 static bfd_boolean preserve_dates;     /* Preserve input file timestamp.  */
@@ -302,6 +303,7 @@ enum command_line_switch
     OPTION_IMAGE_BASE,
     OPTION_SECTION_ALIGNMENT,
     OPTION_STACK,
+    OPTION_INTERLEAVE_WIDTH,
     OPTION_SUBSYSTEM
   };
 
@@ -368,7 +370,8 @@ static struct option copy_options[] =
   {"info", no_argument, 0, OPTION_FORMATS_INFO},
   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
   {"input-target", required_argument, 0, 'I'},
-  {"interleave", required_argument, 0, 'i'},
+  {"interleave", optional_argument, 0, 'i'},
+  {"interleave-width", required_argument, 0, OPTION_INTERLEAVE_WIDTH},
   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
   {"keep-global-symbol", required_argument, 0, 'G'},
   {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
@@ -488,7 +491,8 @@ copy_usage (FILE *stream, int exit_status)
   -w --wildcard                    Permit wildcard in symbol comparison\n\
   -x --discard-all                 Remove all non-global symbols\n\
   -X --discard-locals              Remove any compiler-generated symbols\n\
-  -i --interleave <number>         Only copy one out of every <number> bytes\n\
+  -i --interleave [<number>]       Only copy N out of every <number> bytes\n\
+     --interleave-width <number>   Set N for --interleave\n\
   -b --byte <num>                  Select byte <num> in every interleaved block\n\
      --gap-fill <val>              Fill gaps between sections with <val>\n\
      --pad-to <addr>               Pad the last section up to address <addr>\n\
@@ -2443,7 +2447,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
 
   size = bfd_section_size (ibfd, isection);
   if (copy_byte >= 0)
-    size = (size + interleave - 1) / interleave;
+    size = (size + interleave - 1) / interleave * copy_width;
   else if (extract_symbol)
     size = 0;
   if (! bfd_set_section_size (obfd, osection, size))
@@ -2674,11 +2678,13 @@ copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
          char *from = (char *) memhunk + copy_byte;
          char *to = (char *) memhunk;
          char *end = (char *) memhunk + size;
+         int i;
 
          for (; from < end; from += interleave)
-           *to++ = *from;
+           for (i = 0; i < copy_width; i++)
+             *to++ = from[i];
 
-         size = (size + interleave - 1 - copy_byte) / interleave;
+         size = (size + interleave - 1 - copy_byte) / interleave * copy_width;
          osection->lma /= interleave;
        }
 
@@ -3183,9 +3189,20 @@ copy_main (int argc, char *argv[])
          break;
 
        case 'i':
-         interleave = atoi (optarg);
-         if (interleave < 1)
-           fatal (_("interleave must be positive"));
+         if (optarg)
+           {
+             interleave = atoi (optarg);
+             if (interleave < 1)
+               fatal (_("interleave must be positive"));
+           }
+         else
+           interleave = 4;
+         break;
+
+       case OPTION_INTERLEAVE_WIDTH:
+         copy_width = atoi (optarg);
+         if (copy_width < 1)
+           fatal(_("interleave width must be positive"));
          break;
 
        case 'I':
@@ -3768,9 +3785,15 @@ copy_main (int argc, char *argv[])
   if (show_version)
     print_version ("objcopy");
 
+  if (interleave && copy_byte == -1)
+    fatal (_("interleave start byte must be set with --byte"));
+
   if (copy_byte >= interleave)
     fatal (_("byte number must be less than interleave"));
 
+  if (copy_width > interleave - copy_byte)
+    fatal (_("interleave width must be less than or equal to interleave - byte`"));
+
   if (optind == argc || optind + 2 < argc)
     copy_usage (stderr, 1);
 
index 9e5e22d..93c4937 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-10  Ben Gardiner  <bengardiner@nanometrics.ca>
+
+       * binutils-all/objcopy.exp: Add test of new --interleave-width
+       option.
+
 2010-09-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * binutils-all/objdump.W: Update DW_OP_reg5 expected output.
index 94a31aa..6bfd164 100644 (file)
@@ -1,5 +1,5 @@
 #   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-#   2004, 2006, 2007, 2009
+#   2004, 2006, 2007, 2009, 2010
 #   Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
@@ -144,6 +144,43 @@ if ![string match "" $got] then {
     }
 }
 
+# Test interleaved copy of multiple byte width
+
+set sequence_file sequence_file
+set file [open ${sequence_file} w]
+puts ${file} "12345678"
+close ${file}
+
+if [is_remote host] {
+    remote_upload host ${sequence_file} tmpdir/sequence_file
+    set sequence_file tmpdir/sequence_file
+}
+
+set got [binutils_run $OBJCOPY "-I binary -i 4 -b 0 --interleave-width 2 ${sequence_file} ${copyfile}"]
+
+if ![string match "" $got] then {
+    fail "objcopy -i --interleave-width"
+} else {
+    if [is_remote host] {
+       remote_upload host ${copyfile} tmpdir/interleave_output
+       set interleave_output tmpdir/interleave_output
+    } else {
+       set interleave_output ${copyfile}
+    }
+
+    set file [open ${interleave_output} r]
+    gets $file line
+    send_log "$line\n"
+    verbose $line
+
+    if ![string match "1256" $line] then {
+       fail "objcopy -i --interleave-width"
+    }
+    pass "objcopy -i --interleave-width"
+
+    close $file
+}
+
 # Test generating S records.
 
 # We make the srec filename 8.3 compatible. Note that the header string