update copyright dates
[deliverable/binutils-gdb.git] / bfd / srec.c
index da25a970b1c10b1d71fa76d94bc155c029129b67..baae280d73c3789eea5715ca7f358e5670e0b2a5 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for s-record objects.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
 
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,7 +18,9 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
 
 /* SUBSECTION
        S-Record handling
        We allow symbols to be anywhere in the data stream - the module names
        are always ignored.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
@@ -426,6 +428,11 @@ srec_scan (bfd *abfd)
                  symval <<= 4;
                  symval += NIBBLE (c);
                  c = srec_get_byte (abfd, &error);
+                 if (c == EOF)
+                   {
+                     srec_bad_byte (abfd, lineno, c, error);
+                     goto error_return;
+                   }
                }
 
              if (! srec_new_symbol (abfd, symname, symval))
@@ -451,6 +458,7 @@ srec_scan (bfd *abfd)
            unsigned int bytes;
            bfd_vma address;
            bfd_byte *data;
+           unsigned char check_sum;
 
            /* Starting an S-record.  */
 
@@ -469,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)
@@ -498,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;
@@ -526,39 +538,71 @@ srec_scan (bfd *abfd)
                    char secbuf[20];
                    char *secname;
                    bfd_size_type amt;
+                   flagword flags;
 
                    sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
                    amt = strlen (secbuf) + 1;
                    secname = bfd_alloc (abfd, amt);
                    strcpy (secname, secbuf);
-                   sec = bfd_make_section (abfd, secname);
+                   flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+                   sec = bfd_make_section_with_flags (abfd, secname, flags);
                    if (sec == NULL)
                      goto error_return;
-                   sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
                    sec->vma = address;
                    sec->lma = address;
                    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);
 
@@ -778,10 +822,20 @@ srec_get_section_contents (bfd *abfd,
                           file_ptr offset,
                           bfd_size_type count)
 {
+  if (count == 0)
+    return TRUE;
+
+  if (offset + count < count
+      || offset + count > section->size)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
+
   if (section->used_by_bfd == NULL)
     {
       section->used_by_bfd = bfd_alloc (abfd, section->size);
-      if (section->used_by_bfd == NULL && section->size != 0)
+      if (section->used_by_bfd == NULL)
        return FALSE;
 
       if (! srec_read_section (abfd, section, section->used_by_bfd))
@@ -1099,7 +1153,7 @@ symbolsrec_write_object_contents (bfd *abfd)
 
 static int
 srec_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
-                    bfd_boolean exec ATTRIBUTE_UNUSED)
+                    struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   return 0;
 }
@@ -1122,14 +1176,14 @@ srec_canonicalize_symtab (bfd *abfd, asymbol **alocation)
   unsigned int i;
 
   csymbols = abfd->tdata.srec_data->csymbols;
-  if (csymbols == NULL)
+  if (csymbols == NULL && symcount != 0)
     {
       asymbol *c;
       struct srec_symbol *s;
 
       csymbols = bfd_alloc (abfd, symcount * sizeof (asymbol));
-      if (csymbols == NULL && symcount != 0)
-       return 0;
+      if (csymbols == NULL)
+       return -1;
       abfd->tdata.srec_data->csymbols = csymbols;
 
       for (s = abfd->tdata.srec_data->symbols, c = csymbols;
@@ -1188,13 +1242,11 @@ srec_print_symbol (bfd *abfd,
 #define srec_bfd_is_local_label_name              bfd_generic_is_local_label_name
 #define srec_get_lineno                           _bfd_nosymbols_get_lineno
 #define srec_find_nearest_line                    _bfd_nosymbols_find_nearest_line
+#define srec_find_inliner_info                    _bfd_nosymbols_find_inliner_info
 #define srec_make_empty_symbol                    _bfd_generic_make_empty_symbol
 #define srec_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
 #define srec_read_minisymbols                     _bfd_generic_read_minisymbols
 #define srec_minisymbol_to_symbol                 _bfd_generic_minisymbol_to_symbol
-#define srec_get_reloc_upper_bound                ((long (*) (bfd *, asection *)) bfd_0l)
-#define srec_canonicalize_reloc                   ((long (*) (bfd *, asection *, arelent **, asymbol **)) bfd_0l)
-#define srec_bfd_reloc_type_lookup                _bfd_norelocs_bfd_reloc_type_lookup
 #define srec_get_section_contents_in_window       _bfd_generic_get_section_contents_in_window
 #define srec_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
 #define srec_bfd_relax_section                    bfd_generic_relax_section
@@ -1203,6 +1255,7 @@ srec_print_symbol (bfd *abfd,
 #define srec_bfd_is_group_section                 bfd_generic_is_group_section
 #define srec_bfd_discard_group                    bfd_generic_discard_group
 #define srec_section_already_linked               _bfd_generic_section_already_linked
+#define srec_bfd_define_common_symbol             bfd_generic_define_common_symbol
 #define srec_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
 #define srec_bfd_link_hash_table_free             _bfd_generic_link_hash_table_free
 #define srec_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
@@ -1255,7 +1308,7 @@ const bfd_target srec_vec =
   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
   BFD_JUMP_TABLE_SYMBOLS (srec),
-  BFD_JUMP_TABLE_RELOCS (srec),
+  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
   BFD_JUMP_TABLE_WRITE (srec),
   BFD_JUMP_TABLE_LINK (srec),
   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
@@ -1310,7 +1363,7 @@ const bfd_target symbolsrec_vec =
   BFD_JUMP_TABLE_CORE (_bfd_nocore),
   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
   BFD_JUMP_TABLE_SYMBOLS (srec),
-  BFD_JUMP_TABLE_RELOCS (srec),
+  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
   BFD_JUMP_TABLE_WRITE (srec),
   BFD_JUMP_TABLE_LINK (srec),
   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
This page took 0.042056 seconds and 4 git commands to generate.