Automatic date update in version.in
[binutils-gdb.git] / bfd / vms-alpha.c
index a9f87962f5b63ceac5b3ee0d2f6ec37a24afb1f6..20f8fd28e0ac17c59b6b8d277c8ce53fedefcbf2 100644 (file)
@@ -802,7 +802,7 @@ _bfd_vms_get_object_record (bfd *abfd)
   /* Skip alignment byte if the current position is odd.  */
   if (PRIV (recrd.file_format) == FF_FOREIGN && (bfd_tell (abfd) & 1))
     {
-      if (bfd_bread (PRIV (recrd.buf), 1, abfd) != 1)
+      if (bfd_read (PRIV (recrd.buf), 1, abfd) != 1)
        {
          bfd_set_error (bfd_error_file_truncated);
          return -1;
@@ -810,7 +810,7 @@ _bfd_vms_get_object_record (bfd *abfd)
     }
 
   /* Read the record header  */
-  if (bfd_bread (PRIV (recrd.buf), test_len, abfd) != test_len)
+  if (bfd_read (PRIV (recrd.buf), test_len, abfd) != test_len)
     {
       bfd_set_error (bfd_error_file_truncated);
       return -1;
@@ -880,7 +880,7 @@ vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far)
 
   vms_debug2 ((8, "vms_get_remaining_obj_record: to_read %d\n", to_read));
 
-  if (bfd_bread (PRIV (recrd.buf) + read_so_far, to_read, abfd) != to_read)
+  if (bfd_read (PRIV (recrd.buf) + read_so_far, to_read, abfd) != to_read)
     {
       bfd_set_error (bfd_error_file_truncated);
       return 0;
@@ -1628,7 +1628,7 @@ image_write (bfd *abfd, unsigned char *ptr, unsigned int size)
 
 #if VMS_DEBUG
   _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
-                 (long) off));
+                 (long) off);
 #endif
 
   if (PRIV (image_section)->contents != NULL)
@@ -2803,7 +2803,7 @@ alpha_vms_object_p (bfd *abfd)
       return NULL;
     }
 
-  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
+  if (bfd_seek (abfd, 0, SEEK_SET))
     goto error_ret;
 
   /* The first challenge with VMS is to discover the kind of the file.
@@ -2848,7 +2848,7 @@ alpha_vms_object_p (bfd *abfd)
       if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd))
        goto err_wrong_format;
 
-      if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
+      if (bfd_seek (abfd, 0, SEEK_SET))
        goto error_ret;
 
       free (PRIV (recrd.buf));
@@ -2923,7 +2923,7 @@ alpha_vms_object_p (bfd *abfd)
 
 /* Write an EMH/MHD record.  */
 
-static void
+static bool
 _bfd_vms_write_emh (bfd *abfd)
 {
   struct vms_rec_wr *recwr = &PRIV (recwr);
@@ -2952,12 +2952,12 @@ _bfd_vms_write_emh (bfd *abfd)
   _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
   _bfd_vms_output_dump (recwr, get_vms_time_string (tbuf), EMH_DATE_LENGTH);
   _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
-  _bfd_vms_output_end (abfd, recwr);
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 /* Write an EMH/LMN record.  */
 
-static void
+static bool
 _bfd_vms_write_lmn (bfd *abfd, const char *name)
 {
   char version [64];
@@ -2970,7 +2970,7 @@ _bfd_vms_write_lmn (bfd *abfd, const char *name)
   snprintf (version, sizeof (version), "%s %d.%d.%d", name,
            ver / 10000, (ver / 100) % 100, ver % 100);
   _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version));
-  _bfd_vms_output_end (abfd, recwr);
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 
@@ -3008,8 +3008,7 @@ _bfd_vms_write_eeom (bfd *abfd)
       _bfd_vms_output_long (recwr, 0);
     }
 
-  _bfd_vms_output_end (abfd, recwr);
-  return true;
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 static void *
@@ -3426,7 +3425,7 @@ alpha_vms_write_exec (bfd *abfd)
 
   /* Write first block.  */
   bfd_putl32 (lnkflags, eihd.lnkflags);
-  if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
+  if (bfd_write (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
     return false;
 
   /* Write remaining eisd.  */
@@ -3447,7 +3446,7 @@ alpha_vms_write_exec (bfd *abfd)
              || (next_eisd->file_pos / VMS_BLOCK_SIZE
                  != eisd->file_pos / VMS_BLOCK_SIZE))
            {
-             if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk))
+             if (bfd_write (blk, sizeof (blk), abfd) != sizeof (blk))
                return false;
 
              memset (blk, 0xff, sizeof (blk));
@@ -3465,7 +3464,7 @@ alpha_vms_write_exec (bfd *abfd)
       if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS)
          || sec->contents == NULL)
        continue;
-      if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size)
+      if (bfd_write (sec->contents, sec->size, abfd) != sec->size)
        return false;
 
       /* Pad.  */
@@ -3473,7 +3472,7 @@ alpha_vms_write_exec (bfd *abfd)
       if (len != VMS_BLOCK_SIZE)
        {
          memset (blk, 0, len);
-         if (bfd_bwrite (blk, len, abfd) != len)
+         if (bfd_write (blk, len, abfd) != len)
            return false;
        }
     }
@@ -3484,8 +3483,9 @@ alpha_vms_write_exec (bfd *abfd)
       struct vms_rec_wr *recwr = &PRIV (recwr);
       unsigned int i;
 
-      _bfd_vms_write_emh (abfd);
-      _bfd_vms_write_lmn (abfd, "GNU LD");
+      if (!_bfd_vms_write_emh (abfd)
+         || !_bfd_vms_write_lmn (abfd, "GNU LD"))
+       return false;
 
       /* PSC for the absolute section.  */
       _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
@@ -3496,7 +3496,8 @@ alpha_vms_write_exec (bfd *abfd)
       _bfd_vms_output_long (recwr, 0);
       _bfd_vms_output_counted (recwr, ".$$ABS$$.");
       _bfd_vms_output_end_subrec (recwr);
-      _bfd_vms_output_end (abfd, recwr);
+      if (!_bfd_vms_output_end (abfd, recwr))
+       return false;
 
       for (i = 0; i < PRIV (gsd_sym_count); i++)
        {
@@ -3529,11 +3530,13 @@ alpha_vms_write_exec (bfd *abfd)
          _bfd_vms_output_long (recwr, 0);
          _bfd_vms_output_counted (recwr, sym->name);
          _bfd_vms_output_end_subrec (recwr);
-         if ((i % 5) == 4)
-           _bfd_vms_output_end (abfd, recwr);
+         if ((i % 5) == 4
+             && !_bfd_vms_output_end (abfd, recwr))
+           return false;
        }
-      if ((i % 5) != 0)
-       _bfd_vms_output_end (abfd, recwr);
+      if ((i % 5) != 0
+         && !_bfd_vms_output_end (abfd, recwr))
+       return false;
 
       if (!_bfd_vms_write_eeom (abfd))
        return false;
@@ -3591,7 +3594,8 @@ _bfd_vms_write_egsd (bfd *abfd)
       /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
       if (_bfd_vms_output_check (recwr, 64) < 0)
        {
-         _bfd_vms_output_end (abfd, recwr);
+         if (!_bfd_vms_output_end (abfd, recwr))
+           return false;
          _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
          _bfd_vms_output_long (recwr, 0);
        }
@@ -3687,7 +3691,8 @@ _bfd_vms_write_egsd (bfd *abfd)
         bytes for a possible ABS section.  */
       if (_bfd_vms_output_check (recwr, 80 + 16) < 0)
        {
-         _bfd_vms_output_end (abfd, recwr);
+         if (!_bfd_vms_output_end (abfd, recwr))
+           return false;
          _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
          _bfd_vms_output_long (recwr, 0);
        }
@@ -3766,9 +3771,7 @@ _bfd_vms_write_egsd (bfd *abfd)
     }
 
   _bfd_vms_output_alignment (recwr, 8);
-  _bfd_vms_output_end (abfd, recwr);
-
-  return true;
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 /* Write object header for bfd abfd.  Return FALSE on error.  */
@@ -3784,8 +3787,9 @@ _bfd_vms_write_ehdr (bfd *abfd)
 
   _bfd_vms_output_alignment (recwr, 2);
 
-  _bfd_vms_write_emh (abfd);
-  _bfd_vms_write_lmn (abfd, "GNU AS");
+  if (!_bfd_vms_write_emh (abfd)
+      || !_bfd_vms_write_lmn (abfd, "GNU AS"))
+    return false;
 
   /* SRC.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
@@ -3806,13 +3810,15 @@ _bfd_vms_write_ehdr (bfd *abfd)
   if (symnum == abfd->symcount)
     _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("noname"));
 
-  _bfd_vms_output_end (abfd, recwr);
+  if (!_bfd_vms_output_end (abfd, recwr))
+    return false;
 
   /* TTL.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
   _bfd_vms_output_short (recwr, EMH__C_TTL);
   _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("TTL"));
-  _bfd_vms_output_end (abfd, recwr);
+  if (!_bfd_vms_output_end (abfd, recwr))
+    return false;
 
   /* CPR.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
@@ -3820,9 +3826,7 @@ _bfd_vms_write_ehdr (bfd *abfd)
   _bfd_vms_output_dump (recwr,
                        (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
                         39);
-  _bfd_vms_output_end (abfd, recwr);
-
-  return true;
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 /* Part 4.6, relocations.  */
@@ -3834,12 +3838,12 @@ _bfd_vms_write_ehdr (bfd *abfd)
 
 /* Close the etir/etbt record.  */
 
-static void
+static bool
 end_etir_record (bfd * abfd)
 {
   struct vms_rec_wr *recwr = &PRIV (recwr);
 
-  _bfd_vms_output_end (abfd, recwr);
+  return _bfd_vms_output_end (abfd, recwr);
 }
 
 static void
@@ -3885,7 +3889,7 @@ start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
 /* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
    address VADDR in section specified by SEC_INDEX and NAME.  */
 
-static void
+static bool
 sto_imm (bfd *abfd, asection *section,
         bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
 {
@@ -3905,7 +3909,8 @@ sto_imm (bfd *abfd, asection *section,
       if (_bfd_vms_output_check (recwr, size) < 0)
        {
          /* Doesn't fit, split !  */
-         end_etir_record (abfd);
+         if (!end_etir_record (abfd))
+           return false;
 
          start_etir_or_etbt_record (abfd, section, vaddr);
 
@@ -3928,17 +3933,20 @@ sto_imm (bfd *abfd, asection *section,
       cptr += size;
       ssize -= size;
     }
+  return true;
 }
 
-static void
+static bool
 etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
 {
   if (_bfd_vms_output_check (&PRIV (recwr), checklen) < 0)
     {
       /* Not enough room in this record.  Close it and open a new one.  */
-      end_etir_record (abfd);
+      if (!end_etir_record (abfd))
+       return false;
       start_etir_or_etbt_record (abfd, section, vaddr);
     }
+  return true;
 }
 
 /* Return whether RELOC must be deferred till the end.  */
@@ -4056,7 +4064,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    _bfd_error_handler (_("size error in section %pA"),
                                        section);
                  size = addr - curr_addr;
-                 sto_imm (abfd, section, size, curr_data, curr_addr);
+                 if (!sto_imm (abfd, section, size, curr_data, curr_addr))
+                   return false;
                  curr_data += size;
                  curr_addr += size;
                }
@@ -4073,7 +4082,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    {
                      bfd_vma addend = rptr->addend;
                      slen = strlen ((char *) sym->name);
-                     etir_output_check (abfd, section, curr_addr, slen);
+                     if (!etir_output_check (abfd, section, curr_addr, slen))
+                       return false;
                      if (addend)
                        {
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
@@ -4097,7 +4107,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    }
                  else if (bfd_is_abs_section (sym->section))
                    {
-                     etir_output_check (abfd, section, curr_addr, 16);
+                     if (!etir_output_check (abfd, section, curr_addr, 16))
+                       return false;
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
                      _bfd_vms_output_long (recwr, (unsigned long) sym->value);
                      _bfd_vms_output_end_subrec (recwr);
@@ -4106,7 +4117,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    }
                  else
                    {
-                     etir_output_check (abfd, section, curr_addr, 32);
+                     if (!etir_output_check (abfd, section, curr_addr, 32))
+                       return false;
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
                      _bfd_vms_output_long (recwr,
                                            (unsigned long) sec->target_index);
@@ -4126,7 +4138,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    {
                      bfd_vma addend = rptr->addend;
                      slen = strlen ((char *) sym->name);
-                     etir_output_check (abfd, section, curr_addr, slen);
+                     if (!etir_output_check (abfd, section, curr_addr, slen))
+                       return false;
                      if (addend)
                        {
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
@@ -4149,7 +4162,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    }
                  else if (bfd_is_abs_section (sym->section))
                    {
-                     etir_output_check (abfd, section, curr_addr, 16);
+                     if (!etir_output_check (abfd, section, curr_addr, 16))
+                       return false;
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
                      _bfd_vms_output_quad (recwr, sym->value);
                      _bfd_vms_output_end_subrec (recwr);
@@ -4158,7 +4172,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    }
                  else
                    {
-                     etir_output_check (abfd, section, curr_addr, 32);
+                     if (!etir_output_check (abfd, section, curr_addr, 32))
+                       return false;
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
                      _bfd_vms_output_long (recwr,
                                            (unsigned long) sec->target_index);
@@ -4170,12 +4185,14 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                  break;
 
                case ALPHA_R_HINT:
-                 sto_imm (abfd, section, size, curr_data, curr_addr);
+                 if (!sto_imm (abfd, section, size, curr_data, curr_addr))
+                   return false;
                  break;
 
                case ALPHA_R_LINKAGE:
                  size = 16;
-                 etir_output_check (abfd, section, curr_addr, 64);
+                 if (!etir_output_check (abfd, section, curr_addr, 64))
+                   return false;
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
                  _bfd_vms_output_long
                    (recwr, (unsigned long) rptr->addend);
@@ -4188,7 +4205,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 
                case ALPHA_R_CODEADDR:
                  slen = strlen ((char *) sym->name);
-                 etir_output_check (abfd, section, curr_addr, slen);
+                 if (!etir_output_check (abfd, section, curr_addr, slen))
+                   return false;
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
                  _bfd_vms_output_counted (recwr, sym->name);
                  _bfd_vms_output_end_subrec (recwr);
@@ -4197,8 +4215,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                case ALPHA_R_NOP:
                  udata
                    = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
-                 etir_output_check (abfd, section, curr_addr,
-                                    32 + 1 + strlen (udata->origname));
+                 if (!etir_output_check (abfd, section, curr_addr,
+                                         32 + 1 + strlen (udata->origname)))
+                   return false;
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL);
                  _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
                  _bfd_vms_output_long
@@ -4219,8 +4238,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                case ALPHA_R_LDA:
                  udata
                    = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
-                 etir_output_check (abfd, section, curr_addr,
-                                    32 + 1 + strlen (udata->origname));
+                 if (!etir_output_check (abfd, section, curr_addr,
+                                         32 + 1 + strlen (udata->origname)))
+                   return false;
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LDA_GBL);
                  _bfd_vms_output_long
                    (recwr, (unsigned long) udata->lkindex + 1);
@@ -4238,8 +4258,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                case ALPHA_R_BOH:
                  udata
                    = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
-                 etir_output_check (abfd, section, curr_addr,
-                                      32 + 1 + strlen (udata->origname));
+                 if (!etir_output_check (abfd, section, curr_addr,
+                                         32 + 1 + strlen (udata->origname)))
+                   return false;
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL);
                  _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
                  _bfd_vms_output_long
@@ -4272,7 +4293,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                  return false;
                }
              size = section->size - curr_addr;
-             sto_imm (abfd, section, size, curr_data, curr_addr);
+             if (!sto_imm (abfd, section, size, curr_data, curr_addr))
+               return false;
              curr_data += size;
              curr_addr += size;
 
@@ -4285,9 +4307,11 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
        }
 
       else /* (section->flags & SEC_RELOC) */
-       sto_imm (abfd, section, section->size, section->contents, 0);
+       if (!sto_imm (abfd, section, section->size, section->contents, 0))
+         return false;
 
-      end_etir_record (abfd);
+      if (!end_etir_record (abfd))
+       return false;
     }
 
   _bfd_vms_output_alignment (recwr, 2);
@@ -4577,8 +4601,11 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
 
                case DST__K_SRC_SETFILE:
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
-                 curr_srec->sfile = data;
-                 curr_srec->srec = module->file_table[data].srec;
+                 if ((unsigned int) data < module->file_table_count)
+                   {
+                     curr_srec->sfile = data;
+                     curr_srec->srec = module->file_table[data].srec;
+                   }
                  vms_debug2 ((4, "DST_S_C_SRC_SETFILE: %d\n", data));
                  break;
 
@@ -5289,12 +5316,18 @@ alpha_vms_slurp_relocs (bfd *abfd)
       begin = PRIV (recrd.rec) + 4;
       end = PRIV (recrd.rec) + PRIV (recrd.rec_size);
 
-      for (ptr = begin; ptr < end; ptr += length)
+      for (ptr = begin; ptr + 4 <= end; ptr += length)
        {
          int cmd;
 
          cmd = bfd_getl16 (ptr);
          length = bfd_getl16 (ptr + 2);
+         if (length < 4 || length > end - ptr)
+           {
+           bad_rec:
+             _bfd_error_handler (_("corrupt reloc record"));
+             goto fail;
+           }
 
          cur_address = vaddr;
 
@@ -5310,6 +5343,8 @@ alpha_vms_slurp_relocs (bfd *abfd)
              continue;
 
            case ETIR__C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+             if (length < 16)
+               goto bad_rec;
              cur_psidx = bfd_getl32 (ptr + 4);
              cur_addend = bfd_getl64 (ptr + 8);
              prev_cmd = cmd;
@@ -5343,6 +5378,8 @@ alpha_vms_slurp_relocs (bfd *abfd)
                      goto fail;
                    }
                }
+             if (length < 8)
+               goto bad_rec;
              cur_addend = bfd_getl32 (ptr + 4);
              prev_cmd = cmd;
              continue;
@@ -5357,6 +5394,8 @@ alpha_vms_slurp_relocs (bfd *abfd)
                     _bfd_vms_etir_name (ETIR__C_STA_QW));
                  goto fail;
                }
+             if (length < 12)
+               goto bad_rec;
              cur_addend = bfd_getl64 (ptr + 4);
              prev_cmd = cmd;
              continue;
@@ -5452,12 +5491,16 @@ alpha_vms_slurp_relocs (bfd *abfd)
              goto call_reloc;
 
            call_reloc:
+             if (length < 36)
+               goto bad_rec;
              cur_sym = ptr + 4 + 32;
              cur_address = bfd_getl64 (ptr + 4 + 8);
              cur_addend = bfd_getl64 (ptr + 4 + 24);
              break;
 
            case ETIR__C_STO_IMM:
+             if (length < 8)
+               goto bad_rec;
              vaddr += bfd_getl32 (ptr + 4);
              continue;
 
@@ -5517,12 +5560,16 @@ alpha_vms_slurp_relocs (bfd *abfd)
            if (cur_sym != NULL)
              {
                unsigned int j;
-               unsigned int symlen = *cur_sym;
+               int symlen;
                asymbol **sym;
 
                /* Linear search.  */
+               if (end - cur_sym < 1)
+                 goto bad_rec;
                symlen = *cur_sym;
                cur_sym++;
+               if (end - cur_sym < symlen)
+                 goto bad_rec;
                sym = NULL;
 
                for (j = 0; j < PRIV (gsd_sym_count); j++)
@@ -6850,7 +6897,7 @@ static void
 evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
 {
   bool is_first = true;
-  bool has_records = false;
+  bool has_records = true;
 
   while (1)
     {
@@ -6859,90 +6906,76 @@ evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
       unsigned char *rec;
       unsigned int hdr_size;
       unsigned int type;
+      unsigned char buf[6];
 
-      if (is_first)
+      hdr_size = has_records ? 6 : 4;
+      if (bfd_read (buf, hdr_size, abfd) != hdr_size)
        {
-         unsigned char buf[6];
-
-         is_first = false;
-
-         /* Read 6 bytes.  */
-         if (bfd_bread (buf, sizeof (buf), abfd) != sizeof (buf))
-           {
-             fprintf (file, _("cannot read GST record length\n"));
-             return;
-           }
-         rec_len = bfd_getl16 (buf + 0);
-         if (rec_len == bfd_getl16 (buf + 4)
-             && bfd_getl16 (buf + 2) == EOBJ__C_EMH)
-           {
-             /* The format is raw: record-size, type, record-size.  */
-             has_records = true;
-             pad_len = (rec_len + 1) & ~1U;
-             hdr_size = 4;
-           }
-         else if (rec_len == EOBJ__C_EMH)
-           {
-             has_records = false;
-             pad_len = bfd_getl16 (buf + 2);
-             hdr_size = 6;
-           }
-         else
-           {
-             /* Ill-formed.  */
-             fprintf (file, _("cannot find EMH in first GST record\n"));
-             return;
-           }
-         rec = bfd_malloc (pad_len);
-         memcpy (rec, buf + sizeof (buf) - hdr_size, hdr_size);
+         fprintf (file, _("cannot read GST record header\n"));
+         return;
        }
-      else
+
+      type = bfd_getl16 (buf);
+      rec_len = bfd_getl16 (buf + 2);
+      pad_len = rec_len;
+      if (has_records)
        {
-         unsigned int rec_len2 = 0;
-         unsigned char hdr[4];
+         unsigned int rec_len2 = bfd_getl16 (buf + 4);
 
-         if (has_records)
+         if (is_first)
            {
-             unsigned char buf_len[2];
-
-             if (bfd_bread (buf_len, sizeof (buf_len), abfd)
-                 != sizeof (buf_len))
+             is_first = false;
+             if (type == rec_len2 && rec_len == EOBJ__C_EMH)
+               /* Matched a VMS record EMH.  */
+               ;
+             else
                {
-                 fprintf (file, _("cannot read GST record length\n"));
-                 return;
+                 has_records = false;
+                 if (type != EOBJ__C_EMH)
+                   {
+                     /* Ill-formed.  */
+                     fprintf (file, _("cannot find EMH in first GST record\n"));
+                     return;
+                   }
                }
-             rec_len2 = (unsigned)bfd_getl16 (buf_len);
            }
 
-         if (bfd_bread (hdr, sizeof (hdr), abfd) != sizeof (hdr))
-           {
-             fprintf (file, _("cannot read GST record header\n"));
-             return;
-           }
-         rec_len = (unsigned)bfd_getl16 (hdr + 2);
          if (has_records)
-           pad_len = (rec_len + 1) & ~1U;
-         else
-           pad_len = rec_len;
-         rec = bfd_malloc (pad_len);
-         memcpy (rec, hdr, sizeof (hdr));
-         hdr_size = sizeof (hdr);
-         if (has_records && rec_len2 != rec_len)
            {
-             fprintf (file, _(" corrupted GST\n"));
-             break;
+             /* VMS record format is: record-size, type, record-size.
+                See maybe_adjust_record_pointer_for_object comment.  */
+             if (type == rec_len2)
+               {
+                 type = rec_len;
+                 rec_len = rec_len2;
+               }
+             else
+               rec_len = 0;
+             pad_len = (rec_len + 1) & ~1U;
+             hdr_size = 4;
            }
        }
 
-      if (bfd_bread (rec + hdr_size, pad_len - hdr_size, abfd)
+      if (rec_len < hdr_size)
+       {
+         fprintf (file, _("corrupted GST\n"));
+         return;
+       }
+
+      rec = bfd_malloc (pad_len);
+      if (rec == NULL)
+       return;
+
+      memcpy (rec, buf + (has_records ? 2 : 0), hdr_size);
+
+      if (bfd_read (rec + hdr_size, pad_len - hdr_size, abfd)
          != pad_len - hdr_size)
        {
          fprintf (file, _("cannot read GST record\n"));
+         free (rec);
          return;
        }
 
-      type = (unsigned)bfd_getl16 (rec);
-
       switch (type)
        {
        case EOBJ__C_EMH:
@@ -6955,7 +6988,6 @@ evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
          evax_bfd_print_eeom (file, rec, rec_len);
          free (rec);
          return;
-         break;
        case EOBJ__C_ETIR:
          evax_bfd_print_etir (file, "ETIR", rec, rec_len);
          break;
@@ -7463,7 +7495,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
       unsigned int type;
       unsigned char *buf;
 
-      if (bfd_bread (&dsth, sizeof (dsth), abfd) != sizeof (dsth))
+      if (bfd_read (&dsth, sizeof (dsth), abfd) != sizeof (dsth))
        {
          fprintf (file, _("cannot read DST header\n"));
          return;
@@ -8025,8 +8057,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
   unsigned int eiaf_size = 0;
   unsigned int eihvn_off;
 
-  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)
-      || bfd_bread (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
+  if (bfd_seek (abfd, 0, SEEK_SET)
+      || bfd_read (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
     {
       fprintf (file, _("cannot read EIHD\n"));
       return;
@@ -8153,8 +8185,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
       unsigned int j;
 
       fprintf (file, _("system version array information:\n"));
-      if (bfd_seek (abfd, (file_ptr) eihvn_off, SEEK_SET)
-         || bfd_bread (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn))
+      if (bfd_seek (abfd, eihvn_off, SEEK_SET)
+         || bfd_read (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn))
        {
          fprintf (file, _("cannot read EIHVN header\n"));
          return;
@@ -8164,7 +8196,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
        if (mask & (1u << j))
          {
            struct vms_eihvn_subversion ver;
-           if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver))
+           if (bfd_read (&ver, sizeof (ver), abfd) != sizeof (ver))
              {
                fprintf (file, _("cannot read EIHVN version\n"));
                return;
@@ -8246,8 +8278,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
     {
       struct vms_eiha eiha;
 
-      if (bfd_seek (abfd, (file_ptr) eiha_off, SEEK_SET)
-         || bfd_bread (&eiha, sizeof (eiha), abfd) != sizeof (eiha))
+      if (bfd_seek (abfd, eiha_off, SEEK_SET)
+         || bfd_read (&eiha, sizeof (eiha), abfd) != sizeof (eiha))
        {
          fprintf (file, _("cannot read EIHA\n"));
          return;
@@ -8279,8 +8311,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
     {
       struct vms_eihi eihi;
 
-      if (bfd_seek (abfd, (file_ptr) eihi_off, SEEK_SET)
-         || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
+      if (bfd_seek (abfd, eihi_off, SEEK_SET)
+         || bfd_read (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
        {
          fprintf (file, _("cannot read EIHI\n"));
          return;
@@ -8304,8 +8336,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
     {
       struct vms_eihs eihs;
 
-      if (bfd_seek (abfd, (file_ptr) eihs_off, SEEK_SET)
-         || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
+      if (bfd_seek (abfd, eihs_off, SEEK_SET)
+         || bfd_read (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
        {
          fprintf (file, _("cannot read EIHS\n"));
          return;
@@ -8337,8 +8369,8 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
 
       while (1)
        {
-         if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET)
-             || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
+         if (bfd_seek (abfd, eisd_off, SEEK_SET)
+             || bfd_read (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
            {
              fprintf (file, _("cannot read EISD\n"));
              return;
@@ -8453,7 +8485,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
          struct vms_dmt_header dmth;
          unsigned int count;
 
-         if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
+         if (bfd_read (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
            {
              fprintf (file, _("cannot read DMT header\n"));
              return;
@@ -8469,7 +8501,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
            {
              struct vms_dmt_psect dmtp;
 
-             if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
+             if (bfd_read (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
                {
                  fprintf (file, _("cannot read DMT psect\n"));
                  return;
@@ -10095,25 +10127,12 @@ bfd_vms_get_data (bfd *abfd)
   return (struct vms_private_data_struct *)abfd->tdata.any;
 }
 
-#define vms_bfd_is_target_special_symbol  _bfd_bool_bfd_asymbol_false
-#define vms_bfd_link_just_syms           _bfd_generic_link_just_syms
-#define vms_bfd_copy_link_hash_symbol_type \
-  _bfd_generic_copy_link_hash_symbol_type
-#define vms_bfd_is_group_section         bfd_generic_is_group_section
-#define vms_bfd_group_name               bfd_generic_group_name
-#define vms_bfd_discard_group            bfd_generic_discard_group
-#define vms_section_already_linked       _bfd_generic_section_already_linked
-#define vms_bfd_define_common_symbol     bfd_generic_define_common_symbol
-#define vms_bfd_link_hide_symbol         _bfd_generic_link_hide_symbol
-#define vms_bfd_define_start_stop         bfd_generic_define_start_stop
-#define vms_bfd_copy_private_header_data  _bfd_generic_bfd_copy_private_header_data
-
 #define vms_bfd_copy_private_bfd_data    _bfd_generic_bfd_copy_private_bfd_data
-#define vms_bfd_free_cached_info         _bfd_generic_bfd_free_cached_info
+#define vms_bfd_merge_private_bfd_data   _bfd_generic_bfd_merge_private_bfd_data
 #define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
 #define vms_bfd_copy_private_symbol_data  _bfd_generic_bfd_copy_private_symbol_data
+#define vms_bfd_copy_private_header_data  _bfd_generic_bfd_copy_private_header_data
 #define vms_bfd_set_private_flags        _bfd_generic_bfd_set_private_flags
-#define vms_bfd_merge_private_bfd_data   _bfd_generic_bfd_merge_private_bfd_data
 
 /* Symbols table.  */
 #define alpha_vms_make_empty_symbol       _bfd_generic_make_empty_symbol
@@ -10136,7 +10155,7 @@ bfd_vms_get_data (bfd *abfd)
 
 /* Generic table.  */
 #define alpha_vms_close_and_cleanup       vms_close_and_cleanup
-#define alpha_vms_bfd_free_cached_info    vms_bfd_free_cached_info
+#define alpha_vms_bfd_free_cached_info    _bfd_bool_bfd_true
 #define alpha_vms_new_section_hook        vms_new_section_hook
 #define alpha_vms_set_section_contents    _bfd_vms_set_section_contents
 #define alpha_vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window