Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / vms-alpha.c
index cf4cc061c69bebdade6ccf79de6f96110a7272c9..8e923d2c7926913035dcfada27ebd0c94b64b85f 100644 (file)
@@ -1,6 +1,5 @@
 /* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009, 2010 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.
    MA 02110-1301, USA.  */
 
 /* TODO:
-   o  DMT
+   o  overlayed sections
    o  PIC
    o  Generation of shared image
-   o  Generation of GST in image
    o  Relocation optimizations
    o  EISD for the stack
    o  Vectors isect
    o  64 bits sections
    o  Entry point
+   o  LIB$INITIALIZE
+   o  protected sections (for messages)
    ...
 */
 
 
 /* Debugger symbol definitions.  */
 
-#define DBG_S_L_DMT_MODBEG       0
-#define DBG_S_L_DST_SIZE         4
-#define DBG_S_W_DMT_PSECT_COUNT  8
+#define DBG_S_L_DMT_MODBEG      0
+#define DBG_S_L_DST_SIZE        4
+#define DBG_S_W_DMT_PSECT_COUNT         8
 #define DBG_S_C_DMT_HEADER_SIZE 12
 
-#define DBG_S_L_DMT_PSECT_START  0
+#define DBG_S_L_DMT_PSECT_START         0
 #define DBG_S_L_DMT_PSECT_LENGTH 4
-#define DBG_S_C_DMT_PSECT_SIZE   8
+#define DBG_S_C_DMT_PSECT_SIZE  8
 
 /* VMS module header.  */
 
@@ -167,11 +167,11 @@ struct vms_symbol_entry
   unsigned short flags;
 
   /* Section and offset/value of the symbol.  */
-  unsigned int section;
   unsigned int value;
+  asection *section;
 
   /* Section and offset/value for the entry point (only for subprg).  */
-  unsigned int code_section;
+  asection *code_section;
   unsigned int code_value;
 
   /* Symbol vector offset.  */
@@ -271,8 +271,14 @@ struct vms_private_data_struct
 
   struct hdr_struct hdr_data;          /* data from HDR/EMH record  */
   struct eom_struct eom_data;          /* data from EOM/EEOM record  */
-  unsigned int section_count;          /* # of sections in following array  */
-  asection **sections;                 /* array of GSD/EGSD sections  */
+
+  /* Transfer addresses (entry points).  */
+  bfd_vma transfer_address[4];
+
+  /* Array of GSD sections to get the correspond BFD one.  */
+  unsigned int section_max;            /* Size of the sections array.  */
+  unsigned int section_count;          /* Number of GSD sections.  */
+  asection **sections;
 
   /* Array of raw symbols.  */
   struct vms_symbol_entry **syms;
@@ -297,7 +303,7 @@ struct vms_private_data_struct
 
   struct module *modules;              /* list of all compilation units */
 
-  struct dst_info *dst_info;
+  /* The DST section.  */
   asection *dst_section;
 
   unsigned int dst_ptr_offsets_count;  /* # of offsets in following array  */
@@ -323,11 +329,7 @@ struct vms_private_data_struct
   struct vms_internal_eisd_map *gbl_eisd_tail;
 
   /* linkage index counter used by conditional store commands */
-  int vms_linkage_index;
-
-  /* see tc-alpha.c of gas for a description.  */
-  int flag_hash_long_names;    /* -+, hash instead of truncate */
-  int flag_show_after_trunc;   /* -H, show hashing/truncation */
+  unsigned int vms_linkage_index;
 };
 
 #define PRIV2(abfd, name) \
@@ -362,18 +364,20 @@ struct vms_section_data_struct
   ((struct vms_section_data_struct *)sec->used_by_bfd)
 
 /* To be called from the debugger.  */
-struct vms_private_data_struct *bfd_vms_get_data (bfd *abfd);
+struct vms_private_data_struct *bfd_vms_get_data (bfd *);
 
-static int vms_get_remaining_object_record (bfd *abfd, int read_so_far);
+static int vms_get_remaining_object_record (bfd *, unsigned int);
 static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd);
-static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *);
-static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *);
-static void alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *,
-                                    bfd_vma);
-static void alpha_vms_add_lw_reloc (struct bfd_link_info *info);
-static void alpha_vms_add_qw_reloc (struct bfd_link_info *info);
-static void alpha_vms_add_lw_fixup (struct bfd_link_info *, unsigned int,
-                                    bfd_vma);
+static bfd_boolean alpha_vms_add_fixup_lp (struct bfd_link_info *,
+                                          bfd *, bfd *);
+static bfd_boolean alpha_vms_add_fixup_ca (struct bfd_link_info *,
+                                          bfd *, bfd *);
+static bfd_boolean alpha_vms_add_fixup_qr (struct bfd_link_info *,
+                                          bfd *, bfd *, bfd_vma);
+static bfd_boolean alpha_vms_add_fixup_lr (struct bfd_link_info *,
+                                          unsigned int, bfd_vma);
+static bfd_boolean alpha_vms_add_lw_reloc (struct bfd_link_info *);
+static bfd_boolean alpha_vms_add_qw_reloc (struct bfd_link_info *);
 
 struct vector_type
 {
@@ -390,26 +394,21 @@ struct vector_type
 
 #define VEC_EL(VEC, TYPE, N) (((TYPE *)((VEC).els))[N])
 
-#define VEC_INIT(VEC)                           \
-  do {                                          \
-    (VEC).max_el = 0;                           \
-    (VEC).nbr_el = 0;                           \
-    (VEC).els = NULL;                           \
+#define VEC_INIT(VEC)                          \
+  do {                                         \
+    (VEC).max_el = 0;                          \
+    (VEC).nbr_el = 0;                          \
+    (VEC).els = NULL;                          \
   } while (0)
 
 /* Be sure there is room for a new element.  */
 
-static void vector_grow1 (struct vector_type *vec, size_t elsz);
+static void *vector_grow1 (struct vector_type *vec, size_t elsz);
 
 /* Allocate room for a new element and return its address.  */
 
-#define VEC_APPEND(VEC, TYPE)                                   \
-  (vector_grow1 (&VEC, sizeof (TYPE)), &VEC_EL(VEC, TYPE, (VEC).nbr_el++))
-
-/* Append an element.  */
-
-#define VEC_APPEND_EL(VEC, TYPE, EL)            \
-  (*(VEC_APPEND (VEC, TYPE)) = EL)
+#define VEC_APPEND(VEC, TYPE)                                  \
+  ((TYPE *) vector_grow1 (&VEC, sizeof (TYPE)))
 
 struct alpha_vms_vma_ref
 {
@@ -433,7 +432,7 @@ struct alpha_vms_link_hash_table
 {
   struct bfd_link_hash_table root;
 
-  /* Vector of shared libaries.  */
+  /* Vector of shared libraries.  */
   struct vector_type shrlibs;
 
   /* Fixup section.  */
@@ -463,7 +462,7 @@ struct alpha_vms_link_hash_entry
 
 static bfd_boolean
 _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
-                     unsigned int *eihs_offset)
+                    unsigned int *eihs_offset)
 {
   unsigned int imgtype, size;
   bfd_vma symvva;
@@ -471,6 +470,14 @@ _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
 
   vms_debug2 ((8, "_bfd_vms_slurp_eihd\n"));
 
+  /* PR 21813: Check for an undersized record.  */
+  if (PRIV (recrd.buf_size) < sizeof (* eihd))
+    {
+      _bfd_error_handler (_("corrupt EIHD record - size is too small"));
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
   size = bfd_getl32 (eihd->size);
   imgtype = bfd_getl32 (eihd->imgtype);
 
@@ -491,8 +498,9 @@ _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
   *eihs_offset = bfd_getl32 (eihd->symdbgoff);
 
   vms_debug2 ((4, "EIHD size %d imgtype %d symvva 0x%lx eisd %d eihs %d\n",
-               size, imgtype, (unsigned long)symvva,
-               *eisd_offset, *eihs_offset));
+              size, imgtype, (unsigned long)symvva,
+              *eisd_offset, *eihs_offset));
+  (void) size;
 
   return TRUE;
 }
@@ -512,27 +520,38 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
       struct vms_eisd *eisd;
       unsigned int rec_size;
       unsigned int size;
-      unsigned long long vaddr;
+      bfd_uint64_t vaddr;
       unsigned int flags;
       unsigned int vbn;
       char *name = NULL;
       asection *section;
       flagword bfd_flags;
 
-      eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset);
+      /* 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);
       rec_size = bfd_getl32 (eisd->eisdsize);
-
       if (rec_size == 0)
-        break;
+       break;
 
       /* Skip to next block if pad.  */
       if (rec_size == 0xffffffff)
-        {
-          offset = (offset + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
-          continue;
-        }
-      else
-        offset += rec_size;
+       {
+         offset = (offset + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+         continue;
+       }
+
+      /* Make sure that there is enough data present in the record.  */
+      if (rec_size < offsetof (struct vms_eisd, type) + 1)
+       return FALSE;
+      /* Make sure that the record is not too big either.  */
+      if (rec_size > PRIV (recrd.rec_size) - offset)
+       return FALSE;
+
+      offset += rec_size;
 
       size = bfd_getl32 (eisd->secsize);
       vaddr = bfd_getl64 (eisd->virt_addr);
@@ -540,19 +559,21 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
       vbn = bfd_getl32 (eisd->vbn);
 
       vms_debug2 ((4, "EISD at 0x%x size 0x%x addr 0x%lx flags 0x%x blk %d\n",
-                   offset, size, (unsigned long)vaddr, flags, vbn));
+                  offset, size, (unsigned long)vaddr, flags, vbn));
 
       /* VMS combines psects from .obj files into isects in the .exe.  This
         process doesn't preserve enough information to reliably determine
         what's in each section without examining the data.  This is
         especially true of DWARF debug sections.  */
       bfd_flags = SEC_ALLOC;
+      if (vbn != 0)
+       bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
 
       if (flags & EISD__M_EXE)
-       bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
+       bfd_flags |= SEC_CODE;
 
       if (flags & EISD__M_NONSHRADR)
-       bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
+       bfd_flags |= SEC_DATA;
 
       if (!(flags & EISD__M_WRT))
        bfd_flags |= SEC_READONLY;
@@ -561,35 +582,46 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
        bfd_flags |= SEC_DATA;
 
       if (flags & EISD__M_FIXUPVEC)
-       bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
+       bfd_flags |= SEC_DATA;
 
       if (flags & EISD__M_CRF)
-       bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
+       bfd_flags |= SEC_DATA;
 
       if (flags & EISD__M_GBL)
        {
-         name = _bfd_vms_save_counted_string (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 (abfd, eisd->gblnam,
+                                                rec_size - offsetof (struct vms_eisd, gblnam));
+         else
+           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);
        }
       else if (flags & EISD__M_FIXUPVEC)
-        name = "$FIXUPVEC$";
+       name = "$FIXUPVEC$";
       else if (eisd->type == EISD__K_USRSTACK)
-        name = "$STACK$";
+       name = "$STACK$";
       else
        {
-          const char *pfx;
-
-         name = (char*) bfd_alloc (abfd, 32);
-          if (flags & EISD__M_DZRO)
-            pfx = "BSS";
-          else if (flags & EISD__M_EXE)
-            pfx = "CODE";
-          else if (!(flags & EISD__M_WRT))
-            pfx = "RO";
-          else
-            pfx = "LOCAL";
-          BFD_ASSERT (section_count < 999);
+         const char *pfx;
+
+         name = (char *) bfd_alloc (abfd, 32);
+         if (name == NULL)
+           return FALSE;
+         if (flags & EISD__M_DZRO)
+           pfx = "BSS";
+         else if (flags & EISD__M_EXE)
+           pfx = "CODE";
+         else if (!(flags & EISD__M_WRT))
+           pfx = "RO";
+         else
+           pfx = "LOCAL";
+         BFD_ASSERT (section_count < 999);
          sprintf (name, "$%s_%03d$", pfx, section_count++);
        }
 
@@ -602,7 +634,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;
     }
 
@@ -616,14 +648,30 @@ static bfd_boolean
 _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
 {
   unsigned char *p = PRIV (recrd.rec) + offset;
-  unsigned int gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN);
-  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS__L_GSTSIZE);
-  unsigned int dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN);
-  unsigned int dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE);
-  unsigned int dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN);
-  unsigned int dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
+  unsigned int gstvbn;
+  unsigned int gstsize ATTRIBUTE_UNUSED;
+  unsigned int dstvbn;
+  unsigned int dstsize;
+  unsigned int dmtvbn;
+  unsigned int dmtbytes;
   asection *section;
 
+  /* PR 21611: Check that offset is valid.  */
+  if (offset > PRIV (recrd.rec_size) - (EIHS__L_DMTBYTES + 4))
+    {
+      _bfd_error_handler (_("unable to read EIHS record at offset %#x"),
+                         offset);
+      bfd_set_error (bfd_error_file_truncated);
+      return FALSE;
+    }
+
+  gstvbn   = bfd_getl32 (p + EIHS__L_GSTVBN);
+  gstsize  = bfd_getl32 (p + EIHS__L_GSTSIZE);
+  dstvbn   = bfd_getl32 (p + EIHS__L_DSTVBN);
+  dstsize  = bfd_getl32 (p + EIHS__L_DSTSIZE);
+  dmtvbn   = bfd_getl32 (p + EIHS__L_DMTVBN);
+  dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
+
 #if VMS_DEBUG
   vms_debug (8, "_bfd_vms_slurp_ihs\n");
   vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
@@ -641,7 +689,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;
@@ -659,31 +707,19 @@ _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;
     }
 
   if (gstvbn)
     {
-      flagword bfd_flags = SEC_HAS_CONTENTS;
-
-      section = bfd_make_section (abfd, "$GST$");
-      if (!section)
-       return FALSE;
-
       if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
        {
          bfd_set_error (bfd_error_file_truncated);
          return FALSE;
        }
 
-      if (_bfd_vms_slurp_object_records (abfd) != TRUE)
-       return FALSE;
-
-      section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
-      section->size = bfd_tell (abfd) - section->filepos;
-
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+      if (!_bfd_vms_slurp_object_records (abfd))
        return FALSE;
 
       abfd->flags |= HAS_SYMS;
@@ -764,10 +800,10 @@ _bfd_vms_get_object_record (bfd *abfd)
   if (PRIV (recrd.file_format) == FF_FOREIGN && (bfd_tell (abfd) & 1))
     {
       if (bfd_bread (PRIV (recrd.buf), 1, abfd) != 1)
-        {
-          bfd_set_error (bfd_error_file_truncated);
-          return -1;
-        }
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         return -1;
+       }
     }
 
   /* Read the record header  */
@@ -787,7 +823,7 @@ _bfd_vms_get_object_record (bfd *abfd)
   type = bfd_getl16 (PRIV (recrd.rec));
 
   vms_debug2 ((8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
-               PRIV (recrd.rec), PRIV (recrd.rec_size), type));
+              PRIV (recrd.rec), PRIV (recrd.rec_size), type));
 
   return type;
 }
@@ -796,7 +832,7 @@ _bfd_vms_get_object_record (bfd *abfd)
    Return the size of the record or 0 on failure.  */
 
 static int
-vms_get_remaining_object_record (bfd *abfd, int read_so_far)
+vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far)
 {
   unsigned int to_read;
 
@@ -805,7 +841,7 @@ vms_get_remaining_object_record (bfd *abfd, int read_so_far)
   /* Extract record size.  */
   PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2);
 
-  if (PRIV (recrd.rec_size) <= 0)
+  if (PRIV (recrd.rec_size) == 0)
     {
       bfd_set_error (bfd_error_file_truncated);
       return 0;
@@ -827,11 +863,14 @@ vms_get_remaining_object_record (bfd *abfd, int read_so_far)
   if (to_read > PRIV (recrd.buf_size))
     {
       PRIV (recrd.buf)
-        = (unsigned char *) bfd_realloc (PRIV (recrd.buf), to_read);
+       = (unsigned char *) bfd_realloc_or_free (PRIV (recrd.buf), to_read);
       if (PRIV (recrd.buf) == NULL)
-        return 0;
+       return 0;
       PRIV (recrd.buf_size) = to_read;
     }
+  /* PR 17512: file: 025-1974-0.004.  */
+  else if (to_read <= read_so_far)
+    return 0;
 
   /* Read the remaining record.  */
   to_read -= read_so_far;
@@ -849,7 +888,7 @@ vms_get_remaining_object_record (bfd *abfd, int read_so_far)
   maybe_adjust_record_pointer_for_object (abfd);
 
   vms_debug2 ((8, "vms_get_remaining_obj_record: size %d\n",
-               PRIV (recrd.rec_size)));
+              PRIV (recrd.rec_size)));
 
   return PRIV (recrd.rec_size);
 }
@@ -862,9 +901,12 @@ _bfd_vms_slurp_ehdr (bfd *abfd)
 {
   unsigned char *ptr;
   unsigned char *vms_rec;
+  unsigned char *end;
   int subtype;
 
   vms_rec = PRIV (recrd.rec);
+  /* PR 17512: file: 62736583.  */
+  end = PRIV (recrd.buf) + PRIV (recrd.buf_size);
 
   vms_debug2 ((2, "HDR/EMH\n"));
 
@@ -876,30 +918,47 @@ _bfd_vms_slurp_ehdr (bfd *abfd)
     {
     case EMH__C_MHD:
       /* Module header.  */
+      if (vms_rec + 21 >= end)
+       goto fail;
       PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
       PRIV (hdr_data).hdr_l_arch1  = bfd_getl32 (vms_rec + 8);
       PRIV (hdr_data).hdr_l_arch2  = bfd_getl32 (vms_rec + 12);
       PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
-      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20);
+      if ((vms_rec + 20 + vms_rec[20] + 1) >= end)
+       goto fail;
+      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;
-      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
+      if ((ptr + *ptr + 1) >= end)
+       goto fail;
+      PRIV (hdr_data).hdr_t_version
+       = _bfd_vms_save_counted_string (abfd, ptr, *ptr);
       ptr += *ptr + 1;
-      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
+      if (ptr + 17 >= end)
+       goto fail;
+      PRIV (hdr_data).hdr_t_date
+       = _bfd_vms_save_sized_string (abfd, ptr, 17);
       break;
 
     case EMH__C_LNM:
-      PRIV (hdr_data).hdr_c_lnm =
-        _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      if (vms_rec + PRIV (recrd.rec_size - 6) > end)
+       goto fail;
+      PRIV (hdr_data).hdr_c_lnm
+       = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
       break;
 
     case EMH__C_SRC:
-      PRIV (hdr_data).hdr_c_src =
-        _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      if (vms_rec + PRIV (recrd.rec_size - 6) > end)
+       goto fail;
+      PRIV (hdr_data).hdr_c_src
+       = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
       break;
 
     case EMH__C_TTL:
-      PRIV (hdr_data).hdr_c_ttl =
-        _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      if (vms_rec + PRIV (recrd.rec_size - 6) > end)
+       goto fail;
+      PRIV (hdr_data).hdr_c_ttl
+       = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
       break;
 
     case EMH__C_CPR:
@@ -908,6 +967,7 @@ _bfd_vms_slurp_ehdr (bfd *abfd)
       break;
 
     default:
+    fail:
       bfd_set_error (bfd_error_wrong_format);
       return FALSE;
     }
@@ -940,71 +1000,70 @@ struct sec_flags_struct
 
 /* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible.  */
 
-static struct sec_flags_struct evax_section_flags[] =
+static const struct sec_flags_struct evax_section_flags[] =
   {
     { EVAX_ABS_NAME,
-      (EGPS__V_SHR),
-      (SEC_DATA),
-      (EGPS__V_SHR),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+      EGPS__V_SHR,
+      0,
+      EGPS__V_SHR,
+      0 },
     { EVAX_CODE_NAME,
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE),
-      (SEC_CODE),
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE),
-      (SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
+      SEC_CODE | SEC_READONLY,
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
+      SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_LITERAL_NAME,
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
+      SEC_DATA | SEC_READONLY,
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
+      SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_LINK_NAME,
-      (EGPS__V_REL | EGPS__V_RD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS__V_REL | EGPS__V_RD),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+      EGPS__V_REL | EGPS__V_RD,
+      SEC_DATA | SEC_READONLY,
+      EGPS__V_REL | EGPS__V_RD,
+      SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_DATA_NAME,
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD),
-      (SEC_DATA),
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
+      SEC_DATA,
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+      SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_BSS_NAME,
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD),
-      (SEC_NO_FLAGS),
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD),
-      (SEC_ALLOC) },
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
+      SEC_NO_FLAGS,
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
+      SEC_ALLOC },
     { EVAX_READONLYADDR_NAME,
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
+      SEC_DATA | SEC_READONLY,
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
+      SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_READONLY_NAME,
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
+      SEC_DATA | SEC_READONLY,
+      EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
+      SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_LOCAL_NAME,
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
-      (SEC_DATA),
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+      SEC_DATA,
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+      SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { EVAX_LITERALS_NAME,
-      (EGPS__V_PIC | EGPS__V_OVR),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS__V_PIC | EGPS__V_OVR),
-      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+      EGPS__V_PIC | EGPS__V_OVR,
+      SEC_DATA | SEC_READONLY,
+      EGPS__V_PIC | EGPS__V_OVR,
+      SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
     { NULL,
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
-      (SEC_DATA),
-      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+      SEC_DATA,
+      EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+      SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }
   };
 
-/* Retrieve bfd section flags by name and size.  */
+/* Retrieve BFD section flags by name and size.  */
 
 static flagword
-vms_secflag_by_name (bfd *abfd ATTRIBUTE_UNUSED,
-                    struct sec_flags_struct *section_flags,
-                    char *name,
+vms_secflag_by_name (const struct sec_flags_struct *section_flags,
+                    const char *name,
                     int hassize)
 {
   int i = 0;
@@ -1012,7 +1071,7 @@ vms_secflag_by_name (bfd *abfd ATTRIBUTE_UNUSED,
   while (section_flags[i].name != NULL)
     {
       if (strcmp (name, section_flags[i].name) == 0)
-        {
+       {
          if (hassize)
            return section_flags[i].flags_hassize;
          else
@@ -1025,11 +1084,11 @@ vms_secflag_by_name (bfd *abfd ATTRIBUTE_UNUSED,
   return section_flags[i].flags_always;
 }
 
-/* Retrieve vms section flags by name and size.  */
+/* Retrieve VMS section flags by name and size.  */
 
 static flagword
-vms_esecflag_by_name (struct sec_flags_struct *section_flags,
-                     char *name,
+vms_esecflag_by_name (const struct sec_flags_struct *section_flags,
+                     const char *name,
                      int hassize)
 {
   int i = 0;
@@ -1050,15 +1109,53 @@ vms_esecflag_by_name (struct sec_flags_struct *section_flags,
   return section_flags[i].vflags_always;
 }
 
-/* Input routines.  */
+/* Add SYM to the symbol table of ABFD.
+   Return FALSE in case of error.  */
+
+static bfd_boolean
+add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym)
+{
+  if (PRIV (gsd_sym_count) >= PRIV (max_sym_count))
+    {
+      if (PRIV (max_sym_count) == 0)
+       {
+         PRIV (max_sym_count) = 128;
+         PRIV (syms) = bfd_malloc
+           (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *));
+       }
+      else
+       {
+         PRIV (max_sym_count) *= 2;
+         PRIV (syms) = bfd_realloc_or_free
+           (PRIV (syms),
+            (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *)));
+       }
+      if (PRIV (syms) == NULL)
+       return FALSE;
+    }
+
+  PRIV (syms)[PRIV (gsd_sym_count)++] = sym;
+  return TRUE;
+}
+
+/* Create a symbol whose name is ASCIC and add it to ABFD.
+   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;
@@ -1067,51 +1164,39 @@ add_symbol (bfd *abfd, const unsigned char *ascic)
   entry->name[len] = 0;
   entry->owner = abfd;
 
-  if (PRIV (gsd_sym_count) >= PRIV (max_sym_count))
-    {
-      if (PRIV (max_sym_count) == 0)
-        {
-          PRIV (max_sym_count) = 128;
-          PRIV (syms) = bfd_malloc
-            (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *));
-        }
-      else
-        {
-          PRIV (max_sym_count) *= 2;
-          PRIV (syms) = bfd_realloc
-            (PRIV (syms),
-             (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *)));
-        }
-      if (PRIV (syms) == NULL)
-        return NULL;
-    }
-
-  PRIV (syms)[PRIV (gsd_sym_count)++] = entry;
+  if (!add_symbol_entry (abfd, entry))
+    return NULL;
   return entry;
 }
 
 /* Read and process EGSD.  Return FALSE on failure.  */
 
 static bfd_boolean
-_bfd_vms_slurp_egsd (bfd * abfd)
+_bfd_vms_slurp_egsd (bfd *abfd)
 {
-  int gsd_type, gsd_size;
-  asection *section;
+  int gsd_type;
+  unsigned int gsd_size;
   unsigned char *vms_rec;
-  flagword new_flags, old_flags;
-  char *name;
-  unsigned long base_addr;
-  unsigned long align_addr;
+  bfd_vma base_addr;
+  long psindx;
 
   vms_debug2 ((2, "EGSD\n"));
 
+  if (PRIV (recrd.rec_size) < 8)
+    {
+      _bfd_error_handler (_("corrupt EGSD record: its size (%#x) is too small"),
+                         PRIV (recrd.rec_size));
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
   PRIV (recrd.rec) += 8;       /* Skip type, size, align pad.  */
   PRIV (recrd.rec_size) -= 8;
 
   /* Calculate base address for each section.  */
-  base_addr = 0L;
+  base_addr = 0;
 
-  while (PRIV (recrd.rec_size) > 0)
+  while (PRIV (recrd.rec_size) > 4)
     {
       vms_rec = PRIV (recrd.rec);
 
@@ -1120,136 +1205,238 @@ _bfd_vms_slurp_egsd (bfd * abfd)
 
       vms_debug2 ((3, "egsd_type %d\n", gsd_type));
 
+      /* PR 21615: Check for size overflow.  */
+      if (PRIV (recrd.rec_size) < gsd_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)
+       {
+       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;
+       }
+
       switch (gsd_type)
        {
        case EGSD__C_PSC:
+         /* Program section definition.  */
          {
-           /* Program section definition.  */
-            struct vms_egps *egps = (struct vms_egps *)vms_rec;
-           name = _bfd_vms_save_counted_string (&egps->namlng);
-           section = bfd_make_section (abfd, name);
-           if (!section)
-             return FALSE;
-           old_flags = bfd_getl16 (egps->flags);
-            vms_section_data (section)->flags = old_flags;
-            vms_section_data (section)->no_flags = 0;
-           section->size = bfd_getl32 (egps->alloc);
-           new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
-                                            section->size > 0);
-            if (!(old_flags & EGPS__V_NOMOD))
-              {
-                new_flags |= SEC_HAS_CONTENTS;
-                if (old_flags & EGPS__V_REL)
-                  new_flags |= SEC_RELOC;
-              }
-           if (!bfd_set_section_flags (abfd, section, new_flags))
-             return FALSE;
-           section->alignment_power = egps->align;
-           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;
-           base_addr += section->size;
-           section->filepos = (unsigned int)-1;
-#if VMS_DEBUG
-           vms_debug (4, "EGSD P-section %d (%s, flags %04x) ",
-                      section->index, name, old_flags);
-           vms_debug (4, "%lu bytes at 0x%08lx (mem %p)\n",
-                      (unsigned long)section->size,
-                       (unsigned long)section->vma, section->contents);
-#endif
+           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)
+             {
+               /* Use the global absolute section for all
+                  absolute sections.  */
+               section = bfd_abs_section_ptr;
+             }
+           else
+             {
+               char *name;
+               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)
+                 return FALSE;
+
+               section->filepos = 0;
+               section->size = bfd_getl32 (egps->alloc);
+               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,
+                                                section->name,
+                                                section->size > 0);
+               if (section->size > 0)
+                 new_flags |= SEC_LOAD;
+               if (!(vms_flags & EGPS__V_NOMOD) && section->size > 0)
+                 {
+                   /* Set RELOC and HAS_CONTENTS if the section is not
+                      demand-zero and not empty.  */
+                   new_flags |= SEC_HAS_CONTENTS;
+                   if (vms_flags & EGPS__V_REL)
+                     new_flags |= SEC_RELOC;
+                 }
+               if (vms_flags & EGPS__V_EXE)
+                 {
+                   /* Set CODE if section is executable.  */
+                   new_flags |= SEC_CODE;
+                   new_flags &= ~SEC_DATA;
+                 }
+               if (!bfd_set_section_flags (section, new_flags))
+                 return FALSE;
+
+               /* Give a non-overlapping vma to non absolute sections.  */
+               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;
+             }
+
+           /* Append it to the section array.  */
+           if (PRIV (section_count) >= PRIV (section_max))
+             {
+               if (PRIV (section_max) == 0)
+                 PRIV (section_max) = 16;
+               else
+                 PRIV (section_max) *= 2;
+               PRIV (sections) = bfd_realloc_or_free
+                 (PRIV (sections), PRIV (section_max) * sizeof (asection *));
+               if (PRIV (sections) == NULL)
+                 return FALSE;
+             }
+
+           PRIV (sections)[PRIV (section_count)] = section;
+           PRIV (section_count)++;
          }
          break;
 
        case EGSD__C_SYM:
          {
-            int nameoff;
-            struct vms_symbol_entry *entry;
-            struct vms_egsy *egsy = (struct vms_egsy *) vms_rec;
+           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 (entry == NULL)
-              return FALSE;
+             nameoff = ESDF__B_NAMLNG;
+           else
+             nameoff = ESRF__B_NAMLNG;
+
+           if (nameoff >= gsd_size)
+             goto too_small;
+           entry = add_symbol (abfd, vms_rec + nameoff, gsd_size - nameoff);
+           if (entry == NULL)
+             return FALSE;
 
-            /* Allow only duplicate reference.  */
-            if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF))
-              abort ();
+           /* Allow only duplicate reference.  */
+           if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF))
+             abort ();
 
-            if (entry->typ == 0)
-              {
-                entry->typ = gsd_type;
-                entry->data_type = egsy->datyp;
-                entry->flags = old_flags;
-              }
+           if (entry->typ == 0)
+             {
+               entry->typ = gsd_type;
+               entry->data_type = egsy->datyp;
+               entry->flags = old_flags;
+             }
 
            if (old_flags & EGSY__V_DEF)
-              {
-                struct vms_esdf *esdf = (struct vms_esdf *)vms_rec;
+             {
+               struct vms_esdf *esdf = (struct vms_esdf *) vms_rec;
 
                entry->value = bfd_getl64 (esdf->value);
-               entry->section = bfd_getl32 (esdf->psindx);
+               if (PRIV (sections) == NULL)
+                 return FALSE;
 
-                if (old_flags & EGSY__V_NORM)
-                  {
-                    PRIV (norm_sym_count)++;
+               psindx = bfd_getl32 (esdf->psindx);
+               /* PR 21813: Check for an out of range index.  */
+               if (psindx < 0 || psindx >= (int) PRIV (section_count))
+                 {
+                 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;
+                 }
+               entry->section = PRIV (sections)[psindx];
 
-                    entry->code_value = bfd_getl64 (esdf->code_address);
-                    entry->code_section = bfd_getl32 (esdf->ca_psindx);
-                  }
-              }
+               if (old_flags & EGSY__V_NORM)
+                 {
+                   PRIV (norm_sym_count)++;
+
+                   entry->code_value = bfd_getl64 (esdf->code_address);
+                   psindx = bfd_getl32 (esdf->ca_psindx);
+                   /* PR 21813: Check for an out of range index.  */
+                   if (psindx < 0 || psindx >= (int) PRIV (section_count))
+                     goto bad_psindx;
+                   entry->code_section = PRIV (sections)[psindx];
+                 }
+             }
          }
          break;
 
        case EGSD__C_SYMG:
          {
-            int nameoff;
-            struct vms_symbol_entry *entry;
-            struct vms_egst *egst = (struct vms_egst *)vms_rec;
+           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);
-           if (old_flags & EGSY__V_DEF)
-              nameoff = ESDF__B_NAMLNG;
-            else
-              nameoff = ESRF__B_NAMLNG;
 
-            entry = add_symbol (abfd, &egst->namlng);
-
-            if (entry == NULL)
-              return FALSE;
-
-            entry->typ = gsd_type;
-            entry->data_type = egst->header.datyp;
-            entry->flags = old_flags;
-
-            entry->symbol_vector = bfd_getl32 (egst->value);
-
-            entry->section = bfd_getl32 (egst->psindx);
-            entry->value = bfd_getl64 (egst->lp_2);
-
-            if (old_flags & EGSY__V_NORM)
-              {
-                PRIV (norm_sym_count)++;
+           if (nameoff >= gsd_size)
+             goto too_small;
+           entry = add_symbol (abfd, &egst->namlng, gsd_size - nameoff);
+           if (entry == NULL)
+             return FALSE;
 
-                entry->code_value = bfd_getl64 (egst->lp_1);
-                entry->code_section = 0;
-              }
-          }
+           entry->typ = gsd_type;
+           entry->data_type = egst->header.datyp;
+           entry->flags = old_flags;
+
+           entry->symbol_vector = bfd_getl32 (egst->value);
+
+           if (old_flags & EGSY__V_REL)
+             {
+               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))
+                 goto bad_psindx;
+               entry->section = PRIV (sections)[psindx];
+             }
+           else
+             entry->section = bfd_abs_section_ptr;
+
+           entry->value = bfd_getl64 (egst->lp_2);
+
+           if (old_flags & EGSY__V_NORM)
+             {
+               PRIV (norm_sym_count)++;
+
+               entry->code_value = bfd_getl64 (egst->lp_1);
+               entry->code_section = bfd_abs_section_ptr;
+             }
+         }
          break;
 
-        case EGSD__C_SPSC:
-        case EGSD__C_IDC:
-          /* Currently ignored.  */
-          break;
+       case EGSD__C_SPSC:
+       case EGSD__C_IDC:
+         /* Currently ignored.  */
+         break;
        case EGSD__C_SYMM:
        case EGSD__C_SYMV:
        default:
-         (*_bfd_error_handler) (_("Unknown EGSD subtype %d"), gsd_type);
+         _bfd_error_handler (_("unknown EGSD subtype %d"), gsd_type);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
@@ -1258,6 +1445,8 @@ _bfd_vms_slurp_egsd (bfd * abfd)
       PRIV (recrd.rec) += gsd_size;
     }
 
+  /* FIXME: Should we complain if PRIV (recrd.rec_size) is not zero ?  */
+
   if (PRIV (gsd_sym_count) > 0)
     abfd->flags |= HAS_SYMS;
 
@@ -1268,11 +1457,11 @@ _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",
-               (unsigned long)val, reloc, PRIV (stackptr)));
+              (unsigned long)val, reloc, PRIV (stackptr)));
 
   PRIV (stack[PRIV (stackptr)]).value = val;
   PRIV (stack[PRIV (stackptr)]).reloc = reloc;
@@ -1280,27 +1469,29 @@ _bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc)
   if (PRIV (stackptr) >= STACKSIZE)
     {
       bfd_set_error (bfd_error_bad_value);
-      (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
-      exit (1);
+      _bfd_error_handler (_("stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
+      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);
+      _bfd_error_handler (_("stack underflow in _bfd_vms_pop"));
+      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.  */
@@ -1314,6 +1505,11 @@ image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info)
 
   vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect));
 
+  if (PRIV (sections) == NULL)
+    return;
+  if (sect < 0 || sect >= (int) PRIV (section_count))
+    return;
+
   sec = PRIV (sections)[sect];
 
   if (info)
@@ -1321,15 +1517,15 @@ image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info)
       /* Reading contents to an output bfd.  */
 
       if (sec->output_section == NULL)
-        {
-          /* Section discarded.  */
-          vms_debug2 ((5, " section %s discarded\n", sec->name));
-
-          /* This is not used.  */
-          PRIV (image_section) = NULL;
-          PRIV (image_offset) = 0;
-          return;
-        }
+       {
+         /* Section discarded.  */
+         vms_debug2 ((5, " section %s discarded\n", sec->name));
+
+         /* This is not used.  */
+         PRIV (image_section) = NULL;
+         PRIV (image_offset) = 0;
+         return;
+       }
       PRIV (image_offset) = sec->output_offset + vma;
       PRIV (image_section) = sec->output_section;
     }
@@ -1352,70 +1548,102 @@ image_inc_ptr (bfd *abfd, bfd_vma offset)
 
 /* Save current DST location counter under specified index.  */
 
-static void
+static bfd_boolean
 dst_define_location (bfd *abfd, unsigned int loc)
 {
   vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc));
 
+  if (loc > 1 << 24)
+    {
+      /* 16M entries ought to be plenty.  */
+      bfd_set_error (bfd_error_bad_value);
+      _bfd_error_handler (_("dst_define_location %u too large"), loc);
+      return FALSE;
+    }
+
   /* Grow the ptr offset table if necessary.  */
   if (loc + 1 > PRIV (dst_ptr_offsets_count))
     {
-      PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets),
-                                          (loc + 1) * sizeof (unsigned int));
+      PRIV (dst_ptr_offsets)
+       = bfd_realloc_or_free (PRIV (dst_ptr_offsets),
+                              (loc + 1) * sizeof (unsigned int));
+      if (PRIV (dst_ptr_offsets) == NULL)
+       return FALSE;
       PRIV (dst_ptr_offsets_count) = loc + 1;
     }
 
   PRIV (dst_ptr_offsets)[loc] = PRIV (image_offset);
+  return TRUE;
 }
 
 /* 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.  */
 
 static bfd_boolean
-image_write (bfd *abfd, unsigned char *ptr, int size)
+image_write (bfd *abfd, unsigned char *ptr, unsigned int size)
 {
+  asection *sec = PRIV (image_section);
+  size_t off = PRIV (image_offset);
+
+  /* Check bounds.  */
+  if (off > sec->size
+      || size > sec->size - off)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
 #if VMS_DEBUG
   _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
-                  (long)PRIV (image_offset));
-  _bfd_hexdump (9, ptr, size, 0);
+                 (long) off));
 #endif
 
   if (PRIV (image_section)->contents != NULL)
+    memcpy (sec->contents + off, ptr, size);
+  else
     {
-      asection *sec = PRIV (image_section);
-      file_ptr off = PRIV (image_offset);
-
-      /* Check bounds.  */
-      if (off > (file_ptr)sec->size
-          || size > (file_ptr)sec->size
-          || off + size > (file_ptr)sec->size)
-        {
-          bfd_set_error (bfd_error_bad_value);
-          return FALSE;
-        }
-
-      memcpy (sec->contents + off, ptr, size);
+      unsigned int i;
+      for (i = 0; i < size; i++)
+       if (ptr[i] != 0)
+         {
+           bfd_set_error (bfd_error_bad_value);
+           return FALSE;
+         }
     }
 
+#if VMS_DEBUG
+  _bfd_hexdump (9, ptr, size, 0);
+#endif
+
   PRIV (image_offset) += size;
   return TRUE;
 }
@@ -1530,7 +1758,7 @@ _bfd_vms_etir_name (int cmd)
 
     default:
       /* These names have not yet been added to this switch statement.  */
-      (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
+      _bfd_error_handler (_("unknown ETIR command %d"), cmd);
     }
 
   return NULL;
@@ -1538,14 +1766,16 @@ _bfd_vms_etir_name (int cmd)
 #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
 
 static void
-_bfd_vms_get_value (bfd *abfd, const unsigned char *ascic,
-                    struct bfd_link_info *info,
-                    bfd_vma *vma,
-                    struct alpha_vms_link_hash_entry **hp)
+_bfd_vms_get_value (bfd *abfd,
+                   const unsigned char *ascic,
+                   const unsigned char *max_ascic,
+                   struct bfd_link_info *info,
+                   bfd_vma *vma,
+                   struct alpha_vms_link_hash_entry **hp)
 {
   char name[257];
-  int len;
-  int i;
+  unsigned int len;
+  unsigned int i;
   struct alpha_vms_link_hash_entry *h;
 
   /* Not linking.  Do not try to resolve the symbol.  */
@@ -1557,6 +1787,14 @@ _bfd_vms_get_value (bfd *abfd, const unsigned char *ascic,
     }
 
   len = *ascic;
+  if (ascic + len >= max_ascic)
+    {
+      _bfd_error_handler (_("corrupt vms value"));
+      *vma = 0;
+      *hp = NULL;
+      return;
+    }
+
   for (i = 0; i < len; i++)
     name[i] = ascic[i + 1];
   name[i] = 0;
@@ -1568,7 +1806,7 @@ _bfd_vms_get_value (bfd *abfd, const unsigned char *ascic,
 
   if (h != NULL
       && (h->root.type == bfd_link_hash_defined
-          || h->root.type == bfd_link_hash_defweak))
+         || h->root.type == bfd_link_hash_defweak))
     *vma = h->root.u.def.value
       + h->root.u.def.section->output_offset
       + h->root.u.def.section->output_section->vma;
@@ -1576,9 +1814,8 @@ _bfd_vms_get_value (bfd *abfd, const unsigned char *ascic,
     *vma = 0;
   else
     {
-      if (!(*info->callbacks->undefined_symbol)
-          (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE))
-        abort ();
+      (*info->callbacks->undefined_symbol)
+       (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE);
       *vma = 0;
     }
 }
@@ -1599,46 +1836,45 @@ alpha_vms_sym_to_ctxt (struct alpha_vms_link_hash_entry *h)
   if (h->sym->typ == EGSD__C_SYMG)
     {
       if (h->sym->flags & EGSY__V_REL)
-        return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
+       return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
       else
-        {
-          /* Can this happen ?  I'd like to see an example.  */
-          abort ();
-        }
+       {
+         /* Can this happen (non-relocatable symg) ?  I'd like to see
+            an example.  */
+         abort ();
+       }
     }
   if (h->sym->typ == EGSD__C_SYM)
     {
       if (h->sym->flags & EGSY__V_REL)
-        return RELC_REL;
+       return RELC_REL;
       else
-        return RELC_NONE;
+       return RELC_NONE;
     }
   abort ();
 }
 
 static bfd_vma
-alpha_vms_get_sym_value (unsigned int sect, bfd_vma addr,
-                         struct alpha_vms_link_hash_entry *h)
+alpha_vms_get_sym_value (asection *sect, bfd_vma addr)
 {
-  asection *s;
-
-  BFD_ASSERT (h && (h->root.type == bfd_link_hash_defined
-                    || h->root.type == bfd_link_hash_defweak));
-
-  s = PRIV2 (h->root.u.def.section->owner, sections)[sect];
-  return s->output_section->vma + s->output_offset + addr;
+  return sect->output_section->vma + sect->output_offset + addr;
 }
 
 static bfd_vma
 alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info,
-                       unsigned int rel, bfd_vma vma)
+                      unsigned int rel, bfd_vma vma)
 {
-  asection *sec = PRIV (sections)[rel & RELC_MASK];
+  asection *sec;
+
+  if (PRIV (sections) == NULL)
+    return 0;
+
+  sec = PRIV (sections)[rel & RELC_MASK];
 
   if (info)
     {
       if (sec->output_section == NULL)
-        abort ();
+       abort ();
       return vma + sec->output_section->vma + sec->output_offset;
     }
   else
@@ -1655,10 +1891,10 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
   unsigned char *ptr;
   unsigned int length;
   unsigned char *maxptr;
-  bfd_vma op1;
-  bfd_vma op2;
-  unsigned int rel1;
-  unsigned int rel2;
+  bfd_vma op1 = 0;
+  bfd_vma op2 = 0;
+  unsigned int rel1 = RELC_NONE;
+  unsigned int rel2 = RELC_NONE;
   struct alpha_vms_link_hash_entry *h;
 
   PRIV (recrd.rec) += ETIR__C_HEADER_SIZE;
@@ -1672,599 +1908,704 @@ _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;
+
+      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)
+       {
+       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",
-                      _bfd_vms_etir_name (cmd), cmd);
-      _bfd_hexdump (8, ptr, cmd_length - 4, (long) ptr);
+                     _bfd_vms_etir_name (cmd), cmd);
+      _bfd_hexdump (8, ptr, cmd_length - 4, 0);
 #endif
 
       switch (cmd)
-        {
-          /* Stack global
-             arg: cs   symbol name
-
-             stack 32 bit value of symbol (high bits set to 0).  */
-        case ETIR__C_STA_GBL:
-          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
-          _bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h));
-          break;
-
-          /* Stack longword
-             arg: lw   value
-
-             stack 32 bit value, sign extend to 64 bit.  */
-        case ETIR__C_STA_LW:
-          _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE);
-          break;
-
-          /* Stack quadword
-             arg: qw   value
-
-             stack 64 bit value of symbol.  */
-        case ETIR__C_STA_QW:
-          _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE);
-          break;
-
-          /* Stack psect base plus quadword offset
-             arg: lw   section index
-             qw        signed quadword offset (low 32 bits)
-
-             Stack qw argument and section index
-             (see ETIR__C_STO_OFF, ETIR__C_CTL_SETRB).  */
-        case ETIR__C_STA_PQ:
-          {
-            int psect;
-
-            psect = bfd_getl32 (ptr);
-            if ((unsigned int) psect >= PRIV (section_count))
-              {
-                (*_bfd_error_handler) (_("bad section index in %s"),
-                                       _bfd_vms_etir_name (cmd));
-                bfd_set_error (bfd_error_bad_value);
-                return FALSE;
-              }
-            op1 = bfd_getl64 (ptr + 4);
-            _bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE);
-          }
-          break;
-
-        case ETIR__C_STA_LI:
-        case ETIR__C_STA_MOD:
-        case ETIR__C_STA_CKARG:
-          (*_bfd_error_handler) (_("unsupported STA cmd %s"),
-                                 _bfd_vms_etir_name (cmd));
-          return FALSE;
-          break;
-
-          /* Store byte: pop stack, write byte
-             arg: -.  */
-        case ETIR__C_STO_B:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          image_write_b (abfd, (unsigned int) op1 & 0xff);
-          break;
-
-          /* Store word: pop stack, write word
-             arg: -.  */
-        case ETIR__C_STO_W:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          image_write_w (abfd, (unsigned int) op1 & 0xffff);
-          break;
-
-          /* Store longword: pop stack, write longword
-             arg: -.  */
-        case ETIR__C_STO_LW:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 & RELC_SEC_BASE)
-            {
-              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
-              rel1 = RELC_REL;
-            }
-          else if (rel1 & RELC_SHR_BASE)
-            {
-              alpha_vms_add_lw_fixup (info, rel1 & RELC_MASK, op1);
-              rel1 = RELC_NONE;
-            }
-          if (rel1 != RELC_NONE)
-            {
-              if (rel1 != RELC_REL)
-                abort ();
-              alpha_vms_add_lw_reloc (info);
-            }
-          image_write_l (abfd, op1);
-          break;
-
-          /* Store quadword: pop stack, write quadword
-             arg: -.  */
-        case ETIR__C_STO_QW:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 & RELC_SEC_BASE)
-            {
-              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
-              rel1 = RELC_REL;
-            }
-          else if (rel1 & RELC_SHR_BASE)
-            abort ();
-          if (rel1 != RELC_NONE)
-            {
-              if (rel1 != RELC_REL)
-                abort ();
-              alpha_vms_add_qw_reloc (info);
-            }
-          image_write_q (abfd, op1);
-          break;
-
-          /* Store immediate repeated: pop stack for repeat count
-             arg: lw   byte count
-             da        data.  */
-        case ETIR__C_STO_IMMR:
-          {
-            int size;
-
-            size = bfd_getl32 (ptr);
-            _bfd_vms_pop (abfd, &op1, &rel1);
-            if (rel1 != RELC_NONE)
-              goto bad_context;
-            while (op1-- > 0)
-              image_write (abfd, ptr + 4, size);
-          }
-          break;
-
-          /* Store global: write symbol value
-             arg: cs   global symbol name.  */
-        case ETIR__C_STO_GBL:
-          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
-          if (h && h->sym)
-            {
-              if (h->sym->typ == EGSD__C_SYMG)
-                {
-                  alpha_vms_add_fixup_qr
-                    (info, abfd, h->sym->owner, h->sym->symbol_vector);
-                  op1 = 0;
-                }
-              else
-                {
-                  op1 = alpha_vms_get_sym_value (h->sym->section,
-                                                 h->sym->value, h);
-                  alpha_vms_add_qw_reloc (info);
-                }
-            }
-          image_write_q (abfd, op1);
-          break;
-
-          /* Store code address: write address of entry point
-             arg: cs   global symbol name (procedure).  */
-        case ETIR__C_STO_CA:
-          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
-          if (h && h->sym)
-            {
-              if (h->sym->flags & EGSY__V_NORM)
-                {
-                  /* That's really a procedure.  */
-                  if (h->sym->typ == EGSD__C_SYMG)
-                    {
-                      alpha_vms_add_fixup_ca (info, abfd, h->sym->owner);
-                      op1 = h->sym->symbol_vector;
-                    }
-                  else
-                    {
-                      op1 = alpha_vms_get_sym_value (h->sym->code_section,
-                                                     h->sym->code_value, h);
-                      alpha_vms_add_qw_reloc (info);
-                    }
-                }
-              else
-                {
-                  /* Symbol is not a procedure.  */
-                  abort ();
-                }
-            }
-          image_write_q (abfd, op1);
-          break;
-
-          /* 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 (!(rel1 & RELC_SEC_BASE))
-            abort ();
-
-          op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
-          rel1 = RELC_REL;
-          image_write_q (abfd, op1);
-          break;
-
-          /* Store immediate
-             arg: lw   count of bytes
-             da        data.  */
-        case ETIR__C_STO_IMM:
-          {
-            int size;
-
-            size = bfd_getl32 (ptr);
-            image_write (abfd, ptr + 4, size);
-          }
-          break;
-
-          /* This code is 'reserved to digital' according to the openVMS
-             linker manual, however it is generated by the DEC C compiler
-             and defined in the include file.
-             FIXME, since the following is just a guess
-             store global longword: store 32bit value of symbol
-             arg: cs   symbol name.  */
-        case ETIR__C_STO_GBL_LW:
-          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
-#if 0
-          abort ();
-#endif
-          image_write_l (abfd, op1);
-          break;
-
-        case ETIR__C_STO_RB:
-        case ETIR__C_STO_AB:
-        case ETIR__C_STO_LP_PSB:
-          (*_bfd_error_handler) (_("%s: not supported"),
-                                 _bfd_vms_etir_name (cmd));
-          return FALSE;
-          break;
-        case ETIR__C_STO_HINT_GBL:
-        case ETIR__C_STO_HINT_PS:
-          (*_bfd_error_handler) (_("%s: not implemented"),
-                                 _bfd_vms_etir_name (cmd));
-          return FALSE;
-          break;
-
-          /* 200 Store-conditional Linkage Pair
-             arg: none.  */
-        case ETIR__C_STC_LP:
-
-          /* 202 Store-conditional Address at global address
-             lw        linkage index
-             cs        global name.  */
-
-        case ETIR__C_STC_GBL:
-
-          /* 203 Store-conditional Code Address at global address
-             lw        linkage index
-             cs        procedure name.  */
-        case ETIR__C_STC_GCA:
-
-          /* 204 Store-conditional Address at psect + offset
-             lw        linkage index
-             lw        psect index
-             qw        offset.  */
-        case ETIR__C_STC_PS:
-          (*_bfd_error_handler) (_("%s: not supported"),
-                                 _bfd_vms_etir_name (cmd));
-          return FALSE;
-          break;
-
-          /* 201 Store-conditional Linkage Pair with Procedure Signature
-             lw        linkage index
-             cs        procedure name
-             by        signature length
-             da        signature.  */
-
-        case ETIR__C_STC_LP_PSB:
-          _bfd_vms_get_value (abfd, ptr + 4, info, &op1, &h);
-          if (h && h->sym)
-            {
-              if (h->sym->typ == EGSD__C_SYMG)
-                {
-                  alpha_vms_add_fixup_lp (info, abfd, h->sym->owner);
-                  op1 = h->sym->symbol_vector;
-                  op2 = 0;
-                }
-              else
-                {
-                  op1 = alpha_vms_get_sym_value (h->sym->code_section,
-                                                 h->sym->code_value, h);
-                  op2 = alpha_vms_get_sym_value (h->sym->section,
-                                                h->sym->value, h);
-                }
-            }
-          else
-            {
-              /* Undefined symbol.  */
-              op1 = 0;
-              op2 = 0;
-            }
-          image_write_q (abfd, op1);
-          image_write_q (abfd, op2);
-          break;
-
-          /* 205 Store-conditional NOP at address of global
-             arg: none.  */
-        case ETIR__C_STC_NOP_GBL:
-          /* ALPHA_R_NOP */
-
-          /* 207 Store-conditional BSR at global address
-             arg: none.  */
-
-        case ETIR__C_STC_BSR_GBL:
-          /* ALPHA_R_BSR */
-
-          /* 209 Store-conditional LDA at global address
-             arg: none.  */
-
-        case ETIR__C_STC_LDA_GBL:
-          /* ALPHA_R_LDA */
-
-          /* 211 Store-conditional BSR or Hint at global address
-             arg: none.  */
-
-        case ETIR__C_STC_BOH_GBL:
-          /* Currentl ignored.  */
-          break;
-
-          /* 213 Store-conditional NOP,BSR or HINT at global address
-             arg: none.  */
-
-        case ETIR__C_STC_NBH_GBL:
-
-          /* 206 Store-conditional NOP at pect + offset
-             arg: none.  */
-
-        case ETIR__C_STC_NOP_PS:
-
-          /* 208 Store-conditional BSR at pect + offset
-             arg: none.  */
-
-        case ETIR__C_STC_BSR_PS:
-
-          /* 210 Store-conditional LDA at psect + offset
-             arg: none.  */
-
-        case ETIR__C_STC_LDA_PS:
-
-          /* 212 Store-conditional BSR or Hint at pect + offset
-             arg: none.  */
-
-        case ETIR__C_STC_BOH_PS:
-
-          /* 214 Store-conditional NOP, BSR or HINT at psect + offset
-             arg: none.  */
-        case ETIR__C_STC_NBH_PS:
-          (*_bfd_error_handler) ("%s: not supported",
-                                 _bfd_vms_etir_name (cmd));
-          return FALSE;
-          break;
-
-          /* Det relocation base: pop stack, set image location counter
-             arg: none.  */
-        case ETIR__C_CTL_SETRB:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (!(rel1 & RELC_SEC_BASE))
-            abort ();
-          image_set_ptr (abfd, op1, rel1 & RELC_MASK, info);
-          break;
-
-          /* Augment relocation base: increment image location counter by offset
-             arg: lw   offset value.  */
-        case ETIR__C_CTL_AUGRB:
-          op1 = bfd_getl32 (ptr);
-          image_inc_ptr (abfd, op1);
-          break;
-
-          /* Define location: pop index, save location counter under index
-             arg: none.  */
-        case ETIR__C_CTL_DFLOC:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          dst_define_location (abfd, op1);
-          break;
-
-          /* Set location: pop index, restore location counter from index
-             arg: none.  */
-        case ETIR__C_CTL_STLOC:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          dst_restore_location (abfd, op1);
-          break;
-
-          /* Stack defined location: pop index, push location counter from index
-             arg: none.  */
-        case ETIR__C_CTL_STKDL:
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), RELC_NONE);
-          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 (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);
-          break;
-
-        case ETIR__C_OPR_SUB:      /* Subtract.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 == RELC_NONE && rel2 != RELC_NONE)
-            rel1 = rel2;
-          else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE))
-            {
-              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
-              op2 = alpha_vms_fix_sec_rel (abfd, info, rel2, op2);
-              rel1 = RELC_NONE;
-            }
-          else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, op2 - op1, rel1);
-          break;
-
-        case ETIR__C_OPR_MUL:      /* Multiply.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, op1 * op2, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_DIV:      /* Divide.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
-            goto bad_context;
-          if (op2 == 0)
-            _bfd_vms_push (abfd, 0, RELC_NONE);
-          else
-            _bfd_vms_push (abfd, op2 / op1, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_AND:      /* Logical AND.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, op1 & op2, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_IOR:      /* Logical inclusive OR.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, op1 | op2, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_EOR:      /* Logical exclusive OR.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, op1 ^ op2, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_NEG:      /* Negate.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, -op1, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_COM:      /* Complement.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (rel1 != RELC_NONE)
-            goto bad_context;
-          _bfd_vms_push (abfd, ~op1, RELC_NONE);
-          break;
-
-        case ETIR__C_OPR_ASH:      /* Arithmetic shift.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          _bfd_vms_pop (abfd, &op2, &rel2);
-          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
-            {
-            bad_context:
-              (*_bfd_error_handler) (_("invalid use of %s with contexts"),
-                                     _bfd_vms_etir_name (cmd));
-              return FALSE;
-            }
-          if ((int)op2 < 0)            /* Shift right.  */
-            op1 >>= -(int)op2;
-          else                 /* Shift left.  */
-            op1 <<= (int)op2;
-          _bfd_vms_push (abfd, op1, RELC_NONE); /* FIXME: sym.  */
-          break;
-
-        case ETIR__C_OPR_INSV:      /* Insert field.   */
-        case ETIR__C_OPR_USH:       /* Unsigned shift.   */
-        case ETIR__C_OPR_ROT:       /* Rotate.  */
-        case ETIR__C_OPR_REDEF:     /* Redefine symbol to current location.  */
-        case ETIR__C_OPR_DFLIT:     /* Define a literal.  */
-          (*_bfd_error_handler) (_("%s: not supported"),
-                                 _bfd_vms_etir_name (cmd));
-          return FALSE;
-          break;
-
-        case ETIR__C_OPR_SEL:      /* Select.  */
-          _bfd_vms_pop (abfd, &op1, &rel1);
-          if (op1 & 0x01L)
-            _bfd_vms_pop (abfd, &op1, &rel1);
-          else
-            {
-              _bfd_vms_pop (abfd, &op1, &rel1);
-              _bfd_vms_pop (abfd, &op2, &rel2);
-              _bfd_vms_push (abfd, op1, rel1);
-            }
-          break;
-
-        default:
-          (*_bfd_error_handler) (_("reserved cmd %d"), cmd);
-          return FALSE;
-          break;
-        }
-
-      ptr += cmd_length - 4;
-    }
-
-  return TRUE;
-}
+       {
+         /* Stack global
+            arg: cs    symbol name
+
+            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);
+         if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)))
+           return FALSE;
+         break;
 
-/* Process EDBG/ETBT record.
-   Return TRUE on success, FALSE on error  */
+         /* Stack longword
+            arg: lw    value
 
-static bfd_boolean
-vms_slurp_debug (bfd *abfd)
-{
-  asection *section = PRIV (dst_section);
+            stack 32 bit value, sign extend to 64 bit.  */
+       case ETIR__C_STA_LW:
+         if (ptr + 4 > maxptr)
+           goto corrupt_etir;
+         if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE))
+           return FALSE;
+         break;
 
-  if (section == NULL)
-    {
-      /* We have no way to find out beforehand how much debug info there
-        is in an object file, so pick an initial amount and grow it as
-        needed later.  */
-      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC
-        | SEC_IN_MEMORY;
+         /* Stack quadword
+            arg: qw    value
 
-      section = bfd_make_section (abfd, "$DST$");
-      if (!section)
-       return FALSE;
-      if (!bfd_set_section_flags (abfd, section, flags))
-       return FALSE;
-      PRIV (dst_section) = section;
-    }
+            stack 64 bit value of symbol.  */
+       case ETIR__C_STA_QW:
+         if (ptr + 8 > maxptr)
+           goto corrupt_etir;
+         if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE))
+           return FALSE;
+         break;
 
-  PRIV (image_section) = section;
-  PRIV (image_offset) = section->size;
+         /* Stack psect base plus quadword offset
+            arg: lw    section index
+            qw signed quadword offset (low 32 bits)
 
-  if (!_bfd_vms_slurp_etir (abfd, NULL))
-    return FALSE;
+            Stack qw argument and section index
+            (see ETIR__C_STO_OFF, ETIR__C_CTL_SETRB).  */
+       case ETIR__C_STA_PQ:
+         {
+           int psect;
+
+           if (ptr + 12 > maxptr)
+             goto corrupt_etir;
+           psect = bfd_getl32 (ptr);
+           if ((unsigned int) psect >= PRIV (section_count))
+             {
+               _bfd_error_handler (_("bad section index in %s"),
+                                   _bfd_vms_etir_name (cmd));
+               bfd_set_error (bfd_error_bad_value);
+               return FALSE;
+             }
+           op1 = bfd_getl64 (ptr + 4);
+           if (!_bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE))
+             return FALSE;
+         }
+         break;
 
-  section->size = PRIV (image_offset);
-  return TRUE;
-}
+       case ETIR__C_STA_LI:
+       case ETIR__C_STA_MOD:
+       case ETIR__C_STA_CKARG:
+         _bfd_error_handler (_("unsupported STA cmd %s"),
+                             _bfd_vms_etir_name (cmd));
+         return FALSE;
+         break;
 
-/* Process EDBG record.
-   Return TRUE on success, FALSE on error.  */
+         /* Store byte: pop stack, write byte
+            arg: -.  */
+       case ETIR__C_STO_B:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         if (!image_write_b (abfd, (unsigned int) op1 & 0xff))
+           return FALSE;
+         break;
 
-static bfd_boolean
-_bfd_vms_slurp_edbg (bfd *abfd)
-{
-  vms_debug2 ((2, "EDBG\n"));
+         /* Store word: pop stack, write word
+            arg: -.  */
+       case ETIR__C_STO_W:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         if (!image_write_w (abfd, (unsigned int) op1 & 0xffff))
+           return FALSE;
+         break;
 
-  abfd->flags |= HAS_DEBUG | HAS_LINENO;
+         /* Store longword: pop stack, write longword
+            arg: -.  */
+       case ETIR__C_STO_LW:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 & RELC_SEC_BASE)
+           {
+             op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+             rel1 = RELC_REL;
+           }
+         else if (rel1 & RELC_SHR_BASE)
+           {
+             if (!alpha_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1))
+               return FALSE;
+             rel1 = RELC_NONE;
+           }
+         if (rel1 != RELC_NONE)
+           {
+             if (rel1 != RELC_REL)
+               abort ();
+             if (!alpha_vms_add_lw_reloc (info))
+               return FALSE;
+           }
+         if (!image_write_l (abfd, op1))
+           return FALSE;
+         break;
 
-  return vms_slurp_debug (abfd);
-}
+         /* Store quadword: pop stack, write quadword
+            arg: -.  */
+       case ETIR__C_STO_QW:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 & RELC_SEC_BASE)
+           {
+             op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+             rel1 = RELC_REL;
+           }
+         else if (rel1 & RELC_SHR_BASE)
+           abort ();
+         if (rel1 != RELC_NONE)
+           {
+             if (rel1 != RELC_REL)
+               abort ();
+             if (!alpha_vms_add_qw_reloc (info))
+               return FALSE;
+           }
+         if (!image_write_q (abfd, op1))
+           return FALSE;
+         break;
+
+         /* Store immediate repeated: pop stack for repeat count
+            arg: lw    byte count
+            da data.  */
+       case ETIR__C_STO_IMMR:
+         {
+           int size;
+
+           if (ptr + 4 > maxptr)
+             goto corrupt_etir;
+           size = bfd_getl32 (ptr);
+           if (!_bfd_vms_pop (abfd, &op1, &rel1))
+             return FALSE;
+           if (rel1 != RELC_NONE)
+             goto bad_context;
+           while (op1-- > 0)
+             if (!image_write (abfd, ptr + 4, size))
+               return FALSE;
+         }
+         break;
+
+         /* Store global: write symbol value
+            arg: cs    global symbol name.  */
+       case ETIR__C_STO_GBL:
+         _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
+         if (h && h->sym)
+           {
+             if (h->sym->typ == EGSD__C_SYMG)
+               {
+                 if (!alpha_vms_add_fixup_qr (info, abfd, h->sym->owner,
+                                              h->sym->symbol_vector))
+                   return FALSE;
+                 op1 = 0;
+               }
+             else
+               {
+                 op1 = alpha_vms_get_sym_value (h->sym->section,
+                                                h->sym->value);
+                 if (!alpha_vms_add_qw_reloc (info))
+                   return FALSE;
+               }
+           }
+         if (!image_write_q (abfd, op1))
+           return FALSE;
+         break;
+
+         /* Store code address: write address of entry point
+            arg: cs    global symbol name (procedure).  */
+       case ETIR__C_STO_CA:
+         _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
+         if (h && h->sym)
+           {
+             if (h->sym->flags & EGSY__V_NORM)
+               {
+                 /* That's really a procedure.  */
+                 if (h->sym->typ == EGSD__C_SYMG)
+                   {
+                     if (!alpha_vms_add_fixup_ca (info, abfd, h->sym->owner))
+                       return FALSE;
+                     op1 = h->sym->symbol_vector;
+                   }
+                 else
+                   {
+                     op1 = alpha_vms_get_sym_value (h->sym->code_section,
+                                                    h->sym->code_value);
+                     if (!alpha_vms_add_qw_reloc (info))
+                       return FALSE;
+                   }
+               }
+             else
+               {
+                 /* Symbol is not a procedure.  */
+                 abort ();
+               }
+           }
+         if (!image_write_q (abfd, op1))
+           return FALSE;
+         break;
+
+         /* Store offset to psect: pop stack, add low 32 bits to base of psect
+            arg: none.  */
+       case ETIR__C_STO_OFF:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+
+         if (!(rel1 & RELC_SEC_BASE))
+           abort ();
+
+         op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+         rel1 = RELC_REL;
+         if (!image_write_q (abfd, op1))
+           return FALSE;
+         break;
+
+         /* Store immediate
+            arg: lw    count of bytes
+            da data.  */
+       case ETIR__C_STO_IMM:
+         {
+           unsigned int size;
+
+           if (ptr + 4 > maxptr)
+             goto corrupt_etir;
+           size = bfd_getl32 (ptr);
+           if (!image_write (abfd, ptr + 4, size))
+             return FALSE;
+         }
+         break;
+
+         /* This code is 'reserved to digital' according to the openVMS
+            linker manual, however it is generated by the DEC C compiler
+            and defined in the include file.
+            FIXME, since the following is just a guess
+            store global longword: store 32bit value of symbol
+            arg: cs    symbol name.  */
+       case ETIR__C_STO_GBL_LW:
+         _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
+#if 0
+         abort ();
+#endif
+         if (!image_write_l (abfd, op1))
+           return FALSE;
+         break;
+
+       case ETIR__C_STO_RB:
+       case ETIR__C_STO_AB:
+       case ETIR__C_STO_LP_PSB:
+         _bfd_error_handler (_("%s: not supported"),
+                             _bfd_vms_etir_name (cmd));
+         return FALSE;
+         break;
+       case ETIR__C_STO_HINT_GBL:
+       case ETIR__C_STO_HINT_PS:
+         _bfd_error_handler (_("%s: not implemented"),
+                             _bfd_vms_etir_name (cmd));
+         return FALSE;
+         break;
+
+         /* 200 Store-conditional Linkage Pair
+            arg: none.  */
+       case ETIR__C_STC_LP:
+
+         /* 202 Store-conditional Address at global address
+            lw linkage index
+            cs global name.  */
+
+       case ETIR__C_STC_GBL:
+
+         /* 203 Store-conditional Code Address at global address
+            lw linkage index
+            cs procedure name.  */
+       case ETIR__C_STC_GCA:
+
+         /* 204 Store-conditional Address at psect + offset
+            lw linkage index
+            lw psect index
+            qw offset.  */
+       case ETIR__C_STC_PS:
+         _bfd_error_handler (_("%s: not supported"),
+                             _bfd_vms_etir_name (cmd));
+         return FALSE;
+         break;
+
+         /* 201 Store-conditional Linkage Pair with Procedure Signature
+            lw linkage index
+            cs procedure name
+            by signature length
+            da signature.  */
+
+       case ETIR__C_STC_LP_PSB:
+         _bfd_vms_get_value (abfd, ptr + 4, maxptr, info, &op1, &h);
+         if (h && h->sym)
+           {
+             if (h->sym->typ == EGSD__C_SYMG)
+               {
+                 if (!alpha_vms_add_fixup_lp (info, abfd, h->sym->owner))
+                   return FALSE;
+                 op1 = h->sym->symbol_vector;
+                 op2 = 0;
+               }
+             else
+               {
+                 op1 = alpha_vms_get_sym_value (h->sym->code_section,
+                                                h->sym->code_value);
+                 op2 = alpha_vms_get_sym_value (h->sym->section,
+                                               h->sym->value);
+               }
+           }
+         else
+           {
+             /* Undefined symbol.  */
+             op1 = 0;
+             op2 = 0;
+           }
+         if (!image_write_q (abfd, op1)
+             || !image_write_q (abfd, op2))
+           return FALSE;
+         break;
+
+         /* 205 Store-conditional NOP at address of global
+            arg: none.  */
+       case ETIR__C_STC_NOP_GBL:
+         /* ALPHA_R_NOP */
+
+         /* 207 Store-conditional BSR at global address
+            arg: none.  */
+
+       case ETIR__C_STC_BSR_GBL:
+         /* ALPHA_R_BSR */
+
+         /* 209 Store-conditional LDA at global address
+            arg: none.  */
+
+       case ETIR__C_STC_LDA_GBL:
+         /* ALPHA_R_LDA */
+
+         /* 211 Store-conditional BSR or Hint at global address
+            arg: none.  */
+
+       case ETIR__C_STC_BOH_GBL:
+         /* Currentl ignored.  */
+         break;
+
+         /* 213 Store-conditional NOP,BSR or HINT at global address
+            arg: none.  */
+
+       case ETIR__C_STC_NBH_GBL:
+
+         /* 206 Store-conditional NOP at pect + offset
+            arg: none.  */
+
+       case ETIR__C_STC_NOP_PS:
+
+         /* 208 Store-conditional BSR at pect + offset
+            arg: none.  */
+
+       case ETIR__C_STC_BSR_PS:
+
+         /* 210 Store-conditional LDA at psect + offset
+            arg: none.  */
+
+       case ETIR__C_STC_LDA_PS:
+
+         /* 212 Store-conditional BSR or Hint at pect + offset
+            arg: none.  */
+
+       case ETIR__C_STC_BOH_PS:
+
+         /* 214 Store-conditional NOP, BSR or HINT at psect + offset
+            arg: none.  */
+       case ETIR__C_STC_NBH_PS:
+         _bfd_error_handler (_("%s: not supported"),
+                             _bfd_vms_etir_name (cmd));
+         return FALSE;
+         break;
+
+         /* Det relocation base: pop stack, set image location counter
+            arg: none.  */
+       case ETIR__C_CTL_SETRB:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (!(rel1 & RELC_SEC_BASE))
+           abort ();
+         image_set_ptr (abfd, op1, rel1 & RELC_MASK, info);
+         break;
+
+         /* Augment relocation base: increment image location counter by offset
+            arg: lw    offset value.  */
+       case ETIR__C_CTL_AUGRB:
+         if (ptr + 4 > maxptr)
+           goto corrupt_etir;
+         op1 = bfd_getl32 (ptr);
+         image_inc_ptr (abfd, op1);
+         break;
+
+         /* Define location: pop index, save location counter under index
+            arg: none.  */
+       case ETIR__C_CTL_DFLOC:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         if (!dst_define_location (abfd, op1))
+           return FALSE;
+         break;
+
+         /* Set location: pop index, restore location counter from index
+            arg: none.  */
+       case ETIR__C_CTL_STLOC:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         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
+            arg: none.  */
+       case ETIR__C_CTL_STKDL:
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         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;
+
+       case ETIR__C_OPR_NOP:      /* No-op.  */
+         break;
+
+       case ETIR__C_OPR_ADD:      /* Add.  */
+         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;
+         if (!_bfd_vms_push (abfd, op1 + op2, rel1))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_SUB:      /* Subtract.  */
+         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))
+           {
+             op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+             op2 = alpha_vms_fix_sec_rel (abfd, info, rel2, op2);
+             rel1 = RELC_NONE;
+           }
+         else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
+           goto bad_context;
+         if (!_bfd_vms_push (abfd, op2 - op1, rel1))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_MUL:      /* Multiply.  */
+         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 (!_bfd_vms_push (abfd, op1 * op2, RELC_NONE))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_DIV:      /* Divide.  */
+         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 (op1 == 0)
+           {
+             /* Divide by zero is supposed to give a result of zero,
+                and a non-fatal warning message.  */
+             _bfd_error_handler (_("%s divide by zero"), "ETIR__C_OPR_DIV");
+             if (!_bfd_vms_push (abfd, 0, RELC_NONE))
+               return FALSE;
+           }
+         else
+           {
+             if (!_bfd_vms_push (abfd, op2 / op1, RELC_NONE))
+               return FALSE;
+           }
+         break;
+
+       case ETIR__C_OPR_AND:      /* Logical AND.  */
+         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 (!_bfd_vms_push (abfd, op1 & op2, RELC_NONE))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_IOR:      /* Logical inclusive OR.  */
+         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 (!_bfd_vms_push (abfd, op1 | op2, RELC_NONE))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_EOR:      /* Logical exclusive OR.  */
+         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 (!_bfd_vms_push (abfd, op1 ^ op2, RELC_NONE))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_NEG:      /* Negate.  */
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         if (!_bfd_vms_push (abfd, -op1, RELC_NONE))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_COM:      /* Complement.  */
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (rel1 != RELC_NONE)
+           goto bad_context;
+         if (!_bfd_vms_push (abfd, ~op1, RELC_NONE))
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_ASH:      /* Arithmetic shift.  */
+         if (!_bfd_vms_pop (abfd, &op1, &rel1)
+             || !_bfd_vms_pop (abfd, &op2, &rel2))
+           return FALSE;
+         if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+           {
+           bad_context:
+             _bfd_error_handler (_("invalid use of %s with contexts"),
+                                 _bfd_vms_etir_name (cmd));
+             return FALSE;
+           }
+         if ((int)op2 < 0)             /* Shift right.  */
+           op1 >>= -(int)op2;
+         else                  /* Shift left.  */
+           op1 <<= (int)op2;
+         if (!_bfd_vms_push (abfd, op1, RELC_NONE)) /* FIXME: sym.  */
+           return FALSE;
+         break;
+
+       case ETIR__C_OPR_INSV:      /* Insert field.   */
+       case ETIR__C_OPR_USH:       /* Unsigned shift.   */
+       case ETIR__C_OPR_ROT:       /* Rotate.  */
+       case ETIR__C_OPR_REDEF:     /* Redefine symbol to current location.  */
+       case ETIR__C_OPR_DFLIT:     /* Define a literal.  */
+         _bfd_error_handler (_("%s: not supported"),
+                             _bfd_vms_etir_name (cmd));
+         return FALSE;
+         break;
+
+       case ETIR__C_OPR_SEL:      /* Select.  */
+         if (!_bfd_vms_pop (abfd, &op1, &rel1))
+           return FALSE;
+         if (op1 & 0x01L)
+           {
+             if (!_bfd_vms_pop (abfd, &op1, &rel1))
+               return FALSE;
+           }
+         else
+           {
+             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;
+
+       default:
+         _bfd_error_handler (_("reserved cmd %d"), cmd);
+         return FALSE;
+         break;
+       }
+
+      ptr += cmd_length - 4;
+    }
+
+  return TRUE;
+}
+
+/* Process EDBG/ETBT record.
+   Return TRUE on success, FALSE on error  */
+
+static bfd_boolean
+vms_slurp_debug (bfd *abfd)
+{
+  asection *section = PRIV (dst_section);
+
+  if (section == NULL)
+    {
+      /* We have no way to find out beforehand how much debug info there
+        is in an object file, so pick an initial amount and grow it as
+        needed later.  */
+      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC
+       | SEC_IN_MEMORY;
+
+      section = bfd_make_section (abfd, "$DST$");
+      if (!section)
+       return FALSE;
+      if (!bfd_set_section_flags (section, flags))
+       return FALSE;
+      PRIV (dst_section) = section;
+    }
+
+  PRIV (image_section) = section;
+  PRIV (image_offset) = section->size;
+
+  if (!_bfd_vms_slurp_etir (abfd, NULL))
+    return FALSE;
+
+  section->size = PRIV (image_offset);
+  return TRUE;
+}
+
+/* Process EDBG record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_edbg (bfd *abfd)
+{
+  vms_debug2 ((2, "EDBG\n"));
+
+  abfd->flags |= HAS_DEBUG | HAS_LINENO;
+
+  return vms_slurp_debug (abfd);
+}
 
 /* Process ETBT record.
    Return TRUE on success, FALSE on error.  */
@@ -2289,11 +2630,19 @@ _bfd_vms_slurp_eeom (bfd *abfd)
 
   vms_debug2 ((2, "EEOM\n"));
 
+  /* PR 21813: Check for an undersized record.  */
+  if (PRIV (recrd.buf_size) < sizeof (* eeom))
+    {
+      _bfd_error_handler (_("corrupt EEOM record - size is too small"));
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
   PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps);
   PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod);
   if (PRIV (eom_data).eom_w_comcod > 1)
     {
-      (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
+      _bfd_error_handler (_("object module not error-free !"));
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -2316,7 +2665,7 @@ _bfd_vms_slurp_eeom (bfd *abfd)
 static bfd_boolean
 _bfd_vms_slurp_object_records (bfd * abfd)
 {
-  bfd_boolean err;
+  bfd_boolean ok;
   int type;
 
   do
@@ -2332,28 +2681,28 @@ _bfd_vms_slurp_object_records (bfd * abfd)
 
       switch (type)
        {
-        case EOBJ__C_EMH:
-          err = _bfd_vms_slurp_ehdr (abfd);
-          break;
-        case EOBJ__C_EEOM:
-          err = _bfd_vms_slurp_eeom (abfd);
-          break;
-        case EOBJ__C_EGSD:
-          err = _bfd_vms_slurp_egsd (abfd);
-          break;
-        case EOBJ__C_ETIR:
-          err = TRUE; /* _bfd_vms_slurp_etir (abfd); */
-          break;
-        case EOBJ__C_EDBG:
-          err = _bfd_vms_slurp_edbg (abfd);
-          break;
-        case EOBJ__C_ETBT:
-          err = _bfd_vms_slurp_etbt (abfd);
-          break;
-        default:
-          err = FALSE;
+       case EOBJ__C_EMH:
+         ok = _bfd_vms_slurp_ehdr (abfd);
+         break;
+       case EOBJ__C_EEOM:
+         ok = _bfd_vms_slurp_eeom (abfd);
+         break;
+       case EOBJ__C_EGSD:
+         ok = _bfd_vms_slurp_egsd (abfd);
+         break;
+       case EOBJ__C_ETIR:
+         ok = TRUE; /* _bfd_vms_slurp_etir (abfd); */
+         break;
+       case EOBJ__C_EDBG:
+         ok = _bfd_vms_slurp_edbg (abfd);
+         break;
+       case EOBJ__C_ETBT:
+         ok = _bfd_vms_slurp_etbt (abfd);
+         break;
+       default:
+         ok = FALSE;
        }
-      if (err != TRUE)
+      if (!ok)
        {
          vms_debug2 ((2, "slurp type %d failed\n", type));
          return FALSE;
@@ -2368,7 +2717,7 @@ _bfd_vms_slurp_object_records (bfd * abfd)
 static bfd_boolean
 vms_initialize (bfd * abfd)
 {
-  bfd_size_type amt;
+  size_t amt;
 
   amt = sizeof (struct vms_private_data_struct);
   abfd->tdata.any = bfd_zalloc (abfd, amt);
@@ -2390,13 +2739,29 @@ 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.  */
 
-static const struct bfd_target *
+static bfd_cleanup
 alpha_vms_object_p (bfd *abfd)
 {
-  PTR tdata_save = abfd->tdata.any;
+  void *tdata_save = abfd->tdata.any;
   unsigned int test_len;
   unsigned char *buf;
 
@@ -2404,10 +2769,13 @@ 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;
+    goto error_ret;
 
   /* The first challenge with VMS is to discover the kind of the file.
 
@@ -2426,30 +2794,17 @@ alpha_vms_object_p (bfd *abfd)
      2 bytes size repeated) and 12 bytes for images (4 bytes major id,
      4 bytes minor id, 4 bytes length).  */
   test_len = 12;
-
-  /* Size the main buffer.  */
-  buf = (unsigned char *) bfd_malloc (test_len);
+  buf = _bfd_malloc_and_read (abfd, test_len, test_len);
   if (buf == NULL)
     goto error_ret;
   PRIV (recrd.buf) = buf;
   PRIV (recrd.buf_size) = test_len;
-
-  /* Initialize the record pointer.  */
   PRIV (recrd.rec) = buf;
 
-  if (bfd_bread (buf, test_len, abfd) != test_len)
-    {
-      bfd_set_error (bfd_error_file_truncated);
-      goto error_ret;
-    }
-
   /* Is it an image?  */
   if ((bfd_getl32 (buf) == EIHD__K_MAJORID)
       && (bfd_getl32 (buf + 4) == EIHD__K_MINORID))
     {
-      unsigned int to_read;
-      unsigned int read_so_far;
-      unsigned int remaining;
       unsigned int eisd_offset, eihs_offset;
 
       /* Extract the header size.  */
@@ -2457,55 +2812,38 @@ alpha_vms_object_p (bfd *abfd)
 
       /* The header size is 0 for DSF files.  */
       if (PRIV (recrd.rec_size) == 0)
-        PRIV (recrd.rec_size) = sizeof (struct vms_eihd);
-
-      if (PRIV (recrd.rec_size) > PRIV (recrd.buf_size))
-        {
-          buf = bfd_realloc_or_free (buf, PRIV (recrd.rec_size));
-
-          if (buf == NULL)
-            {
-              PRIV (recrd.buf) = NULL;
-              bfd_set_error (bfd_error_no_memory);
-              goto error_ret;
-            }
-          PRIV (recrd.buf) = buf;
-          PRIV (recrd.buf_size) = PRIV (recrd.rec_size);
-        }
-
-      /* Read the remaining record.  */
-      remaining = PRIV (recrd.rec_size) - test_len;
-      to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining);
-      read_so_far = test_len;
-
-      while (remaining > 0)
-        {
-          if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read)
-            {
-              bfd_set_error (bfd_error_file_truncated);
-              goto err_wrong_format;
-            }
-
-          read_so_far += to_read;
-          remaining -= to_read;
-
-          to_read = MIN (VMS_BLOCK_SIZE, remaining);
-        }
-
-      /* Reset the record pointer.  */
+       PRIV (recrd.rec_size) = sizeof (struct vms_eihd);
+
+      /* PR 21813: Check for a truncated record.  */
+      /* PR 17512: file: 7d7c57c2.  */
+      if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd))
+       goto err_wrong_format;
+
+      if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
+       goto error_ret;
+
+      free (PRIV (recrd.buf));
+      PRIV (recrd.buf) = NULL;
+      buf = _bfd_malloc_and_read (abfd, PRIV (recrd.rec_size),
+                                 PRIV (recrd.rec_size));
+      if (buf == NULL)
+       goto error_ret;
+
+      PRIV (recrd.buf) = buf;
+      PRIV (recrd.buf_size) = PRIV (recrd.rec_size);
       PRIV (recrd.rec) = buf;
 
       vms_debug2 ((2, "file type is image\n"));
 
-      if (_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset) != TRUE)
-        goto err_wrong_format;
+      if (!_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset))
+       goto err_wrong_format;
 
-      if (_bfd_vms_slurp_eisd (abfd, eisd_offset) != TRUE)
-        goto err_wrong_format;
+      if (!_bfd_vms_slurp_eisd (abfd, eisd_offset))
+       goto err_wrong_format;
 
       /* EIHS is optional.  */
-      if (eihs_offset != 0 && _bfd_vms_slurp_eihs (abfd, eihs_offset) != TRUE)
-        goto err_wrong_format;
+      if (eihs_offset != 0 && !_bfd_vms_slurp_eihs (abfd, eihs_offset))
+       goto err_wrong_format;
     }
   else
     {
@@ -2516,22 +2854,22 @@ alpha_vms_object_p (bfd *abfd)
 
       /* But is it really a module?  */
       if (bfd_getl16 (PRIV (recrd.rec)) <= EOBJ__C_MAXRECTYP
-          && bfd_getl16 (PRIV (recrd.rec) + 2) <= EOBJ__C_MAXRECSIZ)
-        {
-          if (vms_get_remaining_object_record (abfd, test_len) <= 0)
-            goto err_wrong_format;
+         && bfd_getl16 (PRIV (recrd.rec) + 2) <= EOBJ__C_MAXRECSIZ)
+       {
+         if (vms_get_remaining_object_record (abfd, test_len) <= 0)
+           goto err_wrong_format;
 
-          vms_debug2 ((2, "file type is module\n"));
+         vms_debug2 ((2, "file type is module\n"));
 
-          type = bfd_getl16 (PRIV (recrd.rec));
-          if (type != EOBJ__C_EMH || _bfd_vms_slurp_ehdr (abfd) != TRUE)
-            goto err_wrong_format;
+         type = bfd_getl16 (PRIV (recrd.rec));
+         if (type != EOBJ__C_EMH || !_bfd_vms_slurp_ehdr (abfd))
+           goto err_wrong_format;
 
-          if (_bfd_vms_slurp_object_records (abfd) != TRUE)
-            goto err_wrong_format;
-        }
+         if (!_bfd_vms_slurp_object_records (abfd))
+           goto err_wrong_format;
+       }
       else
-        goto err_wrong_format;
+       goto err_wrong_format;
     }
 
   /* Set arch_info to alpha.   */
@@ -2539,14 +2877,13 @@ alpha_vms_object_p (bfd *abfd)
   if (! bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0))
     goto err_wrong_format;
 
-  return abfd->xvec;
+  return alpha_vms_free_private;
 
  err_wrong_format:
   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;
@@ -2555,22 +2892,126 @@ alpha_vms_object_p (bfd *abfd)
 \f
 /* Image write.  */
 
+/* Write an EMH/MHD record.  */
+
 static void
-vector_grow1 (struct vector_type *vec, size_t elsz)
+_bfd_vms_write_emh (bfd *abfd)
 {
-  if (vec->nbr_el + 1 < vec->max_el)
-    return;
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  _bfd_vms_output_alignment (recwr, 2);
 
-  if (vec->max_el == 0)
+  /* EMH.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_MHD);
+  _bfd_vms_output_short (recwr, EOBJ__C_STRLVL);
+  _bfd_vms_output_long (recwr, 0);
+  _bfd_vms_output_long (recwr, 0);
+  _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE);
+
+  /* Create module name from filename.  */
+  if (bfd_get_filename (abfd) != 0)
     {
-      vec->max_el = 16;
-      vec->els = bfd_malloc2 (vec->max_el, elsz);
+      char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
+      _bfd_vms_output_counted (recwr, module);
+      free (module);
     }
   else
+    _bfd_vms_output_counted (recwr, "NONAME");
+
+  _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
+  _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH);
+  _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
+  _bfd_vms_output_end (abfd, recwr);
+}
+
+/* Write an EMH/LMN record.  */
+
+static void
+_bfd_vms_write_lmn (bfd *abfd, const char *name)
+{
+  char version [64];
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+  unsigned int ver = BFD_VERSION / 10000;
+
+  /* LMN.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_LNM);
+  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);
+}
+
+
+/* Write eom record for bfd abfd.  Return FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_write_eeom (bfd *abfd)
+{
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  vms_debug2 ((2, "vms_write_eeom\n"));
+
+  _bfd_vms_output_alignment (recwr, 2);
+
+  _bfd_vms_output_begin (recwr, EOBJ__C_EEOM);
+  _bfd_vms_output_long (recwr, PRIV (vms_linkage_index + 1) >> 1);
+  _bfd_vms_output_byte (recwr, 0);     /* Completion code.  */
+  _bfd_vms_output_byte (recwr, 0);     /* Fill byte.  */
+
+  if ((abfd->flags & EXEC_P) == 0
+      && bfd_get_start_address (abfd) != (bfd_vma)-1)
+    {
+      asection *section;
+
+      section = bfd_get_section_by_name (abfd, ".link");
+      if (section == 0)
+       {
+         bfd_set_error (bfd_error_nonrepresentable_section);
+         return FALSE;
+       }
+      _bfd_vms_output_short (recwr, 0);
+      _bfd_vms_output_long (recwr, (unsigned long) section->target_index);
+      _bfd_vms_output_long (recwr,
+                            (unsigned long) bfd_get_start_address (abfd));
+      _bfd_vms_output_long (recwr, 0);
+    }
+
+  _bfd_vms_output_end (abfd, recwr);
+  return TRUE;
+}
+
+static void *
+vector_grow1 (struct vector_type *vec, size_t elsz)
+{
+  if (vec->nbr_el >= vec->max_el)
     {
-      vec->max_el *= 2;
-      vec->els = bfd_realloc2 (vec->els, vec->max_el, elsz);
+      if (vec->max_el == 0)
+       {
+         vec->max_el = 16;
+         vec->els = bfd_malloc (vec->max_el * elsz);
+       }
+      else
+       {
+         size_t amt;
+         if (vec->max_el > -1u / 2)
+           {
+             bfd_set_error (bfd_error_file_too_big);
+             return NULL;
+           }
+         vec->max_el *= 2;
+         if (_bfd_mul_overflow (vec->max_el, elsz, &amt))
+           {
+             bfd_set_error (bfd_error_file_too_big);
+             return NULL;
+           }
+         vec->els = bfd_realloc_or_free (vec->els, amt);
+       }
     }
+  if (vec->els == NULL)
+    return NULL;
+  return (char *) vec->els + elsz * vec->nbr_el++;
 }
 
 /* Bump ABFD file position to next block.  */
@@ -2587,7 +3028,7 @@ alpha_vms_file_position_block (bfd *abfd)
 
 static void
 alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
-                         struct vms_eisd *dst)
+                        struct vms_eisd *dst)
 {
   bfd_putl32 (src->u.eisd.majorid, dst->majorid);
   bfd_putl32 (src->u.eisd.minorid, dst->minorid);
@@ -2606,7 +3047,7 @@ alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
     {
       bfd_putl32 (src->u.gbl_eisd.ident, dst->ident);
       memcpy (dst->gblnam, src->u.gbl_eisd.gblnam,
-              src->u.gbl_eisd.gblnam[0] + 1);
+             src->u.gbl_eisd.gblnam[0] + 1);
     }
 }
 
@@ -2658,7 +3099,7 @@ alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
   eisd->u.gbl_eisd.ident = PRIV2 (shrimg, ident);
   eisd->u.gbl_eisd.gblnam[0] = namlen + 4;
   memcpy (eisd->u.gbl_eisd.gblnam + 1, PRIV2 (shrimg, hdr_data.hdr_t_name),
-          namlen);
+         namlen);
   memcpy (eisd->u.gbl_eisd.gblnam + 1 + namlen, "_001", 4);
 
   /* Append it to the list.  */
@@ -2703,7 +3144,11 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
   if (!(sec->flags & SEC_READONLY))
     eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
 
-  if (!(sec->flags & SEC_LOAD))
+  /* If relocations or fixup will be applied, make this isect writeable.  */
+  if (sec->flags & SEC_RELOC)
+    eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
+
+  if (!(sec->flags & SEC_HAS_CONTENTS))
     {
       eisd->u.eisd.flags |= EISD__M_DZRO;
       eisd->u.eisd.flags &= ~EISD__M_CRF;
@@ -2711,7 +3156,7 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
   if (sec->flags & SEC_LINKER_CREATED)
     {
       if (strcmp (sec->name, "$FIXUP$") == 0)
-        eisd->u.eisd.flags |= EISD__M_FIXUPVEC;
+       eisd->u.eisd.flags |= EISD__M_FIXUPVEC;
     }
 
   /* Append it to the list.  */
@@ -2740,6 +3185,8 @@ alpha_vms_write_exec (bfd *abfd)
   struct vms_internal_eisd_map *eisd;
   asection *dst;
   asection *dmt;
+  file_ptr gst_filepos = 0;
+  unsigned int lnkflags = 0;
 
   /* Build the EIHD.  */
   PRIV (file_pos) = EIHD__C_LENGTH;
@@ -2767,8 +3214,7 @@ alpha_vms_write_exec (bfd *abfd)
   bfd_putl32 (-1, eihd.privreqs + 4);
 
   bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
-              eihd.hdrblkcnt);
-  bfd_putl32 (0, eihd.lnkflags);
+             eihd.hdrblkcnt);
   bfd_putl32 (0, eihd.ident);
   bfd_putl32 (0, eihd.sysver);
 
@@ -2786,11 +3232,10 @@ alpha_vms_write_exec (bfd *abfd)
 
   bfd_putl32 (sizeof (struct vms_eiha), eiha->size);
   bfd_putl32 (0, eiha->spare);
-  bfd_putl32 (0x00000340, eiha->tfradr1);      /* SYS$IMGACT */
-  bfd_putl32 (0xffffffff, eiha->tfradr1_h);
-  bfd_putl64 (bfd_get_start_address (abfd), eiha->tfradr2);
-  bfd_putl64 (0, eiha->tfradr3);
-  bfd_putl64 (0, eiha->tfradr4);
+  bfd_putl64 (PRIV (transfer_address[0]), eiha->tfradr1);
+  bfd_putl64 (PRIV (transfer_address[1]), eiha->tfradr2);
+  bfd_putl64 (PRIV (transfer_address[2]), eiha->tfradr3);
+  bfd_putl64 (PRIV (transfer_address[3]), eiha->tfradr4);
   bfd_putl64 (0, eiha->inishr);
 
   /* Alloc EIHI.  */
@@ -2804,6 +3249,7 @@ alpha_vms_write_exec (bfd *abfd)
     char *module;
     unsigned int len;
 
+    /* Set module name.  */
     module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
     len = strlen (module);
     if (len > sizeof (eihi->imgnam) - 1)
@@ -2812,8 +3258,15 @@ alpha_vms_write_exec (bfd *abfd)
     memcpy (eihi->imgnam + 1, module, len);
     free (module);
   }
-  bfd_putl32 (0, eihi->linktime + 0);
-  bfd_putl32 (0, eihi->linktime + 4);
+  {
+    unsigned int lo;
+    unsigned int hi;
+
+    /* Set time.  */
+    vms_get_time (&hi, &lo);
+    bfd_putl32 (lo, eihi->linktime + 0);
+    bfd_putl32 (hi, eihi->linktime + 4);
+  }
   eihi->imgid[0] = 0;
   eihi->linkid[0] = 0;
   eihi->imgbid[0] = 0;
@@ -2841,7 +3294,7 @@ alpha_vms_write_exec (bfd *abfd)
   for (sec = abfd->sections; sec; sec = sec->next)
     {
       if (!alpha_vms_create_eisd_for_section (abfd, sec))
-        return FALSE;
+       return FALSE;
     }
 
   /* Merge section EIDS which extra ones.  */
@@ -2859,7 +3312,7 @@ alpha_vms_write_exec (bfd *abfd)
     {
       eisd = bfd_zalloc (abfd, sizeof (*eisd));
       if (eisd == NULL)
-        return FALSE;
+       return FALSE;
       eisd->u.eisd.majorid = 0;
       eisd->u.eisd.minorid = 0;
       eisd->u.eisd.eisdsize = 0;
@@ -2873,15 +3326,15 @@ alpha_vms_write_exec (bfd *abfd)
 
       /* First block is a little bit special: there is a word at the end.  */
       if (PRIV (file_pos) < VMS_BLOCK_SIZE && room > 2)
-        room -= 2;
+       room -= 2;
       if (room < eisd->u.eisd.eisdsize + EISD__K_LENEND)
-        alpha_vms_file_position_block (abfd);
+       alpha_vms_file_position_block (abfd);
 
       eisd->file_pos = PRIV (file_pos);
       PRIV (file_pos) += eisd->u.eisd.eisdsize;
 
       if (eisd->u.eisd.flags & EISD__M_FIXUPVEC)
-        bfd_putl64 (eisd->u.eisd.virt_addr, eihd.iafva);
+       bfd_putl64 (eisd->u.eisd.virt_addr, eihd.iafva);
     }
 
   if (first_eisd != NULL)
@@ -2893,13 +3346,13 @@ alpha_vms_write_exec (bfd *abfd)
 
   bfd_putl32 (PRIV (file_pos), eihd.size);
   bfd_putl32 ((PRIV (file_pos) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
-              eihd.hdrblkcnt);
+             eihd.hdrblkcnt);
 
   /* Place sections.  */
   for (sec = abfd->sections; sec; sec = sec->next)
     {
       if (!(sec->flags & SEC_HAS_CONTENTS))
-        continue;
+       continue;
 
       eisd = vms_section_data (sec)->eisd;
 
@@ -2908,21 +3361,30 @@ alpha_vms_write_exec (bfd *abfd)
       sec->filepos = PRIV (file_pos);
 
       if (eisd != NULL)
-        eisd->u.eisd.vbn = (sec->filepos / VMS_BLOCK_SIZE) + 1;
+       eisd->u.eisd.vbn = (sec->filepos / VMS_BLOCK_SIZE) + 1;
 
       PRIV (file_pos) += sec->size;
     }
 
+  /* Update EIHS.  */
   if (eihs != NULL && dst != NULL)
     {
       bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn);
       bfd_putl32 (dst->size, eihs->dstsize);
 
       if (dmt != NULL)
-        {
-          bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
-          bfd_putl32 (dmt->size, eihs->dmtsize);
-        }
+       {
+         lnkflags |= EIHD__M_DBGDMT;
+         bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
+         bfd_putl32 (dmt->size, eihs->dmtsize);
+       }
+      if (PRIV (gsd_sym_count) != 0)
+       {
+         alpha_vms_file_position_block (abfd);
+         gst_filepos = PRIV (file_pos);
+         bfd_putl32 ((gst_filepos / VMS_BLOCK_SIZE) + 1, eihs->gstvbn);
+         bfd_putl32 ((PRIV (gsd_sym_count) + 4) / 5 + 4, eihs->gstsize);
+       }
     }
 
   /* Write EISD in hdr.  */
@@ -2932,6 +3394,7 @@ alpha_vms_write_exec (bfd *abfd)
       (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos));
 
   /* Write first block.  */
+  bfd_putl32 (lnkflags, eihd.lnkflags);
   if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
     return FALSE;
 
@@ -2943,23 +3406,23 @@ alpha_vms_write_exec (bfd *abfd)
 
       memset (blk, 0xff, sizeof (blk));
       while (eisd != NULL)
-        {
-          alpha_vms_swap_eisd_out
-            (eisd,
-             (struct vms_eisd *)(blk + (eisd->file_pos % VMS_BLOCK_SIZE)));
-
-          next_eisd = eisd->next;
-          if (next_eisd == NULL
-              || (next_eisd->file_pos / VMS_BLOCK_SIZE
-                  != eisd->file_pos / VMS_BLOCK_SIZE))
-            {
-              if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk))
-                return FALSE;
+       {
+         alpha_vms_swap_eisd_out
+           (eisd,
+            (struct vms_eisd *)(blk + (eisd->file_pos % VMS_BLOCK_SIZE)));
+
+         next_eisd = eisd->next;
+         if (next_eisd == NULL
+             || (next_eisd->file_pos / VMS_BLOCK_SIZE
+                 != eisd->file_pos / VMS_BLOCK_SIZE))
+           {
+             if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk))
+               return FALSE;
 
-              memset (blk, 0xff, sizeof (blk));
-            }
-          eisd = next_eisd;
-        }
+             memset (blk, 0xff, sizeof (blk));
+           }
+         eisd = next_eisd;
+       }
     }
 
   /* Write sections.  */
@@ -2969,106 +3432,84 @@ alpha_vms_write_exec (bfd *abfd)
       bfd_size_type len;
 
       if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS))
-        continue;
+       continue;
       if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size)
-        return FALSE;
+       return FALSE;
 
       /* Pad.  */
       len = VMS_BLOCK_SIZE - sec->size % VMS_BLOCK_SIZE;
       if (len != VMS_BLOCK_SIZE)
-        {
-          memset (blk, 0, len);
-          if (bfd_bwrite (blk, len, abfd) != len)
-            return FALSE;
-        }
+       {
+         memset (blk, 0, len);
+         if (bfd_bwrite (blk, len, abfd) != len)
+           return FALSE;
+       }
     }
 
-  return TRUE;
-}
-\f
-/* Object write.  */
-
-/* This hash routine borrowed from GNU-EMACS, and strengthened
-   slightly.  ERY.  */
-
-static int
-hash_string (const char *ptr)
-{
-  const unsigned char *p = (unsigned char *) ptr;
-  const unsigned char *end = p + strlen (ptr);
-  unsigned char c;
-  int hash = 0;
-
-  while (p != end)
+  /* Write GST.  */
+  if (gst_filepos != 0)
     {
-      c = *p++;
-      hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
-    }
-  return hash;
-}
-
-/* Generate a length-hashed VMS symbol name (limited to maxlen chars).  */
-
-static char *
-_bfd_vms_length_hash_symbol (bfd *abfd, const char *in, int maxlen)
-{
-  unsigned long result;
-  int in_len;
-  char *new_name;
-  const char *old_name;
-  int i;
-  static char outbuf[EOBJ__C_SYMSIZ + 1];
-  char *out = outbuf;
-
-#if VMS_DEBUG
-  vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
-#endif
-
-  if (maxlen > EOBJ__C_SYMSIZ)
-    maxlen = EOBJ__C_SYMSIZ;
-
-  /* Save this for later.  */
-  new_name = out;
-
-  /* We may need to truncate the symbol, save the hash for later.  */
-  in_len = strlen (in);
+      struct vms_rec_wr *recwr = &PRIV (recwr);
+      unsigned int i;
 
-  result = (in_len > maxlen) ? hash_string (in) : 0;
-
-  old_name = in;
-
-  /* Do the length checking.  */
-  if (in_len <= maxlen)
-    i = in_len;
-  else
-    {
-      if (PRIV (flag_hash_long_names))
-       i = maxlen - 9;
-      else
-       i = maxlen;
-    }
+      _bfd_vms_write_emh (abfd);
+      _bfd_vms_write_lmn (abfd, "GNU LD");
 
-  strncpy (out, in, (size_t) i);
-  in += i;
-  out += i;
+      /* PSC for the absolute section.  */
+      _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+      _bfd_vms_output_long (recwr, 0);
+      _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+      _bfd_vms_output_short (recwr, 0);
+      _bfd_vms_output_short (recwr, EGPS__V_PIC | EGPS__V_LIB | EGPS__V_RD);
+      _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 ((in_len > maxlen)
-      && PRIV (flag_hash_long_names))
-    sprintf (out, "_%08lx", result);
-  else
-    *out = 0;
+      for (i = 0; i < PRIV (gsd_sym_count); i++)
+       {
+         struct vms_symbol_entry *sym = PRIV (syms)[i];
+         bfd_vma val;
+         bfd_vma ep;
 
-#if VMS_DEBUG
-  vms_debug (4, "--> [%d]\"%s\"\n", (int)strlen (outbuf), outbuf);
-#endif
+         if ((i % 5) == 0)
+           {
+             _bfd_vms_output_alignment (recwr, 8);
+             _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+             _bfd_vms_output_long (recwr, 0);
+           }
+         _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYMG);
+         _bfd_vms_output_short (recwr, 0); /* Data type, alignment.  */
+         _bfd_vms_output_short (recwr, sym->flags);
 
-  if (in_len > maxlen
-       && PRIV (flag_hash_long_names)
-       && PRIV (flag_show_after_trunc))
-    printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
+         if (sym->code_section)
+           ep = alpha_vms_get_sym_value (sym->code_section, sym->code_value);
+         else
+           {
+             BFD_ASSERT (sym->code_value == 0);
+             ep = 0;
+           }
+         val = alpha_vms_get_sym_value (sym->section, sym->value);
+         _bfd_vms_output_quad
+           (recwr, sym->typ == EGSD__C_SYMG ? sym->symbol_vector : val);
+         _bfd_vms_output_quad (recwr, ep);
+         _bfd_vms_output_quad (recwr, val);
+         _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) != 0)
+       _bfd_vms_output_end (abfd, recwr);
 
-  return outbuf;
+      if (!_bfd_vms_write_eeom (abfd))
+       return FALSE;
+    }
+  return TRUE;
 }
+\f
+/* Object write.  */
 
 /* Write section and symbol directory of bfd abfd.  Return FALSE on error.  */
 
@@ -3078,18 +3519,13 @@ _bfd_vms_write_egsd (bfd *abfd)
   asection *section;
   asymbol *symbol;
   unsigned int symnum;
-  int last_index = -1;
-  char dummy_name[10];
-  char *sname;
+  const char *sname;
   flagword new_flags, old_flags;
-  int abs_section_index = 0;
+  int abs_section_index = -1;
+  unsigned int target_index = 0;
   struct vms_rec_wr *recwr = &PRIV (recwr);
 
-  vms_debug2 ((2, "vms_write_gsd\n"));
-
-  /* Output sections.  */
-  section = abfd->sections;
-  vms_debug2 ((3, "%d sections found\n", abfd->section_count));
+  vms_debug2 ((2, "vms_write_egsd\n"));
 
   /* Egsd is quadword aligned.  */
   _bfd_vms_output_alignment (recwr, 8);
@@ -3097,15 +3533,28 @@ _bfd_vms_write_egsd (bfd *abfd)
   _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
   _bfd_vms_output_long (recwr, 0);
 
-  while (section != 0)
+  /* Number sections.  */
+  for (section = abfd->sections; section != NULL; section = section->next)
+    {
+      if (section->flags & SEC_DEBUGGING)
+       continue;
+      if (!strcmp (section->name, ".vmsdebug"))
+       {
+         section->flags |= SEC_DEBUGGING;
+         continue;
+       }
+      section->target_index = target_index++;
+    }
+
+  for (section = abfd->sections; section != NULL; section = section->next)
     {
       vms_debug2 ((3, "Section #%d %s, %d bytes\n",
-                   section->index, section->name, (int)section->size));
+                  section->target_index, section->name, (int)section->size));
 
       /* Don't write out the VMS debug info section since it is in the
-         ETBT and EDBG sections in etir. */
-      if (!strcmp (section->name, ".vmsdebug"))
-        goto done;
+        ETBT and EDBG sections in etir. */
+      if (section->flags & SEC_DEBUGGING)
+       continue;
 
       /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
       if (_bfd_vms_output_check (recwr, 64) < 0)
@@ -3115,25 +3564,12 @@ _bfd_vms_write_egsd (bfd *abfd)
          _bfd_vms_output_long (recwr, 0);
        }
 
-      /* Create dummy sections to keep consecutive indices.  */
-      while (section->index - last_index > 1)
-       {
-         vms_debug2 ((3, "index %d, last %d\n", section->index, last_index));
-         _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
-         _bfd_vms_output_short (recwr, 0);
-         _bfd_vms_output_short (recwr, 0);
-         _bfd_vms_output_long (recwr, 0);
-         sprintf (dummy_name, ".DUMMY%02d", last_index);
-         _bfd_vms_output_counted (recwr, dummy_name);
-         _bfd_vms_output_end_subrec (recwr);
-         last_index++;
-       }
-
       /* Don't know if this is necessary for the linker but for now it keeps
-        vms_slurp_gsd happy  */
-      sname = (char *)section->name;
+        vms_slurp_gsd happy.  */
+      sname = section->name;
       if (*sname == '.')
        {
+         /* Remove leading dot.  */
          sname++;
          if ((*sname == 't') && (strcmp (sname, "text") == 0))
            sname = EVAX_CODE_NAME;
@@ -3148,20 +3584,12 @@ _bfd_vms_write_egsd (bfd *abfd)
          else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
            sname = EVAX_LITERAL_NAME;
          else if ((*sname == 'l') && (strcmp (sname, "literals") == 0))
-           {
-             sname = EVAX_LITERALS_NAME;
-             abs_section_index = section->index;
-           }
+           sname = EVAX_LITERALS_NAME;
          else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
            sname = EVAX_COMMON_NAME;
          else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
            sname = EVAX_LOCAL_NAME;
        }
-      else
-       sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ__C_SECSIZ);
-
-      _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
-      _bfd_vms_output_short (recwr, section->alignment_power & 0xff);
 
       if (bfd_is_com_section (section))
        new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD
@@ -3179,16 +3607,19 @@ _bfd_vms_write_egsd (bfd *abfd)
 
       vms_debug2 ((3, "sec flags %x\n", section->flags));
       vms_debug2 ((3, "new_flags %x, _raw_size %lu\n",
-                   new_flags, (unsigned long)section->size));
+                  new_flags, (unsigned long)section->size));
 
+      _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+      _bfd_vms_output_short (recwr, section->alignment_power & 0xff);
       _bfd_vms_output_short (recwr, new_flags);
       _bfd_vms_output_long (recwr, (unsigned long) section->size);
       _bfd_vms_output_counted (recwr, sname);
       _bfd_vms_output_end_subrec (recwr);
 
-      last_index = section->index;
-done:
-      section = section->next;
+      /* If the section is an obsolute one, remind its index as it will be
+        used later for absolute symbols.  */
+      if ((new_flags & EGPS__V_REL) == 0 && abs_section_index < 0)
+       abs_section_index = section->target_index;
     }
 
   /* Output symbols.  */
@@ -3198,33 +3629,54 @@ done:
 
   for (symnum = 0; symnum < abfd->symcount; symnum++)
     {
-      char *hash;
-
       symbol = abfd->outsymbols[symnum];
-      if (*(symbol->name) == '_')
-       {
-         if (strcmp (symbol->name, "__main") == 0)
-           bfd_set_start_address (abfd, (bfd_vma)symbol->value);
-       }
       old_flags = symbol->flags;
 
+      /* Work-around a missing feature:  consider __main as the main entry
+        point.  */
+      if (symbol->name[0] == '_' && strcmp (symbol->name, "__main") == 0)
+       bfd_set_start_address (abfd, (bfd_vma)symbol->value);
+
+      /* Only put in the GSD the global and the undefined symbols.  */
       if (old_flags & BSF_FILE)
        continue;
 
-      if ((old_flags & BSF_GLOBAL) == 0                   /* Not xdef...  */
-         && !bfd_is_und_section (symbol->section) /* and not xref... */
-         && !((old_flags & BSF_SECTION_SYM) != 0  /* and not LIB$INITIALIZE.  */
-              && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
-       continue;
+      if ((old_flags & BSF_GLOBAL) == 0 && !bfd_is_und_section (symbol->section))
+       {
+         /* If the LIB$INITIIALIZE section is present, add a reference to
+            LIB$INITIALIZE symbol.  FIXME: this should be done explicitely
+            in the assembly file.  */
+         if (!((old_flags & BSF_SECTION_SYM) != 0
+               && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
+           continue;
+       }
 
-      /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  */
-      if (_bfd_vms_output_check (recwr, 80) < 0)
+      /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  Add 16 more
+        bytes for a possible ABS section.  */
+      if (_bfd_vms_output_check (recwr, 80 + 16) < 0)
        {
          _bfd_vms_output_end (abfd, recwr);
          _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
          _bfd_vms_output_long (recwr, 0);
        }
 
+      if ((old_flags & BSF_GLOBAL) != 0
+         && bfd_is_abs_section (symbol->section)
+         && abs_section_index <= 0)
+       {
+         /* Create an absolute section if none was defined.  It is highly
+            unlikely that the name $ABS$ clashes with a user defined
+            non-absolute section name.  */
+         _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+         _bfd_vms_output_short (recwr, 4);
+         _bfd_vms_output_short (recwr, EGPS__V_SHR);
+         _bfd_vms_output_long (recwr, 0);
+         _bfd_vms_output_counted (recwr, "$ABS$");
+         _bfd_vms_output_end_subrec (recwr);
+
+         abs_section_index = target_index++;
+       }
+
       _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYM);
 
       /* Data type, alignment.  */
@@ -3261,25 +3713,24 @@ done:
            {
              asymbol *sym;
 
-              sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
+             sym =
+               ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
              code_address = sym->value;
-             ca_psindx = sym->section->index;
+             ca_psindx = sym->section->target_index;
            }
          if (bfd_is_abs_section (symbol->section))
            psindx = abs_section_index;
          else
-           psindx = symbol->section->index;
+           psindx = symbol->section->target_index;
 
          _bfd_vms_output_quad (recwr, symbol->value);
          _bfd_vms_output_quad (recwr, code_address);
          _bfd_vms_output_long (recwr, ca_psindx);
          _bfd_vms_output_long (recwr, psindx);
        }
-      hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ__C_SYMSIZ);
-      _bfd_vms_output_counted (recwr, hash);
+      _bfd_vms_output_counted (recwr, symbol->name);
 
       _bfd_vms_output_end_subrec (recwr);
-
     }
 
   _bfd_vms_output_alignment (recwr, 8);
@@ -3295,44 +3746,14 @@ _bfd_vms_write_ehdr (bfd *abfd)
 {
   asymbol *symbol;
   unsigned int symnum;
-  int had_case = 0;
-  int had_file = 0;
-  char version [256];
   struct vms_rec_wr *recwr = &PRIV (recwr);
 
   vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd));
 
   _bfd_vms_output_alignment (recwr, 2);
 
-  /* EMH.  */
-  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
-  _bfd_vms_output_short (recwr, EMH__C_MHD);
-  _bfd_vms_output_short (recwr, EOBJ__C_STRLVL);
-  _bfd_vms_output_long (recwr, 0);
-  _bfd_vms_output_long (recwr, 0);
-  _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE);
-
-  /* Create module name from filename.  */
-  if (bfd_get_filename (abfd) != 0)
-    {
-      char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
-      _bfd_vms_output_counted (recwr, module);
-      free (module);
-    }
-  else
-    _bfd_vms_output_counted (recwr, "NONAME");
-
-  _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
-  _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH);
-  _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
-  _bfd_vms_output_end (abfd, recwr);
-
-  /* LMN.  */
-  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
-  _bfd_vms_output_short (recwr, EMH__C_LNM);
-  snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
-  _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version));
-  _bfd_vms_output_end (abfd, recwr);
+  _bfd_vms_write_emh (abfd);
+  _bfd_vms_write_lmn (abfd, "GNU AS");
 
   /* SRC.  */
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
@@ -3344,22 +3765,9 @@ _bfd_vms_write_ehdr (bfd *abfd)
 
       if (symbol->flags & BSF_FILE)
        {
-         if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
-           {
-             PRIV (flag_hash_long_names) = symbol->name[6] - '0';
-             PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
-
-             if (had_file)
-               break;
-             had_case = 1;
-             continue;
-           }
-
          _bfd_vms_output_dump (recwr, (unsigned char *) symbol->name,
                                (int) strlen (symbol->name));
-         if (had_case)
-           break;
-         had_file = 1;
+         break;
        }
     }
 
@@ -3378,7 +3786,7 @@ _bfd_vms_write_ehdr (bfd *abfd)
   _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
   _bfd_vms_output_short (recwr, EMH__C_CPR);
   _bfd_vms_output_dump (recwr,
-                        (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
+                       (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
                         39);
   _bfd_vms_output_end (abfd, recwr);
 
@@ -3407,39 +3815,38 @@ start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
 {
   struct vms_rec_wr *recwr = &PRIV (recwr);
 
-  if (section->name[0] == '.' && section->name[1] == 'v'
-      && !strcmp (section->name, ".vmsdebug"))
+  if (section->flags & SEC_DEBUGGING)
     {
       _bfd_vms_output_begin (recwr, EOBJ__C_ETBT);
 
       if (offset == 0)
-        {
-          /* Push start offset.  */
-          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
-          _bfd_vms_output_long (recwr, (unsigned long) 0);
-          _bfd_vms_output_end_subrec (recwr);
+       {
+         /* Push start offset.  */
+         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+         _bfd_vms_output_long (recwr, (unsigned long) 0);
+         _bfd_vms_output_end_subrec (recwr);
 
-          /* Set location.  */
-          _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_DFLOC);
-          _bfd_vms_output_end_subrec (recwr);
-        }
+         /* Set location.  */
+         _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_DFLOC);
+         _bfd_vms_output_end_subrec (recwr);
+       }
     }
   else
     {
       _bfd_vms_output_begin (recwr, EOBJ__C_ETIR);
 
       if (offset == 0)
-        {
-          /* Push start offset.  */
-          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
-          _bfd_vms_output_long (recwr, (unsigned long) section->index);
-          _bfd_vms_output_quad (recwr, offset);
-          _bfd_vms_output_end_subrec (recwr);
-
-          /* Start = pop ().  */
-          _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_SETRB);
-          _bfd_vms_output_end_subrec (recwr);
-        }
+       {
+         /* Push start offset.  */
+         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+         _bfd_vms_output_long (recwr, (unsigned long) section->target_index);
+         _bfd_vms_output_quad (recwr, offset);
+         _bfd_vms_output_end_subrec (recwr);
+
+         /* Start = pop ().  */
+         _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_SETRB);
+         _bfd_vms_output_end_subrec (recwr);
+       }
     }
 }
 
@@ -3448,7 +3855,7 @@ start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
 
 static void
 sto_imm (bfd *abfd, asection *section,
-         bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
+        bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
 {
   bfd_size_type size;
   struct vms_rec_wr *recwr = &PRIV (recwr);
@@ -3468,7 +3875,7 @@ sto_imm (bfd *abfd, asection *section,
          /* Doesn't fit, split !  */
          end_etir_record (abfd);
 
-          start_etir_or_etbt_record (abfd, section, vaddr);
+         start_etir_or_etbt_record (abfd, section, vaddr);
 
          size = _bfd_vms_output_check (recwr, 0);      /* get max size */
          if (size > ssize)                     /* more than what's left ? */
@@ -3532,12 +3939,12 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 
   _bfd_vms_output_alignment (recwr, 4);
 
-  PRIV (vms_linkage_index) = 1;
+  PRIV (vms_linkage_index) = 0;
 
   for (section = abfd->sections; section; section = section->next)
     {
       vms_debug2 ((4, "writing %d. section '%s' (%d bytes)\n",
-                   section->index, section->name, (int) (section->size)));
+                  section->target_index, section->name, (int) (section->size)));
 
       if (!(section->flags & SEC_HAS_CONTENTS)
          || bfd_is_com_section (section))
@@ -3560,9 +3967,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
          int pass2_in_progress = 0;
          unsigned int irel;
 
-         if (section->reloc_count <= 0)
-           (*_bfd_error_handler)
-             (_("SEC_RELOC with no relocs in section %s"), section->name);
+         if (section->reloc_count == 0)
+           _bfd_error_handler
+             (_("SEC_RELOC with no relocs in section %pA"), section);
 
 #if VMS_DEBUG
          else
@@ -3578,9 +3985,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                                  (*(*rptr)->sym_ptr_ptr)->section->name,
                                  (long) (*(*rptr)->sym_ptr_ptr)->value,
                                  (unsigned long)(*rptr)->address,
-                                  (unsigned long)(*rptr)->addend,
+                                 (unsigned long)(*rptr)->addend,
                                  bfd_get_reloc_size ((*rptr)->howto),
-                                  ( *rptr)->howto->name);
+                                 ( *rptr)->howto->name);
                  rptr++;
                }
            }
@@ -3596,7 +4003,6 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
              asection *sec = sym->section;
              bfd_boolean defer = defer_reloc_p (rptr);
              unsigned int slen;
-             char *hash;
 
              if (pass2_in_progress)
                {
@@ -3614,9 +4020,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    }
 
                  /* Regular relocs are intertwined with binary data.  */
-                 if (curr_addr > addr)
-                   (*_bfd_error_handler) (_("Size error in section %s"),
-                                          section->name);
+                 if (curr_addr > addr)
+                   _bfd_error_handler (_("size error in section %pA"),
+                                       section);
                  size = addr - curr_addr;
                  sto_imm (abfd, section, size, curr_data, curr_addr);
                  curr_data += size;
@@ -3626,7 +4032,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
              size = bfd_get_reloc_size (rptr->howto);
 
              switch (rptr->howto->type)
-               {
+               {
                case ALPHA_R_IGNORE:
                  break;
 
@@ -3635,13 +4041,11 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    {
                      bfd_vma addend = rptr->addend;
                      slen = strlen ((char *) sym->name);
-                     hash = _bfd_vms_length_hash_symbol
-                        (abfd, sym->name, EOBJ__C_SYMSIZ);
                      etir_output_check (abfd, section, curr_addr, slen);
                      if (addend)
                        {
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
-                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_counted (recwr, sym->name);
                          _bfd_vms_output_end_subrec (recwr);
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
                          _bfd_vms_output_long (recwr, (unsigned long) addend);
@@ -3654,8 +4058,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                      else
                        {
                          _bfd_vms_output_begin_subrec
-                            (recwr, ETIR__C_STO_GBL_LW);
-                         _bfd_vms_output_counted (recwr, hash);
+                           (recwr, ETIR__C_STO_GBL_LW);
+                         _bfd_vms_output_counted (recwr, sym->name);
                          _bfd_vms_output_end_subrec (recwr);
                        }
                    }
@@ -3672,7 +4076,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    {
                      etir_output_check (abfd, section, curr_addr, 32);
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
-                     _bfd_vms_output_long (recwr, (unsigned long) sec->index);
+                     _bfd_vms_output_long (recwr,
+                                           (unsigned long) sec->target_index);
                      _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
                      _bfd_vms_output_end_subrec (recwr);
                      /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
@@ -3689,13 +4094,11 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    {
                      bfd_vma addend = rptr->addend;
                      slen = strlen ((char *) sym->name);
-                     hash = _bfd_vms_length_hash_symbol
-                        (abfd, sym->name, EOBJ__C_SYMSIZ);
                      etir_output_check (abfd, section, curr_addr, slen);
                      if (addend)
                        {
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
-                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_counted (recwr, sym->name);
                          _bfd_vms_output_end_subrec (recwr);
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
                          _bfd_vms_output_quad (recwr, addend);
@@ -3708,7 +4111,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                      else
                        {
                          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL);
-                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_counted (recwr, sym->name);
                          _bfd_vms_output_end_subrec (recwr);
                        }
                    }
@@ -3725,7 +4128,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                    {
                      etir_output_check (abfd, section, curr_addr, 32);
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
-                     _bfd_vms_output_long (recwr, (unsigned long) sec->index);
+                     _bfd_vms_output_long (recwr,
+                                           (unsigned long) sec->target_index);
                      _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
                      _bfd_vms_output_end_subrec (recwr);
                      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_OFF);
@@ -3738,25 +4142,23 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                  break;
 
                case ALPHA_R_LINKAGE:
+                 size = 16;
                  etir_output_check (abfd, section, curr_addr, 64);
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) PRIV (vms_linkage_index));
-                 PRIV (vms_linkage_index) += 2;
-                 hash = _bfd_vms_length_hash_symbol
-                    (abfd, sym->name, EOBJ__C_SYMSIZ);
-                 _bfd_vms_output_counted (recwr, hash);
+                   (recwr, (unsigned long) rptr->addend);
+                 if (rptr->addend > PRIV (vms_linkage_index))
+                   PRIV (vms_linkage_index) = rptr->addend;
+                 _bfd_vms_output_counted (recwr, sym->name);
                  _bfd_vms_output_byte (recwr, 0);
                  _bfd_vms_output_end_subrec (recwr);
                  break;
 
                case ALPHA_R_CODEADDR:
                  slen = strlen ((char *) sym->name);
-                 hash = _bfd_vms_length_hash_symbol
-                    (abfd, sym->name, EOBJ__C_SYMSIZ);
                  etir_output_check (abfd, section, curr_addr, slen);
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
-                 _bfd_vms_output_counted (recwr, hash);
+                 _bfd_vms_output_counted (recwr, sym->name);
                  _bfd_vms_output_end_subrec (recwr);
                  break;
 
@@ -3768,20 +4170,18 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL);
                  _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) udata->enbsym->section->index);
+                   (recwr, (unsigned long) section->target_index);
                  _bfd_vms_output_quad (recwr, rptr->address);
                  _bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) udata->enbsym->section->index);
+                   (recwr, (unsigned long) section->target_index);
                  _bfd_vms_output_quad (recwr, rptr->addend);
-                 _bfd_vms_output_counted
-                   (recwr, _bfd_vms_length_hash_symbol
-                     (abfd, udata->origname, EOBJ__C_SYMSIZ));
+                 _bfd_vms_output_counted (recwr, udata->origname);
                  _bfd_vms_output_end_subrec (recwr);
                  break;
 
                case ALPHA_R_BSR:
-                 (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc"));
+                 _bfd_error_handler (_("spurious ALPHA_R_BSR reloc"));
                  break;
 
                case ALPHA_R_LDA:
@@ -3793,15 +4193,13 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                  _bfd_vms_output_long
                    (recwr, (unsigned long) udata->lkindex + 1);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) udata->enbsym->section->index);
+                   (recwr, (unsigned long) section->target_index);
                  _bfd_vms_output_quad (recwr, rptr->address);
                  _bfd_vms_output_long (recwr, (unsigned long) 0x237B0000);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) udata->bsym->section->index);
+                   (recwr, (unsigned long) udata->bsym->section->target_index);
                  _bfd_vms_output_quad (recwr, rptr->addend);
-                 _bfd_vms_output_counted
-                   (recwr, _bfd_vms_length_hash_symbol
-                     (abfd, udata->origname, EOBJ__C_SYMSIZ));
+                 _bfd_vms_output_counted (recwr, udata->origname);
                  _bfd_vms_output_end_subrec (recwr);
                  break;
 
@@ -3813,21 +4211,19 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
                  _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL);
                  _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) udata->enbsym->section->index);
+                   (recwr, (unsigned long) section->target_index);
                  _bfd_vms_output_quad (recwr, rptr->address);
                  _bfd_vms_output_long (recwr, (unsigned long) 0xD3400000);
                  _bfd_vms_output_long
-                   (recwr, (unsigned long) udata->enbsym->section->index);
+                   (recwr, (unsigned long) section->target_index);
                  _bfd_vms_output_quad (recwr, rptr->addend);
-                 _bfd_vms_output_counted
-                   (recwr, _bfd_vms_length_hash_symbol
-                     (abfd, udata->origname, EOBJ__C_SYMSIZ));
+                 _bfd_vms_output_counted (recwr, udata->origname);
                  _bfd_vms_output_end_subrec (recwr);
                  break;
 
                default:
-                 (*_bfd_error_handler) (_("Unhandled relocation %s"),
-                                        rptr->howto->name);
+                 _bfd_error_handler (_("unhandled relocation %s"),
+                                     rptr->howto->name);
                  break;
                }
 
@@ -3839,8 +4235,10 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
            {
              /* Output rest of section.  */
              if (curr_addr > section->size)
-               (*_bfd_error_handler) (_("Size error in section %s"),
-                                      section->name);
+               {
+                 _bfd_error_handler (_("size error in section %pA"), section);
+                 return FALSE;
+               }
              size = section->size - curr_addr;
              sto_imm (abfd, section, size, curr_data, curr_addr);
              curr_data += size;
@@ -3864,41 +4262,6 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
   return TRUE;
 }
 
-/* Write eom record for bfd abfd.  Return FALSE on error.  */
-
-static bfd_boolean
-_bfd_vms_write_eeom (bfd *abfd)
-{
-  struct vms_rec_wr *recwr = &PRIV (recwr);
-
-  vms_debug2 ((2, "vms_write_eeom\n"));
-
-  _bfd_vms_output_begin (recwr, EOBJ__C_EEOM);
-  _bfd_vms_output_long (recwr, (unsigned long) (PRIV (vms_linkage_index) >> 1));
-  _bfd_vms_output_byte (recwr, 0);     /* Completion code.  */
-  _bfd_vms_output_byte (recwr, 0);     /* Fill byte.  */
-
-  if (bfd_get_start_address (abfd) != (bfd_vma)-1)
-    {
-      asection *section;
-
-      section = bfd_get_section_by_name (abfd, ".link");
-      if (section == 0)
-       {
-         bfd_set_error (bfd_error_nonrepresentable_section);
-         return FALSE;
-       }
-      _bfd_vms_output_short (recwr, 0);
-      _bfd_vms_output_long (recwr, (unsigned long) (section->index));
-      _bfd_vms_output_long (recwr,
-                            (unsigned long) bfd_get_start_address (abfd));
-      _bfd_vms_output_long (recwr, 0);
-    }
-
-  _bfd_vms_output_end (abfd, recwr);
-  return TRUE;
-}
-
 /* Write cached information into a file being written, at bfd_close.  */
 
 static bfd_boolean
@@ -3913,16 +4276,16 @@ alpha_vms_write_object_contents (bfd *abfd)
   else
     {
       if (abfd->section_count > 0)                     /* we have sections */
-        {
-          if (_bfd_vms_write_ehdr (abfd) != TRUE)
-            return FALSE;
-          if (_bfd_vms_write_egsd (abfd) != TRUE)
-            return FALSE;
-          if (_bfd_vms_write_etir (abfd, EOBJ__C_ETIR) != TRUE)
-            return FALSE;
-          if (_bfd_vms_write_eeom (abfd) != TRUE)
-            return FALSE;
-        }
+       {
+         if (!_bfd_vms_write_ehdr (abfd))
+           return FALSE;
+         if (!_bfd_vms_write_egsd (abfd))
+           return FALSE;
+         if (!_bfd_vms_write_etir (abfd, EOBJ__C_ETIR))
+           return FALSE;
+         if (!_bfd_vms_write_eeom (abfd))
+           return FALSE;
+       }
     }
   return TRUE;
 }
@@ -3948,7 +4311,7 @@ new_module (bfd *abfd)
 
 /* Parse debug info for a module and internalize it.  */
 
-static void
+static bfd_boolean
 parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
              int length)
 {
@@ -3976,20 +4339,21 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
       vms_debug2 ((2, "DST record: leng %d, type %d\n", rec_length, rec_type));
 
       if (length == -1 && rec_type == DST__K_MODEND)
-        break;
+       break;
 
       switch (rec_type)
        {
        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;
          prev_pc = 0;
          curr_linenum = 0;
          prev_linum = 0;
 
-          vms_debug2 ((3, "module: %s\n", module->name));
+         vms_debug2 ((3, "module: %s\n", module->name));
          break;
 
        case DST__K_MODEND:
@@ -3998,14 +4362,15 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
        case DST__K_RTNBEG:
          funcinfo = (struct funcinfo *)
            bfd_zalloc (abfd, sizeof (struct funcinfo));
-          funcinfo->name
-           = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
+         funcinfo->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;
          module->func_table = funcinfo;
 
-          vms_debug2 ((3, "routine: %s at 0x%lx\n",
-                       funcinfo->name, (unsigned long) funcinfo->low));
+         vms_debug2 ((3, "routine: %s at 0x%lx\n",
+                      funcinfo->name, (unsigned long) funcinfo->low));
          break;
 
        case DST__K_RTNEND:
@@ -4015,23 +4380,23 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
          if (module->func_table->high > module->high)
            module->high = module->func_table->high;
 
-          vms_debug2 ((3, "end routine\n"));
+         vms_debug2 ((3, "end routine\n"));
          break;
 
        case DST__K_PROLOG:
-          vms_debug2 ((3, "prologue\n"));
+         vms_debug2 ((3, "prologue\n"));
          break;
 
        case DST__K_EPILOG:
-          vms_debug2 ((3, "epilog\n"));
+         vms_debug2 ((3, "epilog\n"));
          break;
 
        case DST__K_BLKBEG:
-          vms_debug2 ((3, "block\n"));
+         vms_debug2 ((3, "block\n"));
          break;
 
        case DST__K_BLKEND:
-          vms_debug2 ((3, "end block\n"));
+         vms_debug2 ((3, "end block\n"));
          break;
 
        case DST__K_SOURCE:
@@ -4049,24 +4414,27 @@ 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);
+                   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)
                      {
                        module->file_table_count *= 2;
                        module->file_table
-                         = bfd_realloc (module->file_table,
-                                        module->file_table_count
-                                          * sizeof (struct fileinfo));
+                         = bfd_realloc_or_free (module->file_table,
+                                                module->file_table_count
+                                                * sizeof (struct fileinfo));
+                       if (module->file_table == NULL)
+                         return FALSE;
                      }
 
                    module->file_table [fileid].name = filename;
                    module->file_table [fileid].srec = 1;
                    cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
                    vms_debug2 ((4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
-                                 fileid, module->file_table [fileid].name));
+                                fileid, module->file_table [fileid].name));
                  }
                  break;
 
@@ -4151,8 +4519,8 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
                  break;
 
                default:
-                 (*_bfd_error_handler) (_("unknown source command %d"),
-                                        cmd);
+                 _bfd_error_handler (_("unknown source command %d"),
+                                     cmd);
                  cmd_length = 2;
                  break;
                }
@@ -4211,32 +4579,32 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
                  break;
 
                case DST__K_SET_LINUM_INCR:
-                 (*_bfd_error_handler)
-                   (_("DST__K_SET_LINUM_INCR not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_SET_LINUM_INCR");
                  cmd_length = 2;
                  break;
 
                case DST__K_SET_LINUM_INCR_W:
-                 (*_bfd_error_handler)
-                   (_("DST__K_SET_LINUM_INCR_W not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_SET_LINUM_INCR_W");
                  cmd_length = 3;
                  break;
 
                case DST__K_RESET_LINUM_INCR:
-                 (*_bfd_error_handler)
-                   (_("DST__K_RESET_LINUM_INCR not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_RESET_LINUM_INCR");
                  cmd_length = 1;
                  break;
 
                case DST__K_BEG_STMT_MODE:
-                 (*_bfd_error_handler)
-                   (_("DST__K_BEG_STMT_MODE not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_BEG_STMT_MODE");
                  cmd_length = 1;
                  break;
 
                case DST__K_END_STMT_MODE:
-                 (*_bfd_error_handler)
-                   (_("DST__K_END_STMT_MODE not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_END_STMT_MODE");
                  cmd_length = 1;
                  break;
 
@@ -4262,26 +4630,26 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
                  break;
 
                case DST__K_SET_PC:
-                 (*_bfd_error_handler)
-                   (_("DST__K_SET_PC not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_SET_PC");
                  cmd_length = 2;
                  break;
 
                case DST__K_SET_PC_W:
-                 (*_bfd_error_handler)
-                   (_("DST__K_SET_PC_W not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_SET_PC_W");
                  cmd_length = 3;
                  break;
 
                case DST__K_SET_PC_L:
-                 (*_bfd_error_handler)
-                   (_("DST__K_SET_PC_L not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_SET_PC_L");
                  cmd_length = 5;
                  break;
 
                case DST__K_SET_STMTNUM:
-                 (*_bfd_error_handler)
-                   (_("DST__K_SET_STMTNUM not implemented"));
+                 _bfd_error_handler
+                   (_("%s not implemented"), "DST__K_SET_STMTNUM");
                  cmd_length = 2;
                  break;
 
@@ -4320,12 +4688,11 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
                      curr_linenum += 1;
                      cmd_length = 1;
                      vms_debug2 ((4, "bump pc to 0x%lx and line to %d\n",
-                                   (unsigned long)curr_pc, curr_linenum));
+                                  (unsigned long)curr_pc, curr_linenum));
                    }
                  else
                    {
-                     (*_bfd_error_handler) (_("unknown line command %d"),
-                                            cmd);
+                     _bfd_error_handler (_("unknown line command %d"), cmd);
                      cmd_length = 2;
                    }
                  break;
@@ -4347,7 +4714,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
                  prev_linum = curr_linenum;
                  prev_pc = curr_pc;
                  vms_debug2 ((4, "-> correlate pc 0x%lx with line %d\n",
-                               (unsigned long)curr_pc, curr_linenum));
+                              (unsigned long)curr_pc, curr_linenum));
                }
 
              pcl_ptr += cmd_length;
@@ -4382,6 +4749,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
      because parsing can be either performed at module creation
      or deferred until debug info is consumed.  */
   SET_MODULE_PARSED (module);
+  return TRUE;
 }
 
 /* Build the list of modules for the specified BFD.  */
@@ -4398,7 +4766,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);
@@ -4423,7 +4791,7 @@ build_module_list (bfd *abfd)
          ptr += DBG_S_C_DMT_HEADER_SIZE;
 
          vms_debug2 ((3, "module: modbeg = %d, size = %d, count = %d\n",
-                       modbeg, msize, count));
+                      modbeg, msize, count));
 
          /* We create a 'module' structure for each program section since
             we only support contiguous addresses in a 'module' structure.
@@ -4444,7 +4812,7 @@ build_module_list (bfd *abfd)
              ptr += DBG_S_C_DMT_PSECT_SIZE;
 
              vms_debug2 ((4, "section: start = 0x%x, length = %d\n",
-                           start, length));
+                          start, length));
            }
        }
     }
@@ -4453,8 +4821,14 @@ build_module_list (bfd *abfd)
       /* We don't have a DMT section so this must be an object.  Parse
         the module right now in order to compute its start address and
         end address.  */
+      void *dst = PRIV (dst_section)->contents;
+
+      if (dst == NULL)
+       return NULL;
+
       module = new_module (abfd);
-      parse_module (abfd, module, PRIV (dst_section)->contents, -1);
+      if (!parse_module (abfd, module, PRIV (dst_section)->contents, -1))
+       return NULL;
       list = module;
     }
 
@@ -4479,24 +4853,26 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
     {
       unsigned int size = module->size;
       unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
-      unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
+      unsigned char *buffer;
 
       if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
-         || bfd_bread (buffer, size, abfd) != size)
+         || (buffer = _bfd_malloc_and_read (abfd, size, size)) == NULL)
        {
          bfd_set_error (bfd_error_no_debug_section);
          return FALSE;
        }
 
-      parse_module (abfd, module, buffer, size);
+      ret = parse_module (abfd, module, buffer, size);
       free (buffer);
+      if (!ret)
+       return ret;
     }
 
   /* Find out the function (if any) that contains the address.  */
   for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
     if (addr >= funcinfo->low && addr <= funcinfo->high)
       {
-        *func = funcinfo->name;
+       *func = funcinfo->name;
        ret = TRUE;
        break;
       }
@@ -4532,10 +4908,14 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
    location.  */
 
 static bfd_boolean
-_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
-                               asymbol **symbols ATTRIBUTE_UNUSED,
-                               bfd_vma offset, const char **file,
-                               const char **func, unsigned int *line)
+_bfd_vms_find_nearest_line (bfd *abfd,
+                           asymbol **symbols ATTRIBUTE_UNUSED,
+                           asection *section,
+                           bfd_vma offset,
+                           const char **file,
+                           const char **func,
+                           unsigned int *line,
+                           unsigned int *discriminator)
 {
   struct module *module;
 
@@ -4545,15 +4925,19 @@ _bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
   *file = NULL;
   *func = NULL;
   *line = 0;
+  if (discriminator)
+    *discriminator = 0;
 
-  if (PRIV (dst_section) == NULL || !(abfd->flags & (EXEC_P | DYNAMIC)))
+  /* We can't do anything if there is no DST (debug symbol table).  */
+  if (PRIV (dst_section) == NULL)
     return FALSE;
 
+  /* Create the module list - if not already done.  */
   if (PRIV (modules) == NULL)
     {
       PRIV (modules) = build_module_list (abfd);
       if (PRIV (modules) == NULL)
-        return FALSE;
+       return FALSE;
     }
 
   for (module = PRIV (modules); module; module = module->next)
@@ -4583,22 +4967,22 @@ alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym)
     {
     case EGSD__C_SYM:
       if (e->flags & EGSY__V_WEAK)
-        flags |= BSF_WEAK;
+       flags |= BSF_WEAK;
 
       if (e->flags & EGSY__V_DEF)
-        {
-          /* Symbol definition.  */
-          flags |= BSF_GLOBAL;
-          if (e->flags & EGSY__V_NORM)
-            flags |= BSF_FUNCTION;
-          value = e->value;
-          sec = PRIV (sections)[e->section];
-        }
+       {
+         /* Symbol definition.  */
+         flags |= BSF_GLOBAL;
+         if (e->flags & EGSY__V_NORM)
+           flags |= BSF_FUNCTION;
+         value = e->value;
+         sec = e->section;
+       }
       else
-        {
-          /* Symbol reference.  */
-          sec = bfd_und_section_ptr;
-        }
+       {
+         /* Symbol reference.  */
+         sec = bfd_und_section_ptr;
+       }
       break;
 
     case EGSD__C_SYMG:
@@ -4607,46 +4991,20 @@ alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym)
 
       /* ...and dynamic in shared libraries.  */
       if (abfd->flags & DYNAMIC)
-        flags |= BSF_DYNAMIC;
+       flags |= BSF_DYNAMIC;
 
       if (e->flags & EGSY__V_WEAK)
-        flags |= BSF_WEAK;
+       flags |= BSF_WEAK;
 
       if (!(e->flags & EGSY__V_DEF))
-        abort ();
+       abort ();
 
       if (e->flags & EGSY__V_NORM)
-        flags |= BSF_FUNCTION;
-
-      value = e->symbol_vector;
-
-      /* Adding this offset is necessary in order for GDB to
-         read the DWARF-2 debug info from shared libraries.  */
-      if ((abfd->flags & DYNAMIC) && strstr (name, "$DWARF2.DEBUG") != 0)
-        value += PRIV (symvva);
+       flags |= BSF_FUNCTION;
 
+      value = e->value;
+      /* sec = e->section; */
       sec = bfd_abs_section_ptr;
-#if 0
-      /* Find containing section.  */
-      {
-        bfd_vma sbase = 0;
-        asection *s;
-
-        for (s = abfd->sections; s; s = s->next)
-          {
-            if (value >= s->vma
-                && s->vma > sbase
-                && !(s->flags & SEC_COFF_SHARED_LIBRARY)
-                && (s->size > 0 || !(e->flags & EGSY__V_REL)))
-              {
-                sbase = s->vma;
-                sec = s;
-              }
-          }
-        value -= sbase;
-      }
-#endif
-
       break;
 
     default:
@@ -4670,7 +5028,7 @@ static long
 alpha_vms_get_symtab_upper_bound (bfd *abfd)
 {
   vms_debug2 ((1, "alpha_vms_get_symtab_upper_bound (%p), %d symbols\n",
-               abfd, PRIV (gsd_sym_count)));
+              abfd, PRIV (gsd_sym_count)));
 
   return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
 }
@@ -4690,333 +5048,360 @@ alpha_vms_canonicalize_symtab (bfd *abfd, asymbol **symbols)
   if (PRIV (csymbols) == NULL)
     {
       PRIV (csymbols) = (asymbol **) bfd_alloc
-        (abfd, PRIV (gsd_sym_count) * sizeof (asymbol *));
+       (abfd, PRIV (gsd_sym_count) * sizeof (asymbol *));
 
       /* Traverse table and fill symbols vector.  */
       for (i = 0; i < PRIV (gsd_sym_count); i++)
-        {
-          struct vms_symbol_entry *e = PRIV (syms)[i];
-          asymbol *sym;
+       {
+         struct vms_symbol_entry *e = PRIV (syms)[i];
+         asymbol *sym;
+
+         sym = bfd_make_empty_symbol (abfd);
+         if (sym == NULL || !alpha_vms_convert_symbol (abfd, e, sym))
+           {
+             bfd_release (abfd, PRIV (csymbols));
+             PRIV (csymbols) = NULL;
+             return -1;
+           }
+
+         PRIV (csymbols)[i] = sym;
+       }
+    }
+
+  if (symbols != NULL)
+    {
+      for (i = 0; i < PRIV (gsd_sym_count); i++)
+       symbols[i] = PRIV (csymbols)[i];
+      symbols[i] = NULL;
+    }
+
+  return PRIV (gsd_sym_count);
+}
+
+/* Read and convert relocations from ETIR.  We do it once for all sections.  */
+
+static bfd_boolean
+alpha_vms_slurp_relocs (bfd *abfd)
+{
+  int cur_psect = -1;
+
+  vms_debug2 ((3, "alpha_vms_slurp_relocs\n"));
+
+  /* We slurp relocs only once, for all sections.  */
+  if (PRIV (reloc_done))
+      return TRUE;
+  PRIV (reloc_done) = TRUE;
+
+  if (alpha_vms_canonicalize_symtab (abfd, NULL) < 0)
+    return FALSE;
+
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+    return FALSE;
+
+  while (1)
+    {
+      unsigned char *begin;
+      unsigned char *end;
+      unsigned char *ptr;
+      bfd_reloc_code_real_type reloc_code;
+      int type;
+      bfd_vma vaddr = 0;
+
+      int length;
+
+      bfd_vma cur_address;
+      int cur_psidx = -1;
+      unsigned char *cur_sym = NULL;
+      int prev_cmd = -1;
+      bfd_vma cur_addend = 0;
+
+      /* Skip non-ETIR records.  */
+      type = _bfd_vms_get_object_record (abfd);
+      if (type == EOBJ__C_EEOM)
+       break;
+      if (type != EOBJ__C_ETIR)
+       continue;
+
+      begin = PRIV (recrd.rec) + 4;
+      end = PRIV (recrd.rec) + PRIV (recrd.rec_size);
+
+      for (ptr = begin; ptr < end; ptr += length)
+       {
+         int cmd;
+
+         cmd = bfd_getl16 (ptr);
+         length = bfd_getl16 (ptr + 2);
+
+         cur_address = vaddr;
+
+         vms_debug2 ((4, "alpha_vms_slurp_relocs: etir %s\n",
+                      _bfd_vms_etir_name (cmd)));
+
+         switch (cmd)
+           {
+           case ETIR__C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+                                 /* ALPHA_R_REFQUAD und_section, step 1 */
+             cur_sym = ptr + 4;
+             prev_cmd = cmd;
+             continue;
+
+           case ETIR__C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+             cur_psidx = bfd_getl32 (ptr + 4);
+             cur_addend = bfd_getl64 (ptr + 8);
+             prev_cmd = cmd;
+             continue;
+
+           case ETIR__C_CTL_SETRB:
+             if (prev_cmd != ETIR__C_STA_PQ)
+               {
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd),
+                    _bfd_vms_etir_name (cmd));
+                 return FALSE;
+               }
+             cur_psect = cur_psidx;
+             vaddr = cur_addend;
+             cur_psidx = -1;
+             cur_addend = 0;
+             continue;
+
+           case ETIR__C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
+                                /* ALPHA_R_REFLONG und_section, step 2 */
+             if (prev_cmd != -1)
+               {
+                 if (prev_cmd != ETIR__C_STA_GBL)
+                   {
+                     _bfd_error_handler
+                       /* xgettext:c-format */
+                       (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
+                        _bfd_vms_etir_name (ETIR__C_STA_LW));
+                     return FALSE;
+                   }
+               }
+             cur_addend = bfd_getl32 (ptr + 4);
+             prev_cmd = cmd;
+             continue;
+
+           case ETIR__C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
+                                /* ALPHA_R_REFQUAD und_section, step 2 */
+             if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL)
+               {
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
+                    _bfd_vms_etir_name (ETIR__C_STA_QW));
+                 return FALSE;
+               }
+             cur_addend = bfd_getl64 (ptr + 4);
+             prev_cmd = cmd;
+             continue;
+
+           case ETIR__C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+                                /* ALPHA_R_REFLONG abs_section, step 2 */
+                                /* ALPHA_R_REFLONG others, step 2 */
+             if (prev_cmd != ETIR__C_OPR_ADD
+                 && prev_cmd != ETIR__C_STA_LW
+                 && prev_cmd != ETIR__C_STA_PQ)
+               {
+                 /* xgettext:c-format */
+                 _bfd_error_handler (_("unknown reloc %s + %s"),
+                                     _bfd_vms_etir_name (prev_cmd),
+                                     _bfd_vms_etir_name (ETIR__C_STO_LW));
+                 return FALSE;
+               }
+             reloc_code = BFD_RELOC_32;
+             break;
+
+           case ETIR__C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+                                /* ALPHA_R_REFQUAD abs_section, step 2 */
+             if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW)
+               {
+                 /* xgettext:c-format */
+                 _bfd_error_handler (_("unknown reloc %s + %s"),
+                                     _bfd_vms_etir_name (prev_cmd),
+                                     _bfd_vms_etir_name (ETIR__C_STO_QW));
+                 return FALSE;
+               }
+             reloc_code = BFD_RELOC_64;
+             break;
+
+           case ETIR__C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+             if (prev_cmd != ETIR__C_STA_PQ)
+               {
+                 /* xgettext:c-format */
+                 _bfd_error_handler (_("unknown reloc %s + %s"),
+                                     _bfd_vms_etir_name (prev_cmd),
+                                     _bfd_vms_etir_name (ETIR__C_STO_OFF));
+                 return FALSE;
+               }
+             reloc_code = BFD_RELOC_64;
+             break;
+
+           case ETIR__C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+                                 /* ALPHA_R_REFQUAD und_section, step 3 */
+             if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW)
+               {
+                 /* xgettext:c-format */
+                 _bfd_error_handler (_("unknown reloc %s + %s"),
+                                     _bfd_vms_etir_name (prev_cmd),
+                                     _bfd_vms_etir_name (ETIR__C_OPR_ADD));
+                 return FALSE;
+               }
+             prev_cmd = ETIR__C_OPR_ADD;
+             continue;
 
-          sym = bfd_make_empty_symbol (abfd);
-          if (sym == NULL || !alpha_vms_convert_symbol (abfd, e, sym))
-            {
-              bfd_release (abfd, PRIV (csymbols));
-              PRIV (csymbols) = NULL;
-              return -1;
-            }
+           case ETIR__C_STO_CA: /* ALPHA_R_CODEADDR */
+             reloc_code = BFD_RELOC_ALPHA_CODEADDR;
+             cur_sym = ptr + 4;
+             break;
 
-          PRIV (csymbols)[i] = sym;
-        }
-    }
+           case ETIR__C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
+             reloc_code = BFD_RELOC_64;
+             cur_sym = ptr + 4;
+             break;
 
-  if (symbols != NULL)
-    {
-      for (i = 0; i < PRIV (gsd_sym_count); i++)
-        symbols[i] = PRIV (csymbols)[i];
-      symbols[i] = NULL;
-    }
+           case ETIR__C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
+             reloc_code = BFD_RELOC_32;
+             cur_sym = ptr + 4;
+             break;
 
-  return PRIV (gsd_sym_count);
-}
+           case ETIR__C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
+             reloc_code = BFD_RELOC_ALPHA_LINKAGE;
+             cur_sym = ptr + 8;
+             break;
 
-/* Read and convert relocations from ETIR.  We do it once for all sections.  */
+           case ETIR__C_STC_NOP_GBL: /* ALPHA_R_NOP */
+             reloc_code = BFD_RELOC_ALPHA_NOP;
+             goto call_reloc;
 
-static bfd_boolean
-alpha_vms_slurp_relocs (bfd *abfd)
-{
-  int cur_psect = -1;
+           case ETIR__C_STC_BSR_GBL: /* ALPHA_R_BSR */
+             reloc_code = BFD_RELOC_ALPHA_BSR;
+             goto call_reloc;
 
-  vms_debug2 ((3, "alpha_vms_slurp_relocs\n"));
+           case ETIR__C_STC_LDA_GBL: /* ALPHA_R_LDA */
+             reloc_code = BFD_RELOC_ALPHA_LDA;
+             goto call_reloc;
 
-  /* We slurp relocs only once, for all sections.  */
-  if (PRIV (reloc_done))
-      return TRUE;
-  PRIV (reloc_done) = TRUE;
+           case ETIR__C_STC_BOH_GBL: /* ALPHA_R_BOH */
+             reloc_code = BFD_RELOC_ALPHA_BOH;
+             goto call_reloc;
 
-  if (alpha_vms_canonicalize_symtab (abfd, NULL) < 0)
-    return FALSE;
+           call_reloc:
+             cur_sym = ptr + 4 + 32;
+             cur_address = bfd_getl64 (ptr + 4 + 8);
+             cur_addend = bfd_getl64 (ptr + 4 + 24);
+             break;
 
-  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
-    return FALSE;
+           case ETIR__C_STO_IMM:
+             vaddr += bfd_getl32 (ptr + 4);
+             continue;
 
-  while (1)
-    {
-      unsigned char *begin;
-      unsigned char *end;
-      unsigned char *ptr;
-      bfd_reloc_code_real_type reloc_code;
-      int type;
-      bfd_vma vaddr = 0;
+           default:
+             _bfd_error_handler (_("unknown reloc %s"),
+                                 _bfd_vms_etir_name (cmd));
+             return FALSE;
+           }
 
-      int length;
+         {
+           asection *sec;
+           struct vms_section_data_struct *vms_sec;
+           arelent *reloc;
+           bfd_size_type size;
+
+           /* Get section to which the relocation applies.  */
+           if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
+             {
+               _bfd_error_handler (_("invalid section index in ETIR"));
+               return FALSE;
+             }
 
-      bfd_vma cur_address;
-      int cur_psidx = -1;
-      unsigned char *cur_sym = NULL;
-      int prev_cmd = -1;
-      bfd_vma cur_addend = 0;
+           if (PRIV (sections) == NULL)
+             return FALSE;
+           sec = PRIV (sections)[cur_psect];
+           if (sec == bfd_abs_section_ptr)
+             {
+               _bfd_error_handler (_("relocation for non-REL psect"));
+               return FALSE;
+             }
 
-      /* Skip non-ETIR records.  */
-      type = _bfd_vms_get_object_record (abfd);
-      if (type == EOBJ__C_EEOM)
-        break;
-      if (type != EOBJ__C_ETIR)
-        continue;
+           vms_sec = vms_section_data (sec);
 
-      begin = PRIV (recrd.rec) + 4;
-      end = PRIV (recrd.rec) + PRIV (recrd.rec_size);
+           /* Allocate a reloc entry.  */
+           if (sec->reloc_count >= vms_sec->reloc_max)
+             {
+               if (vms_sec->reloc_max == 0)
+                 {
+                   vms_sec->reloc_max = 64;
+                   sec->relocation = bfd_zmalloc
+                     (vms_sec->reloc_max * sizeof (arelent));
+                 }
+               else
+                 {
+                   vms_sec->reloc_max *= 2;
+                   sec->relocation = bfd_realloc_or_free
+                     (sec->relocation, vms_sec->reloc_max * sizeof (arelent));
+                   if (sec->relocation == NULL)
+                     return FALSE;
+                 }
+             }
+           reloc = &sec->relocation[sec->reloc_count];
+           sec->reloc_count++;
+
+           reloc->howto = bfd_reloc_type_lookup (abfd, reloc_code);
+
+           if (cur_sym != NULL)
+             {
+               unsigned int j;
+               unsigned int symlen = *cur_sym;
+               asymbol **sym;
+
+               /* Linear search.  */
+               symlen = *cur_sym;
+               cur_sym++;
+               sym = NULL;
+
+               for (j = 0; j < PRIV (gsd_sym_count); j++)
+                 if (PRIV (syms)[j]->namelen == symlen
+                     && memcmp (PRIV (syms)[j]->name, cur_sym, symlen) == 0)
+                   {
+                     sym = &PRIV (csymbols)[j];
+                     break;
+                   }
+               if (sym == NULL)
+                 {
+                   _bfd_error_handler (_("unknown symbol in command %s"),
+                                       _bfd_vms_etir_name (cmd));
+                   reloc->sym_ptr_ptr = NULL;
+                 }
+               else
+                 reloc->sym_ptr_ptr = sym;
+             }
+           else if (cur_psidx >= 0)
+             {
+               if (PRIV (sections) == NULL || cur_psidx >= (int) PRIV (section_count))
+                 return FALSE;
+               reloc->sym_ptr_ptr =
+                 PRIV (sections)[cur_psidx]->symbol_ptr_ptr;
+             }
+           else
+             reloc->sym_ptr_ptr = NULL;
+
+           reloc->address = cur_address;
+           reloc->addend = cur_addend;
+
+           if (reloc_code == ALPHA_R_LINKAGE)
+             size = 16;
+           else
+             size = bfd_get_reloc_size (reloc->howto);
+           vaddr += size;
+         }
 
-      for (ptr = begin; ptr < end; ptr += length)
-        {
-          int cmd;
-
-          cmd = bfd_getl16 (ptr);
-          length = bfd_getl16 (ptr + 2);
-
-          cur_address = vaddr;
-
-          vms_debug2 ((4, "alpha_vms_slurp_relocs: etir %s\n",
-                       _bfd_vms_etir_name (cmd)));
-
-          switch (cmd)
-            {
-            case ETIR__C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
-                                  /* ALPHA_R_REFQUAD und_section, step 1 */
-              cur_sym = ptr + 4;
-              prev_cmd = cmd;
-              continue;
-
-            case ETIR__C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
-              cur_psidx = bfd_getl32 (ptr + 4);
-              cur_addend = bfd_getl64 (ptr + 8);
-              prev_cmd = cmd;
-              continue;
-
-            case ETIR__C_CTL_SETRB:
-              if (prev_cmd != ETIR__C_STA_PQ)
-                {
-                  (*_bfd_error_handler)
-                    (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd),
-                     _bfd_vms_etir_name (cmd));
-                  return FALSE;
-                }
-              cur_psect = cur_psidx;
-              vaddr = cur_addend;
-              cur_psidx = -1;
-              cur_addend = 0;
-              continue;
-
-            case ETIR__C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
-                                 /* ALPHA_R_REFLONG und_section, step 2 */
-              if (prev_cmd != -1)
-                {
-                  if (prev_cmd != ETIR__C_STA_GBL)
-                    {
-                      (*_bfd_error_handler)
-                        (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
-                         _bfd_vms_etir_name (ETIR__C_STA_LW));
-                      return FALSE;
-                    }
-                }
-              cur_addend = bfd_getl32 (ptr + 4);
-              prev_cmd = cmd;
-              continue;
-
-            case ETIR__C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
-                                /* ALPHA_R_REFQUAD und_section, step 2 */
-              if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL)
-                {
-                  (*_bfd_error_handler)
-                    (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
-                     _bfd_vms_etir_name (ETIR__C_STA_QW));
-                  return FALSE;
-                }
-              cur_addend = bfd_getl64 (ptr + 4);
-              prev_cmd = cmd;
-              continue;
-
-            case ETIR__C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
-                                /* ALPHA_R_REFLONG abs_section, step 2 */
-                                 /* ALPHA_R_REFLONG others, step 2 */
-              if (prev_cmd != ETIR__C_OPR_ADD
-                  && prev_cmd != ETIR__C_STA_LW
-                  && prev_cmd != ETIR__C_STA_PQ)
-                {
-                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
-                                         _bfd_vms_etir_name (prev_cmd),
-                                         _bfd_vms_etir_name (ETIR__C_STO_LW));
-                  return FALSE;
-                }
-              reloc_code = BFD_RELOC_32;
-              break;
-
-            case ETIR__C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
-                                /* ALPHA_R_REFQUAD abs_section, step 2 */
-              if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW)
-                {
-                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
-                                         _bfd_vms_etir_name (prev_cmd),
-                                         _bfd_vms_etir_name (ETIR__C_STO_QW));
-                  return FALSE;
-                }
-              reloc_code = BFD_RELOC_64;
-              break;
-
-            case ETIR__C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
-              if (prev_cmd != ETIR__C_STA_PQ)
-                {
-                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
-                                         _bfd_vms_etir_name (prev_cmd),
-                                         _bfd_vms_etir_name (ETIR__C_STO_OFF));
-                  return FALSE;
-                }
-              reloc_code = BFD_RELOC_64;
-              break;
-
-            case ETIR__C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
-                                  /* ALPHA_R_REFQUAD und_section, step 3 */
-              if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW)
-                {
-                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
-                                         _bfd_vms_etir_name (prev_cmd),
-                                         _bfd_vms_etir_name (ETIR__C_OPR_ADD));
-                  return FALSE;
-                }
-              prev_cmd = ETIR__C_OPR_ADD;
-              continue;
-
-            case ETIR__C_STO_CA: /* ALPHA_R_CODEADDR */
-              reloc_code = BFD_RELOC_ALPHA_CODEADDR;
-              cur_sym = ptr + 4;
-              break;
-
-            case ETIR__C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
-              reloc_code = BFD_RELOC_64;
-              cur_sym = ptr + 4;
-              break;
-
-            case ETIR__C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
-              reloc_code = BFD_RELOC_32;
-              cur_sym = ptr + 4;
-              break;
-
-            case ETIR__C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
-              reloc_code = BFD_RELOC_ALPHA_LINKAGE;
-              cur_sym = ptr + 8;
-              break;
-
-            case ETIR__C_STC_NOP_GBL: /* ALPHA_R_NOP */
-              reloc_code = BFD_RELOC_ALPHA_NOP;
-              goto call_reloc;
-
-            case ETIR__C_STC_BSR_GBL: /* ALPHA_R_BSR */
-              reloc_code = BFD_RELOC_ALPHA_BSR;
-              goto call_reloc;
-
-            case ETIR__C_STC_LDA_GBL: /* ALPHA_R_LDA */
-              reloc_code = BFD_RELOC_ALPHA_LDA;
-              goto call_reloc;
-
-            case ETIR__C_STC_BOH_GBL: /* ALPHA_R_BOH */
-              reloc_code = BFD_RELOC_ALPHA_BOH;
-              goto call_reloc;
-
-            call_reloc:
-              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:
-              vaddr += bfd_getl32 (ptr + 4);
-              continue;
-
-            default:
-              (*_bfd_error_handler) (_("Unknown reloc %s"),
-                                     _bfd_vms_etir_name (cmd));
-              return FALSE;
-            }
-
-          {
-            asection *sec;
-            struct vms_section_data_struct *vms_sec;
-            arelent *reloc;
-
-            /* Get section to which the relocation applies.  */
-            if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
-              {
-                (*_bfd_error_handler) (_("Invalid section index in ETIR"));
-                return FALSE;
-              }
-            sec = PRIV (sections)[cur_psect];
-            vms_sec = vms_section_data (sec);
-
-            /* Allocate a reloc entry.  */
-            if (sec->reloc_count >= vms_sec->reloc_max)
-              {
-                if (vms_sec->reloc_max == 0)
-                  {
-                    vms_sec->reloc_max = 64;
-                    sec->relocation = bfd_zmalloc
-                      (vms_sec->reloc_max * sizeof (arelent));
-                }
-                else
-                  {
-                    vms_sec->reloc_max *= 2;
-                    sec->relocation = bfd_realloc
-                      (sec->relocation, vms_sec->reloc_max * sizeof (arelent));
-                  }
-              }
-            reloc = &sec->relocation[sec->reloc_count];
-            sec->reloc_count++;
-
-            reloc->howto = bfd_reloc_type_lookup (abfd, reloc_code);
-
-            if (cur_sym != NULL)
-              {
-                unsigned int j;
-                unsigned int symlen = *cur_sym;
-                asymbol **sym;
-
-                /* Linear search.  */
-                symlen = *cur_sym;
-                cur_sym++;
-                sym = NULL;
-
-                for (j = 0; j < PRIV (gsd_sym_count); j++)
-                  if (PRIV (syms)[j]->namelen == symlen
-                      && memcmp (PRIV (syms)[j]->name, cur_sym, symlen) == 0)
-                    {
-                      sym = &PRIV (csymbols)[j];
-                      break;
-                    }
-                if (sym == NULL)
-                  {
-                    (*_bfd_error_handler) (_("Unknown symbol in command %s"),
-                                           _bfd_vms_etir_name (cmd));
-                    reloc->sym_ptr_ptr = NULL;
-                  }
-                else
-                  reloc->sym_ptr_ptr = sym;
-              }
-            else if (cur_psidx >= 0)
-              reloc->sym_ptr_ptr =
-                PRIV (sections)[cur_psidx]->symbol_ptr_ptr;
-            else
-              reloc->sym_ptr_ptr = NULL;
-
-            reloc->address = cur_address;
-            reloc->addend = cur_addend;
-
-            vaddr += bfd_get_reloc_size (reloc->howto);
-          }
-
-          cur_addend = 0;
-          prev_cmd = -1;
-          cur_sym = NULL;
-          cur_psidx = -1;
-        }
+         cur_addend = 0;
+         prev_cmd = -1;
+         cur_sym = NULL;
+         cur_psidx = -1;
+       }
     }
   vms_debug2 ((3, "alpha_vms_slurp_relocs: result = TRUE\n"));
 
@@ -5039,7 +5424,7 @@ alpha_vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
 
 static long
 alpha_vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
-                              asymbol **symbols ATTRIBUTE_UNUSED)
+                             asymbol **symbols ATTRIBUTE_UNUSED)
 {
   arelent *tblptr;
   int count;
@@ -5056,6 +5441,11 @@ alpha_vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
   *relptr = (arelent *) NULL;
   return section->reloc_count;
 }
+
+/* Install a new set of internal relocs.  */
+
+#define alpha_vms_set_reloc _bfd_generic_set_reloc
+
 \f
 /* This is just copied from ecoff-alpha, needs to be fixed probably.  */
 
@@ -5263,8 +5653,8 @@ static reloc_howto_type alpha_howto_table[] =
   /* Hack. Linkage is done by linker.  */
   HOWTO (ALPHA_R_LINKAGE,      /* Type.  */
         0,                     /* Rightshift.  */
-        8,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        256,                   /* Bitsize.  */
+        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
         FALSE,                 /* PC relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
@@ -5368,9 +5758,9 @@ static reloc_howto_type alpha_howto_table[] =
 /* Return a pointer to a howto structure which, when invoked, will perform
    the relocation code on data from the architecture noted.  */
 
-static const struct reloc_howto_struct *
+static reloc_howto_type *
 alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
-                                 bfd_reloc_code_real_type code)
+                                bfd_reloc_code_real_type code)
 {
   int alpha_type;
 
@@ -5394,7 +5784,7 @@ alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
       case BFD_RELOC_ALPHA_LDA:                alpha_type = ALPHA_R_LDA;       break;
       case BFD_RELOC_ALPHA_BOH:                alpha_type = ALPHA_R_BOH;       break;
       default:
-       (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
+       _bfd_error_handler (_("reloc (%d) is *UNKNOWN*"), code);
        return NULL;
     }
   vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name));
@@ -5403,7 +5793,7 @@ alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
 
 static reloc_howto_type *
 alpha_vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-                                 const char *r_name)
+                                const char *r_name)
 {
   unsigned int i;
 
@@ -5419,11 +5809,11 @@ alpha_vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 \f
 static long
 alpha_vms_get_synthetic_symtab (bfd *abfd,
-                                long symcount ATTRIBUTE_UNUSED,
-                                asymbol **usyms ATTRIBUTE_UNUSED,
-                                long dynsymcount ATTRIBUTE_UNUSED,
-                                asymbol **dynsyms ATTRIBUTE_UNUSED,
-                                asymbol **ret)
+                               long symcount ATTRIBUTE_UNUSED,
+                               asymbol **usyms ATTRIBUTE_UNUSED,
+                               long dynsymcount ATTRIBUTE_UNUSED,
+                               asymbol **dynsyms ATTRIBUTE_UNUSED,
+                               asymbol **ret)
 {
   asymbol *syms;
   unsigned int i;
@@ -5451,51 +5841,26 @@ alpha_vms_get_synthetic_symtab (bfd *abfd,
       sec = NULL;
 
       switch (e->typ)
-        {
-        case EGSD__C_SYM:
-          if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
-            {
-              value = e->code_value;
-              sec = PRIV (sections)[e->code_section];
-            }
-          else
-            continue;
-          break;
-
-        case EGSD__C_SYMG:
-          if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
-            {
-              bfd_vma sbase = 0;
-              asection *s;
-
-              value = e->code_value;
-
-              /* Find containing section.  */
-              for (s = abfd->sections; s; s = s->next)
-                {
-                  if (value >= s->vma
-                      && s->vma > sbase
-                      && !(s->flags & SEC_COFF_SHARED_LIBRARY)
-                      && (s->size > 0 || !(e->flags & EGSY__V_REL)))
-                    {
-                      sbase = s->vma;
-                      sec = s;
-                    }
-                }
-              value -= sbase;
-            }
-          else
-            continue;
-          break;
-
-        default:
-          abort ();
-        }
+       {
+       case EGSD__C_SYM:
+       case EGSD__C_SYMG:
+         if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
+           {
+             value = e->code_value;
+             sec = e->code_section;
+           }
+         else
+           continue;
+         break;
+
+       default:
+         continue;
+       }
 
       l = strlen (name);
       sname = bfd_alloc (abfd, l + 5);
       if (sname == NULL)
-        return FALSE;
+       return FALSE;
       memcpy (sname, name, l);
       memcpy (sname + l, "..en", 5);
 
@@ -5530,62 +5895,95 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
 {
   struct vms_emh_common *emh = (struct vms_emh_common *)rec;
   unsigned int subtype;
+  int extra;
 
-  subtype = (unsigned)bfd_getl16 (emh->subtyp);
+  subtype = (unsigned) bfd_getl16 (emh->subtyp);
 
+  /* xgettext:c-format */
   fprintf (file, _("  EMH %u (len=%u): "), subtype, rec_len);
 
+  /* PR 21618: Check for invalid lengths.  */
+  if (rec_len < sizeof (* emh))
+    {
+      fprintf (file, _("   Error: The length is less than the length of an EMH record\n"));
+      return;
+    }
+  extra = rec_len - sizeof (struct vms_emh_common);
+
   switch (subtype)
     {
     case EMH__C_MHD:
       {
-        struct vms_emh_mhd *mhd = (struct vms_emh_mhd *)rec;
-        const char *name;
-
-        fprintf (file, _("Module header\n"));
-        fprintf (file, _("   structure level: %u\n"), mhd->strlvl);
-        fprintf (file, _("   max record size: %u\n"),
-                 (unsigned)bfd_getl32 (mhd->recsiz));
-        name = (char *)(mhd + 1);
-        fprintf (file, _("   module name    : %.*s\n"), name[0], name + 1);
-        name += name[0] + 1;
-        fprintf (file, _("   module version : %.*s\n"), name[0], name + 1);
-        name += name[0] + 1;
-        fprintf (file, _("   compile date   : %.17s\n"), name);
+       struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec;
+       const char * name;
+       const char * nextname;
+       const char * maxname;
+
+       /* PR 21840: Check for invalid lengths.  */
+       if (rec_len < sizeof (* mhd))
+         {
+           fprintf (file, _("   Error: The record length is less than the size of an EMH_MHD record\n"));
+           return;
+         }
+       fprintf (file, _("Module header\n"));
+       fprintf (file, _("   structure level: %u\n"), mhd->strlvl);
+       fprintf (file, _("   max record size: %u\n"),
+                (unsigned) bfd_getl32 (mhd->recsiz));
+       name = (char *)(mhd + 1);
+       maxname = (char *) rec + rec_len;
+       if (name > maxname - 2)
+         {
+           fprintf (file, _("   Error: The module name is missing\n"));
+           return;
+         }
+       nextname = name + name[0] + 1;
+       if (nextname >= maxname)
+         {
+           fprintf (file, _("   Error: The module name is too long\n"));
+           return;
+         }
+       fprintf (file, _("   module name    : %.*s\n"), name[0], name + 1);
+       name = nextname;
+       if (name > maxname - 2)
+         {
+           fprintf (file, _("   Error: The module version is missing\n"));
+           return;
+         }
+       nextname = name + name[0] + 1;
+       if (nextname >= maxname)
+         {
+           fprintf (file, _("   Error: The module version is too long\n"));
+           return;
+         }
+       fprintf (file, _("   module version : %.*s\n"), name[0], name + 1);
+       name = nextname;
+       if ((maxname - name) < 17 && maxname[-1] != 0)
+         fprintf (file, _("   Error: The compile date is truncated\n"));
+       else
+         fprintf (file, _("   compile date   : %.17s\n"), name);
       }
       break;
+
     case EMH__C_LNM:
-      {
-        fprintf (file, _("Language Processor Name\n"));
-        fprintf (file, _("   language name: %.*s\n"),
-                 (int)(rec_len - sizeof (struct vms_emh_common)),
-                 (char *)rec + sizeof (struct vms_emh_common));
-      }
+      fprintf (file, _("Language Processor Name\n"));
+      fprintf (file, _("   language name: %.*s\n"), extra, (char *)(emh + 1));
       break;
+
     case EMH__C_SRC:
-      {
-        fprintf (file, _("Source Files Header\n"));
-        fprintf (file, _("   file: %.*s\n"),
-                 (int)(rec_len - sizeof (struct vms_emh_common)),
-                 (char *)rec + sizeof (struct vms_emh_common));
-      }
+      fprintf (file, _("Source Files Header\n"));
+      fprintf (file, _("   file: %.*s\n"), extra, (char *)(emh + 1));
       break;
+
     case EMH__C_TTL:
-      {
-        fprintf (file, _("Title Text Header\n"));
-        fprintf (file, _("   title: %.*s\n"),
-                 (int)(rec_len - sizeof (struct vms_emh_common)),
-                 (char *)rec + sizeof (struct vms_emh_common));
-      }
+      fprintf (file, _("Title Text Header\n"));
+      fprintf (file, _("   title: %.*s\n"), extra, (char *)(emh + 1));
       break;
+
     case EMH__C_CPR:
-      {
-        fprintf (file, _("Copyright Header\n"));
-        fprintf (file, _("   copyright: %.*s\n"),
-                 (int)(rec_len - sizeof (struct vms_emh_common)),
-                 (char *)rec + sizeof (struct vms_emh_common));
-      }
+      fprintf (file, _("Copyright Header\n"));
+      fprintf (file, _("   copyright: %.*s\n"), extra, (char *)(emh + 1));
       break;
+
     default:
       fprintf (file, _("unhandled emh subtype %u\n"), subtype);
       break;
@@ -5598,17 +5996,25 @@ evax_bfd_print_eeom (FILE *file, unsigned char *rec, unsigned int rec_len)
   struct vms_eeom *eeom = (struct vms_eeom *)rec;
 
   fprintf (file, _("  EEOM (len=%u):\n"), rec_len);
+
+  /* PR 21618: Check for invalid lengths.  */
+  if (rec_len < sizeof (* eeom))
+    {
+      fprintf (file, _("   Error: The length is less than the length of an EEOM record\n"));
+      return;
+    }
+
   fprintf (file, _("   number of cond linkage pairs: %u\n"),
-           (unsigned)bfd_getl32 (eeom->total_lps));
+          (unsigned)bfd_getl32 (eeom->total_lps));
   fprintf (file, _("   completion code: %u\n"),
-           (unsigned)bfd_getl16 (eeom->comcod));
+          (unsigned)bfd_getl16 (eeom->comcod));
   if (rec_len > 10)
     {
       fprintf (file, _("   transfer addr flags: 0x%02x\n"), eeom->tfrflg);
       fprintf (file, _("   transfer addr psect: %u\n"),
-               (unsigned)bfd_getl32 (eeom->psindx));
+              (unsigned)bfd_getl32 (eeom->psindx));
       fprintf (file, _("   transfer address   : 0x%08x\n"),
-               (unsigned)bfd_getl32 (eeom->tfradr));
+              (unsigned)bfd_getl32 (eeom->tfradr));
     }
 }
 
@@ -5682,184 +6088,191 @@ evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len)
       type = (unsigned)bfd_getl16 (e->gsdtyp);
       len = (unsigned)bfd_getl16 (e->gsdsiz);
 
+      /* xgettext:c-format */
       fprintf (file, _("  EGSD entry %2u (type: %u, len: %u): "),
-               n, type, len);
+              n, type, len);
       n++;
 
+      if (off + len > rec_len || off + len < off)
+       {
+         fprintf (file, _("   Error: length larger than remaining space in record\n"));
+         return;
+       }
+
       switch (type)
-        {
-        case EGSD__C_PSC:
-          {
-            struct vms_egps *egps = (struct vms_egps *)e;
-            unsigned int flags = bfd_getl16 (egps->flags);
-            unsigned int l;
-
-            fprintf (file, _("PSC - Program section definition\n"));
-            fprintf (file, _("   alignment  : 2**%u\n"), egps->align);
-            fprintf (file, _("   flags      : 0x%04x"), flags);
-            evax_bfd_print_egsd_flags (file, flags);
-            fputc ('\n', file);
-            l = bfd_getl32 (egps->alloc);
-            fprintf (file, _("   alloc (len): %u (0x%08x)\n"), l, l);
-            fprintf (file, _("   name       : %.*s\n"),
-                     egps->namlng, egps->name);
-          }
-          break;
-        case EGSD__C_SPSC:
-          {
-            struct vms_esgps *esgps = (struct vms_esgps *)e;
-            unsigned int flags = bfd_getl16 (esgps->flags);
-            unsigned int l;
-
-            fprintf (file, _("SPSC - Shared Image Program section def\n"));
-            fprintf (file, _("   alignment  : 2**%u\n"), esgps->align);
-            fprintf (file, _("   flags      : 0x%04x"), flags);
-            evax_bfd_print_egsd_flags (file, flags);
-            fputc ('\n', file);
-            l = bfd_getl32 (esgps->alloc);
-            fprintf (file, _("   alloc (len)   : %u (0x%08x)\n"), l, l);
-            fprintf (file, _("   image offset  : 0x%08x\n"),
-                     (unsigned int)bfd_getl32 (esgps->base));
-            fprintf (file, _("   symvec offset : 0x%08x\n"),
-                     (unsigned int)bfd_getl32 (esgps->value));
-            fprintf (file, _("   name          : %.*s\n"),
-                     esgps->namlng, esgps->name);
-          }
-          break;
-        case EGSD__C_SYM:
-          {
-            struct vms_egsy *egsy = (struct vms_egsy *)e;
-            unsigned int flags = bfd_getl16 (egsy->flags);
-
-            if (flags & EGSY__V_DEF)
-              {
-                struct vms_esdf *esdf = (struct vms_esdf *)e;
-
-                fprintf (file, _("SYM - Global symbol definition\n"));
-                fprintf (file, _("   flags: 0x%04x"), flags);
-                exav_bfd_print_egsy_flags (flags, file);
-                fputc ('\n', file);
-                fprintf (file, _("   psect offset: 0x%08x\n"),
-                         (unsigned)bfd_getl32 (esdf->value));
-                if (flags & EGSY__V_NORM)
-                  {
-                    fprintf (file, _("   code address: 0x%08x\n"),
-                             (unsigned)bfd_getl32 (esdf->code_address));
-                    fprintf (file, _("   psect index for entry point : %u\n"),
-                             (unsigned)bfd_getl32 (esdf->ca_psindx));
-                  }
-                fprintf (file, _("   psect index : %u\n"),
-                         (unsigned)bfd_getl32 (esdf->psindx));
-                fprintf (file, _("   name        : %.*s\n"),
-                         esdf->namlng, esdf->name);
-              }
-            else
-              {
-                struct vms_esrf *esrf = (struct vms_esrf *)e;
-
-                fprintf (file, _("SYM - Global symbol reference\n"));
-                fprintf (file, _("   name       : %.*s\n"),
-                         esrf->namlng, esrf->name);
-              }
-          }
-          break;
-        case EGSD__C_IDC:
-          {
-            struct vms_eidc *eidc = (struct vms_eidc *)e;
-            unsigned int flags = bfd_getl32 (eidc->flags);
-            unsigned char *p;
-
-            fprintf (file, _("IDC - Ident Consistency check\n"));
-            fprintf (file, _("   flags         : 0x%08x"), flags);
-            if (flags & EIDC__V_BINIDENT)
-              fputs (" BINDENT", file);
-            fputc ('\n', file);
-            fprintf (file, _("   id match      : %x\n"),
-                     (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK);
-            fprintf (file, _("   error severity: %x\n"),
-                     (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK);
-            p = eidc->name;
-            fprintf (file, _("   entity name   : %.*s\n"), p[0], p + 1);
-            p += 1 + p[0];
-            fprintf (file, _("   object name   : %.*s\n"), p[0], p + 1);
-            p += 1 + p[0];
-            if (flags & EIDC__V_BINIDENT)
-              fprintf (file, _("   binary ident  : 0x%08x\n"),
-                       (unsigned)bfd_getl32 (p + 1));
-            else
-              fprintf (file, _("   ascii ident   : %.*s\n"), p[0], p + 1);
-          }
-          break;
-        case EGSD__C_SYMG:
-          {
-            struct vms_egst *egst = (struct vms_egst *)e;
-            unsigned int flags = bfd_getl16 (egst->header.flags);
-
-            fprintf (file, _("SYMG - Universal symbol definition\n"));
-            fprintf (file, _("   flags: 0x%04x"), flags);
-            exav_bfd_print_egsy_flags (flags, file);
-            fputc ('\n', file);
-            fprintf (file, _("   symbol vector offset: 0x%08x\n"),
-                     (unsigned)bfd_getl32 (egst->value));
-            fprintf (file, _("   entry point: 0x%08x\n"),
-                     (unsigned)bfd_getl32 (egst->lp_1));
-            fprintf (file, _("   proc descr : 0x%08x\n"),
-                     (unsigned)bfd_getl32 (egst->lp_2));
-            fprintf (file, _("   psect index: %u\n"),
-                     (unsigned)bfd_getl32 (egst->psindx));
-            fprintf (file, _("   name       : %.*s\n"),
-                     egst->namlng, egst->name);
-          }
-          break;
-        case EGSD__C_SYMV:
-          {
-            struct vms_esdfv *esdfv = (struct vms_esdfv *)e;
-            unsigned int flags = bfd_getl16 (esdfv->flags);
-
-            fprintf (file, _("SYMV - Vectored symbol definition\n"));
-            fprintf (file, _("   flags: 0x%04x"), flags);
-            exav_bfd_print_egsy_flags (flags, file);
-            fputc ('\n', file);
-            fprintf (file, _("   vector      : 0x%08x\n"),
-                     (unsigned)bfd_getl32 (esdfv->vector));
-            fprintf (file, _("   psect offset: %u\n"),
-                     (unsigned)bfd_getl32 (esdfv->value));
-            fprintf (file, _("   psect index : %u\n"),
-                     (unsigned)bfd_getl32 (esdfv->psindx));
-            fprintf (file, _("   name        : %.*s\n"),
-                     esdfv->namlng, esdfv->name);
-          }
-          break;
-        case EGSD__C_SYMM:
-          {
-            struct vms_esdfm *esdfm = (struct vms_esdfm *)e;
-            unsigned int flags = bfd_getl16 (esdfm->flags);
-
-            fprintf (file, _("SYMM - Global symbol definition with version\n"));
-            fprintf (file, _("   flags: 0x%04x"), flags);
-            exav_bfd_print_egsy_flags (flags, file);
-            fputc ('\n', file);
-            fprintf (file, _("   version mask: 0x%08x\n"),
-                     (unsigned)bfd_getl32 (esdfm->version_mask));
-            fprintf (file, _("   psect offset: %u\n"),
-                     (unsigned)bfd_getl32 (esdfm->value));
-            fprintf (file, _("   psect index : %u\n"),
-                     (unsigned)bfd_getl32 (esdfm->psindx));
-            fprintf (file, _("   name        : %.*s\n"),
-                     esdfm->namlng, esdfm->name);
-          }
-          break;
-        default:
-          fprintf (file, _("unhandled egsd entry type %u\n"), type);
-          break;
-        }
+       {
+       case EGSD__C_PSC:
+         {
+           struct vms_egps *egps = (struct vms_egps *)e;
+           unsigned int flags = bfd_getl16 (egps->flags);
+           unsigned int l;
+
+           fprintf (file, _("PSC - Program section definition\n"));
+           fprintf (file, _("   alignment  : 2**%u\n"), egps->align);
+           fprintf (file, _("   flags      : 0x%04x"), flags);
+           evax_bfd_print_egsd_flags (file, flags);
+           fputc ('\n', file);
+           l = bfd_getl32 (egps->alloc);
+           fprintf (file, _("   alloc (len): %u (0x%08x)\n"), l, l);
+           fprintf (file, _("   name       : %.*s\n"),
+                    egps->namlng, egps->name);
+         }
+         break;
+       case EGSD__C_SPSC:
+         {
+           struct vms_esgps *esgps = (struct vms_esgps *)e;
+           unsigned int flags = bfd_getl16 (esgps->flags);
+           unsigned int l;
+
+           fprintf (file, _("SPSC - Shared Image Program section def\n"));
+           fprintf (file, _("   alignment  : 2**%u\n"), esgps->align);
+           fprintf (file, _("   flags      : 0x%04x"), flags);
+           evax_bfd_print_egsd_flags (file, flags);
+           fputc ('\n', file);
+           l = bfd_getl32 (esgps->alloc);
+           fprintf (file, _("   alloc (len)   : %u (0x%08x)\n"), l, l);
+           fprintf (file, _("   image offset  : 0x%08x\n"),
+                    (unsigned int)bfd_getl32 (esgps->base));
+           fprintf (file, _("   symvec offset : 0x%08x\n"),
+                    (unsigned int)bfd_getl32 (esgps->value));
+           fprintf (file, _("   name          : %.*s\n"),
+                    esgps->namlng, esgps->name);
+         }
+         break;
+       case EGSD__C_SYM:
+         {
+           struct vms_egsy *egsy = (struct vms_egsy *)e;
+           unsigned int flags = bfd_getl16 (egsy->flags);
+
+           if (flags & EGSY__V_DEF)
+             {
+               struct vms_esdf *esdf = (struct vms_esdf *)e;
+
+               fprintf (file, _("SYM - Global symbol definition\n"));
+               fprintf (file, _("   flags: 0x%04x"), flags);
+               exav_bfd_print_egsy_flags (flags, file);
+               fputc ('\n', file);
+               fprintf (file, _("   psect offset: 0x%08x\n"),
+                        (unsigned)bfd_getl32 (esdf->value));
+               if (flags & EGSY__V_NORM)
+                 {
+                   fprintf (file, _("   code address: 0x%08x\n"),
+                            (unsigned)bfd_getl32 (esdf->code_address));
+                   fprintf (file, _("   psect index for entry point : %u\n"),
+                            (unsigned)bfd_getl32 (esdf->ca_psindx));
+                 }
+               fprintf (file, _("   psect index : %u\n"),
+                        (unsigned)bfd_getl32 (esdf->psindx));
+               fprintf (file, _("   name        : %.*s\n"),
+                        esdf->namlng, esdf->name);
+             }
+           else
+             {
+               struct vms_esrf *esrf = (struct vms_esrf *)e;
+
+               fprintf (file, _("SYM - Global symbol reference\n"));
+               fprintf (file, _("   name       : %.*s\n"),
+                        esrf->namlng, esrf->name);
+             }
+         }
+         break;
+       case EGSD__C_IDC:
+         {
+           struct vms_eidc *eidc = (struct vms_eidc *)e;
+           unsigned int flags = bfd_getl32 (eidc->flags);
+           unsigned char *p;
+
+           fprintf (file, _("IDC - Ident Consistency check\n"));
+           fprintf (file, _("   flags         : 0x%08x"), flags);
+           if (flags & EIDC__V_BINIDENT)
+             fputs (" BINDENT", file);
+           fputc ('\n', file);
+           fprintf (file, _("   id match      : %x\n"),
+                    (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK);
+           fprintf (file, _("   error severity: %x\n"),
+                    (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK);
+           p = eidc->name;
+           fprintf (file, _("   entity name   : %.*s\n"), p[0], p + 1);
+           p += 1 + p[0];
+           fprintf (file, _("   object name   : %.*s\n"), p[0], p + 1);
+           p += 1 + p[0];
+           if (flags & EIDC__V_BINIDENT)
+             fprintf (file, _("   binary ident  : 0x%08x\n"),
+                      (unsigned)bfd_getl32 (p + 1));
+           else
+             fprintf (file, _("   ascii ident   : %.*s\n"), p[0], p + 1);
+         }
+         break;
+       case EGSD__C_SYMG:
+         {
+           struct vms_egst *egst = (struct vms_egst *)e;
+           unsigned int flags = bfd_getl16 (egst->header.flags);
+
+           fprintf (file, _("SYMG - Universal symbol definition\n"));
+           fprintf (file, _("   flags: 0x%04x"), flags);
+           exav_bfd_print_egsy_flags (flags, file);
+           fputc ('\n', file);
+           fprintf (file, _("   symbol vector offset: 0x%08x\n"),
+                    (unsigned)bfd_getl32 (egst->value));
+           fprintf (file, _("   entry point: 0x%08x\n"),
+                    (unsigned)bfd_getl32 (egst->lp_1));
+           fprintf (file, _("   proc descr : 0x%08x\n"),
+                    (unsigned)bfd_getl32 (egst->lp_2));
+           fprintf (file, _("   psect index: %u\n"),
+                    (unsigned)bfd_getl32 (egst->psindx));
+           fprintf (file, _("   name       : %.*s\n"),
+                    egst->namlng, egst->name);
+         }
+         break;
+       case EGSD__C_SYMV:
+         {
+           struct vms_esdfv *esdfv = (struct vms_esdfv *)e;
+           unsigned int flags = bfd_getl16 (esdfv->flags);
+
+           fprintf (file, _("SYMV - Vectored symbol definition\n"));
+           fprintf (file, _("   flags: 0x%04x"), flags);
+           exav_bfd_print_egsy_flags (flags, file);
+           fputc ('\n', file);
+           fprintf (file, _("   vector      : 0x%08x\n"),
+                    (unsigned)bfd_getl32 (esdfv->vector));
+           fprintf (file, _("   psect offset: %u\n"),
+                    (unsigned)bfd_getl32 (esdfv->value));
+           fprintf (file, _("   psect index : %u\n"),
+                    (unsigned)bfd_getl32 (esdfv->psindx));
+           fprintf (file, _("   name        : %.*s\n"),
+                    esdfv->namlng, esdfv->name);
+         }
+         break;
+       case EGSD__C_SYMM:
+         {
+           struct vms_esdfm *esdfm = (struct vms_esdfm *)e;
+           unsigned int flags = bfd_getl16 (esdfm->flags);
+
+           fprintf (file, _("SYMM - Global symbol definition with version\n"));
+           fprintf (file, _("   flags: 0x%04x"), flags);
+           exav_bfd_print_egsy_flags (flags, file);
+           fputc ('\n', file);
+           fprintf (file, _("   version mask: 0x%08x\n"),
+                    (unsigned)bfd_getl32 (esdfm->version_mask));
+           fprintf (file, _("   psect offset: %u\n"),
+                    (unsigned)bfd_getl32 (esdfm->value));
+           fprintf (file, _("   psect index : %u\n"),
+                    (unsigned)bfd_getl32 (esdfm->psindx));
+           fprintf (file, _("   name        : %.*s\n"),
+                    esdfm->namlng, esdfm->name);
+         }
+         break;
+       default:
+         fprintf (file, _("unhandled egsd entry type %u\n"), type);
+         break;
+       }
       off += len;
     }
 }
 
 static void
 evax_bfd_print_hex (FILE *file, const char *pfx,
-                    const unsigned char *buf, unsigned int len)
+                   const unsigned char *buf, unsigned int len)
 {
   unsigned int i;
   unsigned int n;
@@ -5868,14 +6281,14 @@ evax_bfd_print_hex (FILE *file, const char *pfx,
   for (i = 0; i < len; i++)
     {
       if (n == 0)
-        fputs (pfx, file);
+       fputs (pfx, file);
       fprintf (file, " %02x", buf[i]);
       n++;
       if (n == 16)
-        {
-          n = 0;
-          fputc ('\n', file);
-        }
+       {
+         n = 0;
+         fputc ('\n', file);
+       }
     }
   if (n != 0)
     fputc ('\n', file);
@@ -5884,36 +6297,41 @@ evax_bfd_print_hex (FILE *file, const char *pfx,
 static void
 evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps)
 {
+  /* xgettext:c-format */
   fprintf (file, _("    linkage index: %u, replacement insn: 0x%08x\n"),
-           (unsigned)bfd_getl32 (buf),
-           (unsigned)bfd_getl32 (buf + 16));
+          (unsigned)bfd_getl32 (buf),
+          (unsigned)bfd_getl32 (buf + 16));
+  /* xgettext:c-format */
   fprintf (file, _("    psect idx 1: %u, offset 1: 0x%08x %08x\n"),
-           (unsigned)bfd_getl32 (buf + 4),
-           (unsigned)bfd_getl32 (buf + 12),
-           (unsigned)bfd_getl32 (buf + 8));
+          (unsigned)bfd_getl32 (buf + 4),
+          (unsigned)bfd_getl32 (buf + 12),
+          (unsigned)bfd_getl32 (buf + 8));
+  /* xgettext:c-format */
   fprintf (file, _("    psect idx 2: %u, offset 2: 0x%08x %08x\n"),
-           (unsigned)bfd_getl32 (buf + 20),
-           (unsigned)bfd_getl32 (buf + 28),
-           (unsigned)bfd_getl32 (buf + 24));
+          (unsigned)bfd_getl32 (buf + 20),
+          (unsigned)bfd_getl32 (buf + 28),
+          (unsigned)bfd_getl32 (buf + 24));
   if (is_ps)
+    /* xgettext:c-format */
     fprintf (file, _("    psect idx 3: %u, offset 3: 0x%08x %08x\n"),
-             (unsigned)bfd_getl32 (buf + 32),
-             (unsigned)bfd_getl32 (buf + 40),
-             (unsigned)bfd_getl32 (buf + 36));
+            (unsigned)bfd_getl32 (buf + 32),
+            (unsigned)bfd_getl32 (buf + 40),
+            (unsigned)bfd_getl32 (buf + 36));
   else
     fprintf (file, _("    global name: %.*s\n"), buf[32], buf + 33);
 }
 
 static void
 evax_bfd_print_etir (FILE *file, const char *name,
-                     unsigned char *rec, unsigned int rec_len)
+                    unsigned char *rec, unsigned int rec_len)
 {
   unsigned int off = sizeof (struct vms_egsd);
-  unsigned int sec_len;
+  unsigned int sec_len = 0;
 
+  /* xgettext:c-format */
   fprintf (file, _("  %s (len=%u+%u):\n"), name,
-           (unsigned)(rec_len - sizeof (struct vms_eobjrec)),
-           (unsigned)sizeof (struct vms_eobjrec));
+          (unsigned)(rec_len - sizeof (struct vms_eobjrec)),
+          (unsigned)sizeof (struct vms_eobjrec));
 
   for (off = sizeof (struct vms_eobjrec); off < rec_len; )
     {
@@ -5926,244 +6344,260 @@ evax_bfd_print_etir (FILE *file, const char *name,
       size = bfd_getl16 (etir->size);
       buf = rec + off + sizeof (struct vms_etir);
 
+      if (off + size > rec_len || off + size < off)
+       {
+         fprintf (file, _("   Error: length larger than remaining space in record\n"));
+         return;
+       }
+
+      /* xgettext:c-format */
       fprintf (file, _("   (type: %3u, size: 4+%3u): "), type, size - 4);
       switch (type)
-        {
-        case ETIR__C_STA_GBL:
-          fprintf (file, _("STA_GBL (stack global) %.*s\n"),
-                   buf[0], buf + 1);
-          break;
-        case ETIR__C_STA_LW:
-          fprintf (file, _("STA_LW (stack longword) 0x%08x\n"),
-                   (unsigned)bfd_getl32 (buf));
-          break;
-        case ETIR__C_STA_QW:
-          fprintf (file, _("STA_QW (stack quadword) 0x%08x %08x\n"),
-                   (unsigned)bfd_getl32 (buf + 4),
-                   (unsigned)bfd_getl32 (buf + 0));
-          break;
-        case ETIR__C_STA_PQ:
-          fprintf (file, _("STA_PQ (stack psect base + offset)\n"));
-          fprintf (file, _("    psect: %u, offset: 0x%08x %08x\n"),
-                   (unsigned)bfd_getl32 (buf + 0),
-                   (unsigned)bfd_getl32 (buf + 8),
-                   (unsigned)bfd_getl32 (buf + 4));
-          break;
-        case ETIR__C_STA_LI:
-          fprintf (file, _("STA_LI (stack literal)\n"));
-          break;
-        case ETIR__C_STA_MOD:
-          fprintf (file, _("STA_MOD (stack module)\n"));
-          break;
-        case ETIR__C_STA_CKARG:
-          fprintf (file, _("STA_CKARG (compare procedure argument)\n"));
-          break;
-
-        case ETIR__C_STO_B:
-          fprintf (file, _("STO_B (store byte)\n"));
-          break;
-        case ETIR__C_STO_W:
-          fprintf (file, _("STO_W (store word)\n"));
-          break;
-        case ETIR__C_STO_LW:
-          fprintf (file, _("STO_LW (store longword)\n"));
-          break;
-        case ETIR__C_STO_QW:
-          fprintf (file, _("STO_QW (store quadword)\n"));
-          break;
-        case ETIR__C_STO_IMMR:
-          {
-            unsigned int len = bfd_getl32 (buf);
-            fprintf (file,
-                     _("STO_IMMR (store immediate repeat) %u bytes\n"),
-                     len);
-            evax_bfd_print_hex (file, "   ", buf + 4, len);
-            sec_len += len;
-          }
-          break;
-        case ETIR__C_STO_GBL:
-          fprintf (file, _("STO_GBL (store global) %.*s\n"),
-                   buf[0], buf + 1);
-          break;
-        case ETIR__C_STO_CA:
-          fprintf (file, _("STO_CA (store code address) %.*s\n"),
-                   buf[0], buf + 1);
-          break;
-        case ETIR__C_STO_RB:
-          fprintf (file, _("STO_RB (store relative branch)\n"));
-          break;
-        case ETIR__C_STO_AB:
-          fprintf (file, _("STO_AB (store absolute branch)\n"));
-          break;
-        case ETIR__C_STO_OFF:
-          fprintf (file, _("STO_OFF (store offset to psect)\n"));
-          break;
-        case ETIR__C_STO_IMM:
-          {
-            unsigned int len = bfd_getl32 (buf);
-            fprintf (file,
-                     _("STO_IMM (store immediate) %u bytes\n"),
-                     len);
-            evax_bfd_print_hex (file, "   ", buf + 4, len);
-            sec_len += len;
-          }
-          break;
-        case ETIR__C_STO_LP_PSB:
-          fprintf (file, _("STO_OFF (store LP with procedure signature)\n"));
-          break;
-        case ETIR__C_STO_HINT_GBL:
-          fprintf (file, _("STO_BR_GBL (store branch global) *todo*\n"));
-          break;
-        case ETIR__C_STO_HINT_PS:
-          fprintf (file, _("STO_BR_PS (store branch psect + offset) *todo*\n"));
-          break;
-
-        case ETIR__C_OPR_NOP:
-          fprintf (file, _("OPR_NOP (no-operation)\n"));
-          break;
-        case ETIR__C_OPR_ADD:
-          fprintf (file, _("OPR_ADD (add)\n"));
-          break;
-        case ETIR__C_OPR_SUB:
-          fprintf (file, _("OPR_SUB (substract)\n"));
-          break;
-        case ETIR__C_OPR_MUL:
-          fprintf (file, _("OPR_MUL (multiply)\n"));
-          break;
-        case ETIR__C_OPR_DIV:
-          fprintf (file, _("OPR_DIV (divide)\n"));
-          break;
-        case ETIR__C_OPR_AND:
-          fprintf (file, _("OPR_AND (logical and)\n"));
-          break;
-        case ETIR__C_OPR_IOR:
-          fprintf (file, _("OPR_IOR (logical inclusive or)\n"));
-          break;
-        case ETIR__C_OPR_EOR:
-          fprintf (file, _("OPR_EOR (logical exclusive or)\n"));
-          break;
-        case ETIR__C_OPR_NEG:
-          fprintf (file, _("OPR_NEG (negate)\n"));
-          break;
-        case ETIR__C_OPR_COM:
-          fprintf (file, _("OPR_COM (complement)\n"));
-          break;
-        case ETIR__C_OPR_INSV:
-          fprintf (file, _("OPR_INSV (insert field)\n"));
-          break;
-        case ETIR__C_OPR_ASH:
-          fprintf (file, _("OPR_ASH (arithmetic shift)\n"));
-          break;
-        case ETIR__C_OPR_USH:
-          fprintf (file, _("OPR_USH (unsigned shift)\n"));
-          break;
-        case ETIR__C_OPR_ROT:
-          fprintf (file, _("OPR_ROT (rotate)\n"));
-          break;
-        case ETIR__C_OPR_SEL:
-          fprintf (file, _("OPR_SEL (select)\n"));
-          break;
-        case ETIR__C_OPR_REDEF:
-          fprintf (file, _("OPR_REDEF (redefine symbol to curr location)\n"));
-          break;
-        case ETIR__C_OPR_DFLIT:
-          fprintf (file, _("OPR_REDEF (define a literal)\n"));
-          break;
-
-        case ETIR__C_STC_LP:
-          fprintf (file, _("STC_LP (store cond linkage pair)\n"));
-          break;
-        case ETIR__C_STC_LP_PSB:
-          fprintf (file,
-                   _("STC_LP_PSB (store cond linkage pair + signature)\n"));
-          fprintf (file, _("   linkage index: %u, procedure: %.*s\n"),
-                   (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
-          buf += 4 + 1 + buf[4];
-          fprintf (file, _("   signature: %.*s\n"), buf[0], buf + 1);
-          break;
-        case ETIR__C_STC_GBL:
-          fprintf (file, _("STC_GBL (store cond global)\n"));
-          fprintf (file, _("   linkage index: %u, global: %.*s\n"),
-                   (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
-          break;
-        case ETIR__C_STC_GCA:
-          fprintf (file, _("STC_GCA (store cond code address)\n"));
-          fprintf (file, _("   linkage index: %u, procedure name: %.*s\n"),
-                   (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
-          break;
-        case ETIR__C_STC_PS:
-          fprintf (file, _("STC_PS (store cond psect + offset)\n"));
-          fprintf (file,
-                   _("   linkage index: %u, psect: %u, offset: 0x%08x %08x\n"),
-                   (unsigned)bfd_getl32 (buf),
-                   (unsigned)bfd_getl32 (buf + 4),
-                   (unsigned)bfd_getl32 (buf + 12),
-                   (unsigned)bfd_getl32 (buf + 8));
-          break;
-        case ETIR__C_STC_NOP_GBL:
-          fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 0);
-          break;
-        case ETIR__C_STC_NOP_PS:
-          fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 1);
-          break;
-        case ETIR__C_STC_BSR_GBL:
-          fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 0);
-          break;
-        case ETIR__C_STC_BSR_PS:
-          fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 1);
-          break;
-        case ETIR__C_STC_LDA_GBL:
-          fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 0);
-          break;
-        case ETIR__C_STC_LDA_PS:
-          fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 1);
-          break;
-        case ETIR__C_STC_BOH_GBL:
-          fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 0);
-          break;
-        case ETIR__C_STC_BOH_PS:
-          fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n"));
-          evax_bfd_print_etir_stc_ir (file, buf, 1);
-          break;
-        case ETIR__C_STC_NBH_GBL:
-          fprintf (file,
-                   _("STC_NBH_GBL (store cond or hint at global addr)\n"));
-          break;
-        case ETIR__C_STC_NBH_PS:
-          fprintf (file,
-                   _("STC_NBH_PS (store cond or hint at psect + offset)\n"));
-          break;
-
-        case ETIR__C_CTL_SETRB:
-          fprintf (file, _("CTL_SETRB (set relocation base)\n"));
-          sec_len += 4;
-          break;
-        case ETIR__C_CTL_AUGRB:
-          {
-            unsigned int val = bfd_getl32 (buf);
-            fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), val);
-          }
-          break;
-        case ETIR__C_CTL_DFLOC:
-          fprintf (file, _("CTL_DFLOC (define location)\n"));
-          break;
-        case ETIR__C_CTL_STLOC:
-          fprintf (file, _("CTL_STLOC (set location)\n"));
-          break;
-        case ETIR__C_CTL_STKDL:
-          fprintf (file, _("CTL_STKDL (stack defined location)\n"));
-          break;
-        default:
-          fprintf (file, _("*unhandled*\n"));
-          break;
-        }
+       {
+       case ETIR__C_STA_GBL:
+         fprintf (file, _("STA_GBL (stack global) %.*s\n"),
+                  buf[0], buf + 1);
+         break;
+       case ETIR__C_STA_LW:
+         fprintf (file, _("STA_LW (stack longword) 0x%08x\n"),
+                  (unsigned)bfd_getl32 (buf));
+         break;
+       case ETIR__C_STA_QW:
+         fprintf (file, _("STA_QW (stack quadword) 0x%08x %08x\n"),
+                  (unsigned)bfd_getl32 (buf + 4),
+                  (unsigned)bfd_getl32 (buf + 0));
+         break;
+       case ETIR__C_STA_PQ:
+         fprintf (file, _("STA_PQ (stack psect base + offset)\n"));
+         /* xgettext:c-format */
+         fprintf (file, _("    psect: %u, offset: 0x%08x %08x\n"),
+                  (unsigned)bfd_getl32 (buf + 0),
+                  (unsigned)bfd_getl32 (buf + 8),
+                  (unsigned)bfd_getl32 (buf + 4));
+         break;
+       case ETIR__C_STA_LI:
+         fprintf (file, _("STA_LI (stack literal)\n"));
+         break;
+       case ETIR__C_STA_MOD:
+         fprintf (file, _("STA_MOD (stack module)\n"));
+         break;
+       case ETIR__C_STA_CKARG:
+         fprintf (file, _("STA_CKARG (compare procedure argument)\n"));
+         break;
+
+       case ETIR__C_STO_B:
+         fprintf (file, _("STO_B (store byte)\n"));
+         break;
+       case ETIR__C_STO_W:
+         fprintf (file, _("STO_W (store word)\n"));
+         break;
+       case ETIR__C_STO_LW:
+         fprintf (file, _("STO_LW (store longword)\n"));
+         break;
+       case ETIR__C_STO_QW:
+         fprintf (file, _("STO_QW (store quadword)\n"));
+         break;
+       case ETIR__C_STO_IMMR:
+         {
+           unsigned int len = bfd_getl32 (buf);
+           fprintf (file,
+                    _("STO_IMMR (store immediate repeat) %u bytes\n"),
+                    len);
+           evax_bfd_print_hex (file, "   ", buf + 4, len);
+           sec_len += len;
+         }
+         break;
+       case ETIR__C_STO_GBL:
+         fprintf (file, _("STO_GBL (store global) %.*s\n"),
+                  buf[0], buf + 1);
+         break;
+       case ETIR__C_STO_CA:
+         fprintf (file, _("STO_CA (store code address) %.*s\n"),
+                  buf[0], buf + 1);
+         break;
+       case ETIR__C_STO_RB:
+         fprintf (file, _("STO_RB (store relative branch)\n"));
+         break;
+       case ETIR__C_STO_AB:
+         fprintf (file, _("STO_AB (store absolute branch)\n"));
+         break;
+       case ETIR__C_STO_OFF:
+         fprintf (file, _("STO_OFF (store offset to psect)\n"));
+         break;
+       case ETIR__C_STO_IMM:
+         {
+           unsigned int len = bfd_getl32 (buf);
+           fprintf (file,
+                    _("STO_IMM (store immediate) %u bytes\n"),
+                    len);
+           evax_bfd_print_hex (file, "   ", buf + 4, len);
+           sec_len += len;
+         }
+         break;
+       case ETIR__C_STO_GBL_LW:
+         fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"),
+                  buf[0], buf + 1);
+         break;
+       case ETIR__C_STO_LP_PSB:
+         fprintf (file, _("STO_OFF (store LP with procedure signature)\n"));
+         break;
+       case ETIR__C_STO_HINT_GBL:
+         fprintf (file, _("STO_BR_GBL (store branch global) *todo*\n"));
+         break;
+       case ETIR__C_STO_HINT_PS:
+         fprintf (file, _("STO_BR_PS (store branch psect + offset) *todo*\n"));
+         break;
+
+       case ETIR__C_OPR_NOP:
+         fprintf (file, _("OPR_NOP (no-operation)\n"));
+         break;
+       case ETIR__C_OPR_ADD:
+         fprintf (file, _("OPR_ADD (add)\n"));
+         break;
+       case ETIR__C_OPR_SUB:
+         fprintf (file, _("OPR_SUB (subtract)\n"));
+         break;
+       case ETIR__C_OPR_MUL:
+         fprintf (file, _("OPR_MUL (multiply)\n"));
+         break;
+       case ETIR__C_OPR_DIV:
+         fprintf (file, _("OPR_DIV (divide)\n"));
+         break;
+       case ETIR__C_OPR_AND:
+         fprintf (file, _("OPR_AND (logical and)\n"));
+         break;
+       case ETIR__C_OPR_IOR:
+         fprintf (file, _("OPR_IOR (logical inclusive or)\n"));
+         break;
+       case ETIR__C_OPR_EOR:
+         fprintf (file, _("OPR_EOR (logical exclusive or)\n"));
+         break;
+       case ETIR__C_OPR_NEG:
+         fprintf (file, _("OPR_NEG (negate)\n"));
+         break;
+       case ETIR__C_OPR_COM:
+         fprintf (file, _("OPR_COM (complement)\n"));
+         break;
+       case ETIR__C_OPR_INSV:
+         fprintf (file, _("OPR_INSV (insert field)\n"));
+         break;
+       case ETIR__C_OPR_ASH:
+         fprintf (file, _("OPR_ASH (arithmetic shift)\n"));
+         break;
+       case ETIR__C_OPR_USH:
+         fprintf (file, _("OPR_USH (unsigned shift)\n"));
+         break;
+       case ETIR__C_OPR_ROT:
+         fprintf (file, _("OPR_ROT (rotate)\n"));
+         break;
+       case ETIR__C_OPR_SEL:
+         fprintf (file, _("OPR_SEL (select)\n"));
+         break;
+       case ETIR__C_OPR_REDEF:
+         fprintf (file, _("OPR_REDEF (redefine symbol to curr location)\n"));
+         break;
+       case ETIR__C_OPR_DFLIT:
+         fprintf (file, _("OPR_REDEF (define a literal)\n"));
+         break;
+
+       case ETIR__C_STC_LP:
+         fprintf (file, _("STC_LP (store cond linkage pair)\n"));
+         break;
+       case ETIR__C_STC_LP_PSB:
+         fprintf (file,
+                  _("STC_LP_PSB (store cond linkage pair + signature)\n"));
+         /* xgettext:c-format */
+         fprintf (file, _("   linkage index: %u, procedure: %.*s\n"),
+                  (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+         buf += 4 + 1 + buf[4];
+         fprintf (file, _("   signature: %.*s\n"), buf[0], buf + 1);
+         break;
+       case ETIR__C_STC_GBL:
+         fprintf (file, _("STC_GBL (store cond global)\n"));
+         /* xgettext:c-format */
+         fprintf (file, _("   linkage index: %u, global: %.*s\n"),
+                  (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+         break;
+       case ETIR__C_STC_GCA:
+         fprintf (file, _("STC_GCA (store cond code address)\n"));
+         /* xgettext:c-format */
+         fprintf (file, _("   linkage index: %u, procedure name: %.*s\n"),
+                  (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+         break;
+       case ETIR__C_STC_PS:
+         fprintf (file, _("STC_PS (store cond psect + offset)\n"));
+         fprintf (file,
+                  /* xgettext:c-format */
+                  _("   linkage index: %u, psect: %u, offset: 0x%08x %08x\n"),
+                  (unsigned)bfd_getl32 (buf),
+                  (unsigned)bfd_getl32 (buf + 4),
+                  (unsigned)bfd_getl32 (buf + 12),
+                  (unsigned)bfd_getl32 (buf + 8));
+         break;
+       case ETIR__C_STC_NOP_GBL:
+         fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 0);
+         break;
+       case ETIR__C_STC_NOP_PS:
+         fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 1);
+         break;
+       case ETIR__C_STC_BSR_GBL:
+         fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 0);
+         break;
+       case ETIR__C_STC_BSR_PS:
+         fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 1);
+         break;
+       case ETIR__C_STC_LDA_GBL:
+         fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 0);
+         break;
+       case ETIR__C_STC_LDA_PS:
+         fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 1);
+         break;
+       case ETIR__C_STC_BOH_GBL:
+         fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 0);
+         break;
+       case ETIR__C_STC_BOH_PS:
+         fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n"));
+         evax_bfd_print_etir_stc_ir (file, buf, 1);
+         break;
+       case ETIR__C_STC_NBH_GBL:
+         fprintf (file,
+                  _("STC_NBH_GBL (store cond or hint at global addr)\n"));
+         break;
+       case ETIR__C_STC_NBH_PS:
+         fprintf (file,
+                  _("STC_NBH_PS (store cond or hint at psect + offset)\n"));
+         break;
+
+       case ETIR__C_CTL_SETRB:
+         fprintf (file, _("CTL_SETRB (set relocation base)\n"));
+         sec_len += 4;
+         break;
+       case ETIR__C_CTL_AUGRB:
+         {
+           unsigned int val = bfd_getl32 (buf);
+           fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), val);
+         }
+         break;
+       case ETIR__C_CTL_DFLOC:
+         fprintf (file, _("CTL_DFLOC (define location)\n"));
+         break;
+       case ETIR__C_CTL_STLOC:
+         fprintf (file, _("CTL_STLOC (set location)\n"));
+         break;
+       case ETIR__C_CTL_STKDL:
+         fprintf (file, _("CTL_STKDL (stack defined location)\n"));
+         break;
+       default:
+         fprintf (file, _("*unhandled*\n"));
+         break;
+       }
       off += size;
     }
 }
@@ -6174,130 +6608,130 @@ evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
   bfd_boolean is_first = TRUE;
   bfd_boolean has_records = FALSE;
 
-  while (1)
-    {
-      unsigned int rec_len;
-      unsigned int pad_len;
-      unsigned char *rec;
-      unsigned int hdr_size;
-      unsigned int type;
+  while (1)
+    {
+      unsigned int rec_len;
+      unsigned int pad_len;
+      unsigned char *rec;
+      unsigned int hdr_size;
+      unsigned int type;
+
+      if (is_first)
+       {
+         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);
+       }
+      else
+       {
+         unsigned int rec_len2 = 0;
+         unsigned char hdr[4];
+
+         if (has_records)
+           {
+             unsigned char buf_len[2];
 
-      if (is_first)
-        {
-          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);
-        }
-      else
-        {
-          unsigned int rec_len2 = 0;
-          unsigned char hdr[4];
-
-          if (has_records)
-            {
-              unsigned char buf_len[2];
-
-              if (bfd_bread (buf_len, sizeof (buf_len), abfd)
-                  != sizeof (buf_len))
-                {
-                  fprintf (file, _("cannot read GST record length\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;
-            }
-        }
+             if (bfd_bread (buf_len, sizeof (buf_len), abfd)
+                 != sizeof (buf_len))
+               {
+                 fprintf (file, _("cannot read GST record length\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;
+           }
+       }
 
       if (bfd_bread (rec + hdr_size, pad_len - hdr_size, abfd)
-          != pad_len - hdr_size)
-        {
-          fprintf (file, _("cannot read GST record\n"));
-          return;
-        }
+         != pad_len - hdr_size)
+       {
+         fprintf (file, _("cannot read GST record\n"));
+         return;
+       }
 
       type = (unsigned)bfd_getl16 (rec);
 
       switch (type)
-        {
-        case EOBJ__C_EMH:
-          evax_bfd_print_emh (file, rec, rec_len);
-          break;
-        case EOBJ__C_EGSD:
-          evax_bfd_print_egsd (file, rec, rec_len);
-          break;
-        case EOBJ__C_EEOM:
-          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;
-        case EOBJ__C_EDBG:
-          evax_bfd_print_etir (file, "EDBG", rec, rec_len);
-          break;
-        case EOBJ__C_ETBT:
-          evax_bfd_print_etir (file, "ETBT", rec, rec_len);
-          break;
-        default:
-          fprintf (file, _(" unhandled EOBJ record type %u\n"), type);
-          break;
-        }
+       {
+       case EOBJ__C_EMH:
+         evax_bfd_print_emh (file, rec, rec_len);
+         break;
+       case EOBJ__C_EGSD:
+         evax_bfd_print_egsd (file, rec, rec_len);
+         break;
+       case EOBJ__C_EEOM:
+         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;
+       case EOBJ__C_EDBG:
+         evax_bfd_print_etir (file, "EDBG", rec, rec_len);
+         break;
+       case EOBJ__C_ETBT:
+         evax_bfd_print_etir (file, "ETBT", rec, rec_len);
+         break;
+       default:
+         fprintf (file, _(" unhandled EOBJ record type %u\n"), type);
+         break;
+       }
       free (rec);
     }
 }
 
 static void
 evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel,
-                                   unsigned int stride)
+                                  unsigned int stride)
 {
   while (1)
     {
@@ -6308,40 +6742,42 @@ evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel,
       count = bfd_getl32 (rel + 0);
 
       if (count == 0)
-        break;
+       break;
       base = bfd_getl32 (rel + 4);
 
+      /* xgettext:c-format */
       fprintf (file, _("  bitcount: %u, base addr: 0x%08x\n"),
-               count, base);
+              count, base);
 
       rel += 8;
       for (j = 0; count > 0; j += 4, count -= 32)
-        {
-          unsigned int k;
-          unsigned int n = 0;
-          unsigned int val;
-
-          val = bfd_getl32 (rel);
-          rel += 4;
-
-          fprintf (file, _("   bitmap: 0x%08x (count: %u):\n"), val, count);
-
-          for (k = 0; k < 32; k++)
-            if (val & (1 << k))
-              {
-                if (n == 0)
-                  fputs ("   ", file);
-                fprintf (file, _(" %08x"), base + (j * 8 + k) * stride);
-                n++;
-                if (n == 8)
-                  {
-                    fputs ("\n", file);
-                    n = 0;
-                  }
-              }
-          if (n)
-            fputs ("\n", file);
-        }
+       {
+         unsigned int k;
+         unsigned int n = 0;
+         unsigned int val;
+
+         val = bfd_getl32 (rel);
+         rel += 4;
+
+         /* xgettext:c-format */
+         fprintf (file, _("   bitmap: 0x%08x (count: %u):\n"), val, count);
+
+         for (k = 0; k < 32; k++)
+           if (val & (1u << k))
+             {
+               if (n == 0)
+                 fputs ("   ", file);
+               fprintf (file, _(" %08x"), base + (j * 8 + k) * stride);
+               n++;
+               if (n == 8)
+                 {
+                   fputs ("\n", file);
+                   n = 0;
+                 }
+             }
+         if (n)
+           fputs ("\n", file);
+       }
     }
 }
 
@@ -6355,17 +6791,19 @@ evax_bfd_print_address_fixups (FILE *file, const unsigned char *rel)
 
       count = bfd_getl32 (rel + 0);
       if (count == 0)
-        return;
+       return;
+      /* xgettext:c-format */
       fprintf (file, _("  image %u (%u entries)\n"),
-               (unsigned)bfd_getl32 (rel + 4), count);
+              (unsigned)bfd_getl32 (rel + 4), count);
       rel += 8;
       for (j = 0; j < count; j++)
-        {
-          fprintf (file, _("   offset: 0x%08x, val: 0x%08x\n"),
-                   (unsigned)bfd_getl32 (rel + 0),
-                   (unsigned)bfd_getl32 (rel + 4));
-          rel += 8;
-        }
+       {
+         /* xgettext:c-format */
+         fprintf (file, _("   offset: 0x%08x, val: 0x%08x\n"),
+                  (unsigned)bfd_getl32 (rel + 0),
+                  (unsigned)bfd_getl32 (rel + 4));
+         rel += 8;
+       }
     }
 }
 
@@ -6381,25 +6819,26 @@ evax_bfd_print_reference_fixups (FILE *file, const unsigned char *rel)
 
       count = bfd_getl32 (rel + 0);
       if (count == 0)
-        break;
+       break;
+      /* xgettext:c-format */
       fprintf (file, _("  image %u (%u entries), offsets:\n"),
-               (unsigned)bfd_getl32 (rel + 4), count);
+              (unsigned)bfd_getl32 (rel + 4), count);
       rel += 8;
       for (j = 0; j < count; j++)
-        {
-          if (n == 0)
-            fputs ("   ", file);
-          fprintf (file, _(" 0x%08x"), (unsigned)bfd_getl32 (rel));
-          n++;
-          if (n == 7)
-            {
-              fputs ("\n", file);
-              n = 0;
-            }
-          rel += 4;
-        }
+       {
+         if (n == 0)
+           fputs ("   ", file);
+         fprintf (file, _(" 0x%08x"), (unsigned)bfd_getl32 (rel));
+         n++;
+         if (n == 7)
+           {
+             fputs ("\n", file);
+             n = 0;
+           }
+         rel += 4;
+       }
       if (n)
-        fputs ("\n", file);
+       fputs ("\n", file);
     }
 }
 
@@ -6515,69 +6954,74 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file)
     }
   else
     {
+      /* xgettext:c-format */
       fprintf (file, _("class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"),
-               bclass, dtype, len, pointer);
+              bclass, dtype, len, pointer);
       switch (bclass)
-        {
-        case DSC__K_CLASS_NCA:
-          {
-            const struct vms_dsc_nca *dsc = (const void *)buf;
-            unsigned int i;
-            const unsigned char *b;
-
-            evax_bfd_print_indent (indent, file);
-            fprintf (file, _("non-contiguous array of %s\n"),
-                     evax_bfd_get_dsc_name (dsc->dtype));
-            evax_bfd_print_indent (indent + 1, file);
-            fprintf (file,
-                     _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"),
-                     dsc->dimct, dsc->aflags, dsc->digits, dsc->scale);
-            evax_bfd_print_indent (indent + 1, file);
-            fprintf (file,
-                     _("arsize: %u, a0: 0x%08x\n"),
-                     (unsigned)bfd_getl32 (dsc->arsize),
-                     (unsigned)bfd_getl32 (dsc->a0));
-            evax_bfd_print_indent (indent + 1, file);
-            fprintf (file, _("Strides:\n"));
-            b = buf + sizeof (*dsc);
-            for (i = 0; i < dsc->dimct; i++)
-              {
-                evax_bfd_print_indent (indent + 2, file);
-                fprintf (file, _("[%u]: %u\n"), i + 1,
-                         (unsigned)bfd_getl32 (b));
-                b += 4;
-              }
-            evax_bfd_print_indent (indent + 1, file);
-            fprintf (file, _("Bounds:\n"));
-            b = buf + sizeof (*dsc);
-            for (i = 0; i < dsc->dimct; i++)
-              {
-                evax_bfd_print_indent (indent + 2, file);
-                fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1,
-                         (unsigned)bfd_getl32 (b + 0),
-                         (unsigned)bfd_getl32 (b + 4));
-                b += 8;
-              }
-          }
-          break;
-        case DSC__K_CLASS_UBS:
-          {
-            const struct vms_dsc_ubs *ubs = (const void *)buf;
-
-            evax_bfd_print_indent (indent, file);
-            fprintf (file, _("unaligned bit-string of %s\n"),
-                     evax_bfd_get_dsc_name (ubs->dtype));
-            evax_bfd_print_indent (indent + 1, file);
-            fprintf (file,
-                     _("base: %u, pos: %u\n"),
-                     (unsigned)bfd_getl32 (ubs->base),
-                     (unsigned)bfd_getl32 (ubs->pos));
-          }
-          break;
-        default:
-          fprintf (file, _("*unhandled*\n"));
-          break;
-        }
+       {
+       case DSC__K_CLASS_NCA:
+         {
+           const struct vms_dsc_nca *dsc = (const void *)buf;
+           unsigned int i;
+           const unsigned char *b;
+
+           evax_bfd_print_indent (indent, file);
+           fprintf (file, _("non-contiguous array of %s\n"),
+                    evax_bfd_get_dsc_name (dsc->dtype));
+           evax_bfd_print_indent (indent + 1, file);
+           fprintf (file,
+                    /* xgettext:c-format */
+                    _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"),
+                    dsc->dimct, dsc->aflags, dsc->digits, dsc->scale);
+           evax_bfd_print_indent (indent + 1, file);
+           fprintf (file,
+                    /* xgettext:c-format */
+                    _("arsize: %u, a0: 0x%08x\n"),
+                    (unsigned)bfd_getl32 (dsc->arsize),
+                    (unsigned)bfd_getl32 (dsc->a0));
+           evax_bfd_print_indent (indent + 1, file);
+           fprintf (file, _("Strides:\n"));
+           b = buf + sizeof (*dsc);
+           for (i = 0; i < dsc->dimct; i++)
+             {
+               evax_bfd_print_indent (indent + 2, file);
+               fprintf (file, "[%u]: %u\n", i + 1,
+                        (unsigned)bfd_getl32 (b));
+               b += 4;
+             }
+           evax_bfd_print_indent (indent + 1, file);
+           fprintf (file, _("Bounds:\n"));
+           b = buf + sizeof (*dsc);
+           for (i = 0; i < dsc->dimct; i++)
+             {
+               evax_bfd_print_indent (indent + 2, file);
+               /* xgettext:c-format */
+               fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1,
+                        (unsigned)bfd_getl32 (b + 0),
+                        (unsigned)bfd_getl32 (b + 4));
+               b += 8;
+             }
+         }
+         break;
+       case DSC__K_CLASS_UBS:
+         {
+           const struct vms_dsc_ubs *ubs = (const void *)buf;
+
+           evax_bfd_print_indent (indent, file);
+           fprintf (file, _("unaligned bit-string of %s\n"),
+                    evax_bfd_get_dsc_name (ubs->dtype));
+           evax_bfd_print_indent (indent + 1, file);
+           fprintf (file,
+                    /* xgettext:c-format */
+                    _("base: %u, pos: %u\n"),
+                    (unsigned)bfd_getl32 (ubs->base),
+                    (unsigned)bfd_getl32 (ubs->pos));
+         }
+         break;
+       default:
+         fprintf (file, _("*unhandled*\n"));
+         break;
+       }
     }
 }
 
@@ -6589,6 +7033,7 @@ evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file)
   unsigned int len = 5;
 
   evax_bfd_print_indent (indent, file);
+  /* xgettext:c-format */
   fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value);
   buf += 5;
 
@@ -6617,25 +7062,26 @@ evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file)
       fprintf (file, _("(at bit offset %u)\n"), value);
       break;
     default:
+      /* xgettext:c-format */
       fprintf (file, _("(reg: %u, disp: %u, indir: %u, kind: "),
-               (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT,
-               vflags & DST__K_DISP ? 1 : 0,
-               vflags & DST__K_INDIR ? 1 : 0);
+              (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT,
+              vflags & DST__K_DISP ? 1 : 0,
+              vflags & DST__K_INDIR ? 1 : 0);
       switch (vflags & DST__K_VALKIND_MASK)
-        {
-        case DST__K_VALKIND_LITERAL:
-          fputs (_("literal"), file);
-          break;
-        case DST__K_VALKIND_ADDR:
-          fputs (_("address"), file);
-          break;
-        case DST__K_VALKIND_DESC:
-          fputs (_("desc"), file);
-          break;
-        case DST__K_VALKIND_REG:
-          fputs (_("reg"), file);
-          break;
-        }
+       {
+       case DST__K_VALKIND_LITERAL:
+         fputs (_("literal"), file);
+         break;
+       case DST__K_VALKIND_ADDR:
+         fputs (_("address"), file);
+         break;
+       case DST__K_VALKIND_DESC:
+         fputs (_("desc"), file);
+         break;
+       case DST__K_VALKIND_REG:
+         fputs (_("reg"), file);
+         break;
+       }
       fputs (")\n", file);
       break;
     }
@@ -6649,55 +7095,57 @@ evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file)
   unsigned int len = (unsigned)bfd_getl16 (buf);
 
   evax_bfd_print_indent (indent, file);
-  fprintf (file, ("len: %2u, kind: %2u "), len, kind);
+  /* xgettext:c-format */
+  fprintf (file, _("len: %2u, kind: %2u "), len, kind);
   buf += 3;
   switch (kind)
     {
     case DST__K_TS_ATOM:
-      fprintf (file, ("atomic, type=0x%02x %s\n"),
-               buf[0], evax_bfd_get_dsc_name (buf[0]));
+    /* xgettext:c-format */
+      fprintf (file, _("atomic, type=0x%02x %s\n"),
+              buf[0], evax_bfd_get_dsc_name (buf[0]));
       break;
     case DST__K_TS_IND:
-      fprintf (file, ("indirect, defined at 0x%08x\n"),
-               (unsigned)bfd_getl32 (buf));
+      fprintf (file, _("indirect, defined at 0x%08x\n"),
+              (unsigned)bfd_getl32 (buf));
       break;
     case DST__K_TS_TPTR:
-      fprintf (file, ("typed pointer\n"));
+      fprintf (file, _("typed pointer\n"));
       evax_bfd_print_typspec (buf, indent + 1, file);
       break;
     case DST__K_TS_PTR:
-      fprintf (file, ("pointer\n"));
+      fprintf (file, _("pointer\n"));
       break;
     case DST__K_TS_ARRAY:
       {
-        const unsigned char *vs;
-        unsigned int vec_len;
-        unsigned int i;
-
-        fprintf (file, ("array, dim: %u, bitmap: "), buf[0]);
-        vec_len = (buf[0] + 1 + 7) / 8;
-        for (i = 0; i < vec_len; i++)
-          fprintf (file, " %02x", buf[i + 1]);
-        fputc ('\n', file);
-        vs = buf + 1 + vec_len;
-        evax_bfd_print_indent (indent, file);
-        fprintf (file, ("array descriptor:\n"));
-        vs += evax_bfd_print_valspec (vs, indent + 1, file);
-        for (i = 0; i < buf[0] + 1U; i++)
-          if (buf[1 + i / 8] & (1 << (i % 8)))
-            {
-              evax_bfd_print_indent (indent, file);
-              if (i == 0)
-                fprintf (file, ("type spec for element:\n"));
-              else
-                fprintf (file, ("type spec for subscript %u:\n"), i);
-              evax_bfd_print_typspec (vs, indent + 1, file);
-              vs += bfd_getl16 (vs);
-            }
+       const unsigned char *vs;
+       unsigned int vec_len;
+       unsigned int i;
+
+       fprintf (file, _("array, dim: %u, bitmap: "), buf[0]);
+       vec_len = (buf[0] + 1 + 7) / 8;
+       for (i = 0; i < vec_len; i++)
+         fprintf (file, " %02x", buf[i + 1]);
+       fputc ('\n', file);
+       vs = buf + 1 + vec_len;
+       evax_bfd_print_indent (indent, file);
+       fprintf (file, _("array descriptor:\n"));
+       vs += evax_bfd_print_valspec (vs, indent + 1, file);
+       for (i = 0; i < buf[0] + 1U; i++)
+         if (buf[1 + i / 8] & (1 << (i % 8)))
+           {
+             evax_bfd_print_indent (indent, file);
+             if (i == 0)
+               fprintf (file, _("type spec for element:\n"));
+             else
+               fprintf (file, _("type spec for subscript %u:\n"), i);
+             evax_bfd_print_typspec (vs, indent + 1, file);
+             vs += bfd_getl16 (vs);
+           }
       }
       break;
     default:
-      fprintf (file, ("*unhandled*\n"));
+      fprintf (file, _("*unhandled*\n"));
     }
 }
 
@@ -6718,405 +7166,421 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
       unsigned char *buf;
 
       if (bfd_bread (&dsth, sizeof (dsth), abfd) != sizeof (dsth))
-        {
-          fprintf (file, _("cannot read DST header\n"));
-          return;
-        }
+       {
+         fprintf (file, _("cannot read DST header\n"));
+         return;
+       }
       len = bfd_getl16 (dsth.length);
       type = bfd_getl16 (dsth.type);
+      /* xgettext:c-format */
       fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "),
-               type, len, off);
+              type, len, off);
       if (len == 0)
-        {
-          fputc ('\n', file);
-          break;
-        }
+       {
+         fputc ('\n', file);
+         break;
+       }
       len++;
       dst_size -= len;
       off += len;
       len -= sizeof (dsth);
-      buf = bfd_malloc (len);
-      if (bfd_bread (buf, len, abfd) != len)
-        {
-          fprintf (file, _("cannot read DST symbol\n"));
-          return;
-        }
+      buf = _bfd_malloc_and_read (abfd, len, len);
+      if (buf == NULL)
+       {
+         fprintf (file, _("cannot read DST symbol\n"));
+         return;
+       }
       switch (type)
-        {
-        case DSC__K_DTYPE_V:
-        case DSC__K_DTYPE_BU:
-        case DSC__K_DTYPE_WU:
-        case DSC__K_DTYPE_LU:
-        case DSC__K_DTYPE_QU:
-        case DSC__K_DTYPE_B:
-        case DSC__K_DTYPE_W:
-        case DSC__K_DTYPE_L:
-        case DSC__K_DTYPE_Q:
-        case DSC__K_DTYPE_F:
-        case DSC__K_DTYPE_D:
-        case DSC__K_DTYPE_FC:
-        case DSC__K_DTYPE_DC:
-        case DSC__K_DTYPE_T:
-        case DSC__K_DTYPE_NU:
-        case DSC__K_DTYPE_NL:
-        case DSC__K_DTYPE_NLO:
-        case DSC__K_DTYPE_NR:
-        case DSC__K_DTYPE_NRO:
-        case DSC__K_DTYPE_NZ:
-        case DSC__K_DTYPE_P:
-        case DSC__K_DTYPE_ZI:
-        case DSC__K_DTYPE_ZEM:
-        case DSC__K_DTYPE_DSC:
-        case DSC__K_DTYPE_OU:
-        case DSC__K_DTYPE_O:
-        case DSC__K_DTYPE_G:
-        case DSC__K_DTYPE_H:
-        case DSC__K_DTYPE_GC:
-        case DSC__K_DTYPE_HC:
-        case DSC__K_DTYPE_CIT:
-        case DSC__K_DTYPE_BPV:
-        case DSC__K_DTYPE_BLV:
-        case DSC__K_DTYPE_VU:
-        case DSC__K_DTYPE_ADT:
-        case DSC__K_DTYPE_VT:
-        case DSC__K_DTYPE_T2:
-        case DSC__K_DTYPE_VT2:
-          fprintf (file, _("standard data: %s\n"),
-                   evax_bfd_get_dsc_name (type));
-          evax_bfd_print_valspec (buf, 4, file);
-          fprintf (file, _("    name: %.*s\n"), buf[5], buf + 6);
-          break;
-        case DST__K_MODBEG:
-          {
-            struct vms_dst_modbeg *dst = (void *)buf;
-            const char *name = (const char *)buf + sizeof (*dst);
-
-            fprintf (file, _("modbeg\n"));
-            fprintf (file, _("   flags: %d, language: %u, "
-                             "major: %u, minor: %u\n"),
-                     dst->flags,
-                     (unsigned)bfd_getl32 (dst->language),
-                     (unsigned)bfd_getl16 (dst->major),
-                     (unsigned)bfd_getl16 (dst->minor));
-            fprintf (file, _("   module name: %.*s\n"),
-                     name[0], name + 1);
-            name += name[0] + 1;
-            fprintf (file, _("   compiler   : %.*s\n"),
-                     name[0], name + 1);
-          }
-          break;
-        case DST__K_MODEND:
-          fprintf (file, _("modend\n"));
-          break;
-        case DST__K_RTNBEG:
-          {
-            struct vms_dst_rtnbeg *dst = (void *)buf;
-            const char *name = (const char *)buf + sizeof (*dst);
-
-            fputs (_("rtnbeg\n"), file);
-            fprintf (file, _("    flags: %u, address: 0x%08x, "
-                             "pd-address: 0x%08x\n"),
-                     dst->flags,
-                     (unsigned)bfd_getl32 (dst->address),
-                     (unsigned)bfd_getl32 (dst->pd_address));
-            fprintf (file, _("    routine name: %.*s\n"),
-                     name[0], name + 1);
-          }
-          break;
-        case DST__K_RTNEND:
-          {
-            struct vms_dst_rtnend *dst = (void *)buf;
-
-            fprintf (file, _("rtnend: size 0x%08x\n"),
-                     (unsigned)bfd_getl32 (dst->size));
-          }
-          break;
-        case DST__K_PROLOG:
-          {
-            struct vms_dst_prolog *dst = (void *)buf;
-
-            fprintf (file, _("prolog: bkpt address 0x%08x\n"),
-                     (unsigned)bfd_getl32 (dst->bkpt_addr));
-          }
-          break;
-        case DST__K_EPILOG:
-          {
-            struct vms_dst_epilog *dst = (void *)buf;
-
-            fprintf (file, _("epilog: flags: %u, count: %u\n"),
-                     dst->flags, (unsigned)bfd_getl32 (dst->count));
-          }
-          break;
-        case DST__K_BLKBEG:
-          {
-            struct vms_dst_blkbeg *dst = (void *)buf;
-            const char *name = (const char *)buf + sizeof (*dst);
-
-            fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"),
-                     (unsigned)bfd_getl32 (dst->address),
-                     name[0], name + 1);
-          }
-          break;
-        case DST__K_BLKEND:
-          {
-            struct vms_dst_blkend *dst = (void *)buf;
-
-            fprintf (file, _("blkend: size: 0x%08x\n"),
-                     (unsigned)bfd_getl32 (dst->size));
-          }
-          break;
-        case DST__K_TYPSPEC:
-          {
-            fprintf (file, _("typspec (len: %u)\n"), len);
-            fprintf (file, _("    name: %.*s\n"), buf[0], buf + 1);
-            evax_bfd_print_typspec (buf + 1 + buf[0], 5, file);
-          }
-          break;
-        case DST__K_SEPTYP:
-          {
-            fprintf (file, _("septyp, name: %.*s\n"), buf[5], buf + 6);
-            evax_bfd_print_valspec (buf, 4, file);
-          }
-          break;
-        case DST__K_RECBEG:
-          {
-            struct vms_dst_recbeg *recbeg = (void *)buf;
-            const char *name = (const char *)buf + sizeof (*recbeg);
-
-            fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1);
-            evax_bfd_print_valspec (buf, 4, file);
-            fprintf (file, ("    len: %u bits\n"),
-                     (unsigned)bfd_getl32 (name + 1 + name[0]));
-          }
-          break;
-        case DST__K_RECEND:
-          fprintf (file, _("recend\n"));
-          break;
-        case DST__K_ENUMBEG:
-          fprintf (file, _("enumbeg, len: %u, name: %.*s\n"),
-                   buf[0], buf[1], buf + 2);
-          break;
-        case DST__K_ENUMELT:
-          fprintf (file, _("enumelt, name: %.*s\n"), buf[5], buf + 6);
-          evax_bfd_print_valspec (buf, 4, file);
-          break;
-        case DST__K_ENUMEND:
-          fprintf (file, _("enumend\n"));
-          break;
-        case DST__K_LABEL:
-          {
-            struct vms_dst_label *lab = (void *)buf;
-            fprintf (file, ("label, name: %.*s\n"),
-                     lab->name[0], lab->name + 1);
-            fprintf (file, ("    address: 0x%08x\n"),
-                     (unsigned)bfd_getl32 (lab->value));
-          }
-          break;
-        case DST__K_DIS_RANGE:
-          {
-            unsigned int cnt = bfd_getl32 (buf);
-            unsigned char *rng = buf + 4;
-            unsigned int i;
-
-            fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt);
-            for (i = 0; i < cnt; i++, rng += 8)
-              fprintf (file, _("    address: 0x%08x, size: %u\n"),
-                       (unsigned)bfd_getl32 (rng),
-                       (unsigned)bfd_getl32 (rng + 4));
-
-          }
-          break;
-        case DST__K_LINE_NUM:
-          {
-            unsigned char *buf_orig = buf;
-
-            fprintf (file, _("line num  (len: %u)\n"), len);
-
-            while (len > 0)
-              {
-                signed char cmd;
-                unsigned char cmdlen;
-                unsigned int val;
-
-                cmd = buf[0];
-                cmdlen = 0;
-
-                fputs ("    ", file);
-
-                switch (cmd)
-                  {
-                  case DST__K_DELTA_PC_W:
-                    val = bfd_getl16 (buf + 1);
-                    fprintf (file, _("delta_pc_w %u\n"), val);
-                    pc += val;
-                    line++;
-                    cmdlen = 3;
-                    break;
-                  case DST__K_INCR_LINUM:
-                    val = buf[1];
-                    fprintf (file, _("incr_linum: +%u\n"), val);
-                    line += val;
-                    cmdlen = 2;
-                    break;
-                  case DST__K_INCR_LINUM_W:
-                    val = bfd_getl16 (buf + 1);
-                    fprintf (file, _("incr_linum: +%u\n"), val);
-                    line += val;
-                    cmdlen = 3;
-                    break;
-                  case DST__K_SET_LINUM:
-                    line = (unsigned)bfd_getl16 (buf + 1);
-                    fprintf (file, _("set_line_num %u\n"), line);
-                    cmdlen = 3;
-                    break;
-                  case DST__K_SET_LINUM_B:
-                    line = buf[1];
-                    fprintf (file, _("set_line_num_b %u\n"), line);
-                    cmdlen = 2;
-                    break;
-                  case DST__K_SET_LINUM_L:
-                    line = (unsigned)bfd_getl32 (buf + 1);
-                    fprintf (file, _("set_line_num_l %u\n"), line);
-                    cmdlen = 5;
-                    break;
-                  case DST__K_SET_ABS_PC:
-                    pc = (unsigned)bfd_getl32 (buf + 1);
-                    fprintf (file, _("set_abs_pc: 0x%08x\n"), pc);
-                    cmdlen = 5;
-                    break;
-                  case DST__K_DELTA_PC_L:
-                    fprintf (file, _("delta_pc_l: +0x%08x\n"),
-                             (unsigned)bfd_getl32 (buf + 1));
-                    cmdlen = 5;
-                    break;
-                  case DST__K_TERM:
-                    fprintf (file, _("term: 0x%02x"), buf[1]);
-                    pc += buf[1];
-                    fprintf (file, _("        pc: 0x%08x\n"), pc);
-                    cmdlen = 2;
-                    break;
-                  case DST__K_TERM_W:
-                    val = bfd_getl16 (buf + 1);
-                    fprintf (file, _("term_w: 0x%04x"), val);
-                    pc += val;
-                    fprintf (file, _("    pc: 0x%08x\n"), pc);
-                    cmdlen = 3;
-                    break;
-                  default:
-                    if (cmd <= 0)
-                      {
-                        fprintf (file, _("delta pc +%-4d"), -cmd);
-                        line++;  /* FIXME: curr increment.  */
-                        pc += -cmd;
-                        fprintf (file, _("    pc: 0x%08x line: %5u\n"),
-                                 pc, line);
-                        cmdlen = 1;
-                      }
-                    else
-                      fprintf (file, _("    *unhandled* cmd %u\n"), cmd);
-                    break;
-                  }
-                if (cmdlen == 0)
-                  break;
-                len -= cmdlen;
-                buf += cmdlen;
-              }
-            buf = buf_orig;
-          }
-          break;
-        case DST__K_SOURCE:
-          {
-            unsigned char *buf_orig = buf;
-
-            fprintf (file, _("source (len: %u)\n"), len);
-
-            while (len > 0)
-              {
-                signed char cmd = buf[0];
-                unsigned char cmdlen = 0;
-
-                switch (cmd)
-                  {
-                  case DST__K_SRC_DECLFILE:
-                    {
-                      struct vms_dst_src_decl_src *src = (void *)(buf + 1);
-                      const char *name;
-
-                      fprintf (file, _("   declfile: len: %u, flags: %u, "
-                                       "fileid: %u\n"),
-                               src->length, src->flags,
-                               (unsigned)bfd_getl16 (src->fileid));
-                      fprintf (file, _("   rms: cdt: 0x%08x %08x, "
-                                       "ebk: 0x%08x, ffb: 0x%04x, "
-                                       "rfo: %u\n"),
-                               (unsigned)bfd_getl32 (src->rms_cdt + 4),
-                               (unsigned)bfd_getl32 (src->rms_cdt + 0),
-                               (unsigned)bfd_getl32 (src->rms_ebk),
-                               (unsigned)bfd_getl16 (src->rms_ffb),
-                               src->rms_rfo);
-                      name = (const char *)buf + 1 + sizeof (*src);
-                      fprintf (file, _("   filename   : %.*s\n"),
-                               name[0], name + 1);
-                      name += name[0] + 1;
-                      fprintf (file, _("   module name: %.*s\n"),
-                               name[0], name + 1);
-                      cmdlen = 2 + src->length;
-                    }
-                    break;
-                  case DST__K_SRC_SETFILE:
-                    fprintf (file, _("   setfile %u\n"),
-                             (unsigned)bfd_getl16 (buf + 1));
-                    cmdlen = 3;
-                    break;
-                  case DST__K_SRC_SETREC_W:
-                    fprintf (file, _("   setrec %u\n"),
-                             (unsigned)bfd_getl16 (buf + 1));
-                    cmdlen = 3;
-                    break;
-                  case DST__K_SRC_SETREC_L:
-                    fprintf (file, _("   setrec %u\n"),
-                             (unsigned)bfd_getl32 (buf + 1));
-                    cmdlen = 5;
-                    break;
-                  case DST__K_SRC_SETLNUM_W:
-                    fprintf (file, _("   setlnum %u\n"),
-                             (unsigned)bfd_getl16 (buf + 1));
-                    cmdlen = 3;
-                    break;
-                  case DST__K_SRC_SETLNUM_L:
-                    fprintf (file, _("   setlnum %u\n"),
-                             (unsigned)bfd_getl32 (buf + 1));
-                    cmdlen = 5;
-                    break;
-                  case DST__K_SRC_DEFLINES_W:
-                    fprintf (file, _("   deflines %u\n"),
-                             (unsigned)bfd_getl16 (buf + 1));
-                    cmdlen = 3;
-                    break;
-                  case DST__K_SRC_DEFLINES_B:
-                    fprintf (file, _("   deflines %u\n"), buf[1]);
-                    cmdlen = 2;
-                    break;
-                  case DST__K_SRC_FORMFEED:
-                    fprintf (file, _("   formfeed\n"));
-                    cmdlen = 1;
-                    break;
-                  default:
-                    fprintf (file, _("   *unhandled* cmd %u\n"), cmd);
-                    break;
-                  }
-                if (cmdlen == 0)
-                  break;
-                len -= cmdlen;
-                buf += cmdlen;
-              }
-            buf = buf_orig;
-          }
-          break;
-        default:
-          fprintf (file, _("*unhandled* dst type %u\n"), type);
-          break;
-        }
+       {
+       case DSC__K_DTYPE_V:
+       case DSC__K_DTYPE_BU:
+       case DSC__K_DTYPE_WU:
+       case DSC__K_DTYPE_LU:
+       case DSC__K_DTYPE_QU:
+       case DSC__K_DTYPE_B:
+       case DSC__K_DTYPE_W:
+       case DSC__K_DTYPE_L:
+       case DSC__K_DTYPE_Q:
+       case DSC__K_DTYPE_F:
+       case DSC__K_DTYPE_D:
+       case DSC__K_DTYPE_FC:
+       case DSC__K_DTYPE_DC:
+       case DSC__K_DTYPE_T:
+       case DSC__K_DTYPE_NU:
+       case DSC__K_DTYPE_NL:
+       case DSC__K_DTYPE_NLO:
+       case DSC__K_DTYPE_NR:
+       case DSC__K_DTYPE_NRO:
+       case DSC__K_DTYPE_NZ:
+       case DSC__K_DTYPE_P:
+       case DSC__K_DTYPE_ZI:
+       case DSC__K_DTYPE_ZEM:
+       case DSC__K_DTYPE_DSC:
+       case DSC__K_DTYPE_OU:
+       case DSC__K_DTYPE_O:
+       case DSC__K_DTYPE_G:
+       case DSC__K_DTYPE_H:
+       case DSC__K_DTYPE_GC:
+       case DSC__K_DTYPE_HC:
+       case DSC__K_DTYPE_CIT:
+       case DSC__K_DTYPE_BPV:
+       case DSC__K_DTYPE_BLV:
+       case DSC__K_DTYPE_VU:
+       case DSC__K_DTYPE_ADT:
+       case DSC__K_DTYPE_VT:
+       case DSC__K_DTYPE_T2:
+       case DSC__K_DTYPE_VT2:
+         fprintf (file, _("standard data: %s\n"),
+                  evax_bfd_get_dsc_name (type));
+         evax_bfd_print_valspec (buf, 4, file);
+         fprintf (file, _("    name: %.*s\n"), buf[5], buf + 6);
+         break;
+       case DST__K_MODBEG:
+         {
+           struct vms_dst_modbeg *dst = (void *)buf;
+           const char *name = (const char *)buf + sizeof (*dst);
+
+           fprintf (file, _("modbeg\n"));
+           /* xgettext:c-format */
+           fprintf (file, _("   flags: %d, language: %u, "
+                            "major: %u, minor: %u\n"),
+                    dst->flags,
+                    (unsigned)bfd_getl32 (dst->language),
+                    (unsigned)bfd_getl16 (dst->major),
+                    (unsigned)bfd_getl16 (dst->minor));
+           fprintf (file, _("   module name: %.*s\n"),
+                    name[0], name + 1);
+           name += name[0] + 1;
+           fprintf (file, _("   compiler   : %.*s\n"),
+                    name[0], name + 1);
+         }
+         break;
+       case DST__K_MODEND:
+         fprintf (file, _("modend\n"));
+         break;
+       case DST__K_RTNBEG:
+         {
+           struct vms_dst_rtnbeg *dst = (void *)buf;
+           const char *name = (const char *)buf + sizeof (*dst);
+
+           fputs (_("rtnbeg\n"), file);
+           /* xgettext:c-format */
+           fprintf (file, _("    flags: %u, address: 0x%08x, "
+                            "pd-address: 0x%08x\n"),
+                    dst->flags,
+                    (unsigned)bfd_getl32 (dst->address),
+                    (unsigned)bfd_getl32 (dst->pd_address));
+           fprintf (file, _("    routine name: %.*s\n"),
+                    name[0], name + 1);
+         }
+         break;
+       case DST__K_RTNEND:
+         {
+           struct vms_dst_rtnend *dst = (void *)buf;
+
+           fprintf (file, _("rtnend: size 0x%08x\n"),
+                    (unsigned)bfd_getl32 (dst->size));
+         }
+         break;
+       case DST__K_PROLOG:
+         {
+           struct vms_dst_prolog *dst = (void *)buf;
+
+           fprintf (file, _("prolog: bkpt address 0x%08x\n"),
+                    (unsigned)bfd_getl32 (dst->bkpt_addr));
+         }
+         break;
+       case DST__K_EPILOG:
+         {
+           struct vms_dst_epilog *dst = (void *)buf;
+
+           /* xgettext:c-format */
+           fprintf (file, _("epilog: flags: %u, count: %u\n"),
+                    dst->flags, (unsigned)bfd_getl32 (dst->count));
+         }
+         break;
+       case DST__K_BLKBEG:
+         {
+           struct vms_dst_blkbeg *dst = (void *)buf;
+           const char *name = (const char *)buf + sizeof (*dst);
+
+           /* xgettext:c-format */
+           fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"),
+                    (unsigned)bfd_getl32 (dst->address),
+                    name[0], name + 1);
+         }
+         break;
+       case DST__K_BLKEND:
+         {
+           struct vms_dst_blkend *dst = (void *)buf;
+
+           fprintf (file, _("blkend: size: 0x%08x\n"),
+                    (unsigned)bfd_getl32 (dst->size));
+         }
+         break;
+       case DST__K_TYPSPEC:
+         {
+           fprintf (file, _("typspec (len: %u)\n"), len);
+           fprintf (file, _("    name: %.*s\n"), buf[0], buf + 1);
+           evax_bfd_print_typspec (buf + 1 + buf[0], 5, file);
+         }
+         break;
+       case DST__K_SEPTYP:
+         {
+           fprintf (file, _("septyp, name: %.*s\n"), buf[5], buf + 6);
+           evax_bfd_print_valspec (buf, 4, file);
+         }
+         break;
+       case DST__K_RECBEG:
+         {
+           struct vms_dst_recbeg *recbeg = (void *)buf;
+           const char *name = (const char *)buf + sizeof (*recbeg);
+
+           fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1);
+           evax_bfd_print_valspec (buf, 4, file);
+           fprintf (file, _("    len: %u bits\n"),
+                    (unsigned)bfd_getl32 (name + 1 + name[0]));
+         }
+         break;
+       case DST__K_RECEND:
+         fprintf (file, _("recend\n"));
+         break;
+       case DST__K_ENUMBEG:
+         /* xgettext:c-format */
+         fprintf (file, _("enumbeg, len: %u, name: %.*s\n"),
+                  buf[0], buf[1], buf + 2);
+         break;
+       case DST__K_ENUMELT:
+         fprintf (file, _("enumelt, name: %.*s\n"), buf[5], buf + 6);
+         evax_bfd_print_valspec (buf, 4, file);
+         break;
+       case DST__K_ENUMEND:
+         fprintf (file, _("enumend\n"));
+         break;
+       case DST__K_LABEL:
+         {
+           struct vms_dst_label *lab = (void *)buf;
+           fprintf (file, _("label, name: %.*s\n"),
+                    lab->name[0], lab->name + 1);
+           fprintf (file, _("    address: 0x%08x\n"),
+                    (unsigned)bfd_getl32 (lab->value));
+         }
+         break;
+       case DST__K_DIS_RANGE:
+         {
+           unsigned int cnt = bfd_getl32 (buf);
+           unsigned char *rng = buf + 4;
+           unsigned int i;
+
+           fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt);
+           for (i = 0; i < cnt; i++, rng += 8)
+             /* xgettext:c-format */
+             fprintf (file, _("    address: 0x%08x, size: %u\n"),
+                      (unsigned)bfd_getl32 (rng),
+                      (unsigned)bfd_getl32 (rng + 4));
+
+         }
+         break;
+       case DST__K_LINE_NUM:
+         {
+           unsigned char *buf_orig = buf;
+
+           fprintf (file, _("line num  (len: %u)\n"), len);
+
+           while (len > 0)
+             {
+               signed char cmd;
+               unsigned char cmdlen;
+               unsigned int val;
+
+               cmd = buf[0];
+               cmdlen = 0;
+
+               fputs ("    ", file);
+
+               switch (cmd)
+                 {
+                 case DST__K_DELTA_PC_W:
+                   val = bfd_getl16 (buf + 1);
+                   fprintf (file, _("delta_pc_w %u\n"), val);
+                   pc += val;
+                   line++;
+                   cmdlen = 3;
+                   break;
+                 case DST__K_INCR_LINUM:
+                   val = buf[1];
+                   fprintf (file, _("incr_linum(b): +%u\n"), val);
+                   line += val;
+                   cmdlen = 2;
+                   break;
+                 case DST__K_INCR_LINUM_W:
+                   val = bfd_getl16 (buf + 1);
+                   fprintf (file, _("incr_linum_w: +%u\n"), val);
+                   line += val;
+                   cmdlen = 3;
+                   break;
+                 case DST__K_INCR_LINUM_L:
+                   val = bfd_getl32 (buf + 1);
+                   fprintf (file, _("incr_linum_l: +%u\n"), val);
+                   line += val;
+                   cmdlen = 5;
+                   break;
+                 case DST__K_SET_LINUM:
+                   line = bfd_getl16 (buf + 1);
+                   fprintf (file, _("set_line_num(w) %u\n"), line);
+                   cmdlen = 3;
+                   break;
+                 case DST__K_SET_LINUM_B:
+                   line = buf[1];
+                   fprintf (file, _("set_line_num_b %u\n"), line);
+                   cmdlen = 2;
+                   break;
+                 case DST__K_SET_LINUM_L:
+                   line = bfd_getl32 (buf + 1);
+                   fprintf (file, _("set_line_num_l %u\n"), line);
+                   cmdlen = 5;
+                   break;
+                 case DST__K_SET_ABS_PC:
+                   pc = bfd_getl32 (buf + 1);
+                   fprintf (file, _("set_abs_pc: 0x%08x\n"), pc);
+                   cmdlen = 5;
+                   break;
+                 case DST__K_DELTA_PC_L:
+                   fprintf (file, _("delta_pc_l: +0x%08x\n"),
+                            (unsigned)bfd_getl32 (buf + 1));
+                   cmdlen = 5;
+                   break;
+                 case DST__K_TERM:
+                   fprintf (file, _("term(b): 0x%02x"), buf[1]);
+                   pc += buf[1];
+                   fprintf (file, _("        pc: 0x%08x\n"), pc);
+                   cmdlen = 2;
+                   break;
+                 case DST__K_TERM_W:
+                   val = bfd_getl16 (buf + 1);
+                   fprintf (file, _("term_w: 0x%04x"), val);
+                   pc += val;
+                   fprintf (file, _("    pc: 0x%08x\n"), pc);
+                   cmdlen = 3;
+                   break;
+                 default:
+                   if (cmd <= 0)
+                     {
+                       fprintf (file, _("delta pc +%-4d"), -cmd);
+                       line++;  /* FIXME: curr increment.  */
+                       pc += -cmd;
+                       /* xgettext:c-format */
+                       fprintf (file, _("    pc: 0x%08x line: %5u\n"),
+                                pc, line);
+                       cmdlen = 1;
+                     }
+                   else
+                     fprintf (file, _("    *unhandled* cmd %u\n"), cmd);
+                   break;
+                 }
+               if (cmdlen == 0)
+                 break;
+               len -= cmdlen;
+               buf += cmdlen;
+             }
+           buf = buf_orig;
+         }
+         break;
+       case DST__K_SOURCE:
+         {
+           unsigned char *buf_orig = buf;
+
+           fprintf (file, _("source (len: %u)\n"), len);
+
+           while (len > 0)
+             {
+               signed char cmd = buf[0];
+               unsigned char cmdlen = 0;
+
+               switch (cmd)
+                 {
+                 case DST__K_SRC_DECLFILE:
+                   {
+                     struct vms_dst_src_decl_src *src = (void *)(buf + 1);
+                     const char *name;
+
+                     /* xgettext:c-format */
+                     fprintf (file, _("   declfile: len: %u, flags: %u, "
+                                      "fileid: %u\n"),
+                              src->length, src->flags,
+                              (unsigned)bfd_getl16 (src->fileid));
+                     /* xgettext:c-format */
+                     fprintf (file, _("   rms: cdt: 0x%08x %08x, "
+                                      "ebk: 0x%08x, ffb: 0x%04x, "
+                                      "rfo: %u\n"),
+                              (unsigned)bfd_getl32 (src->rms_cdt + 4),
+                              (unsigned)bfd_getl32 (src->rms_cdt + 0),
+                              (unsigned)bfd_getl32 (src->rms_ebk),
+                              (unsigned)bfd_getl16 (src->rms_ffb),
+                              src->rms_rfo);
+                     name = (const char *)buf + 1 + sizeof (*src);
+                     fprintf (file, _("   filename   : %.*s\n"),
+                              name[0], name + 1);
+                     name += name[0] + 1;
+                     fprintf (file, _("   module name: %.*s\n"),
+                              name[0], name + 1);
+                     cmdlen = 2 + src->length;
+                   }
+                   break;
+                 case DST__K_SRC_SETFILE:
+                   fprintf (file, _("   setfile %u\n"),
+                            (unsigned)bfd_getl16 (buf + 1));
+                   cmdlen = 3;
+                   break;
+                 case DST__K_SRC_SETREC_W:
+                   fprintf (file, _("   setrec %u\n"),
+                            (unsigned)bfd_getl16 (buf + 1));
+                   cmdlen = 3;
+                   break;
+                 case DST__K_SRC_SETREC_L:
+                   fprintf (file, _("   setrec %u\n"),
+                            (unsigned)bfd_getl32 (buf + 1));
+                   cmdlen = 5;
+                   break;
+                 case DST__K_SRC_SETLNUM_W:
+                   fprintf (file, _("   setlnum %u\n"),
+                            (unsigned)bfd_getl16 (buf + 1));
+                   cmdlen = 3;
+                   break;
+                 case DST__K_SRC_SETLNUM_L:
+                   fprintf (file, _("   setlnum %u\n"),
+                            (unsigned)bfd_getl32 (buf + 1));
+                   cmdlen = 5;
+                   break;
+                 case DST__K_SRC_DEFLINES_W:
+                   fprintf (file, _("   deflines %u\n"),
+                            (unsigned)bfd_getl16 (buf + 1));
+                   cmdlen = 3;
+                   break;
+                 case DST__K_SRC_DEFLINES_B:
+                   fprintf (file, _("   deflines %u\n"), buf[1]);
+                   cmdlen = 2;
+                   break;
+                 case DST__K_SRC_FORMFEED:
+                   fprintf (file, _("   formfeed\n"));
+                   cmdlen = 1;
+                   break;
+                 default:
+                   fprintf (file, _("   *unhandled* cmd %u\n"), cmd);
+                   break;
+                 }
+               if (cmdlen == 0)
+                 break;
+               len -= cmdlen;
+               buf += cmdlen;
+             }
+           buf = buf_orig;
+         }
+         break;
+       default:
+         fprintf (file, _("*unhandled* dst type %u\n"), type);
+         break;
+       }
       free (buf);
     }
 }
@@ -7149,12 +7613,14 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
       fprintf (file, _("cannot read EIHD\n"));
       return;
     }
+  /* xgettext:c-format */
   fprintf (file, _("EIHD: (size: %u, nbr blocks: %u)\n"),
-           (unsigned)bfd_getl32 (eihd.size),
-           (unsigned)bfd_getl32 (eihd.hdrblkcnt));
+          (unsigned)bfd_getl32 (eihd.size),
+          (unsigned)bfd_getl32 (eihd.hdrblkcnt));
+  /* xgettext:c-format */
   fprintf (file, _(" majorid: %u, minorid: %u\n"),
-           (unsigned)bfd_getl32 (eihd.majorid),
-           (unsigned)bfd_getl32 (eihd.minorid));
+          (unsigned)bfd_getl32 (eihd.majorid),
+          (unsigned)bfd_getl32 (eihd.minorid));
 
   val = (unsigned)bfd_getl32 (eihd.imgtype);
   switch (val)
@@ -7169,6 +7635,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
       name = _("unknown");
       break;
     }
+  /* xgettext:c-format */
   fprintf (file, _(" image type: %u (%s)"), val, name);
 
   val = (unsigned)bfd_getl32 (eihd.subtype);
@@ -7184,30 +7651,33 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
       name = _("unknown");
       break;
     }
+  /* xgettext:c-format */
   fprintf (file, _(", subtype: %u (%s)\n"), val, name);
 
   eisd_off = bfd_getl32 (eihd.isdoff);
   eiha_off = bfd_getl32 (eihd.activoff);
   eihi_off = bfd_getl32 (eihd.imgidoff);
   eihs_off = bfd_getl32 (eihd.symdbgoff);
+  /* xgettext:c-format */
   fprintf (file, _(" offsets: isd: %u, activ: %u, symdbg: %u, "
-                   "imgid: %u, patch: %u\n"),
-           eisd_off, eiha_off, eihs_off, eihi_off,
-           (unsigned)bfd_getl32 (eihd.patchoff));
+                  "imgid: %u, patch: %u\n"),
+          eisd_off, eiha_off, eihs_off, eihi_off,
+          (unsigned)bfd_getl32 (eihd.patchoff));
   fprintf (file, _(" fixup info rva: "));
   bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.iafva));
   fprintf (file, _(", symbol vector rva: "));
   bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.symvva));
   eihvn_off = bfd_getl32 (eihd.version_array_off);
   fprintf (file, _("\n"
-                   " version array off: %u\n"),
-           eihvn_off);
+                  " version array off: %u\n"),
+          eihvn_off);
   fprintf (file,
-           _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"),
-           (unsigned)bfd_getl32 (eihd.imgiocnt),
-           (unsigned)bfd_getl32 (eihd.iochancnt),
-           (unsigned)bfd_getl32 (eihd.privreqs + 4),
-           (unsigned)bfd_getl32 (eihd.privreqs + 0));
+          /* xgettext:c-format */
+          _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"),
+          (unsigned)bfd_getl32 (eihd.imgiocnt),
+          (unsigned)bfd_getl32 (eihd.iochancnt),
+          (unsigned)bfd_getl32 (eihd.privreqs + 4),
+          (unsigned)bfd_getl32 (eihd.privreqs + 0));
   val = (unsigned)bfd_getl32 (eihd.lnkflags);
   fprintf (file, _(" linker flags: %08x:"), val);
   if (val & EIHD__M_LNKDEBUG)
@@ -7239,20 +7709,22 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
   if (val & EIHD__M_EXT_BIND_SECT)
     fprintf (file, " EXT_BIND_SECT");
   fprintf (file, "\n");
+  /* xgettext:c-format */
   fprintf (file, _(" ident: 0x%08x, sysver: 0x%08x, "
-                   "match ctrl: %u, symvect_size: %u\n"),
-           (unsigned)bfd_getl32 (eihd.ident),
-           (unsigned)bfd_getl32 (eihd.sysver),
-           eihd.matchctl,
-           (unsigned)bfd_getl32 (eihd.symvect_size));
+                  "match ctrl: %u, symvect_size: %u\n"),
+          (unsigned)bfd_getl32 (eihd.ident),
+          (unsigned)bfd_getl32 (eihd.sysver),
+          eihd.matchctl,
+          (unsigned)bfd_getl32 (eihd.symvect_size));
   fprintf (file, _(" BPAGE: %u"),
-           (unsigned)bfd_getl32 (eihd.virt_mem_block_size));
+          (unsigned)bfd_getl32 (eihd.virt_mem_block_size));
   if (val & (EIHD__M_OMV_READY | EIHD__M_EXT_BIND_SECT))
     {
       eihef_off = bfd_getl32 (eihd.ext_fixup_off);
       eihnp_off = bfd_getl32 (eihd.noopt_psect_off);
+      /* xgettext:c-format */
       fprintf (file, _(", ext fixup offset: %u, no_opt psect off: %u"),
-               eihef_off, eihnp_off);
+              eihef_off, eihnp_off);
     }
   fprintf (file, _(", alias: %u\n"), (unsigned)bfd_getl16 (eihd.alias));
 
@@ -7264,92 +7736,92 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
 
       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))
-        {
-          fprintf (file, _("cannot read EIHVN header\n"));
-          return;
-        }
+         || bfd_bread (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn))
+       {
+         fprintf (file, _("cannot read EIHVN header\n"));
+         return;
+       }
       mask = bfd_getl32 (eihvn.subsystem_mask);
       for (j = 0; j < 32; j++)
-        if (mask & (1 << j))
-          {
-            struct vms_eihvn_subversion ver;
-            if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver))
-              {
-                fprintf (file, _("cannot read EIHVN version\n"));
-                return;
-              }
-            fprintf (file, _("   %02u "), j);
-            switch (j)
-              {
-              case EIHVN__BASE_IMAGE_BIT:
+       if (mask & (1 << j))
+         {
+           struct vms_eihvn_subversion ver;
+           if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver))
+             {
+               fprintf (file, _("cannot read EIHVN version\n"));
+               return;
+             }
+           fprintf (file, _("   %02u "), j);
+           switch (j)
+             {
+             case EIHVN__BASE_IMAGE_BIT:
                fputs (_("BASE_IMAGE       "), file);
-                break;
-              case EIHVN__MEMORY_MANAGEMENT_BIT:
-                fputs (_("MEMORY_MANAGEMENT"), file);
-                break;
-              case EIHVN__IO_BIT:
-                fputs (_("IO               "), file);
-                break;
-              case EIHVN__FILES_VOLUMES_BIT:
-                fputs (_("FILES_VOLUMES    "), file);
-                break;
-              case EIHVN__PROCESS_SCHED_BIT:
-                fputs (_("PROCESS_SCHED    "), file);
-                break;
-              case EIHVN__SYSGEN_BIT:
+               break;
+             case EIHVN__MEMORY_MANAGEMENT_BIT:
+               fputs (_("MEMORY_MANAGEMENT"), file);
+               break;
+             case EIHVN__IO_BIT:
+               fputs (_("IO               "), file);
+               break;
+             case EIHVN__FILES_VOLUMES_BIT:
+               fputs (_("FILES_VOLUMES    "), file);
+               break;
+             case EIHVN__PROCESS_SCHED_BIT:
+               fputs (_("PROCESS_SCHED    "), file);
+               break;
+             case EIHVN__SYSGEN_BIT:
                fputs (_("SYSGEN           "), file);
-                break;
-              case EIHVN__CLUSTERS_LOCKMGR_BIT:
-                fputs (_("CLUSTERS_LOCKMGR "), file);
-                break;
-              case EIHVN__LOGICAL_NAMES_BIT:
-                fputs (_("LOGICAL_NAMES    "), file);
-                break;
-              case EIHVN__SECURITY_BIT:
+               break;
+             case EIHVN__CLUSTERS_LOCKMGR_BIT:
+               fputs (_("CLUSTERS_LOCKMGR "), file);
+               break;
+             case EIHVN__LOGICAL_NAMES_BIT:
+               fputs (_("LOGICAL_NAMES    "), file);
+               break;
+             case EIHVN__SECURITY_BIT:
                fputs (_("SECURITY         "), file);
-                break;
-              case EIHVN__IMAGE_ACTIVATOR_BIT:
-                fputs (_("IMAGE_ACTIVATOR  "), file);
-                break;
-              case EIHVN__NETWORKS_BIT:
+               break;
+             case EIHVN__IMAGE_ACTIVATOR_BIT:
+               fputs (_("IMAGE_ACTIVATOR  "), file);
+               break;
+             case EIHVN__NETWORKS_BIT:
                fputs (_("NETWORKS         "), file);
-                break;
-              case EIHVN__COUNTERS_BIT:
+               break;
+             case EIHVN__COUNTERS_BIT:
                fputs (_("COUNTERS         "), file);
-                break;
-              case EIHVN__STABLE_BIT:
+               break;
+             case EIHVN__STABLE_BIT:
                fputs (_("STABLE           "), file);
-                break;
-              case EIHVN__MISC_BIT:
-                fputs (_("MISC             "), file);
-                break;
-              case EIHVN__CPU_BIT:
-                fputs (_("CPU              "), file);
-                break;
-              case EIHVN__VOLATILE_BIT:
+               break;
+             case EIHVN__MISC_BIT:
+               fputs (_("MISC             "), file);
+               break;
+             case EIHVN__CPU_BIT:
+               fputs (_("CPU              "), file);
+               break;
+             case EIHVN__VOLATILE_BIT:
                fputs (_("VOLATILE         "), file);
-                break;
-              case EIHVN__SHELL_BIT:
+               break;
+             case EIHVN__SHELL_BIT:
                fputs (_("SHELL            "), file);
-                break;
-              case EIHVN__POSIX_BIT:
+               break;
+             case EIHVN__POSIX_BIT:
                fputs (_("POSIX            "), file);
-                break;
-              case EIHVN__MULTI_PROCESSING_BIT:
-                fputs (_("MULTI_PROCESSING "), file);
-                break;
-              case EIHVN__GALAXY_BIT:
+               break;
+             case EIHVN__MULTI_PROCESSING_BIT:
+               fputs (_("MULTI_PROCESSING "), file);
+               break;
+             case EIHVN__GALAXY_BIT:
                fputs (_("GALAXY           "), file);
-                break;
-              default:
-                fputs (_("*unknown*        "), file);
-                break;
-              }
-            fprintf (file, _(": %u.%u\n"),
-                     (unsigned)bfd_getl16 (ver.major),
-                     (unsigned)bfd_getl16 (ver.minor));
-          }
+               break;
+             default:
+               fputs (_("*unknown*        "), file);
+               break;
+             }
+           fprintf (file, ": %u.%u\n",
+                    (unsigned)bfd_getl16 (ver.major),
+                    (unsigned)bfd_getl16 (ver.minor));
+         }
     }
 
   if (eiha_off != 0)
@@ -7357,78 +7829,88 @@ 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))
-        {
-          fprintf (file, _("cannot read EIHA\n"));
-          return;
-        }
+         || bfd_bread (&eiha, sizeof (eiha), abfd) != sizeof (eiha))
+       {
+         fprintf (file, _("cannot read EIHA\n"));
+         return;
+       }
       fprintf (file, _("Image activation:  (size=%u)\n"),
-               (unsigned)bfd_getl32 (eiha.size));
+              (unsigned)bfd_getl32 (eiha.size));
+      /* xgettext:c-format */
       fprintf (file, _(" First address : 0x%08x 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiha.tfradr1_h),
-               (unsigned)bfd_getl32 (eiha.tfradr1));
+              (unsigned)bfd_getl32 (eiha.tfradr1_h),
+              (unsigned)bfd_getl32 (eiha.tfradr1));
+      /* xgettext:c-format */
       fprintf (file, _(" Second address: 0x%08x 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiha.tfradr2_h),
-               (unsigned)bfd_getl32 (eiha.tfradr2));
+              (unsigned)bfd_getl32 (eiha.tfradr2_h),
+              (unsigned)bfd_getl32 (eiha.tfradr2));
+      /* xgettext:c-format */
       fprintf (file, _(" Third address : 0x%08x 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiha.tfradr3_h),
-               (unsigned)bfd_getl32 (eiha.tfradr3));
+              (unsigned)bfd_getl32 (eiha.tfradr3_h),
+              (unsigned)bfd_getl32 (eiha.tfradr3));
+      /* xgettext:c-format */
       fprintf (file, _(" Fourth address: 0x%08x 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiha.tfradr4_h),
-               (unsigned)bfd_getl32 (eiha.tfradr4));
+              (unsigned)bfd_getl32 (eiha.tfradr4_h),
+              (unsigned)bfd_getl32 (eiha.tfradr4));
+      /* xgettext:c-format */
       fprintf (file, _(" Shared image  : 0x%08x 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiha.inishr_h),
-               (unsigned)bfd_getl32 (eiha.inishr));
+              (unsigned)bfd_getl32 (eiha.inishr_h),
+              (unsigned)bfd_getl32 (eiha.inishr));
     }
   if (eihi_off != 0)
     {
       struct vms_eihi eihi;
 
       if (bfd_seek (abfd, (file_ptr) eihi_off, SEEK_SET)
-          || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
-        {
-          fprintf (file, _("cannot read EIHI\n"));
-          return;
-        }
+         || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
+       {
+         fprintf (file, _("cannot read EIHI\n"));
+         return;
+       }
+      /* xgettext:c-format */
       fprintf (file, _("Image identification: (major: %u, minor: %u)\n"),
-               (unsigned)bfd_getl32 (eihi.majorid),
-               (unsigned)bfd_getl32 (eihi.minorid));
+              (unsigned)bfd_getl32 (eihi.majorid),
+              (unsigned)bfd_getl32 (eihi.minorid));
       fprintf (file, _(" image name       : %.*s\n"),
-               eihi.imgnam[0], eihi.imgnam + 1);
+              eihi.imgnam[0], eihi.imgnam + 1);
       fprintf (file, _(" link time        : %s\n"),
-               vms_time_to_str (eihi.linktime));
+              vms_time_to_str (eihi.linktime));
       fprintf (file, _(" image ident      : %.*s\n"),
-               eihi.imgid[0], eihi.imgid + 1);
+              eihi.imgid[0], eihi.imgid + 1);
       fprintf (file, _(" linker ident     : %.*s\n"),
-               eihi.linkid[0], eihi.linkid + 1);
+              eihi.linkid[0], eihi.linkid + 1);
       fprintf (file, _(" image build ident: %.*s\n"),
-               eihi.imgbid[0], eihi.imgbid + 1);
+              eihi.imgbid[0], eihi.imgbid + 1);
     }
   if (eihs_off != 0)
     {
       struct vms_eihs eihs;
 
       if (bfd_seek (abfd, (file_ptr) eihs_off, SEEK_SET)
-          || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
-        {
-          fprintf (file, _("cannot read EIHS\n"));
-          return;
-        }
+         || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
+       {
+         fprintf (file, _("cannot read EIHS\n"));
+         return;
+       }
+      /* xgettext:c-format */
       fprintf (file, _("Image symbol & debug table: (major: %u, minor: %u)\n"),
-               (unsigned)bfd_getl32 (eihs.majorid),
-               (unsigned)bfd_getl32 (eihs.minorid));
+              (unsigned)bfd_getl32 (eihs.majorid),
+              (unsigned)bfd_getl32 (eihs.minorid));
       dst_vbn = bfd_getl32 (eihs.dstvbn);
       dst_size = bfd_getl32 (eihs.dstsize);
+      /* xgettext:c-format */
       fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"),
-               dst_vbn, dst_size, dst_size);
+              dst_vbn, dst_size, dst_size);
       gst_vbn = bfd_getl32 (eihs.gstvbn);
       gst_size = bfd_getl32 (eihs.gstsize);
+      /* xgettext:c-format */
       fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
-               gst_vbn, gst_size);
+              gst_vbn, gst_size);
       dmt_vbn = bfd_getl32 (eihs.dmtvbn);
       dmt_size = bfd_getl32 (eihs.dmtsize);
+      /* xgettext:c-format */
       fprintf (file, _(" debug module table : vbn: %u, size: %u\n"),
-               dmt_vbn, dmt_size);
+              dmt_vbn, dmt_size);
     }
   while (eisd_off != 0)
     {
@@ -7436,57 +7918,59 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
       unsigned int len;
 
       while (1)
-        {
-          if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET)
-              || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
-            {
-              fprintf (file, _("cannot read EISD\n"));
-              return;
-            }
-          len = (unsigned)bfd_getl32 (eisd.eisdsize);
-          if (len != (unsigned)-1)
-            break;
-
-          /* Next block.  */
-          eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
-        }
+       {
+         if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET)
+             || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
+           {
+             fprintf (file, _("cannot read EISD\n"));
+             return;
+           }
+         len = (unsigned)bfd_getl32 (eisd.eisdsize);
+         if (len != (unsigned)-1)
+           break;
+
+         /* Next block.  */
+         eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+       }
+      /* xgettext:c-format */
       fprintf (file, _("Image section descriptor: (major: %u, minor: %u, "
-                       "size: %u, offset: %u)\n"),
-               (unsigned)bfd_getl32 (eisd.majorid),
-               (unsigned)bfd_getl32 (eisd.minorid),
-               len, eisd_off);
+                      "size: %u, offset: %u)\n"),
+              (unsigned)bfd_getl32 (eisd.majorid),
+              (unsigned)bfd_getl32 (eisd.minorid),
+              len, eisd_off);
       if (len == 0)
-        break;
+       break;
+      /* xgettext:c-format */
       fprintf (file, _(" section: base: 0x%08x%08x size: 0x%08x\n"),
-               (unsigned)bfd_getl32 (eisd.virt_addr + 4),
-               (unsigned)bfd_getl32 (eisd.virt_addr + 0),
-               (unsigned)bfd_getl32 (eisd.secsize));
+              (unsigned)bfd_getl32 (eisd.virt_addr + 4),
+              (unsigned)bfd_getl32 (eisd.virt_addr + 0),
+              (unsigned)bfd_getl32 (eisd.secsize));
       val = (unsigned)bfd_getl32 (eisd.flags);
       fprintf (file, _(" flags: 0x%04x"), val);
       if (val & EISD__M_GBL)
-        fprintf (file, " GBL");
+       fprintf (file, " GBL");
       if (val & EISD__M_CRF)
-        fprintf (file, " CRF");
+       fprintf (file, " CRF");
       if (val & EISD__M_DZRO)
-        fprintf (file, " DZRO");
+       fprintf (file, " DZRO");
       if (val & EISD__M_WRT)
-        fprintf (file, " WRT");
+       fprintf (file, " WRT");
       if (val & EISD__M_INITALCODE)
        fprintf (file, " INITALCODE");
       if (val & EISD__M_BASED)
-        fprintf (file, " BASED");
+       fprintf (file, " BASED");
       if (val & EISD__M_FIXUPVEC)
        fprintf (file, " FIXUPVEC");
       if (val & EISD__M_RESIDENT)
        fprintf (file, " RESIDENT");
       if (val & EISD__M_VECTOR)
-        fprintf (file, " VECTOR");
+       fprintf (file, " VECTOR");
       if (val & EISD__M_PROTECT)
        fprintf (file, " PROTECT");
       if (val & EISD__M_LASTCLU)
        fprintf (file, " LASTCLU");
       if (val & EISD__M_EXE)
-        fprintf (file, " EXE");
+       fprintf (file, " EXE");
       if (val & EISD__M_NONSHRADR)
        fprintf (file, " NONSHRADR");
       if (val & EISD__M_QUAD_LENGTH)
@@ -7495,106 +7979,110 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
        fprintf (file, " ALLOC_64BIT");
       fprintf (file, "\n");
       if (val & EISD__M_FIXUPVEC)
-        {
-          eiaf_vbn = bfd_getl32 (eisd.vbn);
-          eiaf_size = bfd_getl32 (eisd.secsize);
-        }
+       {
+         eiaf_vbn = bfd_getl32 (eisd.vbn);
+         eiaf_size = bfd_getl32 (eisd.secsize);
+       }
+      /* xgettext:c-format */
       fprintf (file, _(" vbn: %u, pfc: %u, matchctl: %u type: %u ("),
-               (unsigned)bfd_getl32 (eisd.vbn),
-               eisd.pfc, eisd.matchctl, eisd.type);
+              (unsigned)bfd_getl32 (eisd.vbn),
+              eisd.pfc, eisd.matchctl, eisd.type);
       switch (eisd.type)
-        {
-        case EISD__K_NORMAL:
-          fputs (_("NORMAL"), file);
-          break;
-        case EISD__K_SHRFXD:
-          fputs (_("SHRFXD"), file);
-          break;
-        case EISD__K_PRVFXD:
-          fputs (_("PRVFXD"), file);
-          break;
-        case EISD__K_SHRPIC:
-          fputs (_("SHRPIC"), file);
-          break;
-        case EISD__K_PRVPIC:
-          fputs (_("PRVPIC"), file);
-          break;
-        case EISD__K_USRSTACK:
-          fputs (_("USRSTACK"), file);
-          break;
-        default:
-          fputs (_("*unknown*"), file);
-          break;
-        }
+       {
+       case EISD__K_NORMAL:
+         fputs (_("NORMAL"), file);
+         break;
+       case EISD__K_SHRFXD:
+         fputs (_("SHRFXD"), file);
+         break;
+       case EISD__K_PRVFXD:
+         fputs (_("PRVFXD"), file);
+         break;
+       case EISD__K_SHRPIC:
+         fputs (_("SHRPIC"), file);
+         break;
+       case EISD__K_PRVPIC:
+         fputs (_("PRVPIC"), file);
+         break;
+       case EISD__K_USRSTACK:
+         fputs (_("USRSTACK"), file);
+         break;
+       default:
+         fputs (_("*unknown*"), file);
+         break;
+       }
       fputs (_(")\n"), file);
       if (val & EISD__M_GBL)
-        fprintf (file, _(" ident: 0x%08x, name: %.*s\n"),
-                 (unsigned)bfd_getl32 (eisd.ident),
-                 eisd.gblnam[0], eisd.gblnam + 1);
+       /* xgettext:c-format */
+       fprintf (file, _(" ident: 0x%08x, name: %.*s\n"),
+                (unsigned)bfd_getl32 (eisd.ident),
+                eisd.gblnam[0], eisd.gblnam + 1);
       eisd_off += len;
     }
 
   if (dmt_vbn != 0)
     {
       if (bfd_seek (abfd, (file_ptr) (dmt_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
-        {
-          fprintf (file, _("cannot read DMT\n"));
-          return;
-        }
+       {
+         fprintf (file, _("cannot read DMT\n"));
+         return;
+       }
 
       fprintf (file, _("Debug module table:\n"));
 
       while (dmt_size > 0)
-        {
-          struct vms_dmt_header dmth;
-          unsigned int count;
-
-          if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
-            {
-              fprintf (file, _("cannot read DMT header\n"));
-              return;
-            }
-          count = bfd_getl16 (dmth.psect_count);
-          fprintf (file,
-                   _(" module address: 0x%08x, size: 0x%08x, (%u psects)\n"),
-                   (unsigned)bfd_getl32 (dmth.modbeg),
-                   (unsigned)bfd_getl32 (dmth.size), count);
-          dmt_size -= sizeof (dmth);
-          while (count > 0)
-            {
-              struct vms_dmt_psect dmtp;
-
-              if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
-                {
-                  fprintf (file, _("cannot read DMT psect\n"));
-                  return;
-                }
-              fprintf (file, _("  psect start: 0x%08x, length: %u\n"),
-                       (unsigned)bfd_getl32 (dmtp.start),
-                       (unsigned)bfd_getl32 (dmtp.length));
-              count--;
-              dmt_size -= sizeof (dmtp);
-            }
-        }
+       {
+         struct vms_dmt_header dmth;
+         unsigned int count;
+
+         if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
+           {
+             fprintf (file, _("cannot read DMT header\n"));
+             return;
+           }
+         count = bfd_getl16 (dmth.psect_count);
+         fprintf (file,
+                  /* xgettext:c-format */
+                  _(" module offset: 0x%08x, size: 0x%08x, (%u psects)\n"),
+                  (unsigned)bfd_getl32 (dmth.modbeg),
+                  (unsigned)bfd_getl32 (dmth.size), count);
+         dmt_size -= sizeof (dmth);
+         while (count > 0)
+           {
+             struct vms_dmt_psect dmtp;
+
+             if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
+               {
+                 fprintf (file, _("cannot read DMT psect\n"));
+                 return;
+               }
+             /* xgettext:c-format */
+             fprintf (file, _("  psect start: 0x%08x, length: %u\n"),
+                      (unsigned)bfd_getl32 (dmtp.start),
+                      (unsigned)bfd_getl32 (dmtp.length));
+             count--;
+             dmt_size -= sizeof (dmtp);
+           }
+       }
     }
 
   if (dst_vbn != 0)
     {
       if (bfd_seek (abfd, (file_ptr) (dst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
-        {
-          fprintf (file, _("cannot read DST\n"));
-          return;
-        }
+       {
+         fprintf (file, _("cannot read DST\n"));
+         return;
+       }
 
       evax_bfd_print_dst (abfd, dst_size, file);
     }
   if (gst_vbn != 0)
     {
       if (bfd_seek (abfd, (file_ptr) (gst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
-        {
-          fprintf (file, _("cannot read GST\n"));
-          return;
-        }
+       {
+         fprintf (file, _("cannot read GST\n"));
+         return;
+       }
 
       fprintf (file, _("Global symbol table:\n"));
       evax_bfd_print_eobj (abfd, file);
@@ -7612,174 +8100,182 @@ evax_bfd_print_image (bfd *abfd, FILE *file)
       unsigned int codeadroff;
       unsigned int lpfixoff;
       unsigned int chgprtoff;
+      file_ptr f_off = (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE;
 
-      buf = bfd_malloc (eiaf_size);
-
-      if (bfd_seek (abfd, (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET)
-          || bfd_bread (buf, eiaf_size, abfd) != eiaf_size)
-        {
-          fprintf (file, _("cannot read EIHA\n"));
-          free (buf);
-          return;
-        }
+      if (bfd_seek (abfd, f_off, SEEK_SET) != 0
+         || (buf = _bfd_malloc_and_read (abfd, eiaf_size, eiaf_size)) == NULL)
+       {
+         fprintf (file, _("cannot read EIHA\n"));
+         return;
+       }
       eiaf = (struct vms_eiaf *)buf;
       fprintf (file,
-               _("Image activator fixup: (major: %u, minor: %u)\n"),
-               (unsigned)bfd_getl32 (eiaf->majorid),
-               (unsigned)bfd_getl32 (eiaf->minorid));
+              /* xgettext:c-format */
+              _("Image activator fixup: (major: %u, minor: %u)\n"),
+              (unsigned)bfd_getl32 (eiaf->majorid),
+              (unsigned)bfd_getl32 (eiaf->minorid));
+      /* xgettext:c-format */
       fprintf (file, _("  iaflink : 0x%08x %08x\n"),
-               (unsigned)bfd_getl32 (eiaf->iaflink + 0),
-               (unsigned)bfd_getl32 (eiaf->iaflink + 4));
+              (unsigned)bfd_getl32 (eiaf->iaflink + 0),
+              (unsigned)bfd_getl32 (eiaf->iaflink + 4));
+      /* xgettext:c-format */
       fprintf (file, _("  fixuplnk: 0x%08x %08x\n"),
-               (unsigned)bfd_getl32 (eiaf->fixuplnk + 0),
-               (unsigned)bfd_getl32 (eiaf->fixuplnk + 4));
+              (unsigned)bfd_getl32 (eiaf->fixuplnk + 0),
+              (unsigned)bfd_getl32 (eiaf->fixuplnk + 4));
       fprintf (file, _("  size : %u\n"),
-               (unsigned)bfd_getl32 (eiaf->size));
+              (unsigned)bfd_getl32 (eiaf->size));
       fprintf (file, _("  flags: 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiaf->flags));
+              (unsigned)bfd_getl32 (eiaf->flags));
       qrelfixoff = bfd_getl32 (eiaf->qrelfixoff);
       lrelfixoff = bfd_getl32 (eiaf->lrelfixoff);
+      /* xgettext:c-format */
       fprintf (file, _("  qrelfixoff: %5u, lrelfixoff: %5u\n"),
-               qrelfixoff, lrelfixoff);
+              qrelfixoff, lrelfixoff);
       qdotadroff = bfd_getl32 (eiaf->qdotadroff);
       ldotadroff = bfd_getl32 (eiaf->ldotadroff);
+      /* xgettext:c-format */
       fprintf (file, _("  qdotadroff: %5u, ldotadroff: %5u\n"),
-               qdotadroff, ldotadroff);
+              qdotadroff, ldotadroff);
       codeadroff = bfd_getl32 (eiaf->codeadroff);
       lpfixoff = bfd_getl32 (eiaf->lpfixoff);
+      /* xgettext:c-format */
       fprintf (file, _("  codeadroff: %5u, lpfixoff  : %5u\n"),
-               codeadroff, lpfixoff);
+              codeadroff, lpfixoff);
       chgprtoff = bfd_getl32 (eiaf->chgprtoff);
       fprintf (file, _("  chgprtoff : %5u\n"), chgprtoff);
       shrimgcnt = bfd_getl32 (eiaf->shrimgcnt);
       shlstoff = bfd_getl32 (eiaf->shlstoff);
+      /* xgettext:c-format */
       fprintf (file, _("  shlstoff  : %5u, shrimgcnt : %5u\n"),
-               shlstoff, shrimgcnt);
+              shlstoff, shrimgcnt);
+      /* xgettext:c-format */
       fprintf (file, _("  shlextra  : %5u, permctx   : %5u\n"),
-               (unsigned)bfd_getl32 (eiaf->shlextra),
-               (unsigned)bfd_getl32 (eiaf->permctx));
+              (unsigned)bfd_getl32 (eiaf->shlextra),
+              (unsigned)bfd_getl32 (eiaf->permctx));
       fprintf (file, _("  base_va : 0x%08x\n"),
-               (unsigned)bfd_getl32 (eiaf->base_va));
+              (unsigned)bfd_getl32 (eiaf->base_va));
       fprintf (file, _("  lppsbfixoff: %5u\n"),
-               (unsigned)bfd_getl32 (eiaf->lppsbfixoff));
+              (unsigned)bfd_getl32 (eiaf->lppsbfixoff));
 
       if (shlstoff)
-        {
-          struct vms_shl *shl = (struct vms_shl *)(buf + shlstoff);
-          unsigned int j;
-
-          fprintf (file, _(" Shareable images:\n"));
-          for (j = 0; j < shrimgcnt; j++, shl++)
-            {
-              fprintf (file,
-                       _("  %u: size: %u, flags: 0x%02x, name: %.*s\n"),
-                       j, shl->size, shl->flags,
-                       shl->imgnam[0], shl->imgnam + 1);
-            }
-        }
+       {
+         struct vms_shl *shl = (struct vms_shl *)(buf + shlstoff);
+         unsigned int j;
+
+         fprintf (file, _(" Shareable images:\n"));
+         for (j = 0; j < shrimgcnt; j++, shl++)
+           {
+             fprintf (file,
+                      /* xgettext:c-format */
+                      _("  %u: size: %u, flags: 0x%02x, name: %.*s\n"),
+                      j, shl->size, shl->flags,
+                      shl->imgnam[0], shl->imgnam + 1);
+           }
+       }
       if (qrelfixoff != 0)
-        {
-          fprintf (file, _(" quad-word relocation fixups:\n"));
-          evax_bfd_print_relocation_records (file, buf + qrelfixoff, 8);
-        }
+       {
+         fprintf (file, _(" quad-word relocation fixups:\n"));
+         evax_bfd_print_relocation_records (file, buf + qrelfixoff, 8);
+       }
       if (lrelfixoff != 0)
-        {
-          fprintf (file, _(" long-word relocation fixups:\n"));
-          evax_bfd_print_relocation_records (file, buf + lrelfixoff, 4);
-        }
+       {
+         fprintf (file, _(" long-word relocation fixups:\n"));
+         evax_bfd_print_relocation_records (file, buf + lrelfixoff, 4);
+       }
       if (qdotadroff != 0)
-        {
-          fprintf (file, _(" quad-word .address reference fixups:\n"));
-          evax_bfd_print_address_fixups (file, buf + qdotadroff);
-        }
+       {
+         fprintf (file, _(" quad-word .address reference fixups:\n"));
+         evax_bfd_print_address_fixups (file, buf + qdotadroff);
+       }
       if (ldotadroff != 0)
-        {
-          fprintf (file, _(" long-word .address reference fixups:\n"));
-          evax_bfd_print_address_fixups (file, buf + ldotadroff);
-        }
+       {
+         fprintf (file, _(" long-word .address reference fixups:\n"));
+         evax_bfd_print_address_fixups (file, buf + ldotadroff);
+       }
       if (codeadroff != 0)
-        {
-          fprintf (file, _(" Code Address Reference Fixups:\n"));
-          evax_bfd_print_reference_fixups (file, buf + codeadroff);
-        }
+       {
+         fprintf (file, _(" Code Address Reference Fixups:\n"));
+         evax_bfd_print_reference_fixups (file, buf + codeadroff);
+       }
       if (lpfixoff != 0)
-        {
-          fprintf (file, _(" Linkage Pairs Referece Fixups:\n"));
-          evax_bfd_print_reference_fixups (file, buf + lpfixoff);
-        }
+       {
+         fprintf (file, _(" Linkage Pairs Reference Fixups:\n"));
+         evax_bfd_print_reference_fixups (file, buf + lpfixoff);
+       }
       if (chgprtoff)
-        {
-          unsigned int count = (unsigned)bfd_getl32 (buf + chgprtoff);
-          struct vms_eicp *eicp = (struct vms_eicp *)(buf + chgprtoff + 4);
-          unsigned int j;
-
-          fprintf (file, _(" Change Protection (%u entries):\n"), count);
-          for (j = 0; j < count; j++, eicp++)
-            {
-              unsigned int prot = bfd_getl32 (eicp->newprt);
-              fprintf (file,
-                       _("  base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "),
-                       (unsigned)bfd_getl32 (eicp->baseva + 4),
-                       (unsigned)bfd_getl32 (eicp->baseva + 0),
-                       (unsigned)bfd_getl32 (eicp->size),
-                       (unsigned)bfd_getl32 (eicp->newprt));
-              switch (prot)
-                {
-                case PRT__C_NA:
-                  fprintf (file, "NA");
-                  break;
-                case PRT__C_RESERVED:
-                  fprintf (file, "RES");
-                  break;
-                case PRT__C_KW:
-                  fprintf (file, "KW");
-                  break;
-                case PRT__C_KR:
-                  fprintf (file, "KR");
-                  break;
-                case PRT__C_UW:
-                  fprintf (file, "UW");
-                  break;
-                case PRT__C_EW:
-                  fprintf (file, "EW");
-                  break;
-                case PRT__C_ERKW:
-                  fprintf (file, "ERKW");
-                  break;
-                case PRT__C_ER:
-                  fprintf (file, "ER");
-                  break;
-                case PRT__C_SW:
-                  fprintf (file, "SW");
-                  break;
-                case PRT__C_SREW:
-                  fprintf (file, "SREW");
-                  break;
-                case PRT__C_SRKW:
-                  fprintf (file, "SRKW");
-                  break;
-                case PRT__C_SR:
-                  fprintf (file, "SR");
-                  break;
-                case PRT__C_URSW:
-                  fprintf (file, "URSW");
-                  break;
-                case PRT__C_UREW:
-                  fprintf (file, "UREW");
-                  break;
-                case PRT__C_URKW:
-                  fprintf (file, "URKW");
-                  break;
-                case PRT__C_UR:
-                  fprintf (file, "UR");
-                  break;
-                default:
-                  fputs ("??", file);
-                  break;
-                }
-              fputc ('\n', file);
-            }
-        }
+       {
+         unsigned int count = (unsigned)bfd_getl32 (buf + chgprtoff);
+         struct vms_eicp *eicp = (struct vms_eicp *)(buf + chgprtoff + 4);
+         unsigned int j;
+
+         fprintf (file, _(" Change Protection (%u entries):\n"), count);
+         for (j = 0; j < count; j++, eicp++)
+           {
+             unsigned int prot = bfd_getl32 (eicp->newprt);
+             fprintf (file,
+                      /* xgettext:c-format */
+                      _("  base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "),
+                      (unsigned)bfd_getl32 (eicp->baseva + 4),
+                      (unsigned)bfd_getl32 (eicp->baseva + 0),
+                      (unsigned)bfd_getl32 (eicp->size),
+                      (unsigned)bfd_getl32 (eicp->newprt));
+             switch (prot)
+               {
+               case PRT__C_NA:
+                 fprintf (file, "NA");
+                 break;
+               case PRT__C_RESERVED:
+                 fprintf (file, "RES");
+                 break;
+               case PRT__C_KW:
+                 fprintf (file, "KW");
+                 break;
+               case PRT__C_KR:
+                 fprintf (file, "KR");
+                 break;
+               case PRT__C_UW:
+                 fprintf (file, "UW");
+                 break;
+               case PRT__C_EW:
+                 fprintf (file, "EW");
+                 break;
+               case PRT__C_ERKW:
+                 fprintf (file, "ERKW");
+                 break;
+               case PRT__C_ER:
+                 fprintf (file, "ER");
+                 break;
+               case PRT__C_SW:
+                 fprintf (file, "SW");
+                 break;
+               case PRT__C_SREW:
+                 fprintf (file, "SREW");
+                 break;
+               case PRT__C_SRKW:
+                 fprintf (file, "SRKW");
+                 break;
+               case PRT__C_SR:
+                 fprintf (file, "SR");
+                 break;
+               case PRT__C_URSW:
+                 fprintf (file, "URSW");
+                 break;
+               case PRT__C_UREW:
+                 fprintf (file, "UREW");
+                 break;
+               case PRT__C_URKW:
+                 fprintf (file, "URKW");
+                 break;
+               case PRT__C_UR:
+                 fprintf (file, "UR");
+                 break;
+               default:
+                 fputs ("??", file);
+                 break;
+               }
+             fputc ('\n', file);
+           }
+       }
       free (buf);
     }
 }
@@ -7794,7 +8290,7 @@ vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr)
   else
     {
       if (bfd_seek (abfd, 0, SEEK_SET))
-        return FALSE;
+       return FALSE;
       evax_bfd_print_eobj (abfd, file);
     }
   return TRUE;
@@ -7823,16 +8319,16 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
   if (info)
     {
       if (info->strip == strip_all || info->strip == strip_debugger)
-        {
-          /* Discard the DST section.  */
-          dst_offset = 0;
-          dst_section = NULL;
-        }
+       {
+         /* Discard the DST section.  */
+         dst_offset = 0;
+         dst_section = NULL;
+       }
       else if (dst_section)
-        {
-          dst_offset = dst_section->output_offset;
-          dst_section = dst_section->output_section;
-        }
+       {
+         dst_offset = dst_section->output_offset;
+         dst_section = dst_section->output_section;
+       }
     }
 
   while (1)
@@ -7847,76 +8343,90 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
          return FALSE;
        }
       switch (type)
-        {
-        case EOBJ__C_ETIR:
-          PRIV (image_section) = cur_section;
-          PRIV (image_offset) = cur_offset;
-          res = _bfd_vms_slurp_etir (abfd, info);
-          cur_section = PRIV (image_section);
-          cur_offset = PRIV (image_offset);
-          break;
-        case EOBJ__C_EDBG:
-        case EOBJ__C_ETBT:
-          if (dst_section == NULL)
-            continue;
-          PRIV (image_section) = dst_section;
-          PRIV (image_offset) = dst_offset;
-          res = _bfd_vms_slurp_etir (abfd, info);
-          dst_offset = PRIV (image_offset);
-          break;
-        case EOBJ__C_EEOM:
-          return TRUE;
-        default:
-          continue;
-        }
+       {
+       case EOBJ__C_ETIR:
+         PRIV (image_section) = cur_section;
+         PRIV (image_offset) = cur_offset;
+         res = _bfd_vms_slurp_etir (abfd, info);
+         cur_section = PRIV (image_section);
+         cur_offset = PRIV (image_offset);
+         break;
+       case EOBJ__C_EDBG:
+       case EOBJ__C_ETBT:
+         if (dst_section == NULL)
+           continue;
+         PRIV (image_section) = dst_section;
+         PRIV (image_offset) = dst_offset;
+         res = _bfd_vms_slurp_etir (abfd, info);
+         dst_offset = PRIV (image_offset);
+         break;
+       case EOBJ__C_EEOM:
+         return TRUE;
+       default:
+         continue;
+       }
       if (!res)
-        {
-          vms_debug2 ((2, "slurp eobj type %d failed\n", type));
-          return FALSE;
-        }
+       {
+         vms_debug2 ((2, "slurp eobj type %d failed\n", type));
+         return FALSE;
+       }
     }
 }
 
 static int
 alpha_vms_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
-                          struct bfd_link_info *info ATTRIBUTE_UNUSED)
+                         struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 /* Add a linkage pair fixup at address SECT + OFFSET to SHLIB. */
 
-static void
+static bfd_boolean
 alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib)
 {
   struct alpha_vms_shlib_el *sl;
   asection *sect = PRIV2 (src, image_section);
   file_ptr offset = PRIV2 (src, image_offset);
+  bfd_vma *p;
 
   sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
-                struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+               struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
   sl->has_fixups = TRUE;
-  VEC_APPEND_EL (sl->lp, bfd_vma,
-                 sect->output_section->vma + sect->output_offset + offset);
+  p = VEC_APPEND (sl->lp, bfd_vma);
+  if (p == NULL)
+    return FALSE;
+  *p = sect->output_section->vma + sect->output_offset + offset;
+  sect->output_section->flags |= SEC_RELOC;
+  return TRUE;
 }
 
-static void
+/* Add a code address fixup at address SECT + OFFSET to SHLIB. */
+
+static bfd_boolean
 alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib)
 {
   struct alpha_vms_shlib_el *sl;
   asection *sect = PRIV2 (src, image_section);
   file_ptr offset = PRIV2 (src, image_offset);
+  bfd_vma *p;
 
   sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
-                struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+               struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
   sl->has_fixups = TRUE;
-  VEC_APPEND_EL (sl->ca, bfd_vma,
-                 sect->output_section->vma + sect->output_offset + offset);
+  p = VEC_APPEND (sl->ca, bfd_vma);
+  if (p == NULL)
+    return FALSE;
+  *p = sect->output_section->vma + sect->output_offset + offset;
+  sect->output_section->flags |= SEC_RELOC;
+  return TRUE;
 }
 
-static void
+/* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */
+
+static bfd_boolean
 alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
-                        bfd *shlib, bfd_vma vec)
+                       bfd *shlib, bfd_vma vec)
 {
   struct alpha_vms_shlib_el *sl;
   struct alpha_vms_vma_ref *r;
@@ -7924,45 +8434,44 @@ alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
   file_ptr offset = PRIV2 (src, image_offset);
 
   sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
-                struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+               struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
   sl->has_fixups = TRUE;
   r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref);
+  if (r == NULL)
+    return FALSE;
   r->vma = sect->output_section->vma + sect->output_offset + offset;
   r->ref = vec;
+  sect->output_section->flags |= SEC_RELOC;
+  return TRUE;
 }
 
-static void
-alpha_vms_add_lw_fixup (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                        unsigned int shr ATTRIBUTE_UNUSED,
-                        bfd_vma vec ATTRIBUTE_UNUSED)
+static bfd_boolean
+alpha_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                       unsigned int shr ATTRIBUTE_UNUSED,
+                       bfd_vma vec ATTRIBUTE_UNUSED)
 {
-  abort ();
+  /* Not yet supported.  */
+  return FALSE;
 }
 
-#if 0
-static void
-alpha_vms_add_qw_fixup (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                        unsigned int shr ATTRIBUTE_UNUSED,
-                        bfd_vma vec ATTRIBUTE_UNUSED)
-{
-  abort ();
-}
-#endif
+/* Add relocation.  FIXME: Not yet emitted.  */
 
-static void
+static bfd_boolean
 alpha_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
+  return FALSE;
 }
 
-static void
+static bfd_boolean
 alpha_vms_add_qw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
+  return FALSE;
 }
 
 static struct bfd_hash_entry *
 alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry,
-                             struct bfd_hash_table *table,
-                             const char *string)
+                            struct bfd_hash_table *table,
+                            const char *string)
 {
   struct alpha_vms_link_hash_entry *ret =
     (struct alpha_vms_link_hash_entry *) entry;
@@ -7972,7 +8481,7 @@ alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry,
   if (ret == NULL)
     ret = ((struct alpha_vms_link_hash_entry *)
           bfd_hash_allocate (table,
-                              sizeof (struct alpha_vms_link_hash_entry)));
+                             sizeof (struct alpha_vms_link_hash_entry)));
   if (ret == NULL)
     return NULL;
 
@@ -7986,13 +8495,34 @@ 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 *
 alpha_vms_bfd_link_hash_table_create (bfd *abfd)
 {
   struct alpha_vms_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct alpha_vms_link_hash_table);
+  size_t amt = sizeof (struct alpha_vms_link_hash_table);
 
   ret = (struct alpha_vms_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
@@ -8007,6 +8537,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;
 }
@@ -8024,31 +8555,31 @@ alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       asymbol sym;
 
       if (!alpha_vms_convert_symbol (abfd, e, &sym))
-        return FALSE;
+       return FALSE;
 
       if ((e->flags & EGSY__V_DEF) && abfd->selective_search)
-        {
-          /* In selective_search mode, only add definition that are
-             required.  */
-          h = (struct alpha_vms_link_hash_entry *)bfd_link_hash_lookup
-            (info->hash, sym.name, FALSE, FALSE, FALSE);
-          if (h == NULL || h->root.type != bfd_link_hash_undefined)
-            continue;
-        }
+       {
+         /* In selective_search mode, only add definition that are
+            required.  */
+         h = (struct alpha_vms_link_hash_entry *)bfd_link_hash_lookup
+           (info->hash, sym.name, FALSE, FALSE, FALSE);
+         if (h == NULL || h->root.type != bfd_link_hash_undefined)
+           continue;
+       }
       else
-        h = NULL;
+       h = NULL;
 
       h_root = (struct bfd_link_hash_entry *) h;
-      if (_bfd_generic_link_add_one_symbol
-          (info, abfd, sym.name, sym.flags, sym.section, sym.value,
-           NULL, FALSE, FALSE, &h_root) == FALSE)
-        return FALSE;
+      if (!_bfd_generic_link_add_one_symbol (info, abfd, sym.name, sym.flags,
+                                            sym.section, sym.value, NULL,
+                                            FALSE, FALSE, &h_root))
+       return FALSE;
       h = (struct alpha_vms_link_hash_entry *) h_root;
 
       if ((e->flags & EGSY__V_DEF)
-          && h->sym == NULL
-          && abfd->xvec == info->output_bfd->xvec)
-        h->sym = e;
+         && h->sym == NULL
+         && abfd->xvec == info->output_bfd->xvec)
+       h->sym = e;
     }
 
   if (abfd->flags & DYNAMIC)
@@ -8056,11 +8587,13 @@ alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       struct alpha_vms_shlib_el *shlib;
 
       /* We do not want to include any of the sections in a dynamic
-         object in the output file.  See comment in elflink.c.  */
+        object in the output file.  See comment in elflink.c.  */
       bfd_section_list_clear (abfd);
 
       shlib = VEC_APPEND (alpha_vms_link_hash (info)->shrlibs,
-                          struct alpha_vms_shlib_el);
+                         struct alpha_vms_shlib_el);
+      if (shlib == NULL)
+       return FALSE;
       shlib->abfd = abfd;
       VEC_INIT (shlib->ca);
       VEC_INIT (shlib->lp);
@@ -8112,10 +8645,10 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
             entry if it is the tail, because that would lose any
             entries we add to the list later on.  */
          if (*pundef != info->hash->undefs_tail)
-            {
-              *pundef = *next_pundef;
-              next_pundef = pundef;
-            }
+           {
+             *pundef = *next_pundef;
+             next_pundef = pundef;
+           }
          continue;
        }
 
@@ -8132,32 +8665,35 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
        return FALSE;
 
       if (element->archive_pass == -1 || element->archive_pass == pass)
-        continue;
+       {
+         /* Next symbol if this archive is wrong or already handled.  */
+         continue;
+       }
 
       if (! bfd_check_format (element, bfd_object))
-        {
-          element->archive_pass = -1;
-          return FALSE;
-        }
+       {
+         element->archive_pass = -1;
+         return FALSE;
+       }
 
       orig_element = element;
       if (bfd_is_thin_archive (abfd))
-        {
-          element = _bfd_vms_lib_get_imagelib_file (element);
-          if (element == NULL || !bfd_check_format (element, bfd_object))
-            {
-              orig_element->archive_pass = -1;
-              return FALSE;
-            }
-        }
+       {
+         element = _bfd_vms_lib_get_imagelib_file (element);
+         if (element == NULL || !bfd_check_format (element, bfd_object))
+           {
+             orig_element->archive_pass = -1;
+             return FALSE;
+           }
+       }
 
       /* Unlike the generic linker, we know that this element provides
         a definition for an undefined symbol and we know that we want
         to include it.  We don't need to check anything.  */
-      if (! (*info->callbacks->add_archive_element) (info, element,
-                                                     h->root.string))
-       return FALSE;
-      if (! alpha_vms_link_add_object_symbols (element, info))
+      if (!(*info->callbacks
+           ->add_archive_element) (info, element, h->root.string, &element))
+       continue;
+      if (!alpha_vms_link_add_object_symbols (element, info))
        return FALSE;
 
       orig_element->archive_pass = pass;
@@ -8173,12 +8709,12 @@ alpha_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
     {
     case bfd_object:
       vms_debug2 ((2, "vms_link_add_symbols for object %s\n",
-                   abfd->filename));
+                  abfd->filename));
       return alpha_vms_link_add_object_symbols (abfd, info);
       break;
     case bfd_archive:
       vms_debug2 ((2, "vms_link_add_symbols for archive %s\n",
-                   abfd->filename));
+                  abfd->filename));
       return alpha_vms_link_add_archive_symbols (abfd, info);
       break;
     default:
@@ -8198,6 +8734,8 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
   unsigned int ca_sz = 0;
   unsigned int qr_sz = 0;
   unsigned int shrimg_cnt = 0;
+  unsigned int chgprt_num = 0;
+  unsigned int chgprt_sz = 0;
   struct vms_eiaf *eiaf;
   unsigned int off;
   asection *sec;
@@ -8210,28 +8748,28 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
       shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
 
       if (!shlib->has_fixups)
-        continue;
+       continue;
 
       shrimg_cnt++;
 
       if (VEC_COUNT (shlib->ca) > 0)
-        {
-          /* Header + entries.  */
-          ca_sz += 8;
-          ca_sz += VEC_COUNT (shlib->ca) * 4;
-        }
+       {
+         /* Header + entries.  */
+         ca_sz += 8;
+         ca_sz += VEC_COUNT (shlib->ca) * 4;
+       }
       if (VEC_COUNT (shlib->lp) > 0)
-        {
-          /* Header + entries.  */
-          lp_sz += 8;
-          lp_sz += VEC_COUNT (shlib->lp) * 4;
-        }
+       {
+         /* Header + entries.  */
+         lp_sz += 8;
+         lp_sz += VEC_COUNT (shlib->lp) * 4;
+       }
       if (VEC_COUNT (shlib->qr) > 0)
-        {
-          /* Header + entries.  */
-          qr_sz += 8;
-          qr_sz += VEC_COUNT (shlib->qr) * 8;
-        }
+       {
+         /* Header + entries.  */
+         qr_sz += 8;
+         qr_sz += VEC_COUNT (shlib->qr) * 8;
+       }
     }
   /* Add markers.  */
   if (ca_sz > 0)
@@ -8245,9 +8783,20 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
   if (ca_sz + lp_sz + qr_sz == 0)
     return TRUE;
 
+  /* Add an eicp entry for the fixup itself.  */
+  chgprt_num = 1;
+  for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
+    {
+      /* This isect could be made RO or EXE after relocations are applied.  */
+      if ((sec->flags & SEC_RELOC) != 0
+         && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+       chgprt_num++;
+    }
+  chgprt_sz = 4 + chgprt_num * sizeof (struct vms_eicp);
+
   /* Allocate section content (round-up size)  */
   sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl)
-    + ca_sz + lp_sz + qr_sz;
+    + ca_sz + lp_sz + qr_sz + chgprt_sz;
   sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
   content = bfd_zalloc (info->output_bfd, sz);
   if (content == NULL)
@@ -8285,135 +8834,244 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
 
       /* Write shl.  */
       for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
-        {
-          struct alpha_vms_shlib_el *shlib;
-          struct vms_shl *shl;
-
-          shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
-
-          if (!shlib->has_fixups)
-            continue;
-
-          /* Renumber shared images.  */
-          PRIV2 (shlib->abfd, shr_index) = shrimg_cnt++;
-
-          shl = (struct vms_shl *)(content + off);
-          bfd_putl32 (0, shl->baseva);
-          bfd_putl32 (0, shl->shlptr);
-          bfd_putl32 (0, shl->ident);
-          bfd_putl32 (0, shl->permctx);
-          shl->size = sizeof (struct vms_shl);
-          bfd_putl16 (0, shl->fill_1);
-          shl->flags = 0;
-          bfd_putl32 (0, shl->icb);
-          shl->imgnam[0] = strlen (PRIV2 (shlib->abfd, hdr_data.hdr_t_name));
-          memcpy (shl->imgnam + 1, PRIV2 (shlib->abfd, hdr_data.hdr_t_name),
-                  shl->imgnam[0]);
-
-          off += sizeof (struct vms_shl);
-        }
+       {
+         struct alpha_vms_shlib_el *shlib;
+         struct vms_shl *shl;
+
+         shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+         if (!shlib->has_fixups)
+           continue;
+
+         /* Renumber shared images.  */
+         PRIV2 (shlib->abfd, shr_index) = shrimg_cnt++;
+
+         shl = (struct vms_shl *)(content + off);
+         bfd_putl32 (0, shl->baseva);
+         bfd_putl32 (0, shl->shlptr);
+         bfd_putl32 (0, shl->ident);
+         bfd_putl32 (0, shl->permctx);
+         shl->size = sizeof (struct vms_shl);
+         bfd_putl16 (0, shl->fill_1);
+         shl->flags = 0;
+         bfd_putl32 (0, shl->icb);
+         shl->imgnam[0] = strlen (PRIV2 (shlib->abfd, hdr_data.hdr_t_name));
+         memcpy (shl->imgnam + 1, PRIV2 (shlib->abfd, hdr_data.hdr_t_name),
+                 shl->imgnam[0]);
+
+         off += sizeof (struct vms_shl);
+       }
 
       /* CA fixups.  */
       if (ca_sz != 0)
-        {
-          bfd_putl32 (off, eiaf->codeadroff);
+       {
+         bfd_putl32 (off, eiaf->codeadroff);
 
-          for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
-            {
-              struct alpha_vms_shlib_el *shlib;
-              unsigned int j;
+         for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+           {
+             struct alpha_vms_shlib_el *shlib;
+             unsigned int j;
 
-              shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+             shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
 
-              if (VEC_COUNT (shlib->ca) == 0)
-                continue;
+             if (VEC_COUNT (shlib->ca) == 0)
+               continue;
 
-              bfd_putl32 (VEC_COUNT (shlib->ca), content + off);
-              bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
-              off += 8;
+             bfd_putl32 (VEC_COUNT (shlib->ca), content + off);
+             bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+             off += 8;
 
-              for (j = 0; j < VEC_COUNT (shlib->ca); j++)
-                {
-                  bfd_putl32 (VEC_EL (shlib->ca, bfd_vma, j) - t->base_addr,
-                              content + off);
-                  off += 4;
-                }
-            }
+             for (j = 0; j < VEC_COUNT (shlib->ca); j++)
+               {
+                 bfd_putl32 (VEC_EL (shlib->ca, bfd_vma, j) - t->base_addr,
+                             content + off);
+                 off += 4;
+               }
+           }
 
-          bfd_putl32 (0, content + off);
-          bfd_putl32 (0, content + off + 4);
-          off += 8;
-        }
+         bfd_putl32 (0, content + off);
+         bfd_putl32 (0, content + off + 4);
+         off += 8;
+       }
 
       /* LP fixups.  */
       if (lp_sz != 0)
-        {
-          bfd_putl32 (off, eiaf->lpfixoff);
+       {
+         bfd_putl32 (off, eiaf->lpfixoff);
 
-          for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
-            {
-              struct alpha_vms_shlib_el *shlib;
-              unsigned int j;
+         for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+           {
+             struct alpha_vms_shlib_el *shlib;
+             unsigned int j;
 
-              shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+             shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
 
-              if (VEC_COUNT (shlib->lp) == 0)
-                continue;
+             if (VEC_COUNT (shlib->lp) == 0)
+               continue;
 
-              bfd_putl32 (VEC_COUNT (shlib->lp), content + off);
-              bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
-              off += 8;
+             bfd_putl32 (VEC_COUNT (shlib->lp), content + off);
+             bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+             off += 8;
 
-              for (j = 0; j < VEC_COUNT (shlib->lp); j++)
-                {
-                  bfd_putl32 (VEC_EL (shlib->lp, bfd_vma, j) - t->base_addr,
-                              content + off);
-                  off += 4;
-                }
-            }
+             for (j = 0; j < VEC_COUNT (shlib->lp); j++)
+               {
+                 bfd_putl32 (VEC_EL (shlib->lp, bfd_vma, j) - t->base_addr,
+                             content + off);
+                 off += 4;
+               }
+           }
 
-          bfd_putl32 (0, content + off);
-          bfd_putl32 (0, content + off + 4);
-          off += 8;
-        }
+         bfd_putl32 (0, content + off);
+         bfd_putl32 (0, content + off + 4);
+         off += 8;
+       }
 
       /* QR fixups.  */
       if (qr_sz != 0)
-        {
-          bfd_putl32 (off, eiaf->qdotadroff);
-
-          for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
-            {
-              struct alpha_vms_shlib_el *shlib;
-              unsigned int j;
-
-              shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
-
-              if (VEC_COUNT (shlib->qr) == 0)
-                continue;
-
-              bfd_putl32 (VEC_COUNT (shlib->qr), content + off);
-              bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
-              off += 8;
-
-              for (j = 0; j < VEC_COUNT (shlib->qr); j++)
-                {
-                  struct alpha_vms_vma_ref *r;
-                  r = &VEC_EL (shlib->qr, struct alpha_vms_vma_ref, j);
-                  bfd_putl32 (r->vma - t->base_addr, content + off);
-                  bfd_putl32 (r->ref, content + off + 4);
-                  off += 8;
-                }
-            }
-
-          bfd_putl32 (0, content + off);
-          bfd_putl32 (0, content + off + 4);
-          off += 8;
-        }
+       {
+         bfd_putl32 (off, eiaf->qdotadroff);
 
-      /* CA fixups.  */
+         for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+           {
+             struct alpha_vms_shlib_el *shlib;
+             unsigned int j;
+
+             shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+             if (VEC_COUNT (shlib->qr) == 0)
+               continue;
+
+             bfd_putl32 (VEC_COUNT (shlib->qr), content + off);
+             bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+             off += 8;
+
+             for (j = 0; j < VEC_COUNT (shlib->qr); j++)
+               {
+                 struct alpha_vms_vma_ref *r;
+                 r = &VEC_EL (shlib->qr, struct alpha_vms_vma_ref, j);
+                 bfd_putl32 (r->vma - t->base_addr, content + off);
+                 bfd_putl32 (r->ref, content + off + 4);
+                 off += 8;
+               }
+           }
+
+         bfd_putl32 (0, content + off);
+         bfd_putl32 (0, content + off + 4);
+         off += 8;
+       }
+    }
+
+  /* Write the change protection table.  */
+  bfd_putl32 (off, eiaf->chgprtoff);
+  bfd_putl32 (chgprt_num, content + off);
+  off += 4;
+
+  for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
+    {
+      struct vms_eicp *eicp;
+      unsigned int prot;
+
+      if ((sec->flags & SEC_LINKER_CREATED) != 0 &&
+         strcmp (sec->name, "$FIXUP$") == 0)
+       prot = PRT__C_UREW;
+      else if ((sec->flags & SEC_RELOC) != 0
+              && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+       prot = PRT__C_UR;
+      else
+       continue;
+
+      eicp = (struct vms_eicp *)(content + off);
+      bfd_putl64 (sec->vma - t->base_addr, eicp->baseva);
+      bfd_putl32 ((sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1),
+                 eicp->size);
+      bfd_putl32 (prot, eicp->newprt);
+      off += sizeof (struct vms_eicp);
+    }
+
+  return TRUE;
+}
+
+/* Called by bfd_hash_traverse to fill the symbol table.
+   Return FALSE in case of failure.  */
+
+static bfd_boolean
+alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov)
+{
+  struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh;
+  struct bfd_link_info *info = (struct bfd_link_info *)infov;
+  struct alpha_vms_link_hash_entry *h;
+  struct vms_symbol_entry *sym;
+
+  if (hc->type == bfd_link_hash_warning)
+    {
+      hc = hc->u.i.link;
+      if (hc->type == bfd_link_hash_new)
+       return TRUE;
+    }
+  h = (struct alpha_vms_link_hash_entry *) hc;
+
+  switch (h->root.type)
+    {
+    case bfd_link_hash_undefined:
+      return TRUE;
+    case bfd_link_hash_new:
+    case bfd_link_hash_warning:
+      abort ();
+    case bfd_link_hash_undefweak:
+      return TRUE;
+    case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
+      {
+       asection *sec = h->root.u.def.section;
+
+       /* FIXME: this is certainly a symbol from a dynamic library.  */
+       if (bfd_is_abs_section (sec))
+         return TRUE;
+
+       if (sec->owner->flags & DYNAMIC)
+         return TRUE;
+      }
+      break;
+    case bfd_link_hash_common:
+      break;
+    case bfd_link_hash_indirect:
+      return TRUE;
     }
 
+  /* Do not write not kept symbols.  */
+  if (info->strip == strip_some
+      && bfd_hash_lookup (info->keep_hash, h->root.root.string,
+                         FALSE, FALSE) != NULL)
+    return TRUE;
+
+  if (h->sym == NULL)
+    {
+      /* This symbol doesn't come from a VMS object.  So we suppose it is
+        a data.  */
+      int len = strlen (h->root.root.string);
+
+      sym = (struct vms_symbol_entry *)bfd_zalloc (info->output_bfd,
+                                                  sizeof (*sym) + len);
+      if (sym == NULL)
+       abort ();
+      sym->namelen = len;
+      memcpy (sym->name, h->root.root.string, len);
+      sym->name[len] = 0;
+      sym->owner = info->output_bfd;
+
+      sym->typ = EGSD__C_SYMG;
+      sym->data_type = 0;
+      sym->flags = EGSY__V_DEF | EGSY__V_REL;
+      sym->symbol_vector = h->root.u.def.value;
+      sym->section = h->root.u.def.section;
+      sym->value = h->root.u.def.value;
+    }
+  else
+    sym = h->sym;
+
+  if (!add_symbol_entry (info->output_bfd, sym))
+    return FALSE;
+
   return TRUE;
 }
 
@@ -8429,8 +9087,16 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   asection *dst;
   asection *dmt;
 
-  bfd_get_outsymbols (abfd) = NULL;
-  bfd_get_symcount (abfd) = 0;
+  if (bfd_link_relocatable (info))
+    {
+      /* FIXME: we do not yet support relocatable link.  It is not obvious
+        how to do it for debug infos.  */
+      (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n"));
+      return FALSE;
+    }
+
+  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)
@@ -8443,91 +9109,117 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   for (o = abfd->sections; o != NULL; o = o->next)
     {
       printf ("For section %s (at 0x%08x, flags=0x%08x):\n",
-              o->name, (unsigned)o->vma, (unsigned)o->flags);
+             o->name, (unsigned)o->vma, (unsigned)o->flags);
 
       for (p = o->map_head.link_order; p != NULL; p = p->next)
        {
-          printf (" at 0x%08x - 0x%08x: ",
-                  (unsigned)p->offset, (unsigned)(p->offset + p->size - 1));
+         printf (" at 0x%08x - 0x%08x: ",
+                 (unsigned)p->offset, (unsigned)(p->offset + p->size - 1));
          switch (p->type)
            {
            case bfd_section_reloc_link_order:
            case bfd_symbol_reloc_link_order:
-              printf ("  section/symbol reloc\n");
+             printf ("  section/symbol reloc\n");
              break;
            case bfd_indirect_link_order:
-              printf ("  section %s of %s\n",
-                      p->u.indirect.section->name,
-                      p->u.indirect.section->owner->filename);
+             printf ("  section %s of %s\n",
+                     p->u.indirect.section->name,
+                     p->u.indirect.section->owner->filename);
+             break;
+           case bfd_data_link_order:
+             printf ("  explicit data\n");
              break;
-            case bfd_data_link_order:
-              printf ("  explicit data\n");
-              break;
            default:
-              printf ("  *unknown* type %u\n", p->type);
+             printf ("  *unknown* type %u\n", p->type);
              break;
            }
        }
     }
 #endif
 
+  /* Generate the symbol table.  */
+  BFD_ASSERT (PRIV (syms) == NULL);
+  if (info->strip != strip_all)
+    bfd_hash_traverse (&info->hash->table, alpha_vms_link_output_symbol, info);
+
   /* Find the entry point.  */
   if (bfd_get_start_address (abfd) == 0)
     {
       bfd *startbfd = NULL;
 
-      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
-        {
-          /* Consider only VMS object files.  */
-          if (sub->xvec != abfd->xvec)
-            continue;
-
-          if (!PRIV2 (sub, eom_data).eom_has_transfer)
-            continue;
-          if ((PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR) && startbfd)
-            continue;
-          if (startbfd != NULL
-              && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR))
-            {
-              (*info->callbacks->einfo)
-                (_("%P: multiple entry points: in modules %B and %B\n"),
-                 startbfd, sub);
-              continue;
-            }
-          startbfd = sub;
-        }
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+       {
+         /* Consider only VMS object files.  */
+         if (sub->xvec != abfd->xvec)
+           continue;
+
+         if (!PRIV2 (sub, eom_data).eom_has_transfer)
+           continue;
+         if ((PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR) && startbfd)
+           continue;
+         if (startbfd != NULL
+             && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR))
+           {
+             (*info->callbacks->einfo)
+               /* xgettext:c-format */
+               (_("%P: multiple entry points: in modules %pB and %pB\n"),
+                startbfd, sub);
+             continue;
+           }
+         startbfd = sub;
+       }
 
       if (startbfd)
-        {
-          unsigned int ps_idx = PRIV2 (startbfd, eom_data).eom_l_psindx;
-          bfd_vma tfradr = PRIV2 (startbfd, eom_data).eom_l_tfradr;
-          asection *sec;
+       {
+         unsigned int ps_idx = PRIV2 (startbfd, eom_data).eom_l_psindx;
+         bfd_vma tfradr = PRIV2 (startbfd, eom_data).eom_l_tfradr;
+         asection *sec;
 
-          sec = PRIV2 (startbfd, sections)[ps_idx];
+         sec = PRIV2 (startbfd, sections)[ps_idx];
 
-          bfd_set_start_address
-            (abfd, sec->output_section->vma + sec->output_offset + tfradr);
-        }
+         bfd_set_start_address
+           (abfd, sec->output_section->vma + sec->output_offset + tfradr);
+       }
     }
 
-  /* Allocate contents.  */
+  /* Set transfer addresses.  */
+  {
+    int i;
+    struct bfd_link_hash_entry *h;
+
+    i = 0;
+    PRIV (transfer_address[i++]) = 0xffffffff00000340ULL;      /* SYS$IMGACT */
+    h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", FALSE, FALSE, TRUE);
+    if (h != NULL && h->type == bfd_link_hash_defined)
+      PRIV (transfer_address[i++]) =
+       alpha_vms_get_sym_value (h->u.def.section, h->u.def.value);
+    PRIV (transfer_address[i++]) = bfd_get_start_address (abfd);
+    while (i < 4)
+      PRIV (transfer_address[i++]) = 0;
+  }
+
+  /* Allocate contents.
+     Also compute the virtual base address.  */
   base_addr = (bfd_vma)-1;
   last_addr = 0;
   for (o = abfd->sections; o != NULL; o = o->next)
     {
       if (o->flags & SEC_HAS_CONTENTS)
-        {
-          o->contents = bfd_alloc (abfd, o->size);
-          if (o->contents == NULL)
-            return FALSE;
-        }
+       {
+         o->contents = bfd_alloc (abfd, o->size);
+         if (o->contents == NULL)
+           return FALSE;
+       }
       if (o->flags & SEC_LOAD)
-        {
-          if (o->vma < base_addr)
-            base_addr = o->vma;
-          if (o->vma + o->size > last_addr)
-            last_addr = o->vma + o->size;
-        }
+       {
+         if (o->vma < base_addr)
+           base_addr = o->vma;
+         if (o->vma + o->size > last_addr)
+           last_addr = o->vma + o->size;
+       }
+      /* Clear the RELOC flags.  Currently we don't support incremental
+        linking.  We use the RELOC flag for computing the eicp entries.  */
+      o->flags &= ~SEC_RELOC;
     }
 
   /* Create the fixup section.  */
@@ -8543,31 +9235,33 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   alpha_vms_link_hash (info)->base_addr = base_addr;
 
   /* Create the DMT section, if necessary.  */
-  dst = PRIV (dst_section);
+  BFD_ASSERT (PRIV (dst_section) == NULL);
+  dst = bfd_get_section_by_name (abfd, "$DST$");
   if (dst != NULL && dst->size == 0)
     dst = NULL;
   if (dst != NULL)
     {
+      PRIV (dst_section) = dst;
       dmt = bfd_make_section_anyway_with_flags
-        (info->output_bfd, "$DMT$",
-         SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
+       (info->output_bfd, "$DMT$",
+        SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
       if (dmt == NULL)
-        return FALSE;
+       return FALSE;
     }
   else
     dmt = NULL;
 
   /* Read all sections from the inputs.  */
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
       if (sub->flags & DYNAMIC)
-        {
-          alpha_vms_create_eisd_for_shared (abfd, sub);
-          continue;
-        }
+       {
+         alpha_vms_create_eisd_for_shared (abfd, sub);
+         continue;
+       }
 
       if (!alpha_vms_read_sections_content (sub, info))
-        return FALSE;
+       return FALSE;
     }
 
   /* Handle all the link order information for the sections.
@@ -8580,10 +9274,10 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
            {
            case bfd_section_reloc_link_order:
            case bfd_symbol_reloc_link_order:
-              abort ();
-              return FALSE;
+             abort ();
+             return FALSE;
            case bfd_indirect_link_order:
-              /* Already done.  */
+             /* Already done.  */
              break;
            default:
              if (! _bfd_default_link_order (abfd, info, o, p))
@@ -8605,71 +9299,71 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
 
       /* In pass 1, compute the size.  In pass 2, write the DMT contents.  */
       for (pass = 0; pass < 2; pass++)
-        {
-          unsigned int off = 0;
-
-          /* For each object file (ie for each module).  */
-          for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
-            {
-              asection *sub_dst;
-              struct vms_dmt_header *dmth = NULL;
-              unsigned int psect_count;
-
-              /* Skip this module if it has no DST.  */
-              sub_dst = PRIV2 (sub, dst_section);
-              if (sub_dst == NULL || sub_dst->size == 0)
-                continue;
-
-              if (pass == 1)
-                {
-                  /* Write the header.  */
-                  dmth = (struct vms_dmt_header *)(contents + off);
-                  bfd_putl32 (sub_dst->output_offset, dmth->modbeg);
-                  bfd_putl32 (sub_dst->size, dmth->size);
-                }
-
-              off += sizeof (struct vms_dmt_header);
-              psect_count = 0;
-
-              /* For each section (ie for each psect).  */
-              for (o = sub->sections; o != NULL; o = o->next)
-                {
-                  /* Only consider interesting sections.  */
-                  if (!(o->flags & SEC_ALLOC))
-                    continue;
-                  if (o->flags & SEC_LINKER_CREATED)
-                    continue;
-
-                  if (pass == 1)
-                    {
-                      /* Write an entry.  */
-                      struct vms_dmt_psect *dmtp;
-
-                      dmtp = (struct vms_dmt_psect *)(contents + off);
-                      bfd_putl32 (o->output_offset + o->output_section->vma,
-                                  dmtp->start);
-                      bfd_putl32 (o->size, dmtp->length);
-                      psect_count++;
-                    }
-                  off += sizeof (struct vms_dmt_psect);
-                }
-              if (pass == 1)
-                bfd_putl32 (psect_count, dmth->psect_count);
-            }
-
-          if (pass == 0)
-            {
-              contents = bfd_zalloc (info->output_bfd, off);
-              if (contents == NULL)
-                return FALSE;
-              dmt->contents = contents;
-              dmt->size = off;
-            }
-          else
-            {
-              BFD_ASSERT (off == dmt->size);
-            }
-        }
+       {
+         unsigned int off = 0;
+
+         /* For each object file (ie for each module).  */
+         for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+           {
+             asection *sub_dst;
+             struct vms_dmt_header *dmth = NULL;
+             unsigned int psect_count;
+
+             /* Skip this module if it has no DST.  */
+             sub_dst = PRIV2 (sub, dst_section);
+             if (sub_dst == NULL || sub_dst->size == 0)
+               continue;
+
+             if (pass == 1)
+               {
+                 /* Write the header.  */
+                 dmth = (struct vms_dmt_header *)(contents + off);
+                 bfd_putl32 (sub_dst->output_offset, dmth->modbeg);
+                 bfd_putl32 (sub_dst->size, dmth->size);
+               }
+
+             off += sizeof (struct vms_dmt_header);
+             psect_count = 0;
+
+             /* For each section (ie for each psect).  */
+             for (o = sub->sections; o != NULL; o = o->next)
+               {
+                 /* Only consider interesting sections.  */
+                 if (!(o->flags & SEC_ALLOC))
+                   continue;
+                 if (o->flags & SEC_LINKER_CREATED)
+                   continue;
+
+                 if (pass == 1)
+                   {
+                     /* Write an entry.  */
+                     struct vms_dmt_psect *dmtp;
+
+                     dmtp = (struct vms_dmt_psect *)(contents + off);
+                     bfd_putl32 (o->output_offset + o->output_section->vma,
+                                 dmtp->start);
+                     bfd_putl32 (o->size, dmtp->length);
+                     psect_count++;
+                   }
+                 off += sizeof (struct vms_dmt_psect);
+               }
+             if (pass == 1)
+               bfd_putl32 (psect_count, dmth->psect_count);
+           }
+
+         if (pass == 0)
+           {
+             contents = bfd_zalloc (info->output_bfd, off);
+             if (contents == NULL)
+               return FALSE;
+             dmt->contents = contents;
+             dmt->size = off;
+           }
+         else
+           {
+             BFD_ASSERT (off == dmt->size);
+           }
+       }
     }
 
   return TRUE;
@@ -8681,15 +9375,15 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
 
 static bfd_boolean
 alpha_vms_get_section_contents (bfd *abfd, asection *section,
-                                void *buf, file_ptr offset,
-                                bfd_size_type count)
+                               void *buf, file_ptr offset,
+                               bfd_size_type count)
 {
   asection *sec;
 
   /* Image are easy.  */
   if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
     return _bfd_generic_get_section_contents (abfd, section,
-                                              buf, offset, count);
+                                             buf, offset, count);
 
   /* Safety check.  */
   if (offset + count < count
@@ -8699,25 +9393,33 @@ alpha_vms_get_section_contents (bfd *abfd, asection *section,
       return FALSE;
     }
 
-  /* Alloc in memory and read ETIRs.  */
-  BFD_ASSERT (section->contents == NULL);
+  /* If the section is already in memory, just copy it.  */
+  if (section->flags & SEC_IN_MEMORY)
+    {
+      BFD_ASSERT (section->contents != NULL);
+      memcpy (buf, section->contents + offset, count);
+      return TRUE;
+    }
+  if (section->size == 0)
+    return TRUE;
 
+  /* Alloc in memory and read ETIRs.  */
   for (sec = abfd->sections; sec; sec = sec->next)
     {
       BFD_ASSERT (sec->contents == NULL);
 
       if (sec->size != 0 && (sec->flags & SEC_HAS_CONTENTS))
-        {
-          sec->contents = bfd_alloc (abfd, sec->size);
-          if (sec->contents == NULL)
-            return FALSE;
-        }
+       {
+         sec->contents = bfd_alloc (abfd, sec->size);
+         if (sec->contents == NULL)
+           return FALSE;
+       }
     }
   if (!alpha_vms_read_sections_content (abfd, NULL))
     return FALSE;
   for (sec = abfd->sections; sec; sec = sec->next)
-    if (section->contents)
-      section->flags |= SEC_IN_MEMORY;
+    if (sec->contents)
+      sec->flags |= SEC_IN_MEMORY;
   memcpy (buf, section->contents + offset, count);
   return TRUE;
 }
@@ -8764,35 +9466,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) != TRUE)
-       return FALSE;
-      if (vms_convert_to_var_unix_filename (abfd->filename) != TRUE)
-       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.  */
@@ -8800,40 +9491,21 @@ vms_close_and_cleanup (bfd * abfd)
 static bfd_boolean
 vms_new_section_hook (bfd * abfd, asection *section)
 {
-  bfd_size_type amt;
-
-  /* Count hasn't been incremented yet.  */
-  unsigned int section_count = abfd->section_count + 1;
-
-  vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
-               abfd, section->index, section->name, section_count));
-
-  bfd_set_section_alignment (abfd, section, 0);
+  size_t amt;
 
-  if (section_count > PRIV (section_count))
-    {
-      amt = section_count;
-      amt *= sizeof (asection *);
-      PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
-      if (PRIV (sections) == NULL)
-       return FALSE;
-      PRIV (section_count) = section_count;
-    }
-
-  vms_debug2 ((6, "section_count: %d\n", PRIV (section_count)));
+  vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n",
+              abfd, section->index, section->name));
 
-  PRIV (sections)[section->index] = section;
+  if (!bfd_set_section_alignment (section, 0))
+    return FALSE;
 
-  vms_debug2 ((7, "%d: %s\n", section->index, section->name));
+  vms_debug2 ((7, "%u: %s\n", section->index, section->name));
 
   amt = sizeof (struct vms_section_data_struct);
-  section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+  section->used_by_bfd = bfd_zalloc (abfd, amt);
   if (section->used_by_bfd == NULL)
     return FALSE;
 
-  if (strcmp (bfd_get_section_name (abfd, section), "$DST$") == 0)
-    PRIV (dst_section) = section;
-
   /* Create the section symbol.  */
   return _bfd_generic_new_section_hook (abfd, section);
 }
@@ -8852,7 +9524,7 @@ vms_print_symbol (bfd * abfd,
                  bfd_print_symbol_type how)
 {
   vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n",
-               abfd, file, symbol, how));
+              abfd, file, symbol, how));
 
   switch (how)
     {
@@ -8868,7 +9540,7 @@ vms_print_symbol (bfd * abfd,
          bfd_print_symbol_vandf (abfd, file, symbol);
 
          fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
-        }
+       }
       break;
     }
 }
@@ -8901,7 +9573,7 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
   if (ret == NULL)
     return;
 
-  if (sec == 0)
+  if (sec == NULL)
     ret->type = 'U';
   else if (bfd_is_com_section (sec))
     ret->type = 'C';
@@ -8911,14 +9583,15 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
     ret->type = 'U';
   else if (bfd_is_ind_section (sec))
     ret->type = 'I';
-  else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
+  else if ((symbol->flags & BSF_FUNCTION)
+          || (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 = '-';
+    ret->type = '?';
 
   if (ret->type != 'U')
     ret->value = symbol->value + symbol->section->vma;
@@ -8934,7 +9607,6 @@ static bfd_boolean
 vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
                             const char *name)
 {
-  vms_debug2 ((1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name));
   return name[0] == '$';
 }
 \f
@@ -8951,16 +9623,16 @@ vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
 
 static bfd_boolean
 _bfd_vms_set_section_contents (bfd * abfd,
-                               asection *section,
-                               const void * location,
-                               file_ptr offset,
-                               bfd_size_type count)
+                              asection *section,
+                              const void * location,
+                              file_ptr offset,
+                              bfd_size_type count)
 {
   if (section->contents == NULL)
     {
       section->contents = bfd_alloc (abfd, section->size);
       if (section->contents == NULL)
-        return FALSE;
+       return FALSE;
 
       memcpy (section->contents + offset, location, (size_t) count);
     }
@@ -8974,7 +9646,7 @@ _bfd_vms_set_section_contents (bfd * abfd,
 
 static bfd_boolean
 alpha_vms_set_arch_mach (bfd *abfd,
-                         enum bfd_architecture arch, unsigned long mach)
+                        enum bfd_architecture arch, unsigned long mach)
 {
   if (arch != bfd_arch_alpha
       && arch != bfd_arch_unknown)
@@ -8999,35 +9671,41 @@ bfd_vms_get_data (bfd *abfd)
   return (struct vms_private_data_struct *)abfd->tdata.any;
 }
 
-#define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
-#define vms_bfd_link_just_syms            _bfd_generic_link_just_syms
+#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_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_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_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_set_private_flags         _bfd_generic_bfd_set_private_flags
-#define vms_bfd_merge_private_bfd_data    _bfd_generic_bfd_merge_private_bfd_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
-#define alpha_vms_bfd_is_target_special_symbol \
-   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
-#define alpha_vms_print_symbol             vms_print_symbol
-#define alpha_vms_get_symbol_info          vms_get_symbol_info
-#define alpha_vms_read_minisymbols         _bfd_generic_read_minisymbols
-#define alpha_vms_minisymbol_to_symbol     _bfd_generic_minisymbol_to_symbol
-#define alpha_vms_get_lineno               _bfd_nosymbols_get_lineno
-#define alpha_vms_find_inliner_info        _bfd_nosymbols_find_inliner_info
-#define alpha_vms_bfd_make_debug_symbol    _bfd_nosymbols_bfd_make_debug_symbol
-#define alpha_vms_find_nearest_line        _bfd_vms_find_nearest_dst_line
+#define alpha_vms_make_empty_symbol       _bfd_generic_make_empty_symbol
+#define alpha_vms_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
+#define alpha_vms_print_symbol            vms_print_symbol
+#define alpha_vms_get_symbol_info         vms_get_symbol_info
+#define alpha_vms_get_symbol_version_string \
+  _bfd_nosymbols_get_symbol_version_string
+
+#define alpha_vms_read_minisymbols        _bfd_generic_read_minisymbols
+#define alpha_vms_minisymbol_to_symbol    _bfd_generic_minisymbol_to_symbol
+#define alpha_vms_get_lineno              _bfd_nosymbols_get_lineno
+#define alpha_vms_find_inliner_info       _bfd_nosymbols_find_inliner_info
+#define alpha_vms_bfd_make_debug_symbol           _bfd_nosymbols_bfd_make_debug_symbol
+#define alpha_vms_find_nearest_line       _bfd_vms_find_nearest_line
+#define alpha_vms_find_line               _bfd_nosymbols_find_line
 #define alpha_vms_bfd_is_local_label_name  vms_bfd_is_local_label_name
 
 /* Generic table.  */
@@ -9042,14 +9720,17 @@ bfd_vms_get_data (bfd *abfd)
 
 #define alpha_vms_bfd_relax_section bfd_generic_relax_section
 #define alpha_vms_bfd_gc_sections bfd_generic_gc_sections
+#define alpha_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags
 #define alpha_vms_bfd_merge_sections bfd_generic_merge_sections
 #define alpha_vms_bfd_is_group_section bfd_generic_is_group_section
+#define alpha_vms_bfd_group_name bfd_generic_group_name
 #define alpha_vms_bfd_discard_group bfd_generic_discard_group
 #define alpha_vms_section_already_linked \
   _bfd_generic_section_already_linked
 
 #define alpha_vms_bfd_define_common_symbol bfd_generic_define_common_symbol
-#define alpha_vms_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
+#define alpha_vms_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
+#define alpha_vms_bfd_define_start_stop bfd_generic_define_start_stop
 #define alpha_vms_bfd_link_just_syms _bfd_generic_link_just_syms
 #define alpha_vms_bfd_copy_link_hash_symbol_type \
   _bfd_generic_copy_link_hash_symbol_type
@@ -9064,8 +9745,9 @@ bfd_vms_get_data (bfd *abfd)
   _bfd_nodynamic_get_dynamic_reloc_upper_bound
 #define alpha_vms_canonicalize_dynamic_reloc \
   _bfd_nodynamic_canonicalize_dynamic_reloc
+#define alpha_vms_bfd_link_check_relocs                     _bfd_generic_link_check_relocs
 
-const bfd_target vms_alpha_vec =
+const bfd_target alpha_vms_vec =
 {
   "vms-alpha",                 /* Name.  */
   bfd_target_evax_flavour,
@@ -9080,6 +9762,7 @@ const bfd_target vms_alpha_vec =
   0,                           /* symbol_leading_char.  */
   ' ',                         /* ar_pad_char.  */
   15,                          /* ar_max_namelen.  */
+  0,                           /* match priority.  */
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
@@ -9087,12 +9770,24 @@ const bfd_target vms_alpha_vec =
   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
 
-  {_bfd_dummy_target, alpha_vms_object_p,      /* bfd_check_format.  */
-   _bfd_vms_lib_alpha_archive_p, _bfd_dummy_target},
-  {bfd_false, alpha_vms_mkobject,              /* bfd_set_format.  */
-   _bfd_vms_lib_mkarchive, bfd_false},
-  {bfd_false, alpha_vms_write_object_contents, /* bfd_write_contents.  */
-   _bfd_vms_lib_write_archive_contents, bfd_false},
+  {                            /* bfd_check_format.  */
+    _bfd_dummy_target,
+    alpha_vms_object_p,
+    _bfd_vms_lib_alpha_archive_p,
+    _bfd_dummy_target
+  },
+  {                            /* bfd_set_format.  */
+    _bfd_bool_bfd_false_error,
+    alpha_vms_mkobject,
+    _bfd_vms_lib_alpha_mkarchive,
+    _bfd_bool_bfd_false_error
+  },
+  {                            /* bfd_write_contents.  */
+    _bfd_bool_bfd_false_error,
+    alpha_vms_write_object_contents,
+    _bfd_vms_lib_write_archive_contents,
+    _bfd_bool_bfd_false_error
+  },
 
   BFD_JUMP_TABLE_GENERIC (alpha_vms),
   BFD_JUMP_TABLE_COPY (vms),
@@ -9106,5 +9801,5 @@ const bfd_target vms_alpha_vec =
 
   NULL,
 
-  (PTR) 0
+  NULL
 };
This page took 0.167247 seconds and 4 git commands to generate.