From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2124) id C58A43858D32; Thu, 1 Dec 2022 13:10:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C58A43858D32 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Nick Clifton To: bfd-cvs@sourceware.org Subject: [binutils-gdb] Fix verilog output when the width is > 1. X-Act-Checkin: binutils-gdb X-Git-Author: Nick Clifton X-Git-Refname: refs/heads/master X-Git-Oldrev: 7505bb034c7c8a3d9ecf34e22777114c8bc4a93e X-Git-Newrev: 6ef35c04dffe685ece08212201c4c032baf8aa86 Message-Id: <20221201131015.C58A43858D32@sourceware.org> Date: Thu, 1 Dec 2022 13:10:15 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Dec 2022 13:10:15 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D6ef35c04dffe= 685ece08212201c4c032baf8aa86 commit 6ef35c04dffe685ece08212201c4c032baf8aa86 Author: Nick Clifton Date: Thu Dec 1 13:09:26 2022 +0000 Fix verilog output when the width is > 1. =20 PR 25202 bfd * bfd.c (VerilogDataEndianness): New variable. (verilog_write_record): Use VerilogDataEndianness, if set, to choose the endianness of the output. (verilog_write_section): Adjust the address by the data width. =20 binutils* objcopy.c (copy_object): Set VerilogDataEndianness to the endianness of the input file. (copy_main): Verifiy the value set by the --verilog-data-width option. * testsuite/binutils-all/objcopy.exp: Add tests of the new beha= viour. * testsuite/binutils-all/verilog-I4.hex: New file. Diff: --- bfd/ChangeLog | 8 ++++++ bfd/verilog.c | 23 +++++++++++++--- binutils/ChangeLog | 10 +++++++ binutils/objcopy.c | 25 +++++++++++++++-- binutils/testsuite/binutils-all/objcopy.exp | 38 ++++++++++++++++++++++= ++-- binutils/testsuite/binutils-all/verilog-I4.hex | 6 ++++ 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 24aa783e1a7..eee5d42d6bb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2022-12-01 Nick Clifton + + PR 25202 + * bfd.c (VerilogDataEndianness): New variable. + (verilog_write_record): Use VerilogDataEndianness, if set, to + choose the endianness of the output. + (verilog_write_section): Adjust the address by the data width. + 2022-11-21 Nick Clifton =20 PR 29764 diff --git a/bfd/verilog.c b/bfd/verilog.c index baf0e044c42..52c42c5fdd9 100644 --- a/bfd/verilog.c +++ b/bfd/verilog.c @@ -62,6 +62,10 @@ Data width in bytes. */ unsigned int VerilogDataWidth =3D 1; =20 +/* Modified by obcopy.c + Data endianness. */ +enum bfd_endian VerilogDataEndianness =3D BFD_ENDIAN_UNKNOWN; + /* Macros for converting between hex and binary. */ =20 static const char digs[] =3D "0123456789ABCDEF"; @@ -105,7 +109,7 @@ verilog_set_arch_mach (bfd *abfd, enum bfd_architecture= arch, unsigned long mach return true; } =20 -/* We have to save up all the outpu for a splurge before output. */ +/* We have to save up all the output for a splurge before output. */ =20 static bool verilog_set_section_contents (bfd *abfd, @@ -238,7 +242,8 @@ verilog_write_record (bfd *abfd, *dst++ =3D ' '; } } - else if (bfd_little_endian (abfd)) + else if ((VerilogDataEndianness =3D=3D BFD_ENDIAN_UNKNOWN && bfd_little_= endian (abfd)) /* FIXME: Can this happen ? */ + || (VerilogDataEndianness =3D=3D BFD_ENDIAN_LITTLE)) { /* If the input byte stream contains: 05 04 03 02 01 00 @@ -263,8 +268,10 @@ verilog_write_record (bfd *abfd, TOHEX (dst, *end); dst +=3D 2; } + + /* FIXME: Should padding bytes be inserted here ? */ } - else + else /* Big endian output. */ { for (src =3D data; src < end;) { @@ -274,6 +281,7 @@ verilog_write_record (bfd *abfd, if ((src - data) % VerilogDataWidth =3D=3D 0) *dst++ =3D ' '; } + /* FIXME: Should padding bytes be inserted here ? */ } =20 *dst++ =3D '\r'; @@ -291,7 +299,14 @@ verilog_write_section (bfd *abfd, unsigned int octets_written =3D 0; bfd_byte *location =3D list->data; =20 - verilog_write_address (abfd, list->where); + /* Insist that the starting address is a multiple of the data width. */ + if (list->where % VerilogDataWidth) + { + bfd_set_error (bfd_error_invalid_operation); + return false; + } + + verilog_write_address (abfd, list->where / VerilogDataWidth); while (octets_written < list->size) { unsigned int octets_this_chunk =3D list->size - octets_written; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index dfa5f1f22c8..6ec81ebd099 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2022-12-01 Nick Clifton + + PR 25202 + * objcopy.c (copy_object): Set VerilogDataEndianness to the + endianness of the input file. + (copy_main): Verifiy the value set by the --verilog-data-width + option. + * testsuite/binutils-all/objcopy.exp: Add tests of the new behaviour. + * testsuite/binutils-all/verilog-I4.hex: New file. + 2022-11-21 Nick Clifton =20 PR 29764 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 3d886240ce1..6814e20a2fc 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -546,6 +546,11 @@ extern bool _bfd_srec_forceS3; the --verilog-data-width parameter. */ extern unsigned int VerilogDataWidth; =20 +/* Endianness of data for verilog output. + This variable is declared in bfd/verilog.c and is set in the + copy_object() function. */ +extern enum bfd_endian VerilogDataEndianness; + /* Forward declarations. */ static void setup_section (bfd *, asection *, void *); static void setup_bfd_headers (bfd *, bfd *); @@ -2655,6 +2660,12 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_in= fo_type *input_arch) return false; } =20 + /* Set the Verilog output endianness based upon the input file's + endianness. We may not be producing verilog format output, + but testing this just adds extra code this is not really + necessary. */ + VerilogDataEndianness =3D ibfd->xvec->byteorder; + if (bfd_get_flavour (ibfd) !=3D bfd_target_elf_flavour) { if ((do_debug_sections & compress) !=3D 0 @@ -5847,8 +5858,18 @@ copy_main (int argc, char *argv[]) =20 case OPTION_VERILOG_DATA_WIDTH: VerilogDataWidth =3D parse_vma (optarg, "--verilog-data-width"); - if (VerilogDataWidth < 1) - fatal (_("verilog data width must be at least 1 byte")); + switch (VerilogDataWidth) + { + case 1: + case 2: + case 4: + case 8: + case 16: /* We do not support widths > 16 because the verilog + data is handled internally in 16 byte wide packets. */ + break; + default: + fatal (_("error: verilog data width must be 1, 2, 4, 8 or 16")); + } break; =20 case 0: diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsui= te/binutils-all/objcopy.exp index aebfdb2090b..de6f3aaaef2 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -155,13 +155,13 @@ proc objcopy_test_verilog {testname} { } =20 set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 0 $bin= file $verilog-0.hex"] - if ![regexp "verilog data width must be at least 1 byte" $got] then { + if ![regexp "error: verilog data width must be 1, 2, 4, 8 or 16" $got]= then { fail "objcopy ($testname 0) {$got}" } else { pass "objcopy ($testname 0)" } =20 - foreach width {1 2 4 8} { + foreach width {1 2} { set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $b= infile $verilog-$width.hex"] if ![string equal "" $got] then { fail "objcopy ($testname $width)" @@ -173,6 +173,40 @@ proc objcopy_test_verilog {testname} { fail "objcopy ($testname $width)" } } + + # 16-bit little-endian targets fail the following tests because the + # verilog backend does not convert from 16-bits to 32-bits before it + # converts from internal format to little endian format. + if { [istarget tic54*-*-*] || [istarget pdp11-*-*] } { + untested "verilog width-4 and width-8 tests" + return + } + =20 + foreach width {4 8} { + set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $b= infile $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)" + } + } + + # Test generating endian correct output. =20 + set testname "objcopy (verilog output endian-ness =3D=3D input endian-= ness)" + set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 4 $bin= file $verilog-I4.hex"] + if ![string equal "" $got] then { + fail $testname + } + send_log "regexp_diff $verilog-I4.hex $srcdir/$subdir/verilog-I4.hex\n" + if {! [regexp_diff "$verilog-I4.hex" "$srcdir/$subdir/verilog-I4.hex"]= } { + pass $testname=20 + } else { + fail $testname=20 + } } =20 objcopy_test_verilog "verilog data width" diff --git a/binutils/testsuite/binutils-all/verilog-I4.hex b/binutils/test= suite/binutils-all/verilog-I4.hex new file mode 100644 index 00000000000..4fa1a5c9691 --- /dev/null +++ b/binutils/testsuite/binutils-all/verilog-I4.hex @@ -0,0 +1,6 @@ +@00000000 +(01020304|04030201) 00000000.* +@000000.. +(02000000|00000002).* +#pass +