This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] objcopy: add an interleave width parameter to objcopy
- From: Ben Gardiner <bengardiner at nanometrics dot ca>
- To: binutils at sourceware dot org
- Cc: "William A. Gatliff" <bgat at billgatliff dot com>, Wayne Young <wayne dot young at honeywell dot com>, Ben Gardiner <bengardiner at nanometrics dot ca>
- Date: Sun, 15 Aug 2010 21:51:14 -0400
- Subject: [PATCH] objcopy: add an interleave width parameter to objcopy
Add a width parameter to objcopy that can be used in concert with -b and
-i to produced binary images for 16-bit interleaved flashes.
I was looking to produce a pair of images for 16-bit flashes interleaved
on a 32-bit with objcopy and found that it was not possible but that
there has been some previous interest in this also [1][2].
With this patchset it should now be possible to produce a pair of
interleaved 16-bit flash images with the objcopy options: '-b 0 -i 4
--width 2' and '-b 2 -i 4 --width 2' to two objcopy commands. If the
input was '12345678' then the outputs would be '1256' and '3478'
respectively.
[1] http://permalink.gmane.org/gmane.comp.gcc.cross-compiling/335
[2] http://permalink.gmane.org/gmane.comp.gnu.binutils/7728
Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
CC: William A. Gatliff <bgat@billgatliff.com>
CC: Young, Wayne <wayne.young@honeywell.com>
---
binutils/doc/binutils.texi | 17 +++++++++++-
binutils/objcopy.c | 26 +++++++++++++++---
binutils/testsuite/binutils-all/objcopy.exp | 36 +++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 9f374f8..c694385 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1018,6 +1018,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
[@option{-X}|@option{--discard-locals}]
[@option{-b} @var{byte}|@option{--byte=}@var{byte}]
[@option{-i} @var{interleave}|@option{--interleave=}@var{interleave}]
+ [@option{--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}]
@@ -1248,11 +1249,23 @@ 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.
+Only copy a range out of every @var{interleave} bytes. Select which byte to
+copy with the @option{-b} or @option{--byte} option. Select the size of the range
+with the @option{--width} option. The default is 4.
@command{objcopy} ignores this option if you do not specify either @option{-b} or
@option{--byte}.
+@item --width @var{width}
+Copy @var{width} bytes at a time. Select the start of the range to copy with
+the @option{-b} or @option{--byte} option. The default it 1. The @var{width} plus
+@var{byte} cannot exceed the interleave.
+@command{objcopy} ignores this option if you do not specify either @option{-b} or
+@option{--byte}.
+This option can be used to create images for two 16-bit flashes interleaved
+in a 32-bit bus by passing @command{-b 0 -i 4 --width 2} and @command{-b 2 -i 4
+--width 2} to two objcopy commands. If the input was '12345678' then the
+outputs would be '1256' and '3478' respectively.
+
@item -p
@itemx --preserve-dates
Set the access and modification dates of the output file to be the same
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 87a23ef..f69c9e9 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -83,6 +83,7 @@ static asymbol **osympp = NULL; /* Output symbols that survive stripping. */
/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
static int copy_byte = -1;
static int interleave = 4;
+static int copy_width = 1;
static bfd_boolean verbose; /* Print file and target names. */
static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
@@ -302,7 +303,8 @@ enum command_line_switch
OPTION_IMAGE_BASE,
OPTION_SECTION_ALIGNMENT,
OPTION_STACK,
- OPTION_SUBSYSTEM
+ OPTION_SUBSYSTEM,
+ OPTION_WIDTH
};
/* Options to handle if running as "strip". */
@@ -414,6 +416,7 @@ static struct option copy_options[] =
{"weaken", no_argument, 0, OPTION_WEAKEN},
{"weaken-symbol", required_argument, 0, 'W'},
{"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
+ {"width", required_argument, 0, OPTION_WIDTH},
{"wildcard", no_argument, 0, 'w'},
{"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
{"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
@@ -490,6 +493,7 @@ copy_usage (FILE *stream, int exit_status)
-X --discard-locals Remove any compiler-generated symbols\n\
-i --interleave <number> Only copy one out of every <number> bytes\n\
-b --byte <num> Select byte <num> in every interleaved block\n\
+ --width <num> Select <num> bytes at a time for copy\n\
--gap-fill <val> Fill gaps between sections with <val>\n\
--pad-to <addr> Pad the last section up to address <addr>\n\
--set-start <addr> Set the start address to <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,14 @@ 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 (; from < end; from += interleave) {
+ 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;
}
@@ -3188,6 +3195,12 @@ copy_main (int argc, char *argv[])
fatal (_("interleave must be positive"));
break;
+ case OPTION_WIDTH:
+ copy_width = atoi (optarg);
+ if (copy_width < 1)
+ fatal(_("width must be positive"));
+ break;
+
case 'I':
case 's': /* "source" - 'I' is preferred */
input_target = optarg;
@@ -3771,6 +3784,9 @@ copy_main (int argc, char *argv[])
if (copy_byte >= interleave)
fatal (_("byte number must be less than interleave"));
+ if (copy_width > interleave - copy_byte)
+ fatal (_("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/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 94a31aa..0b54209 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -144,6 +144,42 @@ 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 --width 2 ${sequence_file} ${copyfile}"]
+
+if ![string match "" $got] then {
+ fail "objcopy -i --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 --width"
+ }
+ pass "objcopy -i --width"
+
+ close $file
+}
+
# Test generating S records.
# We make the srec filename 8.3 compatible. Note that the header string
--
1.7.0.4