Convert generic probe interface to C++ (and perform some cleanups)
[deliverable/binutils-gdb.git] / bfd / versados.c
index 5bafcb1d7cd8528bb638d57dab9e956cc2c3baab..d9ede273d76622510017a9142acf2dc93f7036ae 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for VERSAdos-E objects.
-   Copyright (C) 1995-2014 Free Software Foundation, Inc.
+   Copyright (C) 1995-2017 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.  */
@@ -85,8 +86,8 @@ typedef struct versados_data_struct
 tdata_type;
 
 #define VDATA(abfd)       (abfd->tdata.versados_data)
-#define EDATA(abfd, n)    (abfd->tdata.versados_data->e[n])
-#define RDATA(abfd, n)    (abfd->tdata.versados_data->rest[n])
+#define EDATA(abfd, n)    (abfd->tdata.versados_data->e[(n) < 16 ? (n) : 0])
+#define RDATA(abfd, n)    (abfd->tdata.versados_data->rest[(n) < 240 ? (n) : 0])
 
 struct ext_otr
 {
@@ -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;
@@ -181,14 +182,22 @@ versados_new_symbol (bfd *abfd,
   return n;
 }
 
-static int
+static bfd_boolean
 get_record (bfd *abfd, union ext_any *ptr)
 {
   if (bfd_bread (&ptr->size, (bfd_size_type) 1, abfd) != 1
       || (bfd_bread ((char *) ptr + 1, (bfd_size_type) ptr->size, abfd)
          != ptr->size))
-    return 0;
-  return 1;
+    return FALSE;
+
+  {
+    bfd_size_type amt = ptr->size + 1;
+
+    if (amt < sizeof (* ptr))
+      memset ((char *) ptr + amt, 0, sizeof (* ptr) - amt);
+  }
+
+  return TRUE;
 }
 
 static int
@@ -287,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++;
@@ -335,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)
@@ -364,10 +374,18 @@ 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);
-  unsigned char *contents = esdid->contents;
-  int need_contents = 0;
-  unsigned int dst_idx = esdid->pc;
+  struct esdid *esdid;
+  unsigned char *contents;
+  bfd_boolean need_contents = FALSE;
+  unsigned int dst_idx;
+
+  /* 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)
     {
@@ -376,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.  */
@@ -390,8 +412,8 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
              int val = get_offset (offsetlen, srcp + esdids);
 
              if (pass == 1)
-               need_contents = 1;
-             else
+               need_contents = TRUE;
+             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;
@@ -413,10 +435,13 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
                        }
                      else
                        {
-                         arelent *n =
-                         EDATA (abfd, otr->esdid - 1).section->relocation + rn;
-                         n->address = dst_idx;
+                         arelent *n;
 
+                         /* PR 17512: file: 54f733e0.  */
+                         if (EDATA (abfd, otr->esdid - 1).section == NULL)
+                           continue;
+                         n = EDATA (abfd, otr->esdid - 1).section->relocation + rn;
+                         n->address = dst_idx;
                          n->sym_ptr_ptr = (asymbol **) (size_t) id;
                          n->addend = 0;
                          n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1);
@@ -429,19 +454,21 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
        }
       else
        {
-         need_contents = 1;
-         
-         if (esdid->section && dst_idx < esdid->section->size)
+         need_contents = TRUE;
+
+         if (esdid->section && contents && dst_idx < esdid->content_size - 1)
            if (pass == 2)
              {
                /* Absolute code, comes in 16 bit lumps.  */
                contents[dst_idx] = srcp[0];
                contents[dst_idx + 1] = srcp[1];
              }
+
          dst_idx += 2;
          srcp += 2;
        }
     }
+
   EDATA (abfd, otr->esdid - 1).pc = dst_idx;
 
   if (!contents && need_contents)
@@ -452,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;
@@ -461,7 +489,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
 static bfd_boolean
 versados_scan (bfd *abfd)
 {
-  int loop = 1;
+  bfd_boolean loop = TRUE;
   int i;
   int j;
   int nsecs = 0;
@@ -479,13 +507,13 @@ versados_scan (bfd *abfd)
       union ext_any any;
 
       if (!get_record (abfd, &any))
-       return TRUE;
+       return FALSE;
       switch (any.header.type)
        {
        case VHEADER:
          break;
        case VEND:
-         loop = 0;
+         loop = FALSE;
          break;
        case VESTDEF:
          process_esd (abfd, &any.esd, 1);
@@ -512,7 +540,6 @@ versados_scan (bfd *abfd)
        {
          amt = (bfd_size_type) esdid->relocs * sizeof (arelent);
          esdid->section->relocation = bfd_alloc (abfd, amt);
-
          esdid->pc = 0;
 
          if (esdid->contents)
@@ -571,7 +598,7 @@ versados_scan (bfd *abfd)
 
   VDATA (abfd)->ref_idx = 0;
 
-  return 1;
+  return TRUE;
 }
 
 /* Check whether an existing file is a versados  file.  */
@@ -667,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;
 }
@@ -773,6 +808,7 @@ versados_canonicalize_reloc (bfd *abfd,
 
   versados_pass_2 (abfd);
   src = section->relocation;
+
   if (!EDATA (abfd, section->target_index).donerel)
     {
       EDATA (abfd, section->target_index).donerel = 1;
@@ -788,8 +824,15 @@ versados_canonicalize_reloc (bfd *abfd,
              /* Section relative thing.  */
              struct esdid *e = &EDATA (abfd, esdid - 1);
 
-             src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
+             /* PR 17512: file:cd92277c.  */
+             if (e->section)
+               src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
+             else
+               src[count].sym_ptr_ptr = bfd_und_section_ptr->symbol_ptr_ptr;
            }
+         /* PR 17512: file:3757-2936-0.004.  */
+         else if ((unsigned) (esdid - ES_BASE) >= bfd_get_symcount (abfd))
+           src[count].sym_ptr_ptr = bfd_und_section_ptr->symbol_ptr_ptr;
          else
            src[count].sym_ptr_ptr = symbols + esdid - ES_BASE;
        }
@@ -811,6 +854,7 @@ versados_canonicalize_reloc (bfd *abfd,
 #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
@@ -827,6 +871,7 @@ versados_canonicalize_reloc (bfd *abfd,
 #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
@@ -834,6 +879,8 @@ versados_canonicalize_reloc (bfd *abfd,
   _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_link_check_relocs                _bfd_generic_link_check_relocs
+#define versados_set_reloc                           _bfd_generic_set_reloc
 
 const bfd_target m68k_versados_vec =
 {
This page took 0.027987 seconds and 4 git commands to generate.