]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/versados.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / bfd / versados.c
index 95f5f538c877de83ef8e6fa824340366035af5b5..369ec2fe3f05cfe48361b50f465b24a23cc988b8 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for VERSAdos-E objects.
-   Copyright (C) 1995-2015 Free Software Foundation, Inc.
+   Copyright (C) 1995-2018 Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
 
    Versados is a Motorola trademark.
@@ -57,6 +57,7 @@ struct esdid
 {
   asection *section;           /* Ptr to bfd version.  */
   unsigned char *contents;     /* Used to build image.  */
+  bfd_size_type content_size;  /* The size of the contents buffer.  */
   int pc;
   int relocs;                  /* Reloc count, valid end of pass 1.  */
   int donerel;                 /* Have relocs been translated.  */
@@ -121,8 +122,8 @@ struct ext_esd
   unsigned char esd_entries[1];
 };
 
-#define ESD_ABS          0
-#define ESD_COMMON       1
+#define ESD_ABS                  0
+#define ESD_COMMON       1
 #define ESD_STD_REL_SEC   2
 #define ESD_SHRT_REL_SEC  3
 #define ESD_XDEF_IN_SEC   4
@@ -148,7 +149,7 @@ versados_mkobject (bfd *abfd)
   if (abfd->tdata.versados_data == NULL)
     {
       bfd_size_type amt = sizeof (tdata_type);
-      tdata_type *tdata = bfd_alloc (abfd, amt);
+      tdata_type *tdata = bfd_zalloc (abfd, amt);
 
       if (tdata == NULL)
        return FALSE;
@@ -295,6 +296,7 @@ process_esd (bfd *abfd, struct ext_esd *esd, int pass)
          break;
        case ESD_XDEF_IN_ABS:
          sec = bfd_abs_section_ptr;
+         /* Fall through.  */
        case ESD_XDEF_IN_SEC:
          {
            int snum = VDATA (abfd)->def_idx++;
@@ -343,13 +345,13 @@ reloc_howto_type versados_howto_table[] =
 };
 
 static int
-get_offset (int len, unsigned char *ptr)
+get_offset (unsigned int len, unsigned char *ptr)
 {
   int val = 0;
 
   if (len)
     {
-      int i;
+      unsigned int i;
 
       val = *ptr++;
       if (val & 0x80)
@@ -372,7 +374,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
   | (otr->map[2] << 8)
   | (otr->map[3] << 0);
 
-  struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
+  struct esdid *esdid;
   unsigned char *contents;
   bfd_boolean need_contents = FALSE;
   unsigned int dst_idx;
@@ -380,10 +382,11 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
   /* PR 17512: file: ac7da425.  */
   if (otr->esdid == 0)
     return;
-  
+
+  esdid = &EDATA (abfd, otr->esdid - 1);
   contents = esdid->contents;
   dst_idx = esdid->pc;
-  
+
   for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1)
     {
       if (bits & shift)
@@ -391,9 +394,13 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
          int flag = *srcp++;
          int esdids = (flag >> 5) & 0x7;
          int sizeinwords = ((flag >> 3) & 1) ? 2 : 1;
-         int offsetlen = flag & 0x7;
+         unsigned int offsetlen = flag & 0x7;
          int j;
 
+         /* PR 21591: Check for invalid lengths.  */
+         if (srcp + esdids + offsetlen >= endp)
+           return;
+
          if (esdids == 0)
            {
              /* A zero esdid means the new pc is the offset given.  */
@@ -406,7 +413,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
 
              if (pass == 1)
                need_contents = TRUE;
-             else if (contents && dst_idx < esdid->section->size - sizeinwords * 2)
+             else if (contents && dst_idx < esdid->content_size - sizeinwords * 2)
                for (j = 0; j < sizeinwords * 2; j++)
                  {
                    contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
@@ -449,7 +456,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
        {
          need_contents = TRUE;
 
-         if (esdid->section && contents && dst_idx < esdid->section->size)
+         if (esdid->section && contents && dst_idx < esdid->content_size - 1)
            if (pass == 2)
              {
                /* Absolute code, comes in 16 bit lumps.  */
@@ -472,6 +479,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
 
          size = esdid->section->size;
          esdid->contents = bfd_alloc (abfd, size);
+         esdid->content_size = size;
        }
       else
        esdid->contents = NULL;
@@ -686,12 +694,20 @@ versados_get_section_contents (bfd *abfd,
                               file_ptr offset,
                               bfd_size_type count)
 {
+  struct esdid *esdid;
+
   if (!versados_pass_2 (abfd))
     return FALSE;
 
-  memcpy (location,
-         EDATA (abfd, section->target_index).contents + offset,
-         (size_t) count);
+  esdid = &EDATA (abfd, section->target_index);
+
+  if (esdid->contents == NULL
+      || offset < 0
+      || (bfd_size_type) offset > esdid->content_size
+      || offset + count > esdid->content_size)
+    return FALSE;
+
+  memcpy (location, esdid->contents + offset, (size_t) count);
 
   return TRUE;
 }
@@ -829,39 +845,42 @@ versados_canonicalize_reloc (bfd *abfd,
   return section->reloc_count;
 }
 
-#define        versados_close_and_cleanup                    _bfd_generic_close_and_cleanup
-#define versados_bfd_free_cached_info                 _bfd_generic_bfd_free_cached_info
-#define versados_new_section_hook                     _bfd_generic_new_section_hook
-#define versados_bfd_is_target_special_symbol   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
-#define versados_bfd_is_local_label_name              bfd_generic_is_local_label_name
-#define versados_get_lineno                           _bfd_nosymbols_get_lineno
-#define versados_find_nearest_line                    _bfd_nosymbols_find_nearest_line
-#define versados_find_line                            _bfd_nosymbols_find_line
-#define versados_find_inliner_info                    _bfd_nosymbols_find_inliner_info
+#define        versados_close_and_cleanup                    _bfd_generic_close_and_cleanup
+#define versados_bfd_free_cached_info                _bfd_generic_bfd_free_cached_info
+#define versados_new_section_hook                    _bfd_generic_new_section_hook
+#define versados_bfd_is_target_special_symbol  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define versados_bfd_is_local_label_name             bfd_generic_is_local_label_name
+#define versados_get_lineno                          _bfd_nosymbols_get_lineno
+#define versados_find_nearest_line                   _bfd_nosymbols_find_nearest_line
+#define versados_find_line                           _bfd_nosymbols_find_line
+#define versados_find_inliner_info                   _bfd_nosymbols_find_inliner_info
 #define versados_get_symbol_version_string           _bfd_nosymbols_get_symbol_version_string
-#define versados_make_empty_symbol                    _bfd_generic_make_empty_symbol
-#define versados_bfd_make_debug_symbol                _bfd_nosymbols_bfd_make_debug_symbol
-#define versados_read_minisymbols                     _bfd_generic_read_minisymbols
-#define versados_minisymbol_to_symbol                 _bfd_generic_minisymbol_to_symbol
-#define versados_bfd_reloc_type_lookup                _bfd_norelocs_bfd_reloc_type_lookup
-#define versados_bfd_reloc_name_lookup          _bfd_norelocs_bfd_reloc_name_lookup
-#define versados_set_arch_mach                        bfd_default_set_arch_mach
+#define versados_make_empty_symbol                   _bfd_generic_make_empty_symbol
+#define versados_bfd_make_debug_symbol               _bfd_nosymbols_bfd_make_debug_symbol
+#define versados_read_minisymbols                    _bfd_generic_read_minisymbols
+#define versados_minisymbol_to_symbol                _bfd_generic_minisymbol_to_symbol
+#define versados_bfd_reloc_type_lookup               _bfd_norelocs_bfd_reloc_type_lookup
+#define versados_bfd_reloc_name_lookup         _bfd_norelocs_bfd_reloc_name_lookup
+#define versados_set_arch_mach                       bfd_default_set_arch_mach
 #define versados_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
-#define versados_bfd_relax_section                    bfd_generic_relax_section
-#define versados_bfd_gc_sections                      bfd_generic_gc_sections
-#define versados_bfd_lookup_section_flags             bfd_generic_lookup_section_flags
-#define versados_bfd_merge_sections                   bfd_generic_merge_sections
-#define versados_bfd_is_group_section                 bfd_generic_is_group_section
-#define versados_bfd_discard_group                    bfd_generic_discard_group
-#define versados_section_already_linked               _bfd_generic_section_already_linked
-#define versados_bfd_define_common_symbol             bfd_generic_define_common_symbol
-#define versados_bfd_link_hash_table_create           _bfd_generic_link_hash_table_create
-#define versados_bfd_link_add_symbols                 _bfd_generic_link_add_symbols
-#define versados_bfd_link_just_syms                   _bfd_generic_link_just_syms
+#define versados_bfd_relax_section                   bfd_generic_relax_section
+#define versados_bfd_gc_sections                     bfd_generic_gc_sections
+#define versados_bfd_lookup_section_flags            bfd_generic_lookup_section_flags
+#define versados_bfd_merge_sections                  bfd_generic_merge_sections
+#define versados_bfd_is_group_section                bfd_generic_is_group_section
+#define versados_bfd_discard_group                   bfd_generic_discard_group
+#define versados_section_already_linked                      _bfd_generic_section_already_linked
+#define versados_bfd_define_common_symbol            bfd_generic_define_common_symbol
+#define versados_bfd_define_start_stop               bfd_generic_define_start_stop
+#define versados_bfd_link_hash_table_create          _bfd_generic_link_hash_table_create
+#define versados_bfd_link_add_symbols                _bfd_generic_link_add_symbols
+#define versados_bfd_link_just_syms                  _bfd_generic_link_just_syms
 #define versados_bfd_copy_link_hash_symbol_type \
   _bfd_generic_copy_link_hash_symbol_type
-#define versados_bfd_final_link                       _bfd_generic_final_link
-#define versados_bfd_link_split_section               _bfd_generic_link_split_section
+#define versados_bfd_final_link                              _bfd_generic_final_link
+#define versados_bfd_link_split_section                      _bfd_generic_link_split_section
+#define versados_bfd_link_check_relocs               _bfd_generic_link_check_relocs
+#define versados_set_reloc                           _bfd_generic_set_reloc
 
 const bfd_target m68k_versados_vec =
 {