ubsan: alpha-vma: timeout
[deliverable/binutils-gdb.git] / bfd / vms-alpha.c
index 69822a2ce6a4c379e3c2b5c555846de0aa84a695..32f4e68bbba8ab954469cbb8824c324e449c53a8 100644 (file)
@@ -1,5 +1,5 @@
 /* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files.
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
+   Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
    Initial version written by Klaus Kaempf (kkaempf@rmi.de)
    Major rewrite by Adacore.
@@ -529,12 +529,12 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
       asection *section;
       flagword bfd_flags;
 
-      /* PR 17512: file: 3d9e9fe9.
-        12 is the offset of the eisdsize field from the start of the record (8)
-        plus the size of the eisdsize field (4).  */
-      if (offset >= PRIV (recrd.rec_size) - 12)
+      /* PR 17512: file: 3d9e9fe9.  */
+      if (offset > PRIV (recrd.rec_size)
+         || (PRIV (recrd.rec_size) - offset
+             < offsetof (struct vms_eisd, eisdsize) + 4))
        return FALSE;
-      eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset);
+      eisd = (struct vms_eisd *) (PRIV (recrd.rec) + offset);
       rec_size = bfd_getl32 (eisd->eisdsize);
       if (rec_size == 0)
        break;
@@ -547,11 +547,10 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
        }
 
       /* Make sure that there is enough data present in the record.  */
-      /* FIXME: Should we use sizeof (struct vms_eisd) rather than just 32 here ?  */
-      if (rec_size < 32)
+      if (rec_size < offsetof (struct vms_eisd, type) + 1)
        return FALSE;
       /* Make sure that the record is not too big either.  */
-      if (offset + rec_size >= PRIV (recrd.rec_size))
+      if (rec_size > PRIV (recrd.rec_size) - offset)
        return FALSE;
 
       offset += rec_size;
@@ -592,13 +591,16 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
 
       if (flags & EISD__M_GBL)
        {
-         if (rec_size < offsetof (struct vms_eisd, gblnam))
+         if (rec_size <= offsetof (struct vms_eisd, gblnam))
            return FALSE;
          else if (rec_size < sizeof (struct vms_eisd))
-           name = _bfd_vms_save_counted_string (eisd->gblnam,
+           name = _bfd_vms_save_counted_string (abfd, eisd->gblnam,
                                                 rec_size - offsetof (struct vms_eisd, gblnam));
          else
-           name = _bfd_vms_save_counted_string (eisd->gblnam, EISD__K_GBLNAMLEN);
+           name = _bfd_vms_save_counted_string (abfd, eisd->gblnam,
+                                                EISD__K_GBLNAMLEN);
+         if (name == NULL || name[0] == 0)
+           return FALSE;
          bfd_flags |= SEC_COFF_SHARED_LIBRARY;
          bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
        }
@@ -610,7 +612,9 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
        {
          const char *pfx;
 
-         name = (char*) bfd_alloc (abfd, 32);
+         name = (char *) bfd_alloc (abfd, 32);
+         if (name == NULL)
+           return FALSE;
          if (flags & EISD__M_DZRO)
            pfx = "BSS";
          else if (flags & EISD__M_EXE)
@@ -632,7 +636,7 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
       section->size = size;
       section->vma = vaddr;
 
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+      if (!bfd_set_section_flags (section, bfd_flags))
        return FALSE;
     }
 
@@ -687,7 +691,7 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
       section->size = dstsize;
       section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
 
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+      if (!bfd_set_section_flags (section, bfd_flags))
        return FALSE;
 
       PRIV (dst_section) = section;
@@ -705,7 +709,7 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
       section->size = dmtbytes;
       section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
 
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+      if (!bfd_set_section_flags (section, bfd_flags))
        return FALSE;
     }
 
@@ -924,36 +928,39 @@ _bfd_vms_slurp_ehdr (bfd *abfd)
       PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
       if ((vms_rec + 20 + vms_rec[20] + 1) >= end)
        goto fail;
-      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20, vms_rec[20]);
+      PRIV (hdr_data).hdr_t_name
+       = _bfd_vms_save_counted_string (abfd, vms_rec + 20, vms_rec[20]);
       ptr = vms_rec + 20 + vms_rec[20] + 1;
       if ((ptr + *ptr + 1) >= end)
        goto fail;
-      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr, *ptr);
+      PRIV (hdr_data).hdr_t_version
+       = _bfd_vms_save_counted_string (abfd, ptr, *ptr);
       ptr += *ptr + 1;
       if (ptr + 17 >= end)
        goto fail;
-      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
+      PRIV (hdr_data).hdr_t_date
+       = _bfd_vms_save_sized_string (abfd, ptr, 17);
       break;
 
     case EMH__C_LNM:
       if (vms_rec + PRIV (recrd.rec_size - 6) > end)
        goto fail;
-      PRIV (hdr_data).hdr_c_lnm =
-       _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      PRIV (hdr_data).hdr_c_lnm
+       = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
       break;
 
     case EMH__C_SRC:
       if (vms_rec + PRIV (recrd.rec_size - 6) > end)
        goto fail;
-      PRIV (hdr_data).hdr_c_src =
-       _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      PRIV (hdr_data).hdr_c_src
+       = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
       break;
 
     case EMH__C_TTL:
       if (vms_rec + PRIV (recrd.rec_size - 6) > end)
        goto fail;
-      PRIV (hdr_data).hdr_c_ttl =
-       _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      PRIV (hdr_data).hdr_c_ttl
+       = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
       break;
 
     case EMH__C_CPR:
@@ -1137,12 +1144,20 @@ add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym)
    Return NULL in case of error.  */
 
 static struct vms_symbol_entry *
-add_symbol (bfd *abfd, const unsigned char *ascic)
+add_symbol (bfd *abfd, const unsigned char *ascic, unsigned int max)
 {
   struct vms_symbol_entry *entry;
-  int len;
+  unsigned int len;
 
   len = *ascic++;
+  max -= 1;
+  if (len > max)
+    {
+      _bfd_error_handler (_("record is too small for symbol name length"));
+      bfd_set_error (bfd_error_bad_value);
+      return NULL;
+    }
+
   entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len);
   if (entry == NULL)
     return NULL;
@@ -1164,7 +1179,8 @@ _bfd_vms_slurp_egsd (bfd *abfd)
   int gsd_type;
   unsigned int gsd_size;
   unsigned char *vms_rec;
-  unsigned long base_addr;
+  bfd_vma base_addr;
+  long psindx;
 
   vms_debug2 ((2, "EGSD\n"));
 
@@ -1180,7 +1196,7 @@ _bfd_vms_slurp_egsd (bfd *abfd)
   PRIV (recrd.rec_size) -= 8;
 
   /* Calculate base address for each section.  */
-  base_addr = 0L;
+  base_addr = 0;
 
   while (PRIV (recrd.rec_size) > 4)
     {
@@ -1194,16 +1210,19 @@ _bfd_vms_slurp_egsd (bfd *abfd)
       /* PR 21615: Check for size overflow.  */
       if (PRIV (recrd.rec_size) < gsd_size)
        {
-         _bfd_error_handler (_("corrupt EGSD record: size (%#x) is larger than remaining space (%#x)"),
-                             gsd_size, PRIV (recrd.rec_size));
+         _bfd_error_handler (_("corrupt EGSD record type %d: size (%#x) "
+                               "is larger than remaining space (%#x)"),
+                             gsd_type, gsd_size, PRIV (recrd.rec_size));
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
 
       if (gsd_size < 4)
        {
-         _bfd_error_handler (_("corrupt EGSD record: size (%#x) is too small"),
-                             gsd_size);
+       too_small:
+         _bfd_error_handler (_("corrupt EGSD record type %d: size (%#x) "
+                               "is too small"),
+                             gsd_type, gsd_size);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
@@ -1213,10 +1232,12 @@ _bfd_vms_slurp_egsd (bfd *abfd)
        case EGSD__C_PSC:
          /* Program section definition.  */
          {
-           struct vms_egps *egps = (struct vms_egps *)vms_rec;
+           struct vms_egps *egps = (struct vms_egps *) vms_rec;
            flagword new_flags, vms_flags;
            asection *section;
 
+           if (offsetof (struct vms_egps, flags) + 2 > gsd_size)
+             goto too_small;
            vms_flags = bfd_getl16 (egps->flags);
 
            if ((vms_flags & EGPS__V_REL) == 0)
@@ -1228,9 +1249,15 @@ _bfd_vms_slurp_egsd (bfd *abfd)
            else
              {
                char *name;
-               unsigned long align_addr;
-
-               name = _bfd_vms_save_counted_string (&egps->namlng, gsd_size - 4);
+               bfd_vma align_addr;
+               size_t left;
+
+               if (offsetof (struct vms_egps, namlng) >= gsd_size)
+                 goto too_small;
+               left = gsd_size - offsetof (struct vms_egps, namlng);
+               name = _bfd_vms_save_counted_string (abfd, &egps->namlng, left);
+               if (name == NULL || name[0] == 0)
+                 return FALSE;
 
                section = bfd_make_section (abfd, name);
                if (!section)
@@ -1238,12 +1265,13 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
                section->filepos = 0;
                section->size = bfd_getl32 (egps->alloc);
-               section->alignment_power = egps->align;
+               section->alignment_power = egps->align & 31;
 
                vms_section_data (section)->flags = vms_flags;
                vms_section_data (section)->no_flags = 0;
 
-               new_flags = vms_secflag_by_name (evax_section_flags, name,
+               new_flags = vms_secflag_by_name (evax_section_flags,
+                                                section->name,
                                                 section->size > 0);
                if (section->size > 0)
                  new_flags |= SEC_LOAD;
@@ -1261,14 +1289,13 @@ _bfd_vms_slurp_egsd (bfd *abfd)
                    new_flags |= SEC_CODE;
                    new_flags &= ~SEC_DATA;
                  }
-               if (!bfd_set_section_flags (abfd, section, new_flags))
+               if (!bfd_set_section_flags (section, new_flags))
                  return FALSE;
 
                /* Give a non-overlapping vma to non absolute sections.  */
-               align_addr = (1 << section->alignment_power);
-               if ((base_addr % align_addr) != 0)
-                 base_addr += (align_addr - (base_addr % align_addr));
-               section->vma = (bfd_vma)base_addr;
+               align_addr = (bfd_vma) 1 << section->alignment_power;
+               base_addr = (base_addr + align_addr - 1) & -align_addr;
+               section->vma = base_addr;
                base_addr += section->size;
              }
 
@@ -1292,18 +1319,22 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
        case EGSD__C_SYM:
          {
-           int nameoff;
+           unsigned int nameoff;
            struct vms_symbol_entry *entry;
            struct vms_egsy *egsy = (struct vms_egsy *) vms_rec;
            flagword old_flags;
 
+           if (offsetof (struct vms_egsy, flags) + 2 > gsd_size)
+             goto too_small;
            old_flags = bfd_getl16 (egsy->flags);
            if (old_flags & EGSY__V_DEF)
              nameoff = ESDF__B_NAMLNG;
            else
              nameoff = ESRF__B_NAMLNG;
 
-           entry = add_symbol (abfd, vms_rec + nameoff);
+           if (nameoff >= gsd_size)
+             goto too_small;
+           entry = add_symbol (abfd, vms_rec + nameoff, gsd_size - nameoff);
            if (entry == NULL)
              return FALSE;
 
@@ -1320,8 +1351,7 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
            if (old_flags & EGSY__V_DEF)
              {
-               struct vms_esdf *esdf = (struct vms_esdf *)vms_rec;
-               long psindx;
+               struct vms_esdf *esdf = (struct vms_esdf *) vms_rec;
 
                entry->value = bfd_getl64 (esdf->value);
                if (PRIV (sections) == NULL)
@@ -1331,7 +1361,9 @@ _bfd_vms_slurp_egsd (bfd *abfd)
                /* PR 21813: Check for an out of range index.  */
                if (psindx < 0 || psindx >= (int) PRIV (section_count))
                  {
-                   _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"),
+                 bad_psindx:
+                   _bfd_error_handler (_("corrupt EGSD record: its psindx "
+                                         "field is too big (%#lx)"),
                                        psindx);
                    bfd_set_error (bfd_error_bad_value);
                    return FALSE;
@@ -1344,14 +1376,9 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
                    entry->code_value = bfd_getl64 (esdf->code_address);
                    psindx = bfd_getl32 (esdf->ca_psindx);
-               /* PR 21813: Check for an out of range index.  */
+                   /* PR 21813: Check for an out of range index.  */
                    if (psindx < 0 || psindx >= (int) PRIV (section_count))
-                     {
-                       _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"),
-                                           psindx);
-                       bfd_set_error (bfd_error_bad_value);
-                       return FALSE;
-                     }
+                     goto bad_psindx;
                    entry->code_section = PRIV (sections)[psindx];
                  }
              }
@@ -1363,11 +1390,13 @@ _bfd_vms_slurp_egsd (bfd *abfd)
            struct vms_symbol_entry *entry;
            struct vms_egst *egst = (struct vms_egst *)vms_rec;
            flagword old_flags;
+           unsigned int nameoff = offsetof (struct vms_egst, namlng);
 
            old_flags = bfd_getl16 (egst->header.flags);
 
-           entry = add_symbol (abfd, &egst->namlng);
-
+           if (nameoff >= gsd_size)
+             goto too_small;
+           entry = add_symbol (abfd, &egst->namlng, gsd_size - nameoff);
            if (entry == NULL)
              return FALSE;
 
@@ -1379,19 +1408,12 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
            if (old_flags & EGSY__V_REL)
              {
-               long psindx;
-
                if (PRIV (sections) == NULL)
                  return FALSE;
                psindx = bfd_getl32 (egst->psindx);
                /* PR 21813: Check for an out of range index.  */
                if (psindx < 0 || psindx >= (int) PRIV (section_count))
-                 {
-                   _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"),
-                                       psindx);
-                   bfd_set_error (bfd_error_bad_value);
-                   return FALSE;
-                 }
+                 goto bad_psindx;
                entry->section = PRIV (sections)[psindx];
              }
            else
@@ -1437,7 +1459,7 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
 /* Push value and section index.  */
 
-static void
+static bfd_boolean
 _bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc)
 {
   vms_debug2 ((4, "<push %08lx (0x%08x) at %d>\n",
@@ -1450,26 +1472,28 @@ _bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc)
     {
       bfd_set_error (bfd_error_bad_value);
       _bfd_error_handler (_("stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
-      exit (1);
+      return FALSE;
     }
+  return TRUE;
 }
 
 /* Pop value and section index.  */
 
-static void
+static bfd_boolean
 _bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel)
 {
   if (PRIV (stackptr) == 0)
     {
       bfd_set_error (bfd_error_bad_value);
       _bfd_error_handler (_("stack underflow in _bfd_vms_pop"));
-      exit (1);
+      return FALSE;
     }
   PRIV (stackptr)--;
   *val = PRIV (stack[PRIV (stackptr)]).value;
   *rel = PRIV (stack[PRIV (stackptr)]).reloc;
 
   vms_debug2 ((4, "<pop %08lx (0x%08x)>\n", (unsigned long)*val, *rel));
+  return TRUE;
 }
 
 /* Routines to fill sections contents during tir/etir read.  */
@@ -1854,19 +1878,23 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
 
   while (ptr < maxptr)
     {
-      int cmd = bfd_getl16 (ptr);
-      int cmd_length = bfd_getl16 (ptr + 2);
+      int cmd, cmd_length;
 
-      ptr += 4;
+      if (ptr + 4 > maxptr)
+       goto corrupt_etir;
+
+      cmd = bfd_getl16 (ptr);
+      cmd_length = bfd_getl16 (ptr + 2);
 
       /* PR 21589 and 21579: Check for a corrupt ETIR record.  */
-      if (cmd_length < 4 || (ptr + cmd_length > maxptr + 4))
+      if (cmd_length < 4 || ptr + cmd_length > maxptr)
        {
        corrupt_etir:
          _bfd_error_handler (_("corrupt ETIR record encountered"));
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
+      ptr += 4;
 
 #if VMS_DEBUG
       _bfd_vms_debug (4, "etir: %s(%d)\n",
@@ -1882,7 +1910,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
             stack 32 bit value of symbol (high bits set to 0).  */
        case ETIR__C_STA_GBL:
          _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
-         _bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h));
+         if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)))
+           return FALSE;
          break;
 
          /* Stack longword
@@ -1890,9 +1919,10 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
 
             stack 32 bit value, sign extend to 64 bit.  */
        case ETIR__C_STA_LW:
-         if (ptr + 4 >= maxptr)
+         if (ptr + 4 > maxptr)
            goto corrupt_etir;
-         _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE);
+         if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE))
+           return FALSE;
          break;
 
          /* Stack quadword
@@ -1900,9 +1930,10 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
 
             stack 64 bit value of symbol.  */
        case ETIR__C_STA_QW:
-         if (ptr + 8 >= maxptr)
+         if (ptr + 8 > maxptr)
            goto corrupt_etir;
-         _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE);
+         if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE))
+           return FALSE;
          break;
 
          /* Stack psect base plus quadword offset
@@ -1915,7 +1946,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          {
            int psect;
 
-           if (ptr + 12 >= maxptr)
+           if (ptr + 12 > maxptr)
              goto corrupt_etir;
            psect = bfd_getl32 (ptr);
            if ((unsigned int) psect >= PRIV (section_count))
@@ -1926,7 +1957,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
                return FALSE;
              }
            op1 = bfd_getl64 (ptr + 4);
-           _bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE);
+           if (!_bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE))
+             return FALSE;
          }
          break;
 
@@ -1941,7 +1973,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Store byte: pop stack, write byte
             arg: -.  */
        case ETIR__C_STO_B:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
          image_write_b (abfd, (unsigned int) op1 & 0xff);
@@ -1950,7 +1983,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Store word: pop stack, write word
             arg: -.  */
        case ETIR__C_STO_W:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
          image_write_w (abfd, (unsigned int) op1 & 0xffff);
@@ -1959,7 +1993,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Store longword: pop stack, write longword
             arg: -.  */
        case ETIR__C_STO_LW:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 & RELC_SEC_BASE)
            {
              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
@@ -1982,7 +2017,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Store quadword: pop stack, write quadword
             arg: -.  */
        case ETIR__C_STO_QW:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 & RELC_SEC_BASE)
            {
              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
@@ -2006,10 +2042,11 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          {
            int size;
 
-           if (ptr + 4 >= maxptr)
+           if (ptr + 4 > maxptr)
              goto corrupt_etir;
            size = bfd_getl32 (ptr);
-           _bfd_vms_pop (abfd, &op1, &rel1);
+           if (!_bfd_vms_pop (abfd, &op1, &rel1))
+             return FALSE;
            if (rel1 != RELC_NONE)
              goto bad_context;
            while (op1-- > 0)
@@ -2072,7 +2109,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Store offset to psect: pop stack, add low 32 bits to base of psect
             arg: none.  */
        case ETIR__C_STO_OFF:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
 
          if (!(rel1 & RELC_SEC_BASE))
            abort ();
@@ -2089,7 +2127,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          {
            unsigned int size;
 
-           if (ptr + 4 >= maxptr)
+           if (ptr + 4 > maxptr)
              goto corrupt_etir;
            size = bfd_getl32 (ptr);
            image_write (abfd, ptr + 4, size);
@@ -2243,7 +2281,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Det relocation base: pop stack, set image location counter
             arg: none.  */
        case ETIR__C_CTL_SETRB:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (!(rel1 & RELC_SEC_BASE))
            abort ();
          image_set_ptr (abfd, op1, rel1 & RELC_MASK, info);
@@ -2252,7 +2291,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Augment relocation base: increment image location counter by offset
             arg: lw    offset value.  */
        case ETIR__C_CTL_AUGRB:
-         if (ptr + 4 >= maxptr)
+         if (ptr + 4 > maxptr)
            goto corrupt_etir;
          op1 = bfd_getl32 (ptr);
          image_inc_ptr (abfd, op1);
@@ -2261,7 +2300,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Define location: pop index, save location counter under index
             arg: none.  */
        case ETIR__C_CTL_DFLOC:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
          dst_define_location (abfd, op1);
@@ -2270,7 +2310,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Set location: pop index, restore location counter from index
             arg: none.  */
        case ETIR__C_CTL_STLOC:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
          dst_restore_location (abfd, op1);
@@ -2279,28 +2320,34 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          /* Stack defined location: pop index, push location counter from index
             arg: none.  */
        case ETIR__C_CTL_STKDL:
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), RELC_NONE);
+         if (!_bfd_vms_push (abfd, dst_retrieve_location (abfd, op1),
+                             RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_NOP:      /* No-op.  */
          break;
 
        case ETIR__C_OPR_ADD:      /* Add.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 == RELC_NONE && rel2 != RELC_NONE)
            rel1 = rel2;
          else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, op1 + op2, rel1);
+         if (!_bfd_vms_push (abfd, op1 + op2, rel1))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_SUB:      /* Subtract.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 == RELC_NONE && rel2 != RELC_NONE)
            rel1 = rel2;
          else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE))
@@ -2311,69 +2358,90 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
            }
          else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, op2 - op1, rel1);
+         if (!_bfd_vms_push (abfd, op2 - op1, rel1))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_MUL:      /* Multiply.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, op1 * op2, RELC_NONE);
+         if (!_bfd_vms_push (abfd, op1 * op2, RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_DIV:      /* Divide.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
            goto bad_context;
          if (op2 == 0)
-           _bfd_vms_push (abfd, 0, RELC_NONE);
+           {
+             if (!_bfd_vms_push (abfd, 0, RELC_NONE))
+               return FALSE;
+           }
          else
-           _bfd_vms_push (abfd, op2 / op1, RELC_NONE);
+           {
+             if (!_bfd_vms_push (abfd, op2 / op1, RELC_NONE))
+               return FALSE;
+           }
          break;
 
        case ETIR__C_OPR_AND:      /* Logical AND.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, op1 & op2, RELC_NONE);
+         if (!_bfd_vms_push (abfd, op1 & op2, RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_IOR:      /* Logical inclusive OR.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, op1 | op2, RELC_NONE);
+         if (!_bfd_vms_push (abfd, op1 | op2, RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_EOR:      /* Logical exclusive OR.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, op1 ^ op2, RELC_NONE);
+         if (!_bfd_vms_push (abfd, op1 ^ op2, RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_NEG:      /* Negate.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, -op1, RELC_NONE);
+         if (!_bfd_vms_push (abfd, -op1, RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_COM:      /* Complement.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
-         _bfd_vms_push (abfd, ~op1, RELC_NONE);
+         if (!_bfd_vms_push (abfd, ~op1, RELC_NONE))
+           return FALSE;
          break;
 
        case ETIR__C_OPR_ASH:      /* Arithmetic shift.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
-         _bfd_vms_pop (abfd, &op2, &rel2);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
            {
            bad_context:
@@ -2385,7 +2453,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
            op1 >>= -(int)op2;
          else                  /* Shift left.  */
            op1 <<= (int)op2;
-         _bfd_vms_push (abfd, op1, RELC_NONE); /* FIXME: sym.  */
+         if (!_bfd_vms_push (abfd, op1, RELC_NONE)) /* FIXME: sym.  */
+           return FALSE;
          break;
 
        case ETIR__C_OPR_INSV:      /* Insert field.   */
@@ -2399,14 +2468,20 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
          break;
 
        case ETIR__C_OPR_SEL:      /* Select.  */
-         _bfd_vms_pop (abfd, &op1, &rel1);
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
          if (op1 & 0x01L)
-           _bfd_vms_pop (abfd, &op1, &rel1);
+           {
+             if (!_bfd_vms_pop (abfd, &op1, &rel1))
+               return FALSE;
+           }
          else
            {
-             _bfd_vms_pop (abfd, &op1, &rel1);
-             _bfd_vms_pop (abfd, &op2, &rel2);
-             _bfd_vms_push (abfd, op1, rel1);
+             if (!_bfd_vms_pop (abfd, &op1, &rel1)
+                 || !_bfd_vms_pop (abfd, &op2, &rel2))
+               return FALSE;
+             if (!_bfd_vms_push (abfd, op1, rel1))
+               return FALSE;
            }
          break;
 
@@ -2441,7 +2516,7 @@ vms_slurp_debug (bfd *abfd)
       section = bfd_make_section (abfd, "$DST$");
       if (!section)
        return FALSE;
-      if (!bfd_set_section_flags (abfd, section, flags))
+      if (!bfd_set_section_flags (section, flags))
        return FALSE;
       PRIV (dst_section) = section;
     }
@@ -2601,6 +2676,22 @@ vms_initialize (bfd * abfd)
   return FALSE;
 }
 
+/* Free malloc'd memory.  */
+
+static void
+alpha_vms_free_private (bfd *abfd)
+{
+  struct module *module;
+
+  free (PRIV (recrd.buf));
+  free (PRIV (sections));
+  free (PRIV (syms));
+  free (PRIV (dst_ptr_offsets));
+
+  for (module = PRIV (modules); module; module = module->next)
+    free (module->file_table);
+}
+
 /* Check the format for a file being read.
    Return a (bfd_target *) if it's an object file or zero if not.  */
 
@@ -2615,7 +2706,10 @@ alpha_vms_object_p (bfd *abfd)
 
   /* Allocate alpha-vms specific data.  */
   if (!vms_initialize (abfd))
-    goto error_ret;
+    {
+      abfd->tdata.any = tdata_save;
+      return NULL;
+    }
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
     goto err_wrong_format;
@@ -2755,8 +2849,7 @@ alpha_vms_object_p (bfd *abfd)
   bfd_set_error (bfd_error_wrong_format);
 
  error_ret:
-  if (PRIV (recrd.buf))
-    free (PRIV (recrd.buf));
+  alpha_vms_free_private (abfd);
   if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
     bfd_release (abfd, abfd->tdata.any);
   abfd->tdata.any = tdata_save;
@@ -4204,7 +4297,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
        {
        case DST__K_MODBEG:
          module->name
-           = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME,
+           = _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_MODBEG_NAME,
                                            maxptr - (ptr + DST_S_B_MODBEG_NAME));
 
          curr_pc = 0;
@@ -4222,7 +4315,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
          funcinfo = (struct funcinfo *)
            bfd_zalloc (abfd, sizeof (struct funcinfo));
          funcinfo->name
-           = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME,
+           = _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_RTNBEG_NAME,
                                            maxptr - (ptr + DST_S_B_RTNBEG_NAME));
          funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
          funcinfo->next = module->func_table;
@@ -4273,11 +4366,10 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
                  {
                    unsigned int fileid
                      = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
-                   char *filename
-                     = _bfd_vms_save_counted_string (src_ptr + DST_S_B_SRC_DF_FILENAME,
-                                                     (ptr + rec_length) -
-                                                     (src_ptr + DST_S_B_SRC_DF_FILENAME)
-                                                     );
+                   char *filename = _bfd_vms_save_counted_string
+                     (abfd,
+                      src_ptr + DST_S_B_SRC_DF_FILENAME,
+                      ptr + rec_length - (src_ptr + DST_S_B_SRC_DF_FILENAME));
 
                    while (fileid >= module->file_table_count)
                      {
@@ -4623,7 +4715,7 @@ build_module_list (bfd *abfd)
         section and build the list of modules.  This is sufficient
         since we can compute the start address and the end address
         of every module from the section contents.  */
-      bfd_size_type size = bfd_get_section_size (dmt);
+      bfd_size_type size = bfd_section_size (dmt);
       unsigned char *ptr, *end;
 
       ptr = (unsigned char *) bfd_alloc (abfd, size);
@@ -6615,7 +6707,7 @@ evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel,
          fprintf (file, _("   bitmap: 0x%08x (count: %u):\n"), val, count);
 
          for (k = 0; k < 32; k++)
-           if (val & (1 << k))
+           if (val & (1u << k))
              {
                if (n == 0)
                  fputs ("   ", file);
@@ -8336,6 +8428,27 @@ alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry,
   return (struct bfd_hash_entry *) ret;
 }
 
+static void
+alpha_vms_bfd_link_hash_table_free (bfd *abfd)
+{
+  struct alpha_vms_link_hash_table *t;
+  unsigned i;
+
+  t = (struct alpha_vms_link_hash_table *) abfd->link.hash;
+  for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+    {
+      struct alpha_vms_shlib_el *shlib;
+
+      shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+      free (&VEC_EL (shlib->ca, bfd_vma, 0));
+      free (&VEC_EL (shlib->lp, bfd_vma, 0));
+      free (&VEC_EL (shlib->qr, struct alpha_vms_vma_ref, 0));
+    }
+  free (&VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, 0));
+
+  _bfd_generic_link_hash_table_free (abfd);
+}
+
 /* Create an Alpha/VMS link hash table.  */
 
 static struct bfd_link_hash_table *
@@ -8357,6 +8470,7 @@ alpha_vms_bfd_link_hash_table_create (bfd *abfd)
 
   VEC_INIT (ret->shrlibs);
   ret->fixup = NULL;
+  ret->root.hash_table_free = alpha_vms_bfd_link_hash_table_free;
 
   return &ret->root;
 }
@@ -8912,8 +9026,8 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
       return FALSE;
     }
 
-  bfd_get_outsymbols (abfd) = NULL;
-  bfd_get_symcount (abfd) = 0;
+  abfd->outsymbols = NULL;
+  abfd->symcount = 0;
 
   /* Mark all sections which will be included in the output file.  */
   for (o = abfd->sections; o != NULL; o = o->next)
@@ -9283,35 +9397,24 @@ vms_close_and_cleanup (bfd * abfd)
   if (abfd == NULL || abfd->tdata.any == NULL)
     return TRUE;
 
-  if (abfd->format == bfd_archive)
+  if (abfd->format == bfd_object)
     {
-      bfd_release (abfd, abfd->tdata.any);
-      abfd->tdata.any = NULL;
-      return TRUE;
-    }
-
-  if (PRIV (recrd.buf) != NULL)
-    free (PRIV (recrd.buf));
-
-  if (PRIV (sections) != NULL)
-    free (PRIV (sections));
-
-  bfd_release (abfd, abfd->tdata.any);
-  abfd->tdata.any = NULL;
+      alpha_vms_free_private (abfd);
 
 #ifdef VMS
-  if (abfd->direction == write_direction)
-    {
-      /* Last step on VMS is to convert the file to variable record length
-        format.  */
-      if (!bfd_cache_close (abfd))
-       return FALSE;
-      if (!_bfd_vms_convert_to_var_unix_filename (abfd->filename))
-       return FALSE;
-    }
+      if (abfd->direction == write_direction)
+       {
+         /* Last step on VMS is to convert the file to variable record length
+            format.  */
+         if (!bfd_cache_close (abfd))
+           return FALSE;
+         if (!_bfd_vms_convert_to_var_unix_filename (abfd->filename))
+           return FALSE;
+       }
 #endif
+    }
 
-  return TRUE;
+  return _bfd_generic_close_and_cleanup (abfd);
 }
 
 /* Called when a new section is created.  */
@@ -9324,7 +9427,7 @@ vms_new_section_hook (bfd * abfd, asection *section)
   vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n",
               abfd, section->index, section->name));
 
-  if (! bfd_set_section_alignment (abfd, section, 0))
+  if (!bfd_set_section_alignment (section, 0))
     return FALSE;
 
   vms_debug2 ((7, "%u: %s\n", section->index, section->name));
@@ -9412,11 +9515,11 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
   else if (bfd_is_ind_section (sec))
     ret->type = 'I';
   else if ((symbol->flags & BSF_FUNCTION)
-          || (bfd_get_section_flags (abfd, sec) & SEC_CODE))
+          || (bfd_section_flags (sec) & SEC_CODE))
     ret->type = 'T';
-  else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+  else if (bfd_section_flags (sec) & SEC_DATA)
     ret->type = 'D';
-  else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+  else if (bfd_section_flags (sec) & SEC_ALLOC)
     ret->type = 'B';
   else
     ret->type = '?';
This page took 0.038164 seconds and 4 git commands to generate.