+2020-03-16  Alan Modra  <amodra@gmail.com>
+
+       * vms-alpha.c (dst_restore_location): Validate index into
+       dst_ptr_offsets array before accessing.  Return status.
+       (dst_retrieve_location): Similarly, making "loc" parameter a
+       pointer to return value.
+       (_bfd_vms_slurp_etir): Update calls to above functions.
+
 2020-03-14  Kamil Rytarowski  <n54@gmx.com>
 
        * configure.ac: Include netbsd-core.lo for all NetBSD arm and mips
 
 
 /* Restore saved DST location counter from specified index.  */
 
-static void
+static bfd_boolean
 dst_restore_location (bfd *abfd, unsigned int loc)
 {
   vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc));
 
-  PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
+  if (loc < PRIV (dst_ptr_offsets_count))
+    {
+      PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
+      return TRUE;
+    }
+  return FALSE;
 }
 
 /* Retrieve saved DST location counter from specified index.  */
 
-static unsigned int
-dst_retrieve_location (bfd *abfd, unsigned int loc)
+static bfd_boolean
+dst_retrieve_location (bfd *abfd, bfd_vma *loc)
 {
-  vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc));
+  vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int) *loc));
 
-  return PRIV (dst_ptr_offsets)[loc];
+  if (*loc < PRIV (dst_ptr_offsets_count))
+    {
+      *loc = PRIV (dst_ptr_offsets)[*loc];
+      return TRUE;
+    }
+  return FALSE;
 }
 
 /* Write multiple bytes to section image.  */
            return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
-         dst_restore_location (abfd, op1);
+         if (!dst_restore_location (abfd, op1))
+           {
+             bfd_set_error (bfd_error_bad_value);
+             _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STLOC");
+             return FALSE;
+           }
          break;
 
          /* Stack defined location: pop index, push location counter from index
            return FALSE;
          if (rel1 != RELC_NONE)
            goto bad_context;
-         if (!_bfd_vms_push (abfd, dst_retrieve_location (abfd, op1),
-                             RELC_NONE))
+         if (!dst_retrieve_location (abfd, &op1))
+           {
+             bfd_set_error (bfd_error_bad_value);
+             _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STKDL");
+             return FALSE;
+           }
+         if (!_bfd_vms_push (abfd, op1, RELC_NONE))
            return FALSE;
          break;