mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-17 16:05:56 +08:00
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.
This commit is contained in:
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
|
6
binutils/testsuite/binutils-all/verilog-I4.hex
Normal file
6
binutils/testsuite/binutils-all/verilog-I4.hex
Normal file
@ -0,0 +1,6 @@
|
||||
@00000000
|
||||
(01020304|04030201) 00000000.*
|
||||
@000000..
|
||||
(02000000|00000002).*
|
||||
#pass
|
||||
|
Reference in New Issue
Block a user