aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/cache.c4
-rw-r--r--bfd/srec.c38
3 files changed, 47 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6c11aec..3045a38 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2008-02-11 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * cache.c (cache_bread): Set bfd_error_file_truncated if EOF
+ was reached.
+ * srec.c (srec_scan): Calculate the checksum. Complain on mismatch.
+
2008-02-07 Alan Modra <amodra@bigpond.net.au>
* elf32-spu.c (spu_elf_size_stubs): Revert 2008-01-28 doubling
diff --git a/bfd/cache.c b/bfd/cache.c
index 039c1a9..064cebe 100644
--- a/bfd/cache.c
+++ b/bfd/cache.c
@@ -309,6 +309,10 @@ cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
return -1;
}
#endif
+ if (nread < nbytes)
+ /* This may or may not be an error, but in case the calling code
+ bails out because of it, set the right error code. */
+ bfd_set_error (bfd_error_file_truncated);
return nread;
}
diff --git a/bfd/srec.c b/bfd/srec.c
index 371e53a..b7d515c 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);