* elflink.c (_bfd_elf_merge_symbol): Revert previous patch.
[deliverable/binutils-gdb.git] / bfd / vms-tir.c
index aa3e536044254b70fc8a23af6d03399d4d957a1b..5bc61da87aa748f6d79b0d23c425129502518c14 100644 (file)
@@ -1,19 +1,19 @@
 /* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
    EVAX (openVMS/Alpha) files.
 /* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
    EVAX (openVMS/Alpha) files.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
-   Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007,
+   2008, 2009 Free Software Foundation, Inc.
 
    TIR record handling functions
    ETIR record handling functions
 
 
    TIR record handling functions
    ETIR record handling functions
 
-   go and read the openVMS linker manual (esp. appendix B)
+   Go and read the openVMS linker manual (esp. appendix B)
    if you don't know what's going on here :-)
 
    Written by Klaus K"ampf (kkaempf@rmi.de)
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    if you don't know what's going on here :-)
 
    Written by Klaus K"ampf (kkaempf@rmi.de)
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -23,7 +23,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 /* The following type abbreviations are used:
 
 
 /* The following type abbreviations are used:
 
        qw      quadword (8 byte, 64 bit)
        da      data stream  */
 
        qw      quadword (8 byte, 64 bit)
        da      data stream  */
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
-
 #include "vms.h"
 
 #include "vms.h"
 
-static void image_set_ptr
-  PARAMS ((bfd *abfd, int psect, uquad offset));
-static void image_inc_ptr
-  PARAMS ((bfd *abfd, uquad offset));
-static void image_dump
-  PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));
-static void image_write_b
-  PARAMS ((bfd *abfd, unsigned int value));
-static void image_write_w
-  PARAMS ((bfd *abfd, unsigned int value));
-static void image_write_l
-  PARAMS ((bfd *abfd, unsigned long value));
-static void image_write_q
-  PARAMS ((bfd *abfd, uquad value));
-static int check_section
-  PARAMS ((bfd *, int));
-static bfd_boolean etir_sta
-  PARAMS ((bfd *, int, unsigned char *));
-static bfd_boolean etir_sto
-  PARAMS ((bfd *, int, unsigned char *));
-static bfd_boolean etir_opr
-  PARAMS ((bfd *, int, unsigned char *));
-static bfd_boolean etir_ctl
-  PARAMS ((bfd *, int, unsigned char *));
-static bfd_boolean etir_stc
-  PARAMS ((bfd *, int, unsigned char *));
-static asection *new_section
-  PARAMS ((bfd *, int));
-static int alloc_section
-  PARAMS ((bfd *, unsigned int));
-static int etir_cmd
-  PARAMS ((bfd *, int, unsigned char *));
-static int analyze_tir
-  PARAMS ((bfd *, unsigned char *, unsigned int));
-static int analyze_etir
-  PARAMS ((bfd *, unsigned char *, unsigned int));
-static unsigned char * tir_opr
-  PARAMS ((bfd *, unsigned char *));
-static const char * tir_cmd_name
-  PARAMS ((int));
-static const char * cmd_name
-  PARAMS ((int));
+static int check_section (bfd *, int);
+static void image_set_ptr (bfd *abfd, int psect, uquad offset);
+static void image_inc_ptr (bfd *abfd, uquad offset);
+static void dst_define_location (bfd *abfd, uquad loc);
+static void dst_restore_location (bfd *abfd, uquad loc);
+static unsigned int dst_retrieve_location (bfd *abfd, uquad loc);
+static void dst_check_allocation (bfd *abfd, unsigned int size);
+static void image_dump (bfd *abfd, unsigned char *ptr, int size, int offset);
+static void image_write_b (bfd *abfd, unsigned int value);
+static void image_write_w (bfd *abfd, unsigned int value);
+static void image_write_l (bfd *abfd, unsigned long value);
+static void image_write_q (bfd *abfd, uquad value);
+static bfd_boolean etir_sta (bfd *, int, unsigned char *, int *);
+static bfd_boolean etir_sto (bfd *, int, unsigned char *, int *);
+static bfd_boolean etir_opr (bfd *, int, unsigned char *, int *);
+static bfd_boolean etir_ctl (bfd *, int, unsigned char *, int *);
+static bfd_boolean etir_stc (bfd *, int, unsigned char *, int *);
+static asection *new_section (bfd *, int);
+static int alloc_section (bfd *, unsigned int);
+static int etir_cmd (bfd *, int, unsigned char *, int *);
+static int analyze_tir (bfd *, unsigned char *, unsigned int);
+static int analyze_etir (bfd *, unsigned char *, unsigned int);
+static unsigned char *tir_opr (bfd *, unsigned char *);
+static const char *tir_cmd_name (int);
+static const char *cmd_name (int);
 
 \f
 static int
 
 \f
 static int
-check_section (abfd, size)
-     bfd *abfd;
-     int size;
+check_section (bfd * abfd, int size)
 {
   bfd_size_type offset;
 
 {
   bfd_size_type offset;
 
@@ -96,8 +77,8 @@ check_section (abfd, size)
   if (offset + size > PRIV (image_section)->size)
     {
       PRIV (image_section)->contents
   if (offset + size > PRIV (image_section)->size)
     {
       PRIV (image_section)->contents
-       = bfd_realloc (PRIV (image_section)->contents, offset + size);
-      if (PRIV (image_section)->contents == 0)
+       = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size);
+      if (PRIV (image_section)->contents == NULL)
        {
          (*_bfd_error_handler) (_("No Mem !"));
          return -1;
        {
          (*_bfd_error_handler) (_("No Mem !"));
          return -1;
@@ -114,10 +95,7 @@ check_section (abfd, size)
 /* Initialize image buffer pointer to be filled.  */
 
 static void
 /* Initialize image buffer pointer to be filled.  */
 
 static void
-image_set_ptr (abfd, psect, offset)
-     bfd *abfd;
-     int psect;
-     uquad offset;
+image_set_ptr (bfd * abfd, int psect, uquad offset)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
 {
 #if VMS_DEBUG
   _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
@@ -126,33 +104,98 @@ image_set_ptr (abfd, psect, offset)
 
   PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
   PRIV (image_section) = PRIV (sections)[psect];
 
   PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
   PRIV (image_section) = PRIV (sections)[psect];
-  return;
 }
 
 /* Increment image buffer pointer by offset.  */
 
 static void
 }
 
 /* Increment image buffer pointer by offset.  */
 
 static void
-image_inc_ptr (abfd, offset)
-     bfd *abfd;
-     uquad offset;
+image_inc_ptr (bfd * abfd, uquad offset)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
 #endif
 
   PRIV (image_ptr) += offset;
 {
 #if VMS_DEBUG
   _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
 #endif
 
   PRIV (image_ptr) += offset;
+}
+
+/* Save current DST location counter under specified index.  */
+
+static void
+dst_define_location (bfd *abfd, uquad loc)
+{
+  asection *dst_section = PRIV (dst_section);
+
+#if VMS_DEBUG
+  _bfd_vms_debug (4, "dst_define_location (%d)\n", (int)loc);
+#endif
+
+  /* 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_count) = loc + 1;
+    }
+
+  PRIV (dst_ptr_offsets)[loc] = PRIV (image_ptr) - dst_section->contents;
+}
+
+/* Restore saved DST location counter from specified index.  */
+
+static void
+dst_restore_location (bfd *abfd, uquad loc)
+{
+  asection *dst_section = PRIV (dst_section);
+
+#if VMS_DEBUG
+  _bfd_vms_debug (4, "dst_restore_location (%d)\n", (int)loc);
+#endif
+
+  PRIV (image_ptr) = dst_section->contents + PRIV (dst_ptr_offsets)[loc];
+}
+
+/* Retrieve saved DST location counter from specified index.  */
+
+static unsigned int
+dst_retrieve_location (bfd *abfd, uquad loc)
+{
+#if VMS_DEBUG
+  _bfd_vms_debug (4, "dst_retrieve_location (%d)\n", (int)loc);
+#endif
 
 
-  return;
+  return PRIV (dst_ptr_offsets)[loc];
+}
+
+/* Check that the DST section is big enough for the specified
+   amount of bytes.  */
+
+static void
+dst_check_allocation (bfd *abfd, unsigned int size)
+{
+  asection *dst_section = PRIV (dst_section);
+
+  bfd_size_type used = PRIV (image_ptr) - dst_section->contents;
+  bfd_size_type left = dst_section->size - used;
+
+  /* Grow the DST section as necessary */
+  if (size > left)
+    {
+      dst_section->size *= 2;
+      dst_section->contents
+       = bfd_realloc (dst_section->contents, dst_section->size);
+      PRIV (image_ptr) = dst_section->contents + used;
+
+      dst_check_allocation (abfd, size);
+    }
 }
 
 /* Dump multiple bytes to section image.  */
 
 static void
 }
 
 /* Dump multiple bytes to section image.  */
 
 static void
-image_dump (abfd, ptr, size, offset)
-    bfd *abfd;
-    unsigned char *ptr;
-    int size;
-    int offset ATTRIBUTE_UNUSED;
+image_dump (bfd * abfd,
+           unsigned char *ptr,
+           int size,
+           int offset ATTRIBUTE_UNUSED)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
 {
 #if VMS_DEBUG
   _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
@@ -163,55 +206,54 @@ image_dump (abfd, ptr, size, offset)
   if (PRIV (is_vax) && check_section (abfd, size))
     return;
 
   if (PRIV (is_vax) && check_section (abfd, size))
     return;
 
+  if (PRIV (dst_section))
+    dst_check_allocation (abfd, size);
+
   while (size-- > 0)
     *PRIV (image_ptr)++ = *ptr++;
   while (size-- > 0)
     *PRIV (image_ptr)++ = *ptr++;
-  return;
 }
 
 /* Write byte to section image.  */
 
 static void
 }
 
 /* Write byte to section image.  */
 
 static void
-image_write_b (abfd, value)
-     bfd *abfd;
-     unsigned int value;
+image_write_b (bfd * abfd, unsigned int value)
 {
 #if VMS_DEBUG
 {
 #if VMS_DEBUG
-  _bfd_vms_debug (6, "image_write_b(%02x)\n", (int) value);
+  _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
 #endif
 
   if (PRIV (is_vax) && check_section (abfd, 1))
     return;
 
 #endif
 
   if (PRIV (is_vax) && check_section (abfd, 1))
     return;
 
+  if (PRIV (dst_section))
+    dst_check_allocation (abfd, 1);
+
   *PRIV (image_ptr)++ = (value & 0xff);
   *PRIV (image_ptr)++ = (value & 0xff);
-  return;
 }
 
 /* Write 2-byte word to image.  */
 
 static void
 }
 
 /* Write 2-byte word to image.  */
 
 static void
-image_write_w (abfd, value)
-     bfd *abfd;
-     unsigned int value;
+image_write_w (bfd * abfd, unsigned int value)
 {
 #if VMS_DEBUG
 {
 #if VMS_DEBUG
-  _bfd_vms_debug (6, "image_write_w(%04x)\n", (int) value);
+  _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
 #endif
 
   if (PRIV (is_vax) && check_section (abfd, 2))
     return;
 
 #endif
 
   if (PRIV (is_vax) && check_section (abfd, 2))
     return;
 
+  if (PRIV (dst_section))
+    dst_check_allocation (abfd, 2);
+
   bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
   PRIV (image_ptr) += 2;
   bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
   PRIV (image_ptr) += 2;
-
-  return;
 }
 
 /* Write 4-byte long to image.  */
 
 static void
 }
 
 /* Write 4-byte long to image.  */
 
 static void
-image_write_l (abfd, value)
-     bfd *abfd;
-     unsigned long value;
+image_write_l (bfd * abfd, unsigned long value)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
 {
 #if VMS_DEBUG
   _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
@@ -220,18 +262,17 @@ image_write_l (abfd, value)
   if (PRIV (is_vax) && check_section (abfd, 4))
     return;
 
   if (PRIV (is_vax) && check_section (abfd, 4))
     return;
 
+  if (PRIV (dst_section))
+    dst_check_allocation (abfd, 4);
+
   bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
   PRIV (image_ptr) += 4;
   bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
   PRIV (image_ptr) += 4;
-
-  return;
 }
 
 /* Write 8-byte quad to image.  */
 
 static void
 }
 
 /* Write 8-byte quad to image.  */
 
 static void
-image_write_q (abfd, value)
-     bfd *abfd;
-     uquad value;
+image_write_q (bfd * abfd, uquad value)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
 {
 #if VMS_DEBUG
   _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
@@ -240,19 +281,21 @@ image_write_q (abfd, value)
   if (PRIV (is_vax) && check_section (abfd, 8))
     return;
 
   if (PRIV (is_vax) && check_section (abfd, 8))
     return;
 
+  if (PRIV (dst_section))
+    dst_check_allocation (abfd, 8);
+
   bfd_putl64 (value, PRIV (image_ptr));
   PRIV (image_ptr) += 8;
   bfd_putl64 (value, PRIV (image_ptr));
   PRIV (image_ptr) += 8;
-
-  return;
 }
 \f
 static const char *
 }
 \f
 static const char *
-cmd_name (cmd)
-     int cmd;
+cmd_name (int cmd)
 {
   switch (cmd)
     {
     case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
 {
   switch (cmd)
     {
     case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
+    case ETIR_S_C_STA_LW: return "ETIR_S_C_STA_LW";
+    case ETIR_S_C_STA_QW: return "ETIR_S_C_STA_QW";
     case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ";
     case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
     case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD";
     case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ";
     case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
     case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD";
@@ -263,10 +306,16 @@ cmd_name (cmd)
     case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
     case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB";
     case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
     case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
     case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB";
     case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
+    case ETIR_S_C_STO_OFF: return "ETIR_S_C_STO_OFF";
+    case ETIR_S_C_STO_IMM: return "ETIR_S_C_STO_IMM";
+    case ETIR_S_C_STO_IMMR: return "ETIR_S_C_STO_IMMR";
+    case ETIR_S_C_STO_LW: return "ETIR_S_C_STO_LW";
+    case ETIR_S_C_STO_QW: return "ETIR_S_C_STO_QW";
     case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW";
     case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB";
     case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL";
     case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
     case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW";
     case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB";
     case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL";
     case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
+    case ETIR_S_C_OPR_ADD: return "ETIR_S_C_OPR_ADD";
     case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV";
     case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
     case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT";
     case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV";
     case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
     case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT";
@@ -286,44 +335,44 @@ cmd_name (cmd)
     case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
     case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
     case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
     case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
     case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
     case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
+    case ETIR_S_C_CTL_SETRB: return "ETIR_S_C_CTL_SETRB";
+    case ETIR_S_C_STC_LP_PSB: return "ETIR_S_C_STC_LP_PSB";
+    case ETIR_S_C_CTL_DFLOC: return "ETIR_S_C_CTL_DFLOC";
+    case ETIR_S_C_CTL_STLOC: return "ETIR_S_C_CTL_STLOC";
+    case ETIR_S_C_CTL_STKDL: return "ETIR_S_C_CTL_STKDL";
 
     default:
       /* These names have not yet been added to this switch statement.  */
 
     default:
       /* These names have not yet been added to this switch statement.  */
-      abort ();
+      (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
     }
     }
+
+  return NULL;
 }
 #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
 
 /* etir_sta
 
 }
 #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
 
 /* etir_sta
 
-   vms stack commands
+   Vms stack commands.
 
 
-   handle sta_xxx commands in etir section
-   ptr points to data area in record
+   Handle sta_xxx commands in etir section,
+   ptr points to data area in record.
 
 
-   see table B-8 of the openVMS linker manual.  */
+   See table B-8 of the openVMS linker manual.  */
 
 static bfd_boolean
 
 static bfd_boolean
-etir_sta (abfd, cmd, ptr)
-     bfd *abfd;
-     int cmd;
-     unsigned char *ptr;
+etir_sta (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
 {
 {
-
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
   switch (cmd)
     {
 #endif
 
   switch (cmd)
     {
-      /* stack */
-
-      /* stack global
+      /* Stack global
         arg: cs        symbol name
 
         arg: cs        symbol name
 
-        stack 32 bit value of symbol (high bits set to 0)  */
-
+        stack 32 bit value of symbol (high bits set to 0).  */
     case ETIR_S_C_STA_GBL:
       {
        char *name;
     case ETIR_S_C_STA_GBL:
       {
        char *name;
@@ -332,7 +381,7 @@ etir_sta (abfd, cmd, ptr)
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *)
          bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *)
          bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
-       if (entry == (vms_symbol_entry *) NULL)
+       if (entry == NULL)
          {
 #if VMS_DEBUG
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
          {
 #if VMS_DEBUG
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
@@ -341,75 +390,90 @@ etir_sta (abfd, cmd, ptr)
            _bfd_vms_push (abfd, (uquad) 0, -1);
          }
        else
            _bfd_vms_push (abfd, (uquad) 0, -1);
          }
        else
-         {
-           _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
-         }
+         _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
       }
       }
+      *quarter_relocs = 1;
       break;
 
       break;
 
-      /* stack longword
+      /* Stack longword
         arg: lw        value
 
         arg: lw        value
 
-        stack 32 bit value, sign extend to 64 bit  */
-
+        stack 32 bit value, sign extend to 64 bit.  */
     case ETIR_S_C_STA_LW:
       _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
     case ETIR_S_C_STA_LW:
       _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
+      /* This one is special as it is both part of the section header
+         and of the ALPHA_R_REFLONG relocation.  */
+      if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_DFLOC)
+       *quarter_relocs = 0;
+      else if (*quarter_relocs)
+       *quarter_relocs += 1;
+      else
+       *quarter_relocs = 2;
       break;
 
       break;
 
-      /* stack global
+      /* Stack quadword
         arg: qw        value
 
         arg: qw        value
 
-        stack 64 bit value of symbol    */
-
+        stack 64 bit value of symbol.  */
     case ETIR_S_C_STA_QW:
       _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
     case ETIR_S_C_STA_QW:
       _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
+      if (*quarter_relocs)
+       *quarter_relocs += 1;
+      else
+       *quarter_relocs = 2;
       break;
 
       break;
 
-      /* stack psect base plus quadword offset
+      /* Stack psect base plus quadword offset
         arg: lw        section index
         qw     signed quadword offset (low 32 bits)
 
         arg: lw        section index
         qw     signed quadword offset (low 32 bits)
 
-        stack qw argument and section index
-        (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB)  */
-
+        Stack qw argument and section index
+        (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB).  */
     case ETIR_S_C_STA_PQ:
       {
        uquad dummy;
     case ETIR_S_C_STA_PQ:
       {
        uquad dummy;
-       unsigned int psect;
+       int psect;
 
        psect = bfd_getl32 (ptr);
 
        psect = bfd_getl32 (ptr);
-       if (psect >= PRIV (section_count))
+       if ((unsigned int) psect >= PRIV (section_count))
          {
            (*_bfd_error_handler) (_("bad section index in %s"),
                                   cmd_name (cmd));
            bfd_set_error (bfd_error_bad_value);
            return FALSE;
          }
          {
            (*_bfd_error_handler) (_("bad section index in %s"),
                                   cmd_name (cmd));
            bfd_set_error (bfd_error_bad_value);
            return FALSE;
          }
-       dummy = bfd_getl64 (ptr+4);
+       dummy = bfd_getl64 (ptr + 4);
        _bfd_vms_push (abfd, dummy, (int) psect);
       }
        _bfd_vms_push (abfd, dummy, (int) psect);
       }
+      /* This one is special as it is both part of the section header
+         and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations.  */
+      if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_SETRB)
+       *quarter_relocs = 0;
+      else
+       *quarter_relocs = 2;
       break;
 
     case ETIR_S_C_STA_LI:
     case ETIR_S_C_STA_MOD:
     case ETIR_S_C_STA_CKARG:
       (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
       break;
 
     case ETIR_S_C_STA_LI:
     case ETIR_S_C_STA_MOD:
     case ETIR_S_C_STA_CKARG:
       (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
+      *quarter_relocs = 0;
       return FALSE;
       return FALSE;
-      break;
 
     default:
       (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
 
     default:
       (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
+      *quarter_relocs = 0;
       return FALSE;
       return FALSE;
-      break;
     }
     }
+
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_sta true\n");
 #endif
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_sta true\n");
 #endif
+
   return TRUE;
 }
 
   return TRUE;
 }
 
-/*
-   etir_sto
+/* etir_sto
 
    vms store commands
 
 
    vms store commands
 
@@ -419,72 +483,65 @@ etir_sta (abfd, cmd, ptr)
    see table B-9 of the openVMS linker manual.  */
 
 static bfd_boolean
    see table B-9 of the openVMS linker manual.  */
 
 static bfd_boolean
-etir_sto (abfd, cmd, ptr)
-     bfd *abfd;
-     int cmd;
-     unsigned char *ptr;
+etir_sto (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
 {
   uquad dummy;
   int psect;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
 {
   uquad dummy;
   int psect;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
   switch (cmd)
     {
 #endif
 
   switch (cmd)
     {
-      /* store byte: pop stack, write byte
-        arg: -  */
-
+      /* Store byte: pop stack, write byte
+        arg: -.  */
     case ETIR_S_C_STO_B:
       dummy = _bfd_vms_pop (abfd, &psect);
     case ETIR_S_C_STO_B:
       dummy = _bfd_vms_pop (abfd, &psect);
-#if 0
-      if (is_share)            /* FIXME */
-       (*_bfd_error_handler) ("%s: byte fixups not supported",
-                              cmd_name (cmd));
-#endif
-      /* FIXME: check top bits */
+      /* FIXME: check top bits.  */
       image_write_b (abfd, (unsigned int) dummy & 0xff);
       image_write_b (abfd, (unsigned int) dummy & 0xff);
+      *quarter_relocs = 0;
       break;
 
       break;
 
-      /* store word: pop stack, write word
-        arg: -  */
-
+      /* Store word: pop stack, write word
+        arg: -.  */
     case ETIR_S_C_STO_W:
       dummy = _bfd_vms_pop (abfd, &psect);
     case ETIR_S_C_STO_W:
       dummy = _bfd_vms_pop (abfd, &psect);
-#if 0
-      if (is_share)            /* FIXME */
-       (*_bfd_error_handler) ("%s: word fixups not supported",
-                              cmd_name (cmd));
-#endif
       /* FIXME: check top bits */
       image_write_w (abfd, (unsigned int) dummy & 0xffff);
       /* FIXME: check top bits */
       image_write_w (abfd, (unsigned int) dummy & 0xffff);
+      *quarter_relocs = 0;
       break;
 
       break;
 
-      /* store longword: pop stack, write longword
-        arg: -  */
-
+      /* Store longword: pop stack, write longword
+        arg: -.  */
     case ETIR_S_C_STO_LW:
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy += (PRIV (sections)[psect])->vma;
       /* FIXME: check top bits.  */
       image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
     case ETIR_S_C_STO_LW:
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy += (PRIV (sections)[psect])->vma;
       /* FIXME: check top bits.  */
       image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
+      if (*quarter_relocs == 2)
+       *quarter_relocs = 4;
+      else
+       *quarter_relocs += 1;
       break;
 
       break;
 
-      /* store quadword: pop stack, write quadword
-        arg: -  */
-
+      /* Store quadword: pop stack, write quadword
+        arg: -.  */
     case ETIR_S_C_STO_QW:
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy += (PRIV (sections)[psect])->vma;
     case ETIR_S_C_STO_QW:
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy += (PRIV (sections)[psect])->vma;
-      image_write_q (abfd, dummy);             /* FIXME: check top bits */
+      /* FIXME: check top bits.  */
+      image_write_q (abfd, dummy);
+      if (*quarter_relocs == 2)
+       *quarter_relocs = 4;
+      else
+       *quarter_relocs += 1;
       break;
 
       break;
 
-      /* store immediate repeated: pop stack for repeat count
+      /* Store immediate repeated: pop stack for repeat count
         arg: lw        byte count
         arg: lw        byte count
-        da     data  */
-
+        da     data.  */
     case ETIR_S_C_STO_IMMR:
       {
        int size;
     case ETIR_S_C_STO_IMMR:
       {
        int size;
@@ -494,11 +551,11 @@ etir_sto (abfd, cmd, ptr)
        while (dummy-- > 0)
          image_dump (abfd, ptr+4, size, 0);
       }
        while (dummy-- > 0)
          image_dump (abfd, ptr+4, size, 0);
       }
+      *quarter_relocs = 0;
       break;
 
       break;
 
-      /* store global: write symbol value
+      /* Store global: write symbol value
         arg: cs        global symbol name.  */
         arg: cs        global symbol name.  */
-
     case ETIR_S_C_STO_GBL:
       {
        vms_symbol_entry *entry;
     case ETIR_S_C_STO_GBL:
       {
        vms_symbol_entry *entry;
@@ -507,21 +564,18 @@ etir_sto (abfd, cmd, ptr)
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
-       if (entry == (vms_symbol_entry *) NULL)
-         {
-           (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
-                                  cmd_name (cmd), name);
-           return FALSE;
-         }
+       if (entry == NULL)
+         /* FIXME, reloc.  */
+         image_write_q (abfd, (uquad) (0));
        else
          /* FIXME, reloc.  */
          image_write_q (abfd, (uquad) (entry->symbol->value));
       }
        else
          /* FIXME, reloc.  */
          image_write_q (abfd, (uquad) (entry->symbol->value));
       }
+      *quarter_relocs = 4;
       break;
 
       break;
 
-      /* store code address: write address of entry point
+      /* Store code address: write address of entry point
         arg: cs        global symbol name (procedure).  */
         arg: cs        global symbol name (procedure).  */
-
     case ETIR_S_C_STO_CA:
       {
        vms_symbol_entry *entry;
     case ETIR_S_C_STO_CA:
       {
        vms_symbol_entry *entry;
@@ -530,35 +584,33 @@ etir_sto (abfd, cmd, ptr)
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
-       if (entry == (vms_symbol_entry *) NULL)
-         {
-           (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
-                                  cmd_name (cmd), name);
-           return FALSE;
-         }
+       if (entry == NULL)
+         /* FIXME, reloc.  */
+         image_write_q (abfd, (uquad) (0));
        else
        else
-         image_write_q (abfd, (uquad) (entry->symbol->value)); /* FIXME, reloc */
+         /* FIXME, reloc.  */
+         image_write_q (abfd, (uquad) (entry->symbol->value));
       }
       }
+      *quarter_relocs = 4;
       break;
 
       /* Store offset to psect: pop stack, add low 32 bits to base of psect
         arg: none.  */
       break;
 
       /* Store offset to psect: pop stack, add low 32 bits to base of psect
         arg: none.  */
-
     case ETIR_S_C_STO_OFF:
       {
        uquad q;
        int psect1;
 
     case ETIR_S_C_STO_OFF:
       {
        uquad q;
        int psect1;
 
-       q = _bfd_vms_pop (abfd, &psect1);
+       q = _bfd_vms_pop (abfd, & psect1);
        q += (PRIV (sections)[psect1])->vma;
        image_write_q (abfd, q);
       }
        q += (PRIV (sections)[psect1])->vma;
        image_write_q (abfd, q);
       }
+      *quarter_relocs += 2;
       break;
 
       /* Store immediate
         arg: lw        count of bytes
              da        data.  */
       break;
 
       /* Store immediate
         arg: lw        count of bytes
              da        data.  */
-
     case ETIR_S_C_STO_IMM:
       {
        int size;
     case ETIR_S_C_STO_IMM:
       {
        int size;
@@ -566,6 +618,7 @@ etir_sto (abfd, cmd, ptr)
        size = bfd_getl32 (ptr);
        image_dump (abfd, ptr+4, size, 0);
       }
        size = bfd_getl32 (ptr);
        image_dump (abfd, ptr+4, size, 0);
       }
+      *quarter_relocs = 0;
       break;
 
       /* This code is 'reserved to digital' according to the openVMS
       break;
 
       /* This code is 'reserved to digital' according to the openVMS
@@ -574,7 +627,6 @@ etir_sto (abfd, cmd, ptr)
         FIXME, since the following is just a guess
         store global longword: store 32bit value of symbol
         arg: cs        symbol name.  */
         FIXME, since the following is just a guess
         store global longword: store 32bit value of symbol
         arg: cs        symbol name.  */
-
     case ETIR_S_C_STO_GBL_LW:
       {
        vms_symbol_entry *entry;
     case ETIR_S_C_STO_GBL_LW:
       {
        vms_symbol_entry *entry;
@@ -583,7 +635,7 @@ etir_sto (abfd, cmd, ptr)
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
-       if (entry == (vms_symbol_entry *) NULL)
+       if (entry == NULL)
          {
 #if VMS_DEBUG
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
          {
 #if VMS_DEBUG
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
@@ -594,22 +646,26 @@ etir_sto (abfd, cmd, ptr)
          /* FIXME, reloc.  */
          image_write_l (abfd, (unsigned long) (entry->symbol->value));
       }
          /* FIXME, reloc.  */
          image_write_l (abfd, (unsigned long) (entry->symbol->value));
       }
+      *quarter_relocs = 4;
       break;
 
     case ETIR_S_C_STO_RB:
     case ETIR_S_C_STO_AB:
     case ETIR_S_C_STO_LP_PSB:
       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
       break;
 
     case ETIR_S_C_STO_RB:
     case ETIR_S_C_STO_AB:
     case ETIR_S_C_STO_LP_PSB:
       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
-      break;
+      *quarter_relocs = 0;
+      return FALSE;
 
     case ETIR_S_C_STO_HINT_GBL:
     case ETIR_S_C_STO_HINT_PS:
       (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
 
     case ETIR_S_C_STO_HINT_GBL:
     case ETIR_S_C_STO_HINT_PS:
       (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
-      break;
+      *quarter_relocs = 0;
+      return FALSE;
 
     default:
       (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
 
     default:
       (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
-      break;
+      *quarter_relocs = 0;
+      return FALSE;
     }
 
   return TRUE;
     }
 
   return TRUE;
@@ -623,42 +679,46 @@ etir_sto (abfd, cmd, ptr)
    see table B-10 of the openVMS linker manual.  */
 
 static bfd_boolean
    see table B-10 of the openVMS linker manual.  */
 
 static bfd_boolean
-etir_opr (abfd, cmd, ptr)
-     bfd *abfd;
-     int cmd;
-     unsigned char *ptr ATTRIBUTE_UNUSED;
+etir_opr (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
+         int *quarter_relocs)
 {
   long op1, op2;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
 {
   long op1, op2;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
 #endif
 
+  /* No relocation uses OPR commands except ETIR_S_C_OPR_ADD.  */
+  if (cmd == ETIR_S_C_OPR_ADD)
+    *quarter_relocs += 1;
+  else
+    *quarter_relocs = 0;
+
   switch (cmd)
     {
   switch (cmd)
     {
-    case ETIR_S_C_OPR_NOP:      /* no-op  */
+    case ETIR_S_C_OPR_NOP:      /* No-op.  */
       break;
 
       break;
 
-    case ETIR_S_C_OPR_ADD:      /* add  */
+    case ETIR_S_C_OPR_ADD:      /* Add.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
       break;
 
-    case ETIR_S_C_OPR_SUB:      /* subtract  */
+    case ETIR_S_C_OPR_SUB:      /* Subtract.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
       break;
 
-    case ETIR_S_C_OPR_MUL:      /* multiply  */
+    case ETIR_S_C_OPR_MUL:      /* Multiply.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
       break;
 
-    case ETIR_S_C_OPR_DIV:      /* divide  */
+    case ETIR_S_C_OPR_DIV:      /* Divide.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       if (op2 == 0)
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       if (op2 == 0)
@@ -667,54 +727,54 @@ etir_opr (abfd, cmd, ptr)
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
       break;
 
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
       break;
 
-    case ETIR_S_C_OPR_AND:      /* logical and  */
+    case ETIR_S_C_OPR_AND:      /* Logical AND.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
       break;
 
-    case ETIR_S_C_OPR_IOR:      /* logical inclusive or         */
+    case ETIR_S_C_OPR_IOR:      /* Logical inclusive OR.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
       break;
 
-    case ETIR_S_C_OPR_EOR:      /* logical exclusive or  */
+    case ETIR_S_C_OPR_EOR:      /* Logical exclusive OR.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
       break;
 
-    case ETIR_S_C_OPR_NEG:      /* negate  */
+    case ETIR_S_C_OPR_NEG:      /* Negate.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (-op1), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (-op1), -1);
       break;
 
-    case ETIR_S_C_OPR_COM:      /* complement  */
+    case ETIR_S_C_OPR_COM:      /* Complement.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
       break;
 
-    case ETIR_S_C_OPR_ASH:      /* arithmetic shift  */
+    case ETIR_S_C_OPR_ASH:      /* Arithmetic shift.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (op2 < 0)             /* shift right */
+      if (op2 < 0)             /* Shift right.  */
        op1 >>= -op2;
        op1 >>= -op2;
-      else                     /* shift left */
+      else                     /* Shift left.  */
        op1 <<= op2;
       _bfd_vms_push (abfd, (uquad) op1, -1);
       break;
 
        op1 <<= op2;
       _bfd_vms_push (abfd, (uquad) op1, -1);
       break;
 
-    case ETIR_S_C_OPR_INSV:      /* insert field  */
+    case ETIR_S_C_OPR_INSV:      /* Insert field.   */
       (void) _bfd_vms_pop (abfd, NULL);
       (void) _bfd_vms_pop (abfd, NULL);
-    case ETIR_S_C_OPR_USH:       /* unsigned shift  */
-    case ETIR_S_C_OPR_ROT:       /* rotate  */
+    case ETIR_S_C_OPR_USH:       /* Unsigned shift.   */
+    case ETIR_S_C_OPR_ROT:       /* Rotate.  */
     case ETIR_S_C_OPR_REDEF:     /* Redefine symbol to current location.  */
     case ETIR_S_C_OPR_DFLIT:     /* Define a literal.  */
       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
     case ETIR_S_C_OPR_REDEF:     /* Redefine symbol to current location.  */
     case ETIR_S_C_OPR_DFLIT:     /* Define a literal.  */
       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
-      break;
+      return FALSE;
 
 
-    case ETIR_S_C_OPR_SEL:      /* select  */
+    case ETIR_S_C_OPR_SEL:      /* Select.  */
       if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
        (void) _bfd_vms_pop (abfd, NULL);
       else
       if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
        (void) _bfd_vms_pop (abfd, NULL);
       else
@@ -727,7 +787,7 @@ etir_opr (abfd, cmd, ptr)
 
     default:
       (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
 
     default:
       (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
-      break;
+      return FALSE;
     }
 
   return TRUE;
     }
 
   return TRUE;
@@ -738,195 +798,181 @@ etir_opr (abfd, cmd, ptr)
    See table B-11 of the openVMS linker manual.  */
 
 static bfd_boolean
    See table B-11 of the openVMS linker manual.  */
 
 static bfd_boolean
-etir_ctl (abfd, cmd, ptr)
-     bfd *abfd;
-     int cmd;
-     unsigned char *ptr;
+etir_ctl (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
 {
 {
-  uquad         dummy;
+  uquad dummy;
   int psect;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
   int psect;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
 #endif
 
+  /* No relocation uses CTL commands.  */
+  *quarter_relocs = 0;
+
   switch (cmd)
     {
   switch (cmd)
     {
-      /* set relocation base: pop stack, set image location counter
+      /* Det relocation base: pop stack, set image location counter
         arg: none.  */
         arg: none.  */
-
     case ETIR_S_C_CTL_SETRB:
       dummy = _bfd_vms_pop (abfd, &psect);
       image_set_ptr (abfd, psect, dummy);
       break;
 
     case ETIR_S_C_CTL_SETRB:
       dummy = _bfd_vms_pop (abfd, &psect);
       image_set_ptr (abfd, psect, dummy);
       break;
 
-      /* augment relocation base: increment image location counter by offset
-        arg: lw        offset value  */
-
+      /* Augment relocation base: increment image location counter by offset
+        arg: lw        offset value.  */
     case ETIR_S_C_CTL_AUGRB:
       dummy = bfd_getl32 (ptr);
       image_inc_ptr (abfd, dummy);
       break;
 
     case ETIR_S_C_CTL_AUGRB:
       dummy = bfd_getl32 (ptr);
       image_inc_ptr (abfd, dummy);
       break;
 
-      /* define location: pop index, save location counter under index
+      /* Define location: pop index, save location counter under index
         arg: none.  */
         arg: none.  */
-
     case ETIR_S_C_CTL_DFLOC:
       dummy = _bfd_vms_pop (abfd, NULL);
     case ETIR_S_C_CTL_DFLOC:
       dummy = _bfd_vms_pop (abfd, NULL);
-      /* FIXME */
+      dst_define_location (abfd, dummy);
       break;
 
       break;
 
-      /* set location: pop index, restore location counter from index
+      /* Set location: pop index, restore location counter from index
         arg: none.  */
         arg: none.  */
-
     case ETIR_S_C_CTL_STLOC:
     case ETIR_S_C_CTL_STLOC:
-      dummy = _bfd_vms_pop (abfd, &psect);
-      /* FIXME */
+      dummy = _bfd_vms_pop (abfd, NULL);
+      dst_restore_location (abfd, dummy);
       break;
 
       break;
 
-      /* stack defined location: pop index, push location counter from index
+      /* Stack defined location: pop index, push location counter from index
         arg: none.  */
         arg: none.  */
-
     case ETIR_S_C_CTL_STKDL:
     case ETIR_S_C_CTL_STKDL:
-      dummy = _bfd_vms_pop (abfd, &psect);
-      /* FIXME */
+      dummy = _bfd_vms_pop (abfd, NULL);
+      _bfd_vms_push (abfd, dst_retrieve_location (abfd, dummy), -1);
       break;
 
     default:
       (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
       break;
 
     default:
       (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
-      break;
+      return FALSE;
     }
     }
+
   return TRUE;
 }
 
   return TRUE;
 }
 
-/* store conditional commands
+/* Store conditional commands
 
    See table B-12 and B-13 of the openVMS linker manual.  */
 
 static bfd_boolean
 
    See table B-12 and B-13 of the openVMS linker manual.  */
 
 static bfd_boolean
-etir_stc (abfd, cmd, ptr)
-     bfd *abfd;
-     int cmd;
-     unsigned char *ptr ATTRIBUTE_UNUSED;
+etir_stc (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
+         int *quarter_relocs)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
 {
 #if VMS_DEBUG
   _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
   switch (cmd)
     {
       /* 200 Store-conditional Linkage Pair
         arg: none.  */
 #endif
 
   switch (cmd)
     {
       /* 200 Store-conditional Linkage Pair
         arg: none.  */
-
     case ETIR_S_C_STC_LP:
     case ETIR_S_C_STC_LP:
-      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
-      break;
-
-      /* 201 Store-conditional Linkage Pair with Procedure Signature
-        arg:   lw      linkage index
-               cs      procedure name
-               by      signature length
-               da      signature.  */
-
-    case ETIR_S_C_STC_LP_PSB:
-      image_inc_ptr (abfd, (uquad) 16);        /* skip entry,procval */
-      break;
 
       /* 202 Store-conditional Address at global address
         arg:   lw      linkage index
                cs      global name.  */
 
     case ETIR_S_C_STC_GBL:
 
       /* 202 Store-conditional Address at global address
         arg:   lw      linkage index
                cs      global name.  */
 
     case ETIR_S_C_STC_GBL:
-      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
-      break;
 
       /* 203 Store-conditional Code Address at global address
         arg:   lw      linkage index
                cs      procedure name.  */
 
       /* 203 Store-conditional Code Address at global address
         arg:   lw      linkage index
                cs      procedure name.  */
-
     case ETIR_S_C_STC_GCA:
     case ETIR_S_C_STC_GCA:
-      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
-      break;
 
       /* 204 Store-conditional Address at psect + offset
         arg:   lw      linkage index
                lw      psect index
                qw      offset.  */
 
       /* 204 Store-conditional Address at psect + offset
         arg:   lw      linkage index
                lw      psect index
                qw      offset.  */
-
     case ETIR_S_C_STC_PS:
       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
     case ETIR_S_C_STC_PS:
       (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
+      *quarter_relocs = 0;
+      return FALSE;
+
+      /* 201 Store-conditional Linkage Pair with Procedure Signature
+        arg:   lw      linkage index
+               cs      procedure name
+               by      signature length
+               da      signature.  */
+
+    case ETIR_S_C_STC_LP_PSB:
+      image_inc_ptr (abfd, (uquad) 16);        /* skip entry,procval */
+      *quarter_relocs = 4;
       break;
 
       /* 205 Store-conditional NOP at address of global
         arg: none.  */
       break;
 
       /* 205 Store-conditional NOP at address of global
         arg: none.  */
-
     case ETIR_S_C_STC_NOP_GBL:
     case ETIR_S_C_STC_NOP_GBL:
-
-      /* 206 Store-conditional NOP at pect + offset
-        arg: none.  */
-
-    case ETIR_S_C_STC_NOP_PS:
+      /* ALPHA_R_NOP */
 
       /* 207 Store-conditional BSR at global address
         arg: none.  */
 
     case ETIR_S_C_STC_BSR_GBL:
 
       /* 207 Store-conditional BSR at global address
         arg: none.  */
 
     case ETIR_S_C_STC_BSR_GBL:
+      /* ALPHA_R_BSR */
 
 
-      /* 208 Store-conditional BSR at pect + offset
+      /* 209 Store-conditional LDA at global address
         arg: none.  */
 
         arg: none.  */
 
-    case ETIR_S_C_STC_BSR_PS:
+    case ETIR_S_C_STC_LDA_GBL:
+      /* ALPHA_R_LDA */
 
 
-      /* 209 Store-conditional LDA at global address
+      /* 211 Store-conditional BSR or Hint at global address
         arg: none.  */
 
         arg: none.  */
 
-    case ETIR_S_C_STC_LDA_GBL:
+    case ETIR_S_C_STC_BOH_GBL:
+      *quarter_relocs = 4;
+      break;
 
 
-      /* 210 Store-conditional LDA at psect + offset
+      /* 213 Store-conditional NOP,BSR or HINT at global address
         arg: none.  */
 
         arg: none.  */
 
-    case ETIR_S_C_STC_LDA_PS:
+    case ETIR_S_C_STC_NBH_GBL:
 
 
-      /* 211 Store-conditional BSR or Hint at global address
+      /* 206 Store-conditional NOP at pect + offset
         arg: none.  */
 
         arg: none.  */
 
-    case ETIR_S_C_STC_BOH_GBL:
+    case ETIR_S_C_STC_NOP_PS:
 
 
-      /* 212 Store-conditional BSR or Hint at pect + offset
+      /* 208 Store-conditional BSR at pect + offset
         arg: none.  */
 
         arg: none.  */
 
-    case ETIR_S_C_STC_BOH_PS:
+    case ETIR_S_C_STC_BSR_PS:
 
 
-      /* 213 Store-conditional NOP,BSR or HINT at global address
+      /* 210 Store-conditional LDA at psect + offset
         arg: none.  */
 
         arg: none.  */
 
-    case ETIR_S_C_STC_NBH_GBL:
+    case ETIR_S_C_STC_LDA_PS:
 
 
-      /* 214 Store-conditional NOP,BSR or HINT at psect + offset
+      /* 212 Store-conditional BSR or Hint at pect + offset
         arg: none.  */
 
         arg: none.  */
 
+    case ETIR_S_C_STC_BOH_PS:
+
+      /* 214 Store-conditional NOP, BSR or HINT at psect + offset
+        arg: none.  */
     case ETIR_S_C_STC_NBH_PS:
     case ETIR_S_C_STC_NBH_PS:
-      /* FIXME */
-#if 0
       (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd));
       (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd));
-#endif
-      break;
+      *quarter_relocs = 0;
+      return FALSE;
 
     default:
 
     default:
-#if VMS_DEBUG
-      _bfd_vms_debug (3,  "reserved STC cmd %d", cmd);
-#endif
-      break;
+      (*_bfd_error_handler) (_("reserved STC cmd %d"), cmd);
+      *quarter_relocs = 0;
+      return FALSE;
     }
     }
+
   return TRUE;
 }
 
 static asection *
   return TRUE;
 }
 
 static asection *
-new_section (abfd, idx)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     int idx;
+new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
 {
   asection *section;
   char sname[16];
 {
   asection *section;
   char sname[16];
@@ -939,16 +985,16 @@ new_section (abfd, idx)
 
   name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
   if (name == 0)
 
   name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
   if (name == 0)
-    return 0;
+    return NULL;
   strcpy (name, sname);
 
   section = bfd_malloc ((bfd_size_type) sizeof (asection));
   if (section == 0)
     {
 #if VMS_DEBUG
   strcpy (name, sname);
 
   section = bfd_malloc ((bfd_size_type) sizeof (asection));
   if (section == 0)
     {
 #if VMS_DEBUG
-      _bfd_vms_debug (6,  "bfd_make_section (%s) failed", name);
+      _bfd_vms_debug (6,  "new_section (%s) failed", name);
 #endif
 #endif
-      return 0;
+      return NULL;
     }
 
   section->size = 0;
     }
 
   section->size = 0;
@@ -961,9 +1007,7 @@ new_section (abfd, idx)
 }
 
 static int
 }
 
 static int
-alloc_section (abfd, idx)
-     bfd *abfd;
-     unsigned int idx;
+alloc_section (bfd * abfd, unsigned int idx)
 {
   bfd_size_type amt;
 
 {
   bfd_size_type amt;
 
@@ -973,8 +1017,8 @@ alloc_section (abfd, idx)
 
   amt = idx + 1;
   amt *= sizeof (asection *);
 
   amt = idx + 1;
   amt *= sizeof (asection *);
-  PRIV (sections) = (asection **) bfd_realloc (PRIV (sections), amt);
-  if (PRIV (sections) == 0)
+  PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
+  if (PRIV (sections) == NULL)
     return -1;
 
   while (PRIV (section_count) <= idx)
     return -1;
 
   while (PRIV (section_count) <= idx)
@@ -991,15 +1035,15 @@ alloc_section (abfd, idx)
 
 /* tir_sta
 
 
 /* tir_sta
 
-   vax stack commands
+   Vax stack commands.
 
 
-   Handle sta_xxx commands in tir section
-   ptr points to data area in record
+   Handle sta_xxx commands in tir section,
+   ptr points to data area in record.
 
    See table 7-3 of the VAX/VMS linker manual.  */
 
 static unsigned char *
 
    See table 7-3 of the VAX/VMS linker manual.  */
 
 static unsigned char *
-tir_sta (bfd *abfd, unsigned char *ptr)
+tir_sta (bfd * abfd, unsigned char *ptr)
 {
   int cmd = *ptr++;
 
 {
   int cmd = *ptr++;
 
@@ -1022,8 +1066,8 @@ tir_sta (bfd *abfd, unsigned char *ptr)
        name = _bfd_vms_save_counted_string (ptr);
 
        entry = _bfd_vms_enter_symbol (abfd, name);
        name = _bfd_vms_save_counted_string (ptr);
 
        entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == (vms_symbol_entry *) NULL)
-         return 0;
+       if (entry == NULL)
+         return NULL;
 
        _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
        ptr += *ptr + 1;
 
        _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
        ptr += *ptr + 1;
@@ -1064,7 +1108,7 @@ tir_sta (bfd *abfd, unsigned char *ptr)
                by      signed byte offset.  */
       {
        unsigned long dummy;
                by      signed byte offset.  */
       {
        unsigned long dummy;
-       unsigned int psect;
+       int psect;
 
        if (cmd == TIR_S_C_STA_PB)
          psect = *ptr++;
 
        if (cmd == TIR_S_C_STA_PB)
          psect = *ptr++;
@@ -1074,12 +1118,12 @@ tir_sta (bfd *abfd, unsigned char *ptr)
            ptr += 2;
          }
 
            ptr += 2;
          }
 
-       if (psect >= PRIV (section_count))
+       if ((unsigned int) psect >= PRIV (section_count))
          alloc_section (abfd, psect);
 
        dummy = (long) *ptr++;
        dummy += (PRIV (sections)[psect])->vma;
          alloc_section (abfd, psect);
 
        dummy = (long) *ptr++;
        dummy += (PRIV (sections)[psect])->vma;
-       _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
+       _bfd_vms_push (abfd, (uquad) dummy, psect);
       }
       break;
 
       }
       break;
 
@@ -1091,7 +1135,7 @@ tir_sta (bfd *abfd, unsigned char *ptr)
                sh      signed short offset.  */
       {
        unsigned long dummy;
                sh      signed short offset.  */
       {
        unsigned long dummy;
-       unsigned int psect;
+       int psect;
 
        if (cmd == TIR_S_C_STA_PW)
          psect = *ptr++;
 
        if (cmd == TIR_S_C_STA_PW)
          psect = *ptr++;
@@ -1101,12 +1145,12 @@ tir_sta (bfd *abfd, unsigned char *ptr)
            ptr += 2;
          }
 
            ptr += 2;
          }
 
-       if (psect >= PRIV (section_count))
+       if ((unsigned int) psect >= PRIV (section_count))
          alloc_section (abfd, psect);
 
        dummy = bfd_getl16 (ptr); ptr+=2;
        dummy += (PRIV (sections)[psect])->vma;
          alloc_section (abfd, psect);
 
        dummy = bfd_getl16 (ptr); ptr+=2;
        dummy += (PRIV (sections)[psect])->vma;
-       _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
+       _bfd_vms_push (abfd, (uquad) dummy, psect);
       }
       break;
 
       }
       break;
 
@@ -1118,7 +1162,7 @@ tir_sta (bfd *abfd, unsigned char *ptr)
                lw      signed longword offset.  */
       {
        unsigned long dummy;
                lw      signed longword offset.  */
       {
        unsigned long dummy;
-       unsigned int psect;
+       int psect;
 
        if (cmd == TIR_S_C_STA_PL)
          psect = *ptr++;
 
        if (cmd == TIR_S_C_STA_PL)
          psect = *ptr++;
@@ -1128,12 +1172,12 @@ tir_sta (bfd *abfd, unsigned char *ptr)
            ptr += 2;
          }
 
            ptr += 2;
          }
 
-       if (psect >= PRIV (section_count))
+       if ((unsigned int) psect >= PRIV (section_count))
          alloc_section (abfd, psect);
 
        dummy = bfd_getl32 (ptr); ptr += 4;
        dummy += (PRIV (sections)[psect])->vma;
          alloc_section (abfd, psect);
 
        dummy = bfd_getl32 (ptr); ptr += 4;
        dummy += (PRIV (sections)[psect])->vma;
-       _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
+       _bfd_vms_push (abfd, (uquad) dummy, psect);
       }
       break;
 
       }
       break;
 
@@ -1180,8 +1224,8 @@ tir_sta (bfd *abfd, unsigned char *ptr)
 
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
 
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == (vms_symbol_entry *) NULL)
-         return 0;
+       if (entry == NULL)
+         return NULL;
 
        (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
 
        (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
@@ -1214,8 +1258,8 @@ tir_sta (bfd *abfd, unsigned char *ptr)
        ptr += 2;
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
        ptr += 2;
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == (vms_symbol_entry *) NULL)
-         return 0;
+       if (entry == NULL)
+         return NULL;
        (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
        (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
@@ -1248,8 +1292,8 @@ tir_sta (bfd *abfd, unsigned char *ptr)
        ptr += 2;
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
        ptr += 2;
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == (vms_symbol_entry *) NULL)
-         return 0;
+       if (entry == NULL)
+         return NULL;
        (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
        (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
@@ -1266,8 +1310,7 @@ tir_sta (bfd *abfd, unsigned char *ptr)
 }
 
 static const char *
 }
 
 static const char *
-tir_cmd_name (cmd)
-     int cmd;
+tir_cmd_name (int cmd)
 {
   switch (cmd)
     {
 {
   switch (cmd)
     {
@@ -1306,7 +1349,7 @@ tir_cmd_name (cmd)
    See table 7-4 of the VAX/VMS linker manual.  */
 
 static unsigned char *
    See table 7-4 of the VAX/VMS linker manual.  */
 
 static unsigned char *
-tir_sto (bfd *abfd, unsigned char *ptr)
+tir_sto (bfd * abfd, unsigned char *ptr)
 {
   unsigned long dummy;
   int size;
 {
   unsigned long dummy;
   int size;
@@ -1319,28 +1362,28 @@ tir_sto (bfd *abfd, unsigned char *ptr)
   switch (*ptr++)
     {
     case TIR_S_C_STO_SB:
   switch (*ptr++)
     {
     case TIR_S_C_STO_SB:
-      /* store signed byte: pop stack, write byte
+      /* Store signed byte: pop stack, write byte
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_b (abfd, dummy & 0xff);      /* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_SW:
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_b (abfd, dummy & 0xff);      /* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_SW:
-      /* store signed word: pop stack, write word
+      /* Store signed word: pop stack, write word
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_w (abfd, dummy & 0xffff);    /* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_LW:
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_w (abfd, dummy & 0xffff);    /* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_LW:
-      /* store longword: pop stack, write longword
+      /* Store longword: pop stack, write longword
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_l (abfd, dummy & 0xffffffff);        /* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_BD:
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_l (abfd, dummy & 0xffffffff);        /* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_BD:
-      /* store byte displaced: pop stack, sub lc+1, write byte
+      /* Store byte displaced: pop stack, sub lc+1, write byte
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy -= ((PRIV (sections)[psect])->vma + 1);
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy -= ((PRIV (sections)[psect])->vma + 1);
@@ -1348,7 +1391,7 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_WD:
       break;
 
     case TIR_S_C_STO_WD:
-      /* store word displaced: pop stack, sub lc+2, write word
+      /* Store word displaced: pop stack, sub lc+2, write word
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy -= ((PRIV (sections)[psect])->vma + 2);
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy -= ((PRIV (sections)[psect])->vma + 2);
@@ -1356,7 +1399,7 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_LD:
       break;
 
     case TIR_S_C_STO_LD:
-      /* store long displaced: pop stack, sub lc+4, write long
+      /* Store long displaced: pop stack, sub lc+4, write long
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy -= ((PRIV (sections)[psect])->vma + 4);
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       dummy -= ((PRIV (sections)[psect])->vma + 4);
@@ -1364,14 +1407,14 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_LI:
       break;
 
     case TIR_S_C_STO_LI:
-      /* store short literal: pop stack, write byte
+      /* Store short literal: pop stack, write byte
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_PIDR:
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
       break;
 
     case TIR_S_C_STO_PIDR:
-      /* store position independent data reference: pop stack, write longword
+      /* Store position independent data reference: pop stack, write longword
         arg: none.
         FIXME: incomplete !  */
       dummy = _bfd_vms_pop (abfd, &psect);
         arg: none.
         FIXME: incomplete !  */
       dummy = _bfd_vms_pop (abfd, &psect);
@@ -1379,7 +1422,7 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_PICR:
       break;
 
     case TIR_S_C_STO_PICR:
-      /* store position independent code reference: pop stack, write longword
+      /* Store position independent code reference: pop stack, write longword
         arg: none.
         FIXME: incomplete !  */
       dummy = _bfd_vms_pop (abfd, &psect);
         arg: none.
         FIXME: incomplete !  */
       dummy = _bfd_vms_pop (abfd, &psect);
@@ -1388,7 +1431,7 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_RIVB:
       break;
 
     case TIR_S_C_STO_RIVB:
-      /* store repeated immediate variable bytes
+      /* Store repeated immediate variable bytes
         1-byte count n field followed by n bytes of data
         pop stack, write n bytes <stack> times.  */
       size = *ptr++;
         1-byte count n field followed by n bytes of data
         pop stack, write n bytes <stack> times.  */
       size = *ptr++;
@@ -1399,19 +1442,19 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_B:
       break;
 
     case TIR_S_C_STO_B:
-      /* store byte from top longword.  */
+      /* Store byte from top longword.  */
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       image_write_b (abfd, dummy & 0xff);
       break;
 
     case TIR_S_C_STO_W:
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       image_write_b (abfd, dummy & 0xff);
       break;
 
     case TIR_S_C_STO_W:
-      /* store word from top longword.  */
+      /* Store word from top longword.  */
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       image_write_w (abfd, dummy & 0xffff);
       break;
 
     case TIR_S_C_STO_RB:
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       image_write_w (abfd, dummy & 0xffff);
       break;
 
     case TIR_S_C_STO_RB:
-      /* store repeated byte from top longword.  */
+      /* Store repeated byte from top longword.  */
       size = (unsigned long) _bfd_vms_pop (abfd, NULL);
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       while (size-- > 0)
       size = (unsigned long) _bfd_vms_pop (abfd, NULL);
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       while (size-- > 0)
@@ -1419,7 +1462,7 @@ tir_sto (bfd *abfd, unsigned char *ptr)
       break;
 
     case TIR_S_C_STO_RW:
       break;
 
     case TIR_S_C_STO_RW:
-      /* store repeated word from top longword.  */
+      /* Store repeated word from top longword.  */
       size = (unsigned long) _bfd_vms_pop (abfd, NULL);
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       while (size-- > 0)
       size = (unsigned long) _bfd_vms_pop (abfd, NULL);
       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
       while (size-- > 0)
@@ -1446,17 +1489,15 @@ tir_sto (bfd *abfd, unsigned char *ptr)
   return ptr;
 }
 
   return ptr;
 }
 
-/* stack operator commands
-   all 32 bit signed arithmetic
-   all word just like a stack calculator
-   arguments are popped from stack, results are pushed on stack
+/* Stack operator commands
+   All 32 bit signed arithmetic
+   All word just like a stack calculator
+   Arguments are popped from stack, results are pushed on stack
 
    See table 7-5 of the VAX/VMS linker manual.  */
 
 static unsigned char *
 
    See table 7-5 of the VAX/VMS linker manual.  */
 
 static unsigned char *
-tir_opr (abfd, ptr)
-     bfd *abfd;
-     unsigned char *ptr;
+tir_opr (bfd * abfd, unsigned char *ptr)
 {
   long op1, op2;
 
 {
   long op1, op2;
 
@@ -1464,31 +1505,31 @@ tir_opr (abfd, ptr)
   _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
 #endif
 
   _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
 #endif
 
+  /* Operation.  */
   switch (*ptr++)
     {
   switch (*ptr++)
     {
-      /* operation */
-    case TIR_S_C_OPR_NOP: /* no-op */
+    case TIR_S_C_OPR_NOP: /* No-op.  */
       break;
 
       break;
 
-    case TIR_S_C_OPR_ADD: /* add */
+    case TIR_S_C_OPR_ADD: /* Add.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
       break;
 
-    case TIR_S_C_OPR_SUB: /* subtract */
+    case TIR_S_C_OPR_SUB: /* Subtract.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
       break;
 
-    case TIR_S_C_OPR_MUL: /* multiply */
+    case TIR_S_C_OPR_MUL: /* Multiply.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
       break;
 
-    case TIR_S_C_OPR_DIV: /* divide */
+    case TIR_S_C_OPR_DIV: /* Divide.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       if (op2 == 0)
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       if (op2 == 0)
@@ -1497,77 +1538,77 @@ tir_opr (abfd, ptr)
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
       break;
 
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
       break;
 
-    case TIR_S_C_OPR_AND: /* logical and */
+    case TIR_S_C_OPR_AND: /* Logical AND.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
       break;
 
-    case TIR_S_C_OPR_IOR: /* logical inclusive or */
+    case TIR_S_C_OPR_IOR: /* Logical inclusive OR.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
       break;
 
-    case TIR_S_C_OPR_EOR: /* logical exclusive or */
+    case TIR_S_C_OPR_EOR: /* Logical exclusive OR.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
       break;
 
-    case TIR_S_C_OPR_NEG: /* negate */
+    case TIR_S_C_OPR_NEG: /* Negate.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (-op1), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (-op1), -1);
       break;
 
-    case TIR_S_C_OPR_COM: /* complement */
+    case TIR_S_C_OPR_COM: /* Complement.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
       break;
 
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
       break;
 
-    case TIR_S_C_OPR_INSV: /* insert field */
+    case TIR_S_C_OPR_INSV: /* Insert field.  */
       (void) _bfd_vms_pop (abfd, NULL);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
       (void) _bfd_vms_pop (abfd, NULL);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
-    case TIR_S_C_OPR_ASH: /* arithmetic shift */
+    case TIR_S_C_OPR_ASH: /* Arithmetic shift.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (HIGHBIT (op1))       /* shift right */
+      if (HIGHBIT (op1))       /* Shift right.  */
        op2 >>= op1;
        op2 >>= op1;
-      else                     /* shift left */
+      else                     /* Shift left.  */
        op2 <<= op1;
       _bfd_vms_push (abfd, (uquad) op2, -1);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
        op2 <<= op1;
       _bfd_vms_push (abfd, (uquad) op2, -1);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
-    case TIR_S_C_OPR_USH: /* unsigned shift */
+    case TIR_S_C_OPR_USH: /* Unsigned shift.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (HIGHBIT (op1))       /* shift right */
+      if (HIGHBIT (op1))       /* Shift right.  */
        op2 >>= op1;
        op2 >>= op1;
-      else                     /* shift left */
+      else                     /* Shift left.  */
        op2 <<= op1;
       _bfd_vms_push (abfd, (uquad) op2, -1);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
        op2 <<= op1;
       _bfd_vms_push (abfd, (uquad) op2, -1);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
-    case TIR_S_C_OPR_ROT: /* rotate */
+    case TIR_S_C_OPR_ROT: /* Rotate.  */
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
       op1 = (long) _bfd_vms_pop (abfd, NULL);
       op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (HIGHBIT (0)) /* shift right */
+      if (HIGHBIT (0)) /* Shift right.  */
        op2 >>= op1;
        op2 >>= op1;
-      else             /* shift left */
+      else             /* Shift left.  */
        op2 <<= op1;
       _bfd_vms_push (abfd, (uquad) op2, -1);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
        op2 <<= op1;
       _bfd_vms_push (abfd, (uquad) op2, -1);
       (*_bfd_error_handler)  (_("%s: not fully implemented"),
                              tir_cmd_name (ptr[-1]));
       break;
 
-    case TIR_S_C_OPR_SEL: /* select */
+    case TIR_S_C_OPR_SEL: /* Select.  */
       if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
        (void) _bfd_vms_pop (abfd, NULL);
       else
       if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
        (void) _bfd_vms_pop (abfd, NULL);
       else
@@ -1592,15 +1633,15 @@ tir_opr (abfd, ptr)
   return ptr;
 }
 
   return ptr;
 }
 
-/* control commands
+/* Control commands
 
    See table 7-6 of the VAX/VMS linker manual.  */
 
 static unsigned char *
 
    See table 7-6 of the VAX/VMS linker manual.  */
 
 static unsigned char *
-tir_ctl (bfd *abfd, unsigned char *ptr)
+tir_ctl (bfd * abfd, unsigned char *ptr)
 {
   unsigned long dummy;
 {
   unsigned long dummy;
-  unsigned int psect;
+  int psect;
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
 
 #if VMS_DEBUG
   _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
@@ -1612,9 +1653,9 @@ tir_ctl (bfd *abfd, unsigned char *ptr)
       /* Set relocation base: pop stack, set image location counter
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
       /* Set relocation base: pop stack, set image location counter
         arg: none.  */
       dummy = _bfd_vms_pop (abfd, &psect);
-      if (psect >= PRIV (section_count))
+      if ((unsigned int) psect >= PRIV (section_count))
        alloc_section (abfd, psect);
        alloc_section (abfd, psect);
-      image_set_ptr (abfd, (int) psect, (uquad) dummy);
+      image_set_ptr (abfd, psect, (uquad) dummy);
       break;
 
     case TIR_S_C_CTL_AUGRB:
       break;
 
     case TIR_S_C_CTL_AUGRB:
@@ -1658,9 +1699,9 @@ tir_ctl (bfd *abfd, unsigned char *ptr)
 /* Handle command from TIR section.  */
 
 static unsigned char *
 /* Handle command from TIR section.  */
 
 static unsigned char *
-tir_cmd (bfd *abfd, unsigned char *ptr)
+tir_cmd (bfd * abfd, unsigned char *ptr)
 {
 {
-  struct
+  static const struct
   {
     int mincod;
     int maxcod;
   {
     int mincod;
     int maxcod;
@@ -1678,11 +1719,12 @@ tir_cmd (bfd *abfd, unsigned char *ptr)
 
 #if VMS_DEBUG
   _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
 
 #if VMS_DEBUG
   _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
 #endif
 
-  if (*ptr & 0x80)                             /* store immediate */
+  if (*ptr & 0x80)
     {
     {
+      /* Store immediate.  */
       i = 128 - (*ptr++ & 0x7f);
       image_dump (abfd, ptr, i, 0);
       ptr += i;
       i = 128 - (*ptr++ & 0x7f);
       image_dump (abfd, ptr, i, 0);
       ptr += i;
@@ -1712,16 +1754,13 @@ tir_cmd (bfd *abfd, unsigned char *ptr)
 /* Handle command from ETIR section.  */
 
 static int
 /* Handle command from ETIR section.  */
 
 static int
-etir_cmd (abfd, cmd, ptr)
-     bfd *abfd;
-     int cmd;
-     unsigned char *ptr;
+etir_cmd (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
 {
 {
-  static struct
+  static const struct
   {
     int mincod;
     int maxcod;
   {
     int mincod;
     int maxcod;
-    bfd_boolean (*explain) PARAMS ((bfd *, int, unsigned char *));
+    bfd_boolean (*explain) (bfd *, int, unsigned char *, int *);
   }
   etir_table[] =
   {
   }
   etir_table[] =
   {
@@ -1736,8 +1775,8 @@ etir_cmd (abfd, cmd, ptr)
   int i = 0;
 
 #if VMS_DEBUG
   int i = 0;
 
 #if VMS_DEBUG
-  _bfd_vms_debug (4, "etir_cmd %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (int) ptr);
+  _bfd_vms_debug (4, "etir_cmd: %s(%d)\n", cmd_name (cmd), cmd);
+  _bfd_hexdump (8, ptr, 16, (long) ptr);
 #endif
 
   while (etir_table[i].mincod >= 0)
 #endif
 
   while (etir_table[i].mincod >= 0)
@@ -1745,7 +1784,7 @@ etir_cmd (abfd, cmd, ptr)
       if ( (etir_table[i].mincod <= cmd)
           && (cmd <= etir_table[i].maxcod))
        {
       if ( (etir_table[i].mincod <= cmd)
           && (cmd <= etir_table[i].maxcod))
        {
-         if (!etir_table[i].explain (abfd, cmd, ptr))
+         if (!etir_table[i].explain (abfd, cmd, ptr, quarter_relocs))
            return -1;
          break;
        }
            return -1;
          break;
        }
@@ -1753,7 +1792,7 @@ etir_cmd (abfd, cmd, ptr)
     }
 
 #if VMS_DEBUG
     }
 
 #if VMS_DEBUG
-  _bfd_vms_debug (4, "etir_cmd: = 0\n");
+  _bfd_vms_debug (4, "etir_cmd: result = 0\n");
 #endif
   return 0;
 }
 #endif
   return 0;
 }
@@ -1762,10 +1801,7 @@ etir_cmd (abfd, cmd, ptr)
    handle tir record.  */
 
 static int
    handle tir record.  */
 
 static int
-analyze_tir (abfd, ptr, length)
-     bfd *abfd;
-     unsigned char *ptr;
-     unsigned int length;
+analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
 {
   unsigned char *maxptr;
 
 {
   unsigned char *maxptr;
 
@@ -1789,33 +1825,69 @@ analyze_tir (abfd, ptr, length)
    handle etir record.  */
 
 static int
    handle etir record.  */
 
 static int
-analyze_etir (abfd, ptr, length)
-     bfd *abfd;
-     unsigned char *ptr;
-     unsigned int length;
+analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
 {
 {
-  int cmd;
-  unsigned char *maxptr;
+  unsigned char *maxptr = ptr + length;
+  /* Relocations are made of 1, 2 or 4 ETIR commands.
+     We therefore count them using quarters.  */
+  int quarter_relocs = 0;
   int result = 0;
 
 #if VMS_DEBUG
   _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
 #endif
 
   int result = 0;
 
 #if VMS_DEBUG
   _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
 #endif
 
-  maxptr = ptr + length;
-
   while (ptr < maxptr)
     {
   while (ptr < maxptr)
     {
-      cmd = bfd_getl16 (ptr);
-      length = bfd_getl16 (ptr + 2);
-      result = etir_cmd (abfd, cmd, ptr+4);
+      int cmd = bfd_getl16 (ptr);
+      int cmd_length = bfd_getl16 (ptr + 2);
+      result = etir_cmd (abfd, cmd, ptr + 4, &quarter_relocs);
       if (result != 0)
        break;
       if (result != 0)
        break;
-      ptr += length;
+
+      /* If we have a relocation, we record its length to size
+        future buffers and bump the reloc count of the section.  */
+      if (quarter_relocs)
+       {
+         vms_section_data (PRIV (image_section))->reloc_size += cmd_length;
+         abfd->flags |= HAS_RELOC;
+
+         if (quarter_relocs == 4)
+           {
+             PRIV (image_section)->reloc_count++;
+
+#if VMS_DEBUG
+             _bfd_vms_debug (4, "-> reloc %d at 0x%x\n",
+                             PRIV (image_section)->reloc_count-1,
+                             ptr - (maxptr - length));
+#endif
+
+             quarter_relocs = 0;
+           }
+         else if (quarter_relocs > 4)
+           {
+
+#if VMS_DEBUG
+             _bfd_vms_debug (4, "Reloc count error (%d) in section %s\n",
+                             PRIV (image_section)->reloc_count,
+                             PRIV (image_section)->name);
+#endif
+
+             quarter_relocs = 0;
+           }
+       }
+
+      /* If we have a Store Immediate, we reserve space for the
+        count argument.  */
+      else if (cmd == ETIR_S_C_STO_IMM)
+        vms_section_data (PRIV (image_section))->reloc_size
+         += ETIR_S_C_HEADER_SIZE + 4;
+
+      ptr += cmd_length;
     }
 
 #if VMS_DEBUG
     }
 
 #if VMS_DEBUG
-  _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
+  _bfd_vms_debug (3, "analyze_etir: result = %d\n", result);
 #endif
 
   return result;
 #endif
 
   return result;
@@ -1825,9 +1897,7 @@ analyze_etir (abfd, ptr, length)
    Return 0 on success, -1 on error.  */
 
 int
    Return 0 on success, -1 on error.  */
 
 int
-_bfd_vms_slurp_tir (abfd, objtype)
-     bfd *abfd;
-     int objtype;
+_bfd_vms_slurp_tir (bfd * abfd, int objtype)
 {
   int result;
 
 {
   int result;
 
@@ -1838,12 +1908,12 @@ _bfd_vms_slurp_tir (abfd, objtype)
   switch (objtype)
     {
     case EOBJ_S_C_ETIR:
   switch (objtype)
     {
     case EOBJ_S_C_ETIR:
-      PRIV (vms_rec) += 4;     /* skip type, size */
-      PRIV (rec_size) -= 4;
+      PRIV (vms_rec) += ETIR_S_C_HEADER_SIZE;
+      PRIV (rec_size) -= ETIR_S_C_HEADER_SIZE;
       result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
       break;
     case OBJ_S_C_TIR:
       result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
       break;
     case OBJ_S_C_TIR:
-      PRIV (vms_rec) += 1;     /* skip type */
+      PRIV (vms_rec) += 1;     /* Skip type.  */
       PRIV (rec_size) -= 1;
       result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
       break;
       PRIV (rec_size) -= 1;
       result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
       break;
@@ -1855,36 +1925,361 @@ _bfd_vms_slurp_tir (abfd, objtype)
   return result;
 }
 
   return result;
 }
 
-/* Process EDBG record
-   Return 0 on success, -1 on error
-
-   Not implemented yet.  */
+ /* Slurp relocs from ETIR sections and (temporarily) save them
+    in the per-section reloc buffer.  */
 
 int
 
 int
-_bfd_vms_slurp_dbg (abfd, objtype)
-     bfd *abfd;
-     int objtype ATTRIBUTE_UNUSED;
+_bfd_vms_slurp_relocs (bfd *abfd)
 {
 {
+  struct vms_section_data_struct *vsd;
+  unsigned char *begin = PRIV (vms_rec) + 4;
+  unsigned char *end = PRIV (vms_rec) + PRIV (rec_size);
+  unsigned char *ptr;
+  int cmd, length, slurped_length;
+
+#if VMS_DEBUG
+  _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: %d bytes\n", PRIV (rec_size));
+#endif
+
+  for (ptr = begin; ptr < end; ptr += length)
+    {
+      cmd = bfd_getl16 (ptr);
+      length = bfd_getl16 (ptr + 2);
+      slurped_length = length;
+
+      switch (cmd)
+       {
+       case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+         /* This one is special as it is both part of the section header
+            and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations.  */
+         if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_SETRB)
+           {
+             int psect = bfd_getl32 (ptr + ETIR_S_C_HEADER_SIZE);
+             PRIV (image_section) = PRIV (sections)[psect];
+             continue;
+           }
+
+       case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+                              /* ALPHA_R_REFQUAD und_section, step 1 */
+         break;
+
+       case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG und_section, step 2 */
+                             /* ALPHA_R_REFLONG abs_section, step 1 */
+         /* This one is special as it is both part of the section header
+            and of the ALPHA_R_REFLONG relocation.  */
+         if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_DFLOC)
+           {
+             PRIV (image_section) = PRIV (dst_section);
+             continue;
+           }
+
+       case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD und_section, step 2 */
+                             /* ALPHA_R_REFQUAD abs_section, step 1 */
+
+       case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+                             /* ALPHA_R_REFLONG abs_section, step 2 */
+                             /* ALPHA_R_REFLONG others, step 2 */
+
+       case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+                             /* ALPHA_R_REFQUAD abs_section, step 2 */
+
+       case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+
+       case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+                              /* ALPHA_R_REFQUAD und_section, step 3 */
+
+       case ETIR_S_C_STO_CA:      /* ALPHA_R_CODEADDR */
+       case ETIR_S_C_STO_GBL:     /* ALPHA_R_REFQUAD und_section */
+       case ETIR_S_C_STO_GBL_LW:  /* ALPHA_R_REFLONG und_section */
+       case ETIR_S_C_STC_LP_PSB:  /* ALPHA_R_LINKAGE */
+       case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
+       case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
+       case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
+       case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
+         break;
+
+       case ETIR_S_C_STO_IMM:
+         if (PRIV (image_section)->reloc_count == 0)
+           continue;
+         /* This is not a relocation, but we nevertheless slurp the
+            count argument.  We'll use it to compute the addresses
+            of the relocations.  */
+         slurped_length = ETIR_S_C_HEADER_SIZE + 4;
+         break;
+
+       default:
+         continue;
+       }
+
+      vsd = vms_section_data (PRIV (image_section));
+      memcpy (vsd->reloc_stream + vsd->reloc_offset, ptr, slurped_length);
+      vsd->reloc_offset += slurped_length;
+      if (vsd->reloc_offset > vsd->reloc_size)
+        {
+         (*_bfd_error_handler) (_("Reloc size error in section %s"),
+                                PRIV (image_section)->name);
+         return -1;
+       }
+    }
+
 #if VMS_DEBUG
 #if VMS_DEBUG
-  _bfd_vms_debug (2, "DBG/EDBG\n");
+  _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: result = 0\n");
 #endif
 
 #endif
 
-  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
   return 0;
 }
 
   return 0;
 }
 
-/* Process ETBT record
-   Return 0 on success, -1 on error
-
-   Not implemented yet.  */
+/* Decode relocs from the reloc buffer of the specified section
+   and internalize them in the specified buffer.  */
 
 int
 
 int
-_bfd_vms_slurp_tbt (abfd, objtype)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     int objtype ATTRIBUTE_UNUSED;
+_bfd_vms_decode_relocs (bfd *abfd, arelent *relocs, asection *section,
+                       asymbol **symbols ATTRIBUTE_UNUSED)
 {
 {
+  int saved_cmd, saved_sym_offset, saved_sec_offset, saved_addend_offset;
+  int cmd, sym_offset, sec_offset, address_offset, addend_offset;
+  struct vms_section_data_struct *vsd = vms_section_data (section);
+  bfd_reloc_code_real_type reloc_code;
+  vms_symbol_entry *entry;
+  bfd_vma vaddr = 0;
+  unsigned char *begin = vsd->reloc_stream;
+  unsigned char *end = vsd->reloc_stream + vsd->reloc_size;
+  unsigned char *ptr, *arg_ptr;
+  const char *name;
+  int length;
+
 #if VMS_DEBUG
 #if VMS_DEBUG
-  _bfd_vms_debug (2, "TBT/ETBT\n");
+  _bfd_vms_debug (3, "_bfd_vms_decode_relocs: %d bytes\n", vsd->reloc_size);
+#endif
+
+  #define PUSH_CMD()                                   \
+    {                                                  \
+      saved_cmd = cmd;                                 \
+      saved_sym_offset = sym_offset - length;          \
+      saved_sec_offset = sec_offset - length;          \
+      saved_addend_offset = addend_offset - length;    \
+      continue;                                                \
+    }
+
+  #define POP_CMD()                                    \
+    {                                                  \
+      cmd = saved_cmd;                                 \
+      saved_cmd = ETIR_S_C_MAXSTCCOD + 1;              \
+      sym_offset = saved_sym_offset;                   \
+      sec_offset = saved_sec_offset;                   \
+      addend_offset= saved_addend_offset;              \
+    }
+
+  #define CMD_PUSHED (saved_cmd != ETIR_S_C_MAXSTCCOD + 1)
+
+  #define NO_OFFSET -128
+
+  saved_cmd = ETIR_S_C_MAXSTCCOD + 1;
+  saved_sym_offset = NO_OFFSET;
+  saved_sec_offset = NO_OFFSET;
+  saved_addend_offset = NO_OFFSET;
+
+  for (ptr = begin; ptr < end; ptr += length)
+    {
+      cmd = bfd_getl16 (ptr);
+      length = bfd_getl16 (ptr + 2);
+
+      arg_ptr = ptr + ETIR_S_C_HEADER_SIZE;
+      sym_offset = NO_OFFSET;
+      sec_offset = NO_OFFSET;
+      address_offset = NO_OFFSET;
+      addend_offset = NO_OFFSET;
+
+      switch (cmd)
+       {
+       case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+                              /* ALPHA_R_REFQUAD und_section, step 1 */
+         sym_offset = 0;
+         PUSH_CMD ()
+
+       case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+         sec_offset = 0;
+         addend_offset = 4;
+         PUSH_CMD ()
+
+       case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
+                             /* ALPHA_R_REFLONG und_section, step 2 */
+         if (CMD_PUSHED)
+           {
+             POP_CMD ()
+             if (cmd != ETIR_S_C_STA_GBL)
+               {
+                 (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+                                        cmd_name (cmd),
+                                        cmd_name (ETIR_S_C_STA_LW));
+                 return 0;
+               }
+             cmd = ETIR_S_C_STA_LW;
+           }
+         addend_offset = 0;
+         PUSH_CMD ()
+
+       case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
+                             /* ALPHA_R_REFQUAD und_section, step 2 */
+         if (CMD_PUSHED)
+           {
+             POP_CMD ()
+             if (cmd != ETIR_S_C_STA_GBL)
+               {
+                 (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+                                        cmd_name (cmd),
+                                        cmd_name (ETIR_S_C_STA_QW));
+                 return 0;
+               }
+             cmd = ETIR_S_C_STA_QW;
+           }
+         addend_offset = 0;
+         PUSH_CMD ()
+
+       case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+                             /* ALPHA_R_REFLONG abs_section, step 2 */
+                             /* ALPHA_R_REFLONG others, step 2 */
+         POP_CMD ()
+         if (cmd != ETIR_S_C_OPR_ADD
+             && cmd != ETIR_S_C_STA_LW
+             && cmd != ETIR_S_C_STA_PQ)
+           {
+             (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+               cmd_name (cmd), cmd_name (ETIR_S_C_STO_LW));
+             return 0;
+           }
+         reloc_code = BFD_RELOC_32;
+         break;
+
+       case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+                             /* ALPHA_R_REFQUAD abs_section, step 2 */
+         POP_CMD ()
+         if (cmd != ETIR_S_C_OPR_ADD && cmd != ETIR_S_C_STA_QW)
+           {
+             (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+               cmd_name (cmd), cmd_name (ETIR_S_C_STO_QW));
+             return 0;
+           }
+         reloc_code = BFD_RELOC_64;
+         break;
+
+       case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+         POP_CMD ()
+         if (cmd != ETIR_S_C_STA_PQ)
+           {
+             (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+               cmd_name (cmd), cmd_name (ETIR_S_C_STO_OFF));
+             return 0;
+           }
+         reloc_code = BFD_RELOC_64;
+         break;
+
+       case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+                              /* ALPHA_R_REFQUAD und_section, step 3 */
+         POP_CMD ()
+         if (cmd != ETIR_S_C_STA_LW && cmd != ETIR_S_C_STA_QW)
+           {
+             (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+               cmd_name (cmd), cmd_name (ETIR_S_C_OPR_ADD));
+             return 0;
+           }
+         cmd = ETIR_S_C_OPR_ADD;
+         PUSH_CMD ()
+
+       case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */
+         reloc_code = BFD_RELOC_ALPHA_CODEADDR;
+         sym_offset = 0;
+         break;
+
+       case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
+         reloc_code = BFD_RELOC_64;
+         sym_offset = 0;
+         break;
+
+       case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
+         reloc_code = BFD_RELOC_32;
+         sym_offset = 0;
+         break;
+
+       case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
+         reloc_code = BFD_RELOC_ALPHA_LINKAGE;
+         sym_offset = 4;
+         break;
+
+       case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
+         reloc_code = BFD_RELOC_ALPHA_NOP;
+         goto call_reloc;
+
+       case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
+         reloc_code = BFD_RELOC_ALPHA_BSR;
+         goto call_reloc;
+
+       case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
+         reloc_code = BFD_RELOC_ALPHA_LDA;
+         goto call_reloc;
+
+       case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
+         reloc_code = BFD_RELOC_ALPHA_BOH;
+         goto call_reloc;
+
+       call_reloc:
+         sym_offset = 32;
+         address_offset = 8;
+         addend_offset = 24;
+         break;
+
+       case ETIR_S_C_STO_IMM:
+         vaddr += bfd_getl32 (arg_ptr);
+         length = ETIR_S_C_HEADER_SIZE + 4;
+         continue;
+
+       default:
+         continue;
+       }
+
+      relocs->howto = bfd_reloc_type_lookup (abfd, reloc_code);
+
+      if (sym_offset > NO_OFFSET)
+       {
+         name = _bfd_vms_save_counted_string (arg_ptr + sym_offset);
+         entry = (vms_symbol_entry *)
+           bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
+         if (entry == NULL)
+           {
+             (*_bfd_error_handler) (_("Unknown symbol %s in command %s"),
+                                    name, cmd_name (cmd));
+             relocs->sym_ptr_ptr = NULL;
+           }
+         else
+           /* ??? This is a hack.  We should point in 'symbols'.  */
+           relocs->sym_ptr_ptr = &entry->symbol;
+       }
+      else if (sec_offset > NO_OFFSET)
+       relocs->sym_ptr_ptr
+         = PRIV (sections)[bfd_getl32 (arg_ptr + sec_offset)]->symbol_ptr_ptr;
+      else
+       relocs->sym_ptr_ptr = NULL;
+
+      if (address_offset > NO_OFFSET)
+       relocs->address = bfd_getl64 (arg_ptr + address_offset);
+      else
+       relocs->address = vaddr;
+
+      if (addend_offset > NO_OFFSET)
+       relocs->addend = bfd_getl64 (arg_ptr + addend_offset);
+      else
+       relocs->addend = 0;
+
+      vaddr += bfd_get_reloc_size (relocs->howto);
+      relocs++;     
+    }
+
+  #undef PUSH_CMD
+  #undef POP_CMD
+  #undef NO_OFFSET
+
+#if VMS_DEBUG
+  _bfd_vms_debug (3, "_bfd_vms_decode_relocs: result = 0\n");
 #endif
 
   return 0;
 #endif
 
   return 0;
@@ -1896,9 +2291,8 @@ _bfd_vms_slurp_tbt (abfd, objtype)
    Not implemented yet.  */
 
 int
    Not implemented yet.  */
 
 int
-_bfd_vms_slurp_lnk (abfd, objtype)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     int objtype ATTRIBUTE_UNUSED;
+_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
+                   int objtype ATTRIBUTE_UNUSED)
 {
 #if VMS_DEBUG
   _bfd_vms_debug (2, "LNK\n");
 {
 #if VMS_DEBUG
   _bfd_vms_debug (2, "LNK\n");
@@ -1911,40 +2305,75 @@ _bfd_vms_slurp_lnk (abfd, objtype)
 
    This is still under construction and therefore not documented.  */
 
 
    This is still under construction and therefore not documented.  */
 
-static void start_etir_record
-  PARAMS ((bfd *abfd, int index, uquad offset, bfd_boolean justoffset));
-static void sto_imm
-  PARAMS ((bfd *abfd, vms_section *sptr, bfd_vma vaddr, int index));
-static void end_etir_record
-  PARAMS ((bfd *abfd));
+static void start_etir_record (bfd *abfd, int index, uquad offset,
+                              bfd_boolean justoffset);
+static void start_first_etbt_record (bfd *abfd);
+static void start_another_etbt_record (bfd *abfd);
+static void sto_imm (bfd *abfd, bfd_size_type, unsigned char *, bfd_vma vaddr,
+                    int index, const char *name);
+static void end_etir_record (bfd *abfd);
+static void etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr,
+                              int checklen);
+
+/* Start ETIR record for section #index at virtual addr offset.  */
 
 static void
 
 static void
-sto_imm (abfd, sptr, vaddr, index)
-     bfd *abfd;
-     vms_section *sptr;
-     bfd_vma vaddr;
-     int index;
+start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset)
 {
 {
-  int size;
-  int ssize;
-  unsigned char *cptr;
+  if (!justoffset)
+    {
+      /* One ETIR per section.  */
+      _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
+      _bfd_vms_output_push (abfd);
+    }
+
+  /* Push start offset.  */
+  _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
+  _bfd_vms_output_long (abfd, (unsigned long) index);
+  _bfd_vms_output_quad (abfd, (uquad) offset);
+  _bfd_vms_output_flush (abfd);
+
+  /* Start = pop ().  */
+  _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);
+  _bfd_vms_output_flush (abfd);
+}
+
+static void
+end_etir_record (bfd * abfd)
+{
+  _bfd_vms_output_pop (abfd);
+  _bfd_vms_output_end (abfd);
+}
+
+/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
+   address VADDR in section specified by INDEX and NAME.  */
+
+static void
+sto_imm (bfd *abfd, bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr,
+        int index, const char *name)
+{
+  bfd_size_type size;
 
 #if VMS_DEBUG
 
 #if VMS_DEBUG
-  _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
-  _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
+  _bfd_vms_debug (8, "sto_imm %d bytes\n", ssize);
+  _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
 #endif
 
 #endif
 
-  ssize = sptr->size;
-  cptr = sptr->contents;
-
   while (ssize > 0)
     {
   while (ssize > 0)
     {
-      size = ssize;                            /* try all the rest */
+      /* Try all the rest.  */
+      size = ssize;
 
       if (_bfd_vms_output_check (abfd, size) < 0)
 
       if (_bfd_vms_output_check (abfd, size) < 0)
-       {                                       /* doesn't fit, split ! */
+       {
+         /* Doesn't fit, split !  */
          end_etir_record (abfd);
          end_etir_record (abfd);
-         start_etir_record (abfd, index, vaddr, FALSE);
+
+         if (name [0] && name[1] == 'v' && !strcmp (name, ".vmsdebug"))
+           start_another_etbt_record (abfd);
+         else
+           start_etir_record (abfd, index, vaddr, FALSE);
+
          size = _bfd_vms_output_check (abfd, 0);       /* get max size */
          if (size > ssize)                     /* more than what's left ? */
            size = ssize;
          size = _bfd_vms_output_check (abfd, 0);       /* get max size */
          if (size > ssize)                     /* more than what's left ? */
            size = ssize;
@@ -1961,55 +2390,72 @@ sto_imm (abfd, sptr, vaddr, index)
 #endif
 
       vaddr += size;
 #endif
 
       vaddr += size;
-      ssize -= size;
       cptr += size;
       cptr += size;
+      ssize -= size;
     }
 }
 
     }
 }
 
-/* Start ETIR record for section #index at virtual addr offset.  */
+/* Start ETBT record for section #index at virtual addr offset.  */
 
 static void
 
 static void
-start_etir_record (abfd, index, offset, justoffset)
-    bfd *abfd;
-    int index;
-    uquad offset;
-    bfd_boolean justoffset;
+start_first_etbt_record (bfd *abfd)
 {
 {
-  if (!justoffset)
-    {
-      _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1); /* one ETIR per section */
-      _bfd_vms_output_push (abfd);
-    }
+  _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1);
+  _bfd_vms_output_push (abfd);
 
 
-  _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);   /* push start offset */
-  _bfd_vms_output_long (abfd, (unsigned long) index);
-  _bfd_vms_output_quad (abfd, (uquad) offset);
+  _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);   /* push start offset */
+  _bfd_vms_output_long (abfd, (unsigned long) 0);
   _bfd_vms_output_flush (abfd);
 
   _bfd_vms_output_flush (abfd);
 
-  _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);        /* start = pop () */
+  _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_DFLOC, -1);        /* start = pop() */
   _bfd_vms_output_flush (abfd);
 }
 
   _bfd_vms_output_flush (abfd);
 }
 
-/* End etir record.  */
+static void
+start_another_etbt_record (bfd *abfd)
+{
+  _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1);
+  _bfd_vms_output_push (abfd);
+}
 
 static void
 
 static void
-end_etir_record (abfd)
-    bfd *abfd;
+etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
 {
 {
-  _bfd_vms_output_pop (abfd);
-  _bfd_vms_output_end (abfd);
+  if (_bfd_vms_output_check (abfd, checklen) < 0)
+    {
+      end_etir_record (abfd);
+      if (section->name[0] && section->name[1] == 'v'
+         && !strcmp (section->name, ".vmsdebug"))
+       start_another_etbt_record (abfd);
+      else
+       start_etir_record (abfd, section->index, vaddr, FALSE);
+    }
+}
+
+/* Return whether RELOC must be deferred till the end.  */
+
+static int
+defer_reloc_p (arelent *reloc)
+{
+  switch (reloc->howto->type)
+    {
+    case ALPHA_R_NOP:
+    case ALPHA_R_LDA:
+    case ALPHA_R_BSR:
+    case ALPHA_R_BOH:
+      return 1;
+
+    default:
+      return 0;
+    }
 }
 
 /* Write section contents for bfd abfd.  */
 
 int
 }
 
 /* Write section contents for bfd abfd.  */
 
 int
-_bfd_vms_write_tir (abfd, objtype)
-     bfd *abfd;
-     int objtype ATTRIBUTE_UNUSED;
+_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
 {
   asection *section;
 {
   asection *section;
-  vms_section *sptr;
-  int nextoffset;
 
 #if VMS_DEBUG
   _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
 
 #if VMS_DEBUG
   _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
@@ -2017,399 +2463,346 @@ _bfd_vms_write_tir (abfd, objtype)
 
   _bfd_vms_output_alignment (abfd, 4);
 
 
   _bfd_vms_output_alignment (abfd, 4);
 
-  nextoffset = 0;
   PRIV (vms_linkage_index) = 1;
 
   PRIV (vms_linkage_index) = 1;
 
-  /* Dump all other sections.  */
-
-  section = abfd->sections;
-
-  while (section != NULL)
+  for (section = abfd->sections; section; section = section->next)
     {
     {
-
 #if VMS_DEBUG
       _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
                      section->index, section->name,
                      (int) (section->size));
 #endif
 
 #if VMS_DEBUG
       _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
                      section->index, section->name,
                      (int) (section->size));
 #endif
 
+      if (!(section->flags & SEC_HAS_CONTENTS)
+         || bfd_is_com_section (section))
+       continue;
+
+      if (!section->contents)
+       {
+         bfd_set_error (bfd_error_no_contents);
+         return -1;
+       }
+
+      if (section->name[0]
+         && section->name[1] == 'v'
+         && !strcmp (section->name, ".vmsdebug"))
+       start_first_etbt_record (abfd);
+      else
+       start_etir_record (abfd, section->index, 0, FALSE);
+
       if (section->flags & SEC_RELOC)
        {
       if (section->flags & SEC_RELOC)
        {
-         int i;
+         bfd_vma curr_addr = 0;
+         unsigned char *curr_data = section->contents;
+         bfd_size_type size;
+         int pass2_needed = 0;
+         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 ((i = section->reloc_count) <= 0)
-           {
-             (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
-                                    section->name);
-           }
 #if VMS_DEBUG
          else
            {
 #if VMS_DEBUG
          else
            {
-             arelent **rptr;
+             int i = section->reloc_count;
+             arelent **rptr = section->orelocation;
              _bfd_vms_debug (4, "%d relocations:\n", i);
              _bfd_vms_debug (4, "%d relocations:\n", i);
-             rptr = section->orelocation;
              while (i-- > 0)
                {
              while (i-- > 0)
                {
-                 _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
+                 _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, "
+                                    "addr %08lx, off %08lx, len %d: %s\n",
                                  (*(*rptr)->sym_ptr_ptr)->name,
                                  (*(*rptr)->sym_ptr_ptr)->section->name,
                                  (long) (*(*rptr)->sym_ptr_ptr)->value,
                                  (*rptr)->address, (*rptr)->addend,
                                  bfd_get_reloc_size ((*rptr)->howto),
                                  (*(*rptr)->sym_ptr_ptr)->name,
                                  (*(*rptr)->sym_ptr_ptr)->section->name,
                                  (long) (*(*rptr)->sym_ptr_ptr)->value,
                                  (*rptr)->address, (*rptr)->addend,
                                  bfd_get_reloc_size ((*rptr)->howto),
-                                 (*rptr)->howto->name);
+                                  ( *rptr)->howto->name);
                  rptr++;
                }
            }
 #endif
                  rptr++;
                }
            }
 #endif
-       }
 
 
-      if ((section->flags & SEC_HAS_CONTENTS)
-         && (! bfd_is_com_section (section)))
-       {
-         bfd_vma vaddr;                /* Virtual addr in section.  */
-
-         sptr = _bfd_get_vms_section (abfd, section->index);
-         if (sptr == NULL)
+       new_pass:
+         for (irel = 0; irel < section->reloc_count; irel++)
            {
            {
-             bfd_set_error (bfd_error_no_contents);
-             return -1;
-           }
-
-         vaddr = (bfd_vma) (sptr->offset);
-
-         start_etir_record (abfd, section->index, (uquad) sptr->offset,
-                            FALSE);
+             struct evax_private_udata_struct *udata;
+             arelent *rptr = section->orelocation [irel];
+             bfd_vma addr = rptr->address;
+             asymbol *sym = *rptr->sym_ptr_ptr;
+             asection *sec = sym->section;
+             int defer = defer_reloc_p (rptr);
+             unsigned int slen;
+             char *hash;
+
+             if (pass2_in_progress)
+               {
+                 /* Non-deferred relocs have already been output.  */
+                 if (!defer)
+                   continue;
+               }
+             else
+               {
+                 /* Deferred relocs must be output at the very end.  */
+                 if (defer)
+                   {
+                     pass2_needed = 1;
+                     continue;
+                   }
+
+                 /* Regular relocs are intertwined with binary data.  */
+                 if (curr_addr > addr)
+                   (*_bfd_error_handler) (_("Size error in section %s"),
+                                          section->name);
+                 size = addr - curr_addr;
+                 sto_imm (abfd, size, curr_data, curr_addr,
+                         section->index, section->name);
+                 curr_data += size;
+                 curr_addr += size;
+               }
 
 
-         while (sptr != NULL)  /* one STA_PQ, CTL_SETRB per vms_section */
-           {
+             size = bfd_get_reloc_size (rptr->howto);
 
 
-             if (section->flags & SEC_RELOC)   /* check for relocs */
-               {
-                 arelent **rptr = section->orelocation;
-                 int i = section->reloc_count;
+             switch (rptr->howto->type)
+               {
+               case ALPHA_R_IGNORE:
+                 break;
 
 
-                 for (;;)
+               case ALPHA_R_REFLONG:
+                 if (bfd_is_und_section (sym->section))
                    {
                    {
-                     bfd_size_type addr = (*rptr)->address;
-                     bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
-                     if (sptr->offset < addr)  /* sptr starts before reloc */
+                     bfd_vma addend = rptr->addend;
+                     slen = strlen ((char *) sym->name);
+                     hash = _bfd_vms_length_hash_symbol
+                              (abfd, sym->name, EOBJ_S_C_SYMSIZ);
+                     etir_output_check (abfd, section, curr_addr, slen);
+                     if (addend)
                        {
                        {
-                         bfd_size_type before = addr - sptr->offset;
-                         if (sptr->size <= before)     /* complete before */
-                           {
-                             sto_imm (abfd, sptr, vaddr, section->index);
-                             vaddr += sptr->size;
-                             break;
-                           }
-                         else                          /* partly before */
-                           {
-                             int after = sptr->size - before;
-                             sptr->size = before;
-                             sto_imm (abfd, sptr, vaddr, section->index);
-                             vaddr += sptr->size;
-                             sptr->contents += before;
-                             sptr->offset += before;
-                             sptr->size = after;
-                           }
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
+                         _bfd_vms_output_counted (abfd, hash);
+                         _bfd_vms_output_flush (abfd);
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
+                         _bfd_vms_output_long (abfd, (unsigned long) addend);
+                         _bfd_vms_output_flush (abfd);
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
+                         _bfd_vms_output_flush (abfd);
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
+                         _bfd_vms_output_flush (abfd);
                        }
                        }
-                     else if (sptr->offset == addr) /* sptr starts at reloc */
+                     else
                        {
                        {
-                         asymbol *sym = *(*rptr)->sym_ptr_ptr;
-                         asection *sec = sym->section;
-
-                         switch ((*rptr)->howto->type)
-                           {
-                           case ALPHA_R_IGNORE:
-                             break;
-
-                           case ALPHA_R_REFLONG:
-                             {
-                               if (bfd_is_und_section (sym->section))
-                                 {
-                                   int slen = strlen ((char *) sym->name);
-                                   char *hash;
-
-                                   if (_bfd_vms_output_check (abfd, slen) < 0)
-                                     {
-                                       end_etir_record (abfd);
-                                       start_etir_record (abfd,
-                                                          section->index,
-                                                          vaddr, FALSE);
-                                     }
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STO_GBL_LW,
-                                                          -1);
-                                   hash = (_bfd_vms_length_hash_symbol
-                                           (abfd, sym->name, EOBJ_S_C_SYMSIZ));
-                                   _bfd_vms_output_counted (abfd, hash);
-                                   _bfd_vms_output_flush (abfd);
-                                 }
-                               else if (bfd_is_abs_section (sym->section))
-                                 {
-                                   if (_bfd_vms_output_check (abfd, 16) < 0)
-                                     {
-                                       end_etir_record (abfd);
-                                       start_etir_record (abfd,
-                                                          section->index,
-                                                          vaddr, FALSE);
-                                     }
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STA_LW,
-                                                          -1);
-                                   _bfd_vms_output_quad (abfd,
-                                                         (uquad) sym->value);
-                                   _bfd_vms_output_flush (abfd);
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STO_LW,
-                                                          -1);
-                                   _bfd_vms_output_flush (abfd);
-                                 }
-                               else
-                                 {
-                                   if (_bfd_vms_output_check (abfd, 32) < 0)
-                                     {
-                                       end_etir_record (abfd);
-                                       start_etir_record (abfd,
-                                                          section->index,
-                                                          vaddr, FALSE);
-                                     }
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STA_PQ,
-                                                          -1);
-                                   _bfd_vms_output_long (abfd,
-                                                         (unsigned long) (sec->index));
-                                   _bfd_vms_output_quad (abfd,
-                                                         ((uquad) (*rptr)->addend
-                                                          + (uquad) sym->value));
-                                   _bfd_vms_output_flush (abfd);
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STO_LW,
-                                                          -1);
-                                   _bfd_vms_output_flush (abfd);
-                                 }
-                             }
-                             break;
-
-                           case ALPHA_R_REFQUAD:
-                             {
-                               if (bfd_is_und_section (sym->section))
-                                 {
-                                   int slen = strlen ((char *) sym->name);
-                                   char *hash;
-                                   if (_bfd_vms_output_check (abfd, slen) < 0)
-                                     {
-                                       end_etir_record (abfd);
-                                       start_etir_record (abfd,
-                                                          section->index,
-                                                          vaddr, FALSE);
-                                     }
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STO_GBL,
-                                                          -1);
-                                   hash = (_bfd_vms_length_hash_symbol
-                                           (abfd, sym->name, EOBJ_S_C_SYMSIZ));
-                                   _bfd_vms_output_counted (abfd, hash);
-                                   _bfd_vms_output_flush (abfd);
-                                 }
-                               else if (bfd_is_abs_section (sym->section))
-                                 {
-                                   if (_bfd_vms_output_check (abfd, 16) < 0)
-                                     {
-                                       end_etir_record (abfd);
-                                       start_etir_record (abfd,
-                                                          section->index,
-                                                          vaddr, FALSE);
-                                     }
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STA_QW,
-                                                          -1);
-                                   _bfd_vms_output_quad (abfd,
-                                                         (uquad) sym->value);
-                                   _bfd_vms_output_flush (abfd);
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STO_QW,
-                                                          -1);
-                                   _bfd_vms_output_flush (abfd);
-                                 }
-                               else
-                                 {
-                                   if (_bfd_vms_output_check (abfd, 32) < 0)
-                                     {
-                                       end_etir_record (abfd);
-                                       start_etir_record (abfd,
-                                                          section->index,
-                                                          vaddr, FALSE);
-                                     }
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STA_PQ,
-                                                          -1);
-                                   _bfd_vms_output_long (abfd,
-                                                         (unsigned long) (sec->index));
-                                   _bfd_vms_output_quad (abfd,
-                                                         ((uquad) (*rptr)->addend
-                                                          + (uquad) sym->value));
-                                   _bfd_vms_output_flush (abfd);
-                                   _bfd_vms_output_begin (abfd,
-                                                          ETIR_S_C_STO_OFF,
-                                                          -1);
-                                   _bfd_vms_output_flush (abfd);
-                                 }
-                             }
-                             break;
-
-                           case ALPHA_R_HINT:
-                             {
-                               int hint_size;
-                               char *hash ATTRIBUTE_UNUSED;
-
-                               hint_size = sptr->size;
-                               sptr->size = len;
-                               sto_imm (abfd, sptr, vaddr, section->index);
-                               sptr->size = hint_size;
-#if 0
-                               vms_output_begin (abfd,
-                                                 ETIR_S_C_STO_HINT_GBL, -1);
-                               vms_output_long (abfd,
-                                                (unsigned long) (sec->index));
-                               vms_output_quad (abfd, (uquad) addr);
-
-                               hash = (_bfd_vms_length_hash_symbol
-                                       (abfd, sym->name, EOBJ_S_C_SYMSIZ));
-                               vms_output_counted (abfd, hash);
-
-                               vms_output_flush (abfd);
-#endif
-                             }
-                             break;
-                           case ALPHA_R_LINKAGE:
-                             {
-                               char *hash;
-
-                               if (_bfd_vms_output_check (abfd, 64) < 0)
-                                 {
-                                   end_etir_record (abfd);
-                                   start_etir_record (abfd, section->index,
-                                                      vaddr, FALSE);
-                                 }
-                               _bfd_vms_output_begin (abfd,
-                                                      ETIR_S_C_STC_LP_PSB,
-                                                      -1);
-                               _bfd_vms_output_long (abfd,
-                                                     (unsigned long) PRIV (vms_linkage_index));
-                               PRIV (vms_linkage_index) += 2;
-                               hash = (_bfd_vms_length_hash_symbol
-                                       (abfd, sym->name, EOBJ_S_C_SYMSIZ));
-                               _bfd_vms_output_counted (abfd, hash);
-                               _bfd_vms_output_byte (abfd, 0);
-                               _bfd_vms_output_flush (abfd);
-                             }
-                             break;
-
-                           case ALPHA_R_CODEADDR:
-                             {
-                               int slen = strlen ((char *) sym->name);
-                               char *hash;
-                               if (_bfd_vms_output_check (abfd, slen) < 0)
-                                 {
-                                   end_etir_record (abfd);
-                                   start_etir_record (abfd,
-                                                      section->index,
-                                                      vaddr, FALSE);
-                                 }
-                               _bfd_vms_output_begin (abfd,
-                                                      ETIR_S_C_STO_CA,
-                                                      -1);
-                               hash = (_bfd_vms_length_hash_symbol
-                                       (abfd, sym->name, EOBJ_S_C_SYMSIZ));
-                               _bfd_vms_output_counted (abfd, hash);
-                               _bfd_vms_output_flush (abfd);
-                             }
-                             break;
-
-                           default:
-                             (*_bfd_error_handler) (_("Unhandled relocation %s"),
-                                                    (*rptr)->howto->name);
-                             break;
-                           }
-
-                         vaddr += len;
-
-                         if (len == sptr->size)
-                           {
-                             break;
-                           }
-                         else
-                           {
-                             sptr->contents += len;
-                             sptr->offset += len;
-                             sptr->size -= len;
-                             i--;
-                             rptr++;
-                           }
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL_LW, -1);
+                         _bfd_vms_output_counted (abfd, hash);
+                         _bfd_vms_output_flush (abfd);
                        }
                        }
-                     else                      /* sptr starts after reloc */
+                   }
+                 else if (bfd_is_abs_section (sym->section))
+                   {
+                     etir_output_check (abfd, section, curr_addr, 16);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
+                     _bfd_vms_output_long (abfd, (unsigned long) sym->value);
+                     _bfd_vms_output_flush (abfd);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
+                     _bfd_vms_output_flush (abfd);
+                   }
+                 else
+                   {
+                     etir_output_check (abfd, section, curr_addr, 32);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
+                     _bfd_vms_output_long (abfd, (unsigned long) sec->index);
+                     _bfd_vms_output_quad (abfd, (uquad) rptr->addend
+                                                   + (uquad) sym->value);
+                     _bfd_vms_output_flush (abfd);
+                     /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
+                        says that we should have a ETIR_S_C_STO_OFF here.
+                        But the relocation would not be BFD_RELOC_32 then.
+                        This case is very likely unreachable.  */
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
+                     _bfd_vms_output_flush (abfd);
+                   }
+                 break;
+
+               case ALPHA_R_REFQUAD:
+                 if (bfd_is_und_section (sym->section))
+                   {
+                     bfd_vma addend = rptr->addend;
+                     slen = strlen ((char *) sym->name);
+                     hash = _bfd_vms_length_hash_symbol
+                              (abfd, sym->name, EOBJ_S_C_SYMSIZ);
+                     etir_output_check (abfd, section, curr_addr, slen);
+                     if (addend)
                        {
                        {
-                         i--;                  /* check next reloc */
-                         rptr++;
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
+                         _bfd_vms_output_counted (abfd, hash);
+                         _bfd_vms_output_flush (abfd);
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1);
+                         _bfd_vms_output_quad (abfd, (uquad) addend);
+                         _bfd_vms_output_flush (abfd);
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
+                         _bfd_vms_output_flush (abfd);
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
+                         _bfd_vms_output_flush (abfd);
                        }
                        }
-
-                     if (i==0)                 /* all reloc checked */
+                     else
                        {
                        {
-                         if (sptr->size > 0)
-                           {
-                             /* dump rest */
-                             sto_imm (abfd, sptr, vaddr, section->index);
-                             vaddr += sptr->size;
-                           }
-                         break;
+                         _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL, -1);
+                         _bfd_vms_output_counted (abfd, hash);
+                         _bfd_vms_output_flush (abfd);
                        }
                        }
-                   } /* for (;;) */
-               } /* if SEC_RELOC */
-             else                              /* no relocs, just dump */
-               {
-                 sto_imm (abfd, sptr, vaddr, section->index);
-                 vaddr += sptr->size;
+                   }
+                 else if (bfd_is_abs_section (sym->section))
+                   {
+                     etir_output_check (abfd, section, curr_addr, 16);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1);
+                     _bfd_vms_output_quad (abfd, (uquad) sym->value);
+                     _bfd_vms_output_flush (abfd);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
+                     _bfd_vms_output_flush (abfd);
+                   }
+                 else
+                   {
+                     etir_output_check (abfd, section, curr_addr, 32);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
+                     _bfd_vms_output_long (abfd, (unsigned long) sec->index);
+                     _bfd_vms_output_quad (abfd, (uquad) rptr->addend
+                                                   + (uquad) sym->value);
+                     _bfd_vms_output_flush (abfd);
+                     _bfd_vms_output_begin (abfd, ETIR_S_C_STO_OFF, -1);
+                     _bfd_vms_output_flush (abfd);
+                   }
+                 break;
+
+               case ALPHA_R_HINT:
+                 sto_imm (abfd, size, curr_data, curr_addr,
+                          section->index, section->name);
+                 break;
+               
+               case ALPHA_R_LINKAGE:
+                 etir_output_check (abfd, section, curr_addr, 64);
+                 _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LP_PSB, -1);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) PRIV (vms_linkage_index));
+                 PRIV (vms_linkage_index) += 2;
+                 hash = _bfd_vms_length_hash_symbol
+                          (abfd, sym->name, EOBJ_S_C_SYMSIZ);
+                 _bfd_vms_output_counted (abfd, hash);
+                 _bfd_vms_output_byte (abfd, 0);
+                 _bfd_vms_output_flush (abfd);
+                 break;
+
+               case ALPHA_R_CODEADDR:
+                 slen = strlen ((char *) sym->name);
+                 hash = _bfd_vms_length_hash_symbol
+                          (abfd, sym->name, EOBJ_S_C_SYMSIZ);
+                 etir_output_check (abfd, section, curr_addr, slen);
+                 _bfd_vms_output_begin (abfd, ETIR_S_C_STO_CA, -1);
+                 _bfd_vms_output_counted (abfd, hash);
+                 _bfd_vms_output_flush (abfd);
+                 break;
+
+               case ALPHA_R_NOP:
+                 udata
+                   = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+                 etir_output_check (abfd, section, curr_addr,
+                                    32 + 1 + strlen (udata->origname));
+                 _bfd_vms_output_begin (abfd, ETIR_S_C_STC_NOP_GBL, -1);
+                 _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (abfd, (uquad) rptr->address);
+                 _bfd_vms_output_long (abfd, (unsigned long) 0x47ff041f);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
+                 _bfd_vms_output_counted
+                   (abfd, _bfd_vms_length_hash_symbol
+                            (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
+                 _bfd_vms_output_flush (abfd);
+                 break;
+
+               case ALPHA_R_BSR:
+                 (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc"));
+                 break;
+
+               case ALPHA_R_LDA:
+                 udata
+                   = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+                 etir_output_check (abfd, section, curr_addr,
+                                    32 + 1 + strlen (udata->origname));
+                 _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LDA_GBL, -1);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->lkindex + 1);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (abfd, (uquad) rptr->address);
+                 _bfd_vms_output_long (abfd, (unsigned long) 0x237B0000);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->bsym->section->index);
+                 _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
+                 _bfd_vms_output_counted
+                   (abfd, _bfd_vms_length_hash_symbol
+                           (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
+                 _bfd_vms_output_flush (abfd);
+                 break;
+
+               case ALPHA_R_BOH:
+                 udata
+                   = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+                 etir_output_check (abfd, section, curr_addr,
+                                      32 + 1 + strlen (udata->origname));
+                 _bfd_vms_output_begin (abfd, ETIR_S_C_STC_BOH_GBL, -1);
+                 _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (abfd, (uquad) rptr->address);
+                 _bfd_vms_output_long (abfd, (unsigned long) 0xD3400000);
+                 _bfd_vms_output_long
+                   (abfd, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
+                 _bfd_vms_output_counted
+                   (abfd, _bfd_vms_length_hash_symbol
+                            (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
+                 _bfd_vms_output_flush (abfd);
+                 break;
+
+               default:
+                 (*_bfd_error_handler) (_("Unhandled relocation %s"),
+                                        rptr->howto->name);
+                 break;
                }
 
                }
 
-             sptr = sptr->next;
+             curr_data += size;
+             curr_addr += size;
+           } /* End of relocs loop.  */
 
 
-           } /* while (sptr != 0) */
-
-         end_etir_record (abfd);
-
-       } /* has_contents */
+         if (!pass2_in_progress)
+           {
+             /* Output rest of section.  */
+             if (curr_addr > section->size)
+               (*_bfd_error_handler) (_("Size error in section %s"),
+                                      section->name);
+             size = section->size - curr_addr;
+             sto_imm (abfd, size, curr_data, curr_addr,
+                      section->index, section->name);
+             curr_data += size;
+             curr_addr += size;
+
+             if (pass2_needed)
+               {
+                 pass2_in_progress = 1;
+                 goto new_pass;
+               }
+           }
+       }
+  
+      else /* (section->flags & SEC_RELOC) */
+       sto_imm (abfd, section->size, section->contents, 0,
+                section->index, section->name);
 
 
-      section = section->next;
+      end_etir_record (abfd);
     }
 
   _bfd_vms_output_alignment (abfd, 2);
   return 0;
 }
     }
 
   _bfd_vms_output_alignment (abfd, 2);
   return 0;
 }
-
-/* Write traceback data for bfd abfd.  */
-
-int
-_bfd_vms_write_tbt (abfd, objtype)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     int objtype ATTRIBUTE_UNUSED;
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
-#endif
-
-  return 0;
-}
-
-/* Write debug info for bfd abfd.  */
-
-int
-_bfd_vms_write_dbg (abfd, objtype)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     int objtype ATTRIBUTE_UNUSED;
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
-#endif
-
-  return 0;
-}
This page took 0.094479 seconds and 4 git commands to generate.