From 6ef35c04dffe685ece08212201c4c032baf8aa86 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 1 Dec 2022 13:09:26 +0000 Subject: Fix verilog output when the width is > 1. 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. 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 behaviour. * testsuite/binutils-all/verilog-I4.hex: New file. --- binutils/ChangeLog | 10 +++++++ binutils/objcopy.c | 25 +++++++++++++++-- binutils/testsuite/binutils-all/objcopy.exp | 38 ++++++++++++++++++++++++-- binutils/testsuite/binutils-all/verilog-I4.hex | 6 ++++ 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 binutils/testsuite/binutils-all/verilog-I4.hex (limited to 'binutils') diff --git a/binutils/ChangeLog b/binutils/ChangeLog index dfa5f1f..6ec81eb 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 PR 29764 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 3d88624..6814e20 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; +/* 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_info_type *input_arch) return false; } + /* 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 = ibfd->xvec->byteorder; + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) { if ((do_debug_sections & compress) != 0 @@ -5847,8 +5858,18 @@ copy_main (int argc, char *argv[]) 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")); + 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; case 0: diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index aebfdb2..de6f3aa 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -155,13 +155,13 @@ proc objcopy_test_verilog {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 { + 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)" } - foreach width {1 2 4 8} { + foreach width {1 2} { set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $binfile $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 + } + + foreach width {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)" + } + } + + # Test generating endian correct output. + set testname "objcopy (verilog output endian-ness == input endian-ness)" + set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 4 $binfile $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 + } else { + fail $testname + } } objcopy_test_verilog "verilog data width" diff --git a/binutils/testsuite/binutils-all/verilog-I4.hex b/binutils/testsuite/binutils-all/verilog-I4.hex new file mode 100644 index 0000000..4fa1a5c --- /dev/null +++ b/binutils/testsuite/binutils-all/verilog-I4.hex @@ -0,0 +1,6 @@ +@00000000 +(01020304|04030201) 00000000.* +@000000.. +(02000000|00000002).* +#pass + -- cgit v1.1