aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/verilog.c23
-rw-r--r--binutils/ChangeLog10
-rw-r--r--binutils/objcopy.c25
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp38
-rw-r--r--binutils/testsuite/binutils-all/verilog-I4.hex6
6 files changed, 102 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 24aa783..eee5d42 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2022-12-01 Nick Clifton <nickc@redhat.com>
+
+ 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 <nickc@redhat.com>
PR 29764
diff --git a/bfd/verilog.c b/bfd/verilog.c
index baf0e04..52c42c5 100644
--- a/bfd/verilog.c
+++ b/bfd/verilog.c
@@ -62,6 +62,10 @@
Data width in bytes. */
unsigned int VerilogDataWidth = 1;
+/* Modified by obcopy.c
+ Data endianness. */
+enum bfd_endian VerilogDataEndianness = BFD_ENDIAN_UNKNOWN;
+
/* Macros for converting between hex and binary. */
static const char digs[] = "0123456789ABCDEF";
@@ -105,7 +109,7 @@ verilog_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach
return true;
}
-/* 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. */
static bool
verilog_set_section_contents (bfd *abfd,
@@ -238,7 +242,8 @@ verilog_write_record (bfd *abfd,
*dst++ = ' ';
}
}
- else if (bfd_little_endian (abfd))
+ else if ((VerilogDataEndianness == BFD_ENDIAN_UNKNOWN && bfd_little_endian (abfd)) /* FIXME: Can this happen ? */
+ || (VerilogDataEndianness == 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 += 2;
}
+
+ /* FIXME: Should padding bytes be inserted here ? */
}
- else
+ else /* Big endian output. */
{
for (src = data; src < end;)
{
@@ -274,6 +281,7 @@ verilog_write_record (bfd *abfd,
if ((src - data) % VerilogDataWidth == 0)
*dst++ = ' ';
}
+ /* FIXME: Should padding bytes be inserted here ? */
}
*dst++ = '\r';
@@ -291,7 +299,14 @@ verilog_write_section (bfd *abfd,
unsigned int octets_written = 0;
bfd_byte *location = list->data;
- 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 = list->size - octets_written;
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 <nickc@redhat.com>
+
+ 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 <nickc@redhat.com>
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
+