aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog12
-rw-r--r--binutils/NEWS3
-rw-r--r--binutils/doc/binutils.texi52
-rw-r--r--binutils/objcopy.c43
-rw-r--r--binutils/testsuite/ChangeLog5
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp39
6 files changed, 129 insertions, 25 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index b62e9e0..dbbe42e 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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
diff --git a/binutils/NEWS b/binutils/NEWS
index 720df35..8e3c4bb 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -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
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 0f0d8ee..82c3a67 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -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
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 87a23ef..84b9feb 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -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);
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 9e5e22d..93c4937 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -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.
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 94a31aa..6bfd164 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -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