Add new option to objcopy: --verilog-data-width. Use this option to set the size...
authorJamey Hicks <jamey.hicks@gmail.com>
Tue, 14 May 2019 09:40:04 +0000 (10:40 +0100)
committerNick Clifton <nickc@redhat.com>
Tue, 14 May 2019 09:42:25 +0000 (10:42 +0100)
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
bfd/verilog.c
binutils/ChangeLog
binutils/NEWS
binutils/doc/binutils.texi
binutils/objcopy.c
binutils/testsuite/binutils-all/objcopy.exp
binutils/testsuite/binutils-all/verilog-1.hex [new file with mode: 0644]
binutils/testsuite/binutils-all/verilog-2.hex [new file with mode: 0644]
binutils/testsuite/binutils-all/verilog-4.hex [new file with mode: 0644]
binutils/testsuite/binutils-all/verilog-8.hex [new file with mode: 0644]

index 61b70ec804852bc6285db27bb9e730c90151466d..60069c28c9c3e93660ec2256d1aaa629ddfab36b 100644 (file)
@@ -1,3 +1,9 @@
+2019-05-14  Jamey Hicks  <jamey.hicks@gmail.com>
+
+       PR 19921
+       * verilog.c: (VerilogDataWidth): New variable.
+       (verilog_write_record): Emit bytes in VerilogDataWidth bundles.
+
 2019-05-08  Nick Clifton  <nickc@redhat.com>
 
        PR 24523
index 680f4fab98f1fa7836f17c9333fd2fbc35b12308..252e240277ab65d6d11398508d2e80ee09fca4d3 100644 (file)
 #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;
index 9f52572ad4169a5f38d4f2b7348a8fa3b72bf462..2783e58913c67ab75031ada3ac3b01fa100bee82 100644 (file)
@@ -1,3 +1,16 @@
+2019-05-14  Jamey Hicks  <jamey.hicks@gmail.com>
+
+       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  <amodra@gmail.com>
 
        * testsuite/binutils-all/objdump.exp (test_objdump_disas_limited),
index 7c9d7bef30b024bdb03bc0d86b1ffbc1506ffe66..d7e40de4a8730f67b9b0ecfaa6a3211ab79e1899 100644 (file)
@@ -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
index 502f68d5dd64f0a1024706a943bb2e7b7d1aa380..4a7f0f97d1f74b212cda429fda7412ae4d26a3eb 100644 (file)
@@ -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.
index 673e1f640ae9800748c46456d6437bbe2ad3a648..28b9d3bf9291518bffe93e98aa9b9b50a8fff3e2 100644 (file)
@@ -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 <number> 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;
index 921e6a23c4f2f3c12169d8941d1c4f7912589e81..ba5ddc8651a18c0e99699fa2b71993326e6895ef 100644 (file)
@@ -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 (file)
index 0000000..0a59a58
--- /dev/null
@@ -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 (file)
index 0000000..f1e0d7a
--- /dev/null
@@ -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 (file)
index 0000000..119f009
--- /dev/null
@@ -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 (file)
index 0000000..567d33e
--- /dev/null
@@ -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