summaryrefslogtreecommitdiff
path: root/bfd/srec.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2008-02-11 13:52:02 +0000
committerDaniel Jacobowitz <dan@debian.org>2008-02-11 13:52:02 +0000
commit56aee9cb12ea677441210e0b7f1d8080840c6499 (patch)
treeb4fe4d0d1520074f47a92d6752b307586b1d70ad /bfd/srec.c
parent7a124716d4750b282038a8a0ac6a1d80a1805ebc (diff)
downloadbinutils-redhat-56aee9cb12ea677441210e0b7f1d8080840c6499.tar.gz
* cache.c (cache_bread): Set bfd_error_file_truncated if EOF
was reached. * srec.c (srec_scan): Calculate the checksum. Complain on mismatch.
Diffstat (limited to 'bfd/srec.c')
-rw-r--r--bfd/srec.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/bfd/srec.c b/bfd/srec.c
index 371e53a366..b7d515ccb9 100644
--- a/bfd/srec.c
+++ b/bfd/srec.c
@@ -458,6 +458,7 @@ srec_scan (bfd *abfd)
unsigned int bytes;
bfd_vma address;
bfd_byte *data;
+ unsigned char check_sum;
/* Starting an S-record. */
@@ -476,7 +477,7 @@ srec_scan (bfd *abfd)
goto error_return;
}
- bytes = HEX (hdr + 1);
+ check_sum = bytes = HEX (hdr + 1);
if (bytes * 2 > bufsize)
{
if (buf != NULL)
@@ -505,18 +506,22 @@ srec_scan (bfd *abfd)
break;
case '3':
+ check_sum += HEX (data);
address = HEX (data);
data += 2;
--bytes;
/* Fall through. */
case '2':
+ check_sum += HEX (data);
address = (address << 8) | HEX (data);
data += 2;
--bytes;
/* Fall through. */
case '1':
+ check_sum += HEX (data);
address = (address << 8) | HEX (data);
data += 2;
+ check_sum += HEX (data);
address = (address << 8) | HEX (data);
data += 2;
bytes -= 2;
@@ -548,25 +553,56 @@ srec_scan (bfd *abfd)
sec->size = bytes;
sec->filepos = pos;
}
+
+ while (bytes > 0)
+ {
+ check_sum += HEX (data);
+ data += 2;
+ bytes--;
+ }
+ check_sum = 255 - (check_sum & 0xff);
+ if (check_sum != HEX (data))
+ {
+ (*_bfd_error_handler)
+ (_("%B:%d: Bad checksum in S-record file\n"),
+ abfd, lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
break;
case '7':
+ check_sum += HEX (data);
address = HEX (data);
data += 2;
/* Fall through. */
case '8':
+ check_sum += HEX (data);
address = (address << 8) | HEX (data);
data += 2;
/* Fall through. */
case '9':
+ check_sum += HEX (data);
address = (address << 8) | HEX (data);
data += 2;
+ check_sum += HEX (data);
address = (address << 8) | HEX (data);
data += 2;
/* This is a termination record. */
abfd->start_address = address;
+ check_sum = 255 - (check_sum & 0xff);
+ if (check_sum != HEX (data))
+ {
+ (*_bfd_error_handler)
+ (_("%B:%d: Bad checksum in S-record file\n"),
+ abfd, lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
if (buf != NULL)
free (buf);