From 37d0d09177dc02e0002ab8b90d9b7bc402af9240 Mon Sep 17 00:00:00 2001 From: Jamey Hicks Date: Tue, 14 May 2019 10:40:04 +0100 Subject: [PATCH] Add new option to objcopy: --verilog-data-width. Use this option to set the size of byte bundles generated in verilog format files. PR 19921 binutils* objcopy.c: Add new option --verilog-data-width. Use it to set the value of VerilogDataWidth. * doc/binutils.texi: Document the new option. * testsuite/binutils-all/objcopy.exp: Run tests of new option. * testsuite/binutils-all/verilog-1.hex: New file. * testsuite/binutils-all/verilog-2.hex: New file. * testsuite/binutils-all/verilog-4.hex: New file. * testsuite/binutils-all/verilog-8.hex: New file. * NEWS: Mention the new feature. bfd * verilog.c: (VerilogDataWidth): New variable. (verilog_write_record): Emit bytes in VerilogDataWidth bundles. --- bfd/ChangeLog | 6 ++ bfd/verilog.c | 80 ++++++++++++++++--- binutils/ChangeLog | 13 +++ binutils/NEWS | 3 + binutils/doc/binutils.texi | 10 ++- binutils/objcopy.c | 14 ++++ binutils/testsuite/binutils-all/objcopy.exp | 44 ++++++++++ binutils/testsuite/binutils-all/verilog-1.hex | 5 ++ binutils/testsuite/binutils-all/verilog-2.hex | 5 ++ binutils/testsuite/binutils-all/verilog-4.hex | 6 ++ binutils/testsuite/binutils-all/verilog-8.hex | 5 ++ 11 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 binutils/testsuite/binutils-all/verilog-1.hex create mode 100644 binutils/testsuite/binutils-all/verilog-2.hex create mode 100644 binutils/testsuite/binutils-all/verilog-4.hex create mode 100644 binutils/testsuite/binutils-all/verilog-8.hex diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 61b70ec8048..60069c28c9c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2019-05-14 Jamey Hicks + + PR 19921 + * verilog.c: (VerilogDataWidth): New variable. + (verilog_write_record): Emit bytes in VerilogDataWidth bundles. + 2019-05-08 Nick Clifton PR 24523 diff --git a/bfd/verilog.c b/bfd/verilog.c index 680f4fab98f..252e240277a 100644 --- a/bfd/verilog.c +++ b/bfd/verilog.c @@ -58,12 +58,16 @@ #include "libiberty.h" #include "safe-ctype.h" +/* Modified by obcopy.c + Data width in bytes. */ +unsigned int VerilogDataWidth = 1; + /* Macros for converting between hex and binary. */ static const char digs[] = "0123456789ABCDEF"; -#define NIBBLE(x) hex_value(x) -#define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1])) +#define NIBBLE(x) hex_value (x) +#define HEX(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1])) #define TOHEX(d, x) \ d[1] = digs[(x) & 0xf]; \ d[0] = digs[((x) >> 4) & 0xf]; @@ -183,26 +187,82 @@ verilog_write_address (bfd *abfd, bfd_vma address) } /* Write a record of type, of the supplied number of bytes. The - supplied bytes and length don't have a checksum. That's worked out - here. */ + supplied bytes and length don't have a checksum. That's worked + out here. */ static bfd_boolean verilog_write_record (bfd *abfd, const bfd_byte *data, const bfd_byte *end) { - char buffer[50]; + char buffer[52]; const bfd_byte *src = data; char *dst = buffer; bfd_size_type wrlen; - /* Write the data. */ - for (src = data; src < end; src++) + /* Paranoia - check that we will not overflow "buffer". */ + if (((end - data) * 2) /* Number of hex characters we want to emit. */ + + ((end - data) / VerilogDataWidth) /* Number of spaces we want to emit. */ + + 2 /* The carriage return & line feed characters. */ + > (long) sizeof (buffer)) { - TOHEX (dst, *src); - dst += 2; - *dst++ = ' '; + /* FIXME: Should we generate an error message ? */ + return FALSE; + } + + /* Write the data. + FIXME: Under some circumstances we can emit a space at the end of + the line. This is not really necessary, but catching these cases + would make the code more complicated. */ + if (VerilogDataWidth == 1) + { + for (src = data; src < end;) + { + TOHEX (dst, *src); + dst += 2; + src ++; + if (src < end) + *dst++ = ' '; + } } + else if (bfd_little_endian (abfd)) + { + /* If the input byte stream contains: + 05 04 03 02 01 00 + and VerilogDataWidth is 4 then we want to emit: + 02030405 0001 */ + int i; + + for (src = data; src < (end - VerilogDataWidth); src += VerilogDataWidth) + { + for (i = VerilogDataWidth - 1; i >= 0; i--) + { + TOHEX (dst, src[i]); + dst += 2; + } + *dst++ = ' '; + } + + /* Emit any remaining bytes. Be careful not to read beyond "end". */ + while (end > src) + { + -- end; + TOHEX (dst, *end); + dst += 2; + } + } + else + { + for (src = data; src < end;) + { + TOHEX (dst, *src); + dst += 2; + ++ src; + if ((src - data) % VerilogDataWidth == 0) + *dst++ = ' '; + } + } + *dst++ = '\r'; *dst++ = '\n'; wrlen = dst - buffer; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 9f52572ad41..2783e58913c 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,16 @@ +2019-05-14 Jamey Hicks + + PR 19921 + * objcopy.c: Add new option --verilog-data-width. Use it to set + the value of VerilogDataWidth. + * doc/binutils.texi: Document the new option. + * testsuite/binutils-all/objcopy.exp: Run tests of new option. + * testsuite/binutils-all/verilog-1.hex: New file. + * testsuite/binutils-all/verilog-2.hex: New file. + * testsuite/binutils-all/verilog-4.hex: New file. + * testsuite/binutils-all/verilog-8.hex: New file. + * NEWS: Mention the new feature. + 2019-05-10 Alan Modra * testsuite/binutils-all/objdump.exp (test_objdump_disas_limited), diff --git a/binutils/NEWS b/binutils/NEWS index 7c9d7bef30b..d7e40de4a87 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Add --verilog-data-width option to objcopy for verilog targets to control + width of data elements in verilog hex format. + * The separate debug info file options of readelf (--debug-dump=links and --debug-dump=follow) and objdump (--dwarf=links and --dwarf=follow-links) will now display and/or follow multiple links if diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 502f68d5dd6..4a7f0f97d1f 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1215,6 +1215,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{--elf-stt-common=@var{val}}] [@option{--merge-notes}] [@option{--no-merge-notes}] + [@option{--verilog-data-width=@var{val}}] [@option{-v}|@option{--verbose}] [@option{-V}|@option{--version}] [@option{--help}] [@option{--info}] @@ -1858,7 +1859,7 @@ like this: @smallexample objcopy --add-gnu-debuglink=foo.debug @end smallexample - + At debug time the debugger will attempt to look for the separate debug info file in a set of known locations. The exact set of these locations varies depending upon the distribution being used, but it @@ -2048,6 +2049,11 @@ SHT_NOTE type sections by removing duplicate notes. @itemx --version Show the version number of @command{objcopy}. +@item --verilog-data-width=@var{bytes} +For Verilog output, this options controls the number of bytes +converted for each output data element. The input target controls the +endianness of the conversion. + @item -v @itemx --verbose Verbose output: list all object files modified. In the case of @@ -3060,7 +3066,7 @@ sequences that it can find. For backwards compatibility any file that occurs after a command-line option of just @option{-} will also be scanned in full, regardless of -the presence of any @option{-d} option. +the presence of any @option{-d} option. @command{strings} is mainly useful for determining the contents of non-text files. diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 673e1f640ae..28b9d3bf929 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -357,6 +357,7 @@ enum command_line_switch OPTION_STRIP_UNNEEDED_SYMBOLS, OPTION_SUBSYSTEM, OPTION_UPDATE_SECTION, + OPTION_VERILOG_DATA_WIDTH, OPTION_WEAKEN, OPTION_WEAKEN_SYMBOLS, OPTION_WRITABLE_TEXT @@ -493,6 +494,7 @@ static struct option copy_options[] = {"target", required_argument, 0, 'F'}, {"update-section", required_argument, 0, OPTION_UPDATE_SECTION}, {"verbose", no_argument, 0, 'v'}, + {"verilog-data-width", required_argument, 0, OPTION_VERILOG_DATA_WIDTH}, {"version", no_argument, 0, 'V'}, {"weaken", no_argument, 0, OPTION_WEAKEN}, {"weaken-symbol", required_argument, 0, 'W'}, @@ -519,6 +521,11 @@ extern unsigned int _bfd_srec_len; on by the --srec-forceS3 command line switch. */ extern bfd_boolean _bfd_srec_forceS3; +/* Width of data in bytes for verilog output. + This variable is declared in bfd/verilog.c and can be modified by + the --verilog-data-width parameter. */ +extern unsigned int VerilogDataWidth; + /* Forward declarations. */ static void setup_section (bfd *, asection *, void *); static void setup_bfd_headers (bfd *, bfd *); @@ -653,6 +660,7 @@ copy_usage (FILE *stream, int exit_status) --decompress-debug-sections Decompress DWARF debug sections using zlib\n\ --elf-stt-common=[yes|no] Generate ELF common symbols with STT_COMMON\n\ type\n\ + --verilog-data-width Specifies data width, in bytes, for verilog output\n\ -M --merge-notes Remove redundant entries in note sections\n\ --no-merge-notes Do not attempt to remove redundant notes (default)\n\ -v --verbose List all object files modified\n\ @@ -5478,6 +5486,12 @@ copy_main (int argc, char *argv[]) } break; + case OPTION_VERILOG_DATA_WIDTH: + VerilogDataWidth = parse_vma (optarg, "--verilog-data-width"); + if (VerilogDataWidth < 1) + fatal (_("verilog data width must be at least 1 byte")); + break; + case 0: /* We've been given a long option. */ break; diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index 921e6a23c4f..ba5ddc8651a 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -102,6 +102,50 @@ proc objcopy_test {testname srcfile} { objcopy_test "simple copy" bintest.s +# Test verilog data width +proc objcopy_test_verilog {testname} { + global OBJCOPY + global OBJCOPYFLAGS + global srcdir + global subdir + global copyfile + set binfile tmpdir/verilogtest.o + set verilog tmpdir/verilog + + set got [binutils_assemble $srcdir/$subdir/verilogtest.s $binfile] + if {![binutils_assemble $srcdir/$subdir/verilogtest.s $binfile]} then { + unresolved "objcopy ($testname)" + return + } + + set got [binutils_run $OBJCOPY "-O verilog $binfile $verilog"] + if ![string equal "" $got] then { + fail "objcopy ($testname)" + } + + set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 0 $binfile $verilog-0.hex"] + if ![regexp "verilog data width must be at least 1 byte" $got] then { + fail "objcopy ($testname 0) {$got}" + } else { + pass "objcopy ($testname 0)" + } + + foreach width {1 2 4 8} { + set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $binfile $verilog-$width.hex"] + if ![string equal "" $got] then { + fail "objcopy ($testname $width)" + } + send_log "regexp_diff $verilog-$width.hex $srcdir/$subdir/verilog-$width.hex\n" + if {! [regexp_diff "$verilog-$width.hex" "$srcdir/$subdir/verilog-$width.hex"]} { + pass "objcopy ($testname $width)" + } else { + fail "objcopy ($testname $width)" + } + } +} + +objcopy_test_verilog "verilog data width" + if { [file exists $tempfile] } { # Test reversing bytes in a section. diff --git a/binutils/testsuite/binutils-all/verilog-1.hex b/binutils/testsuite/binutils-all/verilog-1.hex new file mode 100644 index 00000000000..0a59a582612 --- /dev/null +++ b/binutils/testsuite/binutils-all/verilog-1.hex @@ -0,0 +1,5 @@ +@00000000 +0[134] 0[234] 0[123] 0[124] 00 00 00 00.* +@000000.. +0[02] 00 0[02] 0[02].* +#pass diff --git a/binutils/testsuite/binutils-all/verilog-2.hex b/binutils/testsuite/binutils-all/verilog-2.hex new file mode 100644 index 00000000000..f1e0d7aa2d7 --- /dev/null +++ b/binutils/testsuite/binutils-all/verilog-2.hex @@ -0,0 +1,5 @@ +@00000000 +0[1234]0[1234] 0[1234]0[1234] 0000 0000.* +@000000.. +0[02]0[02] 0[02]0[02].* +#pass diff --git a/binutils/testsuite/binutils-all/verilog-4.hex b/binutils/testsuite/binutils-all/verilog-4.hex new file mode 100644 index 00000000000..119f00975b1 --- /dev/null +++ b/binutils/testsuite/binutils-all/verilog-4.hex @@ -0,0 +1,6 @@ +@00000000 +0[134]0[234]0[123]0[124] 00000000.* +@000000.. +0[20]000[02]0[02].* +#pass + diff --git a/binutils/testsuite/binutils-all/verilog-8.hex b/binutils/testsuite/binutils-all/verilog-8.hex new file mode 100644 index 00000000000..567d33ed045 --- /dev/null +++ b/binutils/testsuite/binutils-all/verilog-8.hex @@ -0,0 +1,5 @@ +@00000000 +0[0134]0[0234]0[0123]0[0124]0[40]0[30]0[20]0[10].* +@000000.. +0[20]000[02]0[20].* +#pass -- 2.30.2