* cache.c (cache_bread): Set bfd_error_file_truncated if EOF
authorDaniel Jacobowitz <drow@false.org>
Mon, 11 Feb 2008 13:52:02 +0000 (13:52 +0000)
committerDaniel Jacobowitz <drow@false.org>
Mon, 11 Feb 2008 13:52:02 +0000 (13:52 +0000)
was reached.
* srec.c (srec_scan): Calculate the checksum.  Complain on mismatch.

bfd/ChangeLog
bfd/cache.c
bfd/srec.c

index 6c11aeca0e1cfe882315ff328656e5377788f223..3045a389f913b434501e056985eb3198298e8071 100644 (file)
@@ -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
index 039c1a941b4e53ea91935eb667f24a728232cd40..064cebeb3cb3ec4362bb62b2cc96776f20b8cce7 100644 (file)
@@ -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;
 }
 
index 371e53a36656b2d01d961675794f7e315cf5c485..b7d515ccb9ec60e1919d9ff354bf942df9a29a75 100644 (file)
@@ -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);