mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-14 03:02:39 +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>
|
2022-11-21 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR 29764
|
PR 29764
|
||||||
|
@ -62,6 +62,10 @@
|
|||||||
Data width in bytes. */
|
Data width in bytes. */
|
||||||
unsigned int VerilogDataWidth = 1;
|
unsigned int VerilogDataWidth = 1;
|
||||||
|
|
||||||
|
/* Modified by obcopy.c
|
||||||
|
Data endianness. */
|
||||||
|
enum bfd_endian VerilogDataEndianness = BFD_ENDIAN_UNKNOWN;
|
||||||
|
|
||||||
/* Macros for converting between hex and binary. */
|
/* Macros for converting between hex and binary. */
|
||||||
|
|
||||||
static const char digs[] = "0123456789ABCDEF";
|
static const char digs[] = "0123456789ABCDEF";
|
||||||
@ -105,7 +109,7 @@ verilog_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach
|
|||||||
return true;
|
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
|
static bool
|
||||||
verilog_set_section_contents (bfd *abfd,
|
verilog_set_section_contents (bfd *abfd,
|
||||||
@ -238,7 +242,8 @@ verilog_write_record (bfd *abfd,
|
|||||||
*dst++ = ' ';
|
*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:
|
/* If the input byte stream contains:
|
||||||
05 04 03 02 01 00
|
05 04 03 02 01 00
|
||||||
@ -263,8 +268,10 @@ verilog_write_record (bfd *abfd,
|
|||||||
TOHEX (dst, *end);
|
TOHEX (dst, *end);
|
||||||
dst += 2;
|
dst += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Should padding bytes be inserted here ? */
|
||||||
}
|
}
|
||||||
else
|
else /* Big endian output. */
|
||||||
{
|
{
|
||||||
for (src = data; src < end;)
|
for (src = data; src < end;)
|
||||||
{
|
{
|
||||||
@ -274,6 +281,7 @@ verilog_write_record (bfd *abfd,
|
|||||||
if ((src - data) % VerilogDataWidth == 0)
|
if ((src - data) % VerilogDataWidth == 0)
|
||||||
*dst++ = ' ';
|
*dst++ = ' ';
|
||||||
}
|
}
|
||||||
|
/* FIXME: Should padding bytes be inserted here ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst++ = '\r';
|
*dst++ = '\r';
|
||||||
@ -291,7 +299,14 @@ verilog_write_section (bfd *abfd,
|
|||||||
unsigned int octets_written = 0;
|
unsigned int octets_written = 0;
|
||||||
bfd_byte *location = list->data;
|
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)
|
while (octets_written < list->size)
|
||||||
{
|
{
|
||||||
unsigned int octets_this_chunk = list->size - octets_written;
|
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>
|
2022-11-21 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR 29764
|
PR 29764
|
||||||
|
@ -546,6 +546,11 @@ extern bool _bfd_srec_forceS3;
|
|||||||
the --verilog-data-width parameter. */
|
the --verilog-data-width parameter. */
|
||||||
extern unsigned int VerilogDataWidth;
|
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. */
|
/* Forward declarations. */
|
||||||
static void setup_section (bfd *, asection *, void *);
|
static void setup_section (bfd *, asection *, void *);
|
||||||
static void setup_bfd_headers (bfd *, bfd *);
|
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;
|
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 (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
|
||||||
{
|
{
|
||||||
if ((do_debug_sections & compress) != 0
|
if ((do_debug_sections & compress) != 0
|
||||||
@ -5847,8 +5858,18 @@ copy_main (int argc, char *argv[])
|
|||||||
|
|
||||||
case OPTION_VERILOG_DATA_WIDTH:
|
case OPTION_VERILOG_DATA_WIDTH:
|
||||||
VerilogDataWidth = parse_vma (optarg, "--verilog-data-width");
|
VerilogDataWidth = parse_vma (optarg, "--verilog-data-width");
|
||||||
if (VerilogDataWidth < 1)
|
switch (VerilogDataWidth)
|
||||||
fatal (_("verilog data width must be at least 1 byte"));
|
{
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
case 0:
|
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"]
|
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}"
|
fail "objcopy ($testname 0) {$got}"
|
||||||
} else {
|
} else {
|
||||||
pass "objcopy ($testname 0)"
|
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"]
|
set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $binfile $verilog-$width.hex"]
|
||||||
if ![string equal "" $got] then {
|
if ![string equal "" $got] then {
|
||||||
fail "objcopy ($testname $width)"
|
fail "objcopy ($testname $width)"
|
||||||
@ -173,6 +173,40 @@ proc objcopy_test_verilog {testname} {
|
|||||||
fail "objcopy ($testname $width)"
|
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"
|
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