diff --git a/binutils/ChangeLog b/binutils/ChangeLog index b62e9e003be..dbbe42ea903 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,15 @@ +2010-09-10 Ben Gardiner + + * 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 * dwarf.c (decode_location_expression): Fix data adjustment diff --git a/binutils/NEWS b/binutils/NEWS index 720df352158..8e3c4bbe5bd 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 0f0d8ee4b80..82c3a675fc0 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. +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{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}. +@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 87a23efb3ee..84b9febbf3b 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 Only copy one out of every bytes\n\ + -i --interleave [] Only copy N out of every bytes\n\ + --interleave-width Set N for --interleave\n\ -b --byte Select byte in every interleaved block\n\ --gap-fill Fill gaps between sections with \n\ --pad-to Pad the last section up to address \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 9e5e22da741..93c493762f9 100644 --- a/binutils/testsuite/ChangeLog +++ b/binutils/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-10 Ben Gardiner + + * binutils-all/objcopy.exp: Add test of new --interleave-width + option. + 2010-09-03 Jan Kratochvil * 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 94a31aa3571..6bfd164b65e 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