2010-04-14 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Wed, 14 Apr 2010 09:24:59 +0000 (09:24 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 14 Apr 2010 09:24:59 +0000 (09:24 +0000)
* Makefile.am (BFD32_BACKENDS): Remove vms-gsd.lo, vms-hdr.lo,
vms-tir.lo, vms.lo and add vms-alpha.lo
(BFD32_BACKENDS_CFILES): Remove vms-gsd.c, vms-hdr.c,
vms-tir.c, vms.c and add vms-alpha.c
* Makefile.in: Regenerate.
* configure.in (TDEFINES): Adjust file list for vms_alpha_vec.
Remove vms_vax_vec.
* configure: Regenerate.
* targets.c (vms_vax_vec): Remove the declaration.
(_bfd_target_vector): Remove vms_vax_vec.
* vms-alpha.c: New file.
* vms-gsd.c: Removed, rewritten in vms-alpha.c
* vms-hdr.c: Ditto.
* vms-tir.c: Ditto.
* vms.c: Ditto.
* vms-misc.c: Fix indentation and comments.  Replace most of
#if VMS_DEBUG/vms_debug with vms_debug2.
(_bfd_vms_hash_newfunc): Moved to vms-alpha.c
(hash_string): Ditto.
(_bfd_vms_length_hash_symbol): Ditto.
(maybe_adjust_record_pointer_for_object): Ditto.
(_bfd_vms_get_object_record): Ditto.
(vms_get_remaining_object_record): Ditto.
(_bfd_vms_push): Ditto.
(_bfd_vms_pop): Ditto.
(_bfd_vms_get_header_values): Removed.
(_bfd_vms_get_first_record): Removed.
(vms_get_remaining_image_record): Removed.
(new_symbol): Removed.
(_bfd_vms_enter_symbol): Removed.
(_bfd_vms_save_sized_string): Use memcpy instead of strncpy.
(_bfd_vms_output_begin): Remove rechead parameter.  Replace bfd
parameter with struct vms_rec_wr.
(_bfd_vms_output_push): Removed and replaced by ...
(_bfd_vms_output_begin_subrec): ... new function.
(_bfd_vms_output_alignment): Replace bfd parameter with
struct vms_rec_wr, and adjust.
(_bfd_vms_output_check): Ditto
(_bfd_vms_output_byte): Ditto.
(_bfd_vms_output_short): Ditto.
(_bfd_vms_output_long): Ditto.
(_bfd_vms_output_quad): Ditto.
(_bfd_vms_output_counted): Ditto.
(_bfd_vms_output_dump): Ditto.
(_bfd_vms_output_fill): Ditto.
(_bfd_vms_output_pop): Removed and replaced by ...
(_bfd_vms_output_end_subrec): ... new function.
(_bfd_vms_output_flush): Removed.
(_bfd_vms_output_align): New function.
(_bfd_vms_output_end): Add recwr parameter.  Adjust for this new
parameter.
(vms_convert_to_var): New function imported from vms.c
(vms_convert_to_var_1): Ditto.
(vms_convert_to_var_unix_filename): Ditto.
(vms_get_module_name): Ditto.
(get_vms_time_string): Ditto.
(vms_time_to_time_t): Ditto.
(vms_rawtime_to_time_t): Ditto.
* vms.h: All macros for the VMS file format are now in include/vms.
Prototypes for vms.c, vms-gsd.c, vms-misc.c, vms-hdr.c, vms-tir.c
have been removed.
(struct vms_symbol_struct, struct stack_struct): Moved to vms-alpha.c
(struct fileinfo, struct srecinfo, struct lineinfo): Ditto.
(struct funcinfo, struct vms_private_data_struct): Ditto.
(struct vms_section_data_struct): Ditto.
(struct vms_rec_rd, stryct vms_rec_wr): New declarations.
(vms_get_module_name, get_vms_time_string): New declarations.
(vms_time_to_time_t, vms_rawtime_to_time_t): Ditto.
(_bfd_vms_output_begin_subrec, _bfd_vms_output_end_subrec): Ditto.
(_bfd_vms_save_sized_string, _bfd_vms_save_counted_string): Adjusted.
(_bfd_vms_output_begin, _bfd_vms_output_alignment): Ditto.
(_bfd_vms_output_end,_bfd_vms_output_check): Ditto.
(_bfd_vms_output_byte, _bfd_vms_output_short): Ditto.
(_bfd_vms_output_long, _bfd_vms_output_quad): Ditto.
(_bfd_vms_output_counted, _bfd_vms_output_dump): Ditto.
(_bfd_vms_output_fill): Ditto.
(bfd_vms_set_section_flags): Ditto.

13 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/configure
bfd/configure.in
bfd/targets.c
bfd/vms-alpha.c [new file with mode: 0644]
bfd/vms-gsd.c [deleted file]
bfd/vms-hdr.c [deleted file]
bfd/vms-misc.c
bfd/vms-tir.c [deleted file]
bfd/vms.c [deleted file]
bfd/vms.h

index 3ec74f2201bf5fbd2f5598e6a44b788a3b69156c..59e1cba2cff963dab007ae303a192fcef712f788 100644 (file)
@@ -1,3 +1,83 @@
+2010-04-14  Tristan Gingold  <gingold@adacore.com>
+
+       * Makefile.am (BFD32_BACKENDS): Remove vms-gsd.lo, vms-hdr.lo,
+       vms-tir.lo, vms.lo and add vms-alpha.lo
+       (BFD32_BACKENDS_CFILES): Remove vms-gsd.c, vms-hdr.c,
+       vms-tir.c, vms.c and add vms-alpha.c
+       * Makefile.in: Regenerate.
+       * configure.in (TDEFINES): Adjust file list for vms_alpha_vec.
+       Remove vms_vax_vec.
+       * configure: Regenerate.
+       * targets.c (vms_vax_vec): Remove the declaration.
+       (_bfd_target_vector): Remove vms_vax_vec.
+       * vms-alpha.c: New file.
+       * vms-gsd.c: Removed, rewritten in vms-alpha.c
+       * vms-hdr.c: Ditto.
+       * vms-tir.c: Ditto.
+       * vms.c: Ditto.
+       * vms-misc.c: Fix indentation and comments.  Replace most of
+       #if VMS_DEBUG/vms_debug with vms_debug2.
+       (_bfd_vms_hash_newfunc): Moved to vms-alpha.c
+       (hash_string): Ditto.
+       (_bfd_vms_length_hash_symbol): Ditto.
+       (maybe_adjust_record_pointer_for_object): Ditto.
+       (_bfd_vms_get_object_record): Ditto.
+       (vms_get_remaining_object_record): Ditto.
+       (_bfd_vms_push): Ditto.
+       (_bfd_vms_pop): Ditto.
+       (_bfd_vms_get_header_values): Removed.
+       (_bfd_vms_get_first_record): Removed.
+       (vms_get_remaining_image_record): Removed.
+       (new_symbol): Removed.
+       (_bfd_vms_enter_symbol): Removed.
+       (_bfd_vms_save_sized_string): Use memcpy instead of strncpy.
+       (_bfd_vms_output_begin): Remove rechead parameter.  Replace bfd
+       parameter with struct vms_rec_wr.
+       (_bfd_vms_output_push): Removed and replaced by ...
+       (_bfd_vms_output_begin_subrec): ... new function.
+       (_bfd_vms_output_alignment): Replace bfd parameter with
+       struct vms_rec_wr, and adjust.
+       (_bfd_vms_output_check): Ditto
+       (_bfd_vms_output_byte): Ditto.
+       (_bfd_vms_output_short): Ditto.
+       (_bfd_vms_output_long): Ditto.
+       (_bfd_vms_output_quad): Ditto.
+       (_bfd_vms_output_counted): Ditto.
+       (_bfd_vms_output_dump): Ditto.
+       (_bfd_vms_output_fill): Ditto.
+       (_bfd_vms_output_pop): Removed and replaced by ...
+       (_bfd_vms_output_end_subrec): ... new function.
+       (_bfd_vms_output_flush): Removed.
+       (_bfd_vms_output_align): New function.
+       (_bfd_vms_output_end): Add recwr parameter.  Adjust for this new
+       parameter.
+       (vms_convert_to_var): New function imported from vms.c
+       (vms_convert_to_var_1): Ditto.
+       (vms_convert_to_var_unix_filename): Ditto.
+       (vms_get_module_name): Ditto.
+       (get_vms_time_string): Ditto.
+       (vms_time_to_time_t): Ditto.
+       (vms_rawtime_to_time_t): Ditto.
+       * vms.h: All macros for the VMS file format are now in include/vms.
+       Prototypes for vms.c, vms-gsd.c, vms-misc.c, vms-hdr.c, vms-tir.c
+       have been removed.
+       (struct vms_symbol_struct, struct stack_struct): Moved to vms-alpha.c
+       (struct fileinfo, struct srecinfo, struct lineinfo): Ditto.
+       (struct funcinfo, struct vms_private_data_struct): Ditto.
+       (struct vms_section_data_struct): Ditto.
+       (struct vms_rec_rd, stryct vms_rec_wr): New declarations.
+       (vms_get_module_name, get_vms_time_string): New declarations.
+       (vms_time_to_time_t, vms_rawtime_to_time_t): Ditto.
+       (_bfd_vms_output_begin_subrec, _bfd_vms_output_end_subrec): Ditto.
+       (_bfd_vms_save_sized_string, _bfd_vms_save_counted_string): Adjusted.
+       (_bfd_vms_output_begin, _bfd_vms_output_alignment): Ditto.
+       (_bfd_vms_output_end,_bfd_vms_output_check): Ditto.
+       (_bfd_vms_output_byte, _bfd_vms_output_short): Ditto.
+       (_bfd_vms_output_long, _bfd_vms_output_quad): Ditto.
+       (_bfd_vms_output_counted, _bfd_vms_output_dump): Ditto.
+       (_bfd_vms_output_fill): Ditto.
+       (bfd_vms_set_section_flags): Ditto.
+
 2010-04-14  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
        * elflink.c (_bfd_elf_merge_symbol): Tighten up the test for early
index ac38177ed0c1974d5a00326ce201222cd813707b..ef545f5f02c065d8604be6b8fbc920688bca7e8b 100644 (file)
@@ -391,12 +391,9 @@ BFD32_BACKENDS = \
        vaxbsd.lo \
        vaxnetbsd.lo \
        versados.lo \
-       vms-gsd.lo \
-       vms-hdr.lo \
+       vms-alpha.lo \
        vms-lib.lo \
        vms-misc.lo \
-       vms-tir.lo \
-       vms.lo \
        xcofflink.lo \
        xsym.lo \
        xtensa-isa.lo \
@@ -576,12 +573,9 @@ BFD32_BACKENDS_CFILES = \
        vaxbsd.c \
        vaxnetbsd.c \
        versados.c \
-       vms-gsd.c \
-       vms-hdr.c \
+       vms-alpha.c \
        vms-lib.c \
        vms-misc.c \
-       vms-tir.c \
-       vms.c \
        xcofflink.c \
        xsym.c \
        xtensa-isa.c \
index ed626c957dd3eb26a5cf9cedce120a135765eadb..7134a704edf4698acc0ec6294fbbe911fc93f640 100644 (file)
@@ -688,12 +688,9 @@ BFD32_BACKENDS = \
        vaxbsd.lo \
        vaxnetbsd.lo \
        versados.lo \
-       vms-gsd.lo \
-       vms-hdr.lo \
-       vms-lib.lo \
        vms-misc.lo \
-       vms-tir.lo \
-       vms.lo \
+       vms-alpha.lo \
+       vms-lib.lo \
        xcofflink.lo \
        xsym.lo \
        xtensa-isa.lo \
@@ -873,12 +870,9 @@ BFD32_BACKENDS_CFILES = \
        vaxbsd.c \
        vaxnetbsd.c \
        versados.c \
-       vms-gsd.c \
-       vms-hdr.c \
+       vms-alpha.c \
        vms-lib.c \
        vms-misc.c \
-       vms-tir.c \
-       vms.c \
        xcofflink.c \
        xsym.c \
        xtensa-isa.c \
@@ -1488,12 +1482,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vaxnetbsd.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verilog.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/versados.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-gsd.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-hdr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-alpha.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-lib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-misc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-tir.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcofflink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsym.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-isa.Plo@am__quote@
index 928f984f7ba4d6ea6b3f50d46dc2356c804eb3bb..7d16fab0be6cb73058145d8bb4e5fedb295fda71 100755 (executable)
@@ -15283,9 +15283,8 @@ do
     vax1knetbsd_vec)           tb="$tb vax1knetbsd.lo aout32.lo" ;;
     vaxbsd_vec)                        tb="$tb vaxbsd.lo aout32.lo" ;;
     versados_vec)              tb="$tb versados.lo" ;;
-    vms_alpha_vec)             tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo vms-lib.lo"; target_size=64 ;;
+    vms_alpha_vec)             tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;;
     vms_lib_txt_vec)           tb="$tb vms-lib.lo vms-misc.lo" ;;
-    vms_vax_vec)               tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo" ;;
     w65_vec)                   tb="$tb coff-w65.lo reloc16.lo" ;;
     we32kcoff_vec)             tb="$tb coff-we32k.lo" ;;
     z80coff_vec)               tb="$tb coff-z80.lo reloc16.lo" ;;
index 28d5bdd6006cc43aa1508936e6b18475ce01115a..eb9d7e7634062a908cf240f5ebb00369714f66fb 100644 (file)
@@ -927,9 +927,8 @@ do
     vax1knetbsd_vec)           tb="$tb vax1knetbsd.lo aout32.lo" ;;
     vaxbsd_vec)                        tb="$tb vaxbsd.lo aout32.lo" ;;
     versados_vec)              tb="$tb versados.lo" ;;
-    vms_alpha_vec)             tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo vms-lib.lo"; target_size=64 ;;
+    vms_alpha_vec)             tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;;
     vms_lib_txt_vec)           tb="$tb vms-lib.lo vms-misc.lo" ;;
-    vms_vax_vec)               tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo" ;;
     w65_vec)                   tb="$tb coff-w65.lo reloc16.lo" ;;
     we32kcoff_vec)             tb="$tb coff-we32k.lo" ;;
     z80coff_vec)               tb="$tb coff-z80.lo reloc16.lo" ;;
index 5ee73c46e74d892fb6a8827b4e525c06b24f02bd..2e330e6dbed37909b61a4b49589682002ea12ef0 100644 (file)
@@ -828,7 +828,6 @@ extern const bfd_target vax1knetbsd_vec;
 extern const bfd_target versados_vec;
 extern const bfd_target vms_alpha_vec;
 extern const bfd_target vms_lib_txt_vec;
-extern const bfd_target vms_vax_vec;
 extern const bfd_target w65_vec;
 extern const bfd_target we32kcoff_vec;
 extern const bfd_target x86_64pe_vec;
@@ -1229,7 +1228,6 @@ static const bfd_target * const _bfd_target_vector[] =
        &vms_alpha_vec,
 #endif
         &vms_lib_txt_vec,
-       &vms_vax_vec,
        &w65_vec,
        &we32kcoff_vec,
        &z80coff_vec,
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
new file mode 100644 (file)
index 0000000..e213f4e
--- /dev/null
@@ -0,0 +1,8968 @@
+/* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+   Initial version written by Klaus Kaempf (kkaempf@rmi.de)
+   Major rewrite by Adacore.
+
+   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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* TODO:
+   o  DMT
+   o  PIC
+   o  Generation of shared image
+   o  Generation of GST in image
+   o  Relocation optimizations
+   o  EISD for the stack
+   o  Vectors isect
+   o  64 bits sections
+   o  Entry point
+   ...
+*/
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "bfdver.h"
+
+#include "vms.h"
+#include "vms/eihd.h"
+#include "vms/eiha.h"
+#include "vms/eihi.h"
+#include "vms/eihs.h"
+#include "vms/eisd.h"
+#include "vms/dmt.h"
+#include "vms/dst.h"
+#include "vms/eihvn.h"
+#include "vms/eobjrec.h"
+#include "vms/egsd.h"
+#include "vms/egps.h"
+#include "vms/eeom.h"
+#include "vms/emh.h"
+#include "vms/eiaf.h"
+#include "vms/shl.h"
+#include "vms/eicp.h"
+#include "vms/etir.h"
+#include "vms/egsy.h"
+#include "vms/esdf.h"
+#include "vms/esdfm.h"
+#include "vms/esdfv.h"
+#include "vms/esrf.h"
+#include "vms/egst.h"
+#include "vms/dsc.h"
+#include "vms/prt.h"
+#include "vms/internal.h"
+\f
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/* The r_type field in a reloc is one of the following values.  */
+#define ALPHA_R_IGNORE         0
+#define ALPHA_R_REFQUAD                1
+#define ALPHA_R_BRADDR         2
+#define ALPHA_R_HINT           3
+#define ALPHA_R_SREL16         4
+#define ALPHA_R_SREL32         5
+#define ALPHA_R_SREL64         6
+#define ALPHA_R_OP_PUSH                7
+#define ALPHA_R_OP_STORE       8
+#define ALPHA_R_OP_PSUB                9
+#define ALPHA_R_OP_PRSHIFT     10
+#define ALPHA_R_LINKAGE                11
+#define ALPHA_R_REFLONG                12
+#define ALPHA_R_CODEADDR       13
+#define ALPHA_R_NOP            14
+#define ALPHA_R_BSR            15
+#define ALPHA_R_LDA            16
+#define ALPHA_R_BOH            17
+/* These are used with DST_S_C_LINE_NUM.  */
+#define DST_S_C_LINE_NUM_HEADER_SIZE 4
+
+/* These are used with DST_S_C_SOURCE */
+
+#define DST_S_B_PCLINE_UNSBYTE  1
+#define DST_S_W_PCLINE_UNSWORD  1
+#define DST_S_L_PCLINE_UNSLONG  1
+
+#define DST_S_B_MODBEG_NAME    14
+#define DST_S_L_RTNBEG_ADDRESS  5
+#define DST_S_B_RTNBEG_NAME    13
+#define DST_S_L_RTNEND_SIZE     5
+
+/* These are used with DST_S_C_SOURCE.  */
+#define DST_S_C_SOURCE_HEADER_SIZE 4
+
+#define DST_S_B_SRC_DF_LENGTH    1
+#define DST_S_W_SRC_DF_FILEID    3
+#define DST_S_B_SRC_DF_FILENAME         20
+#define DST_S_B_SRC_UNSBYTE      1
+#define DST_S_W_SRC_UNSWORD      1
+#define DST_S_L_SRC_UNSLONG      1
+
+/* Debugger symbol definitions.  */
+
+#define DBG_S_L_DMT_MODBEG       0
+#define DBG_S_L_DST_SIZE         4
+#define DBG_S_W_DMT_PSECT_COUNT  8
+#define DBG_S_C_DMT_HEADER_SIZE 12
+
+#define DBG_S_L_DMT_PSECT_START  0
+#define DBG_S_L_DMT_PSECT_LENGTH 4
+#define DBG_S_C_DMT_PSECT_SIZE   8
+
+/* VMS module header.  */
+
+struct hdr_struct
+{
+  char hdr_b_strlvl;
+  int hdr_l_arch1;
+  int hdr_l_arch2;
+  int hdr_l_recsiz;
+  char *hdr_t_name;
+  char *hdr_t_version;
+  char *hdr_t_date;
+  char *hdr_c_lnm;
+  char *hdr_c_src;
+  char *hdr_c_ttl;
+};
+
+#define EMH_DATE_LENGTH  17
+
+/* VMS End-Of-Module records (EOM/EEOM).  */
+
+struct eom_struct
+{
+  unsigned int eom_l_total_lps;
+  unsigned short eom_w_comcod;
+  bfd_boolean eom_has_transfer;
+  unsigned char eom_b_tfrflg;
+  unsigned int eom_l_psindx;
+  unsigned int eom_l_tfradr;
+};
+
+struct vms_symbol_entry
+{
+  bfd *owner;
+
+  /* Common fields.  */
+  unsigned char typ;
+  unsigned char data_type;
+  unsigned short flags;
+
+  /* Section and offset/value of the symbol.  */
+  unsigned int section;
+  unsigned int value;
+
+  /* Section and offset/value for the entry point (only for subprg).  */
+  unsigned int code_section;
+  unsigned int code_value;
+
+  /* Symbol vector offset.  */
+  unsigned int symbol_vector;
+
+  /* Length of the name.  */
+  unsigned char namelen;
+
+  char name[1];
+};
+
+/* Stack value for push/pop commands.  */
+
+struct stack_struct
+{
+  bfd_vma value;
+  unsigned int reloc;
+};
+
+#define STACKSIZE 128
+
+/* A minimal decoding of DST compilation units.  We only decode
+   what's needed to get to the line number information.  */
+
+struct fileinfo
+{
+  char *name;
+  unsigned int srec;
+};
+
+struct srecinfo
+{
+  struct srecinfo *next;
+  unsigned int line;
+  unsigned int sfile;
+  unsigned int srec;
+};
+
+struct lineinfo
+{
+  struct lineinfo *next;
+  bfd_vma address;
+  unsigned int line;
+};
+
+struct funcinfo
+{
+  struct funcinfo *next;
+  char *name;
+  bfd_vma low;
+  bfd_vma high;
+};
+
+struct module
+{
+  /* Chain the previously read compilation unit.  */
+  struct module *next;
+
+  /* The module name.  */
+  char *name;
+
+  /* The start offset and size of debug info in the DST section.  */
+  unsigned int modbeg;
+  unsigned int size;
+
+  /* The lowest and highest addresses contained in this compilation
+     unit as specified in the compilation unit header.  */
+  bfd_vma low;
+  bfd_vma high;
+
+  /* The listing line table.  */
+  struct lineinfo *line_table;
+
+  /* The source record table.  */
+  struct srecinfo *srec_table;
+
+  /* A list of the functions found in this module.  */
+  struct funcinfo *func_table;
+
+  /* Current allocation of file_table.  */
+  unsigned int file_table_count;
+
+  /* An array of the files making up this module.  */
+  struct fileinfo *file_table;
+};
+
+/* BFD private data for alpha-vms.  */
+
+struct vms_private_data_struct
+{
+  /* If true, relocs have been read.  */
+  bfd_boolean reloc_done;
+
+  /* Record input buffer.  */
+  struct vms_rec_rd recrd;
+  struct vms_rec_wr recwr;
+
+  struct hdr_struct hdr_data;          /* data from HDR/EMH record  */
+  struct eom_struct eom_data;          /* data from EOM/EEOM record  */
+  unsigned int section_count;          /* # of sections in following array  */
+  asection **sections;                 /* array of GSD/EGSD sections  */
+
+  /* Array of raw symbols.  */
+  struct vms_symbol_entry **syms;
+
+  /* Canonicalized symbols.  */
+  asymbol **csymbols;
+
+  /* Number of symbols.  */
+  unsigned int gsd_sym_count;
+  /* Size of the syms array.  */
+  unsigned int max_sym_count;
+  /* Number of procedure symbols.  */
+  unsigned int norm_sym_count;
+
+  /* Stack used to evaluate TIR/ETIR commands.  */
+  struct stack_struct *stack;
+  int stackptr;
+
+  /* Content reading.  */
+  asection *image_section;             /* section for image_ptr  */
+  file_ptr image_offset;               /* Offset for image_ptr.  */
+  bfd_boolean image_autoextend;                /* Resize section if necessary.  */
+
+  struct module *modules;              /* list of all compilation units */
+
+  struct dst_info *dst_info;
+  asection *dst_section;
+
+  unsigned int dst_ptr_offsets_count;  /* # of offsets in following array  */
+  unsigned int *dst_ptr_offsets;       /* array of saved image_ptr offsets */
+
+  /* Shared library support */
+  bfd_vma symvva; /* relative virtual address of symbol vector */
+  unsigned int ident;
+  unsigned char matchctl;
+
+  /* Shared library index.  This is used for input bfd while linking.  */
+  unsigned int shr_index;
+
+  /* Used to place structures in the file.  */
+  file_ptr file_pos;
+
+  /* Simply linked list of eisd.  */
+  struct vms_internal_eisd_map *eisd_head;
+  struct vms_internal_eisd_map *eisd_tail;
+
+  /* Simply linked list of eisd for shared libraries.  */
+  struct vms_internal_eisd_map *gbl_eisd_head;
+  struct vms_internal_eisd_map *gbl_eisd_tail;
+
+  /* linkage index counter used by conditional store commands */
+  int vms_linkage_index;
+
+  /* see tc-alpha.c of gas for a description.  */
+  int flag_hash_long_names;    /* -+, hash instead of truncate */
+  int flag_show_after_trunc;   /* -H, show hashing/truncation */
+};
+
+#define PRIV2(abfd, name) \
+  (((struct vms_private_data_struct *)(abfd)->tdata.any)->name)
+#define PRIV(name) PRIV2(abfd,name)
+
+
+/* Used to keep extra VMS specific information for a given section.
+
+   reloc_size holds the size of the relocation stream, note this
+   is very different from the number of relocations as VMS relocations
+   are variable length.
+
+   reloc_stream is the actual stream of relocation entries.  */
+
+struct vms_section_data_struct
+{
+  /* Maximnum number of entries in sec->relocation.  */
+  unsigned reloc_max;
+
+  /* Corresponding eisd.  Used only while generating executables.  */
+  struct vms_internal_eisd_map *eisd;
+
+  /* PSC flags to be clear.  */
+  flagword no_flags;
+
+  /* PSC flags to be set.  */
+  flagword flags;
+};
+
+#define vms_section_data(sec) \
+  ((struct vms_section_data_struct *)sec->used_by_bfd)
+
+/* To be called from the debugger.  */
+struct vms_private_data_struct *bfd_vms_get_data (bfd *abfd);
+
+static int vms_get_remaining_object_record (bfd *abfd, int read_so_far);
+static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd);
+static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *);
+static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *);
+static void alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *,
+                                    bfd_vma);
+static void alpha_vms_add_lw_reloc (struct bfd_link_info *info);
+static void alpha_vms_add_qw_reloc (struct bfd_link_info *info);
+static void alpha_vms_add_lw_fixup (struct bfd_link_info *, unsigned int,
+                                    bfd_vma);
+
+struct vector_type
+{
+  unsigned int max_el;
+  unsigned int nbr_el;
+  void *els;
+};
+
+/* Number of elements in VEC.  */
+
+#define VEC_COUNT(VEC) ((VEC).nbr_el)
+
+/* Get the address of the Nth element.  */
+
+#define VEC_EL(VEC, TYPE, N) (((TYPE *)((VEC).els))[N])
+
+#define VEC_INIT(VEC)                           \
+  do {                                          \
+    (VEC).max_el = 0;                           \
+    (VEC).nbr_el = 0;                           \
+    (VEC).els = NULL;                           \
+  } while (0)
+
+/* Be sure there is room for a new element.  */
+
+static void vector_grow1 (struct vector_type *vec, size_t elsz);
+
+/* Allocate room for a new element and return its address.  */
+
+#define VEC_APPEND(VEC, TYPE)                                   \
+  (vector_grow1 (&VEC, sizeof (TYPE)), &VEC_EL(VEC, TYPE, (VEC).nbr_el++))
+
+/* Append an element.  */
+
+#define VEC_APPEND_EL(VEC, TYPE, EL)            \
+  (*(VEC_APPEND (VEC, TYPE)) = EL)
+
+struct alpha_vms_vma_ref
+{
+  bfd_vma vma; /* Vma in the output.  */
+  bfd_vma ref; /* Reference in the input.  */
+};
+
+struct alpha_vms_shlib_el
+{
+  bfd *abfd;
+  bfd_boolean has_fixups;
+
+  struct vector_type lp;       /* Vector of bfd_vma.  */
+  struct vector_type ca;       /* Vector of bfd_vma.  */
+  struct vector_type qr;       /* Vector of struct alpha_vms_vma_ref.  */
+};
+
+/* Alpha VMS linker hash table.  */
+
+struct alpha_vms_link_hash_table
+{
+  struct bfd_link_hash_table root;
+
+  /* Vector of shared libaries.  */
+  struct vector_type shrlibs;
+
+  /* Fixup section.  */
+  asection *fixup;
+
+  /* Base address.  Used by fixups.  */
+  bfd_vma base_addr;
+};
+
+#define alpha_vms_link_hash(INFO) \
+  ((struct alpha_vms_link_hash_table *)(INFO->hash))
+
+/* Alpha VMS linker hash table entry.  */
+
+struct alpha_vms_link_hash_entry
+{
+  struct bfd_link_hash_entry root;
+
+  /* Pointer to the original vms symbol.  */
+  struct vms_symbol_entry *sym;
+};
+\f
+/* Image reading.  */
+
+/* Read & process EIHD record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
+                     unsigned int *eihs_offset)
+{
+  unsigned int imgtype, size;
+  bfd_vma symvva;
+  struct vms_eihd *eihd = (struct vms_eihd *)PRIV (recrd.rec);
+
+  vms_debug2 ((8, "_bfd_vms_slurp_eihd\n"));
+
+  size = bfd_getl32 (eihd->size);
+  imgtype = bfd_getl32 (eihd->imgtype);
+
+  if (imgtype == EIHD__K_EXE || imgtype == EIHD__K_LIM)
+    abfd->flags |= EXEC_P;
+
+  symvva = bfd_getl64 (eihd->symvva);
+  if (symvva != 0)
+    {
+      PRIV (symvva) = symvva;
+      abfd->flags |= DYNAMIC;
+    }
+
+  PRIV (ident) = bfd_getl32 (eihd->ident);
+  PRIV (matchctl) = eihd->matchctl;
+
+  *eisd_offset = bfd_getl32 (eihd->isdoff);
+  *eihs_offset = bfd_getl32 (eihd->symdbgoff);
+
+  vms_debug2 ((4, "EIHD size %d imgtype %d symvva 0x%lx eisd %d eihs %d\n",
+               size, imgtype, (unsigned long)symvva,
+               *eisd_offset, *eihs_offset));
+
+  return FALSE;
+}
+
+/* Read & process EISD record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
+{
+  int section_count = 0;
+
+  vms_debug2 ((8, "_bfd_vms_slurp_eisd\n"));
+
+  while (1)
+    {
+      struct vms_eisd *eisd;
+      unsigned int rec_size;
+      unsigned int size;
+      unsigned long long vaddr;
+      unsigned int flags;
+      unsigned int vbn;
+      char *name = NULL;
+      asection *section;
+      flagword bfd_flags;
+
+      eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset);
+      rec_size = bfd_getl32 (eisd->eisdsize);
+
+      if (rec_size == 0)
+        break;
+
+      /* Skip to next block if pad.  */
+      if (rec_size == 0xffffffff)
+        {
+          offset = (offset + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+          continue;
+        }
+      else
+        offset += rec_size;
+
+      size = bfd_getl32 (eisd->secsize);
+      vaddr = bfd_getl64 (eisd->virt_addr);
+      flags = bfd_getl32 (eisd->flags);
+      vbn = bfd_getl32 (eisd->vbn);
+
+      vms_debug2 ((4, "EISD at 0x%x size 0x%x addr 0x%lx flags 0x%x blk %d\n",
+                   offset, size, (unsigned long)vaddr, flags, vbn));
+
+      /* VMS combines psects from .obj files into isects in the .exe.  This
+        process doesn't preserve enough information to reliably determine
+        what's in each section without examining the data.  This is
+        especially true of DWARF debug sections.  */
+      bfd_flags = SEC_ALLOC;
+
+      if (flags & EISD__M_EXE)
+       bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
+
+      if (flags & EISD__M_NONSHRADR)
+       bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
+
+      if (!(flags & EISD__M_WRT))
+       bfd_flags |= SEC_READONLY;
+
+      if (flags & EISD__M_DZRO)
+       bfd_flags |= SEC_DATA;
+
+      if (flags & EISD__M_FIXUPVEC)
+       bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
+
+      if (flags & EISD__M_CRF)
+       bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
+
+      if (flags & EISD__M_GBL)
+       {
+         name = _bfd_vms_save_counted_string (eisd->gblnam);
+         bfd_flags |= SEC_COFF_SHARED_LIBRARY;
+         bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
+       }
+      else if (flags & EISD__M_FIXUPVEC)
+        name = "$FIXUPVEC$";
+      else if (eisd->type == EISD__K_USRSTACK)
+        name = "$STACK$";
+      else
+       {
+          const char *pfx;
+
+         name = (char*) bfd_alloc (abfd, 32);
+          if (flags & EISD__M_DZRO)
+            pfx = "BSS";
+          else if (flags & EISD__M_EXE)
+            pfx = "CODE";
+          else if (!(flags & EISD__M_WRT))
+            pfx = "RO";
+          else
+            pfx = "LOCAL";
+          BFD_ASSERT (section_count < 999);
+         sprintf (name, "$%s_%03d$", pfx, section_count++);
+       }
+
+      section = bfd_make_section (abfd, name);
+
+      if (!section)
+       return FALSE;
+
+      section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : 0;
+      section->size = size;
+      section->vma = vaddr;
+
+      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
+/* Read & process EIHS record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
+{
+  unsigned char *p = PRIV (recrd.rec) + offset;
+  unsigned int gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN);
+  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS__L_GSTSIZE);
+  unsigned int dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN);
+  unsigned int dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE);
+  unsigned int dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN);
+  unsigned int dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
+  asection *section;
+
+#if VMS_DEBUG
+  vms_debug (8, "_bfd_vms_slurp_ihs\n");
+  vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
+            gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
+#endif
+
+  if (dstvbn)
+    {
+      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
+
+      section = bfd_make_section (abfd, "$DST$");
+      if (!section)
+       return FALSE;
+
+      section->size = dstsize;
+      section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
+
+      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+       return FALSE;
+
+      PRIV (dst_section) = section;
+      abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+    }
+
+  if (dmtvbn)
+    {
+      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
+
+      section = bfd_make_section (abfd, "$DMT$");
+      if (!section)
+       return FALSE;
+
+      section->size = dmtbytes;
+      section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
+
+      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+       return FALSE;
+    }
+
+  if (gstvbn)
+    {
+      flagword bfd_flags = SEC_HAS_CONTENTS;
+
+      section = bfd_make_section (abfd, "$GST$");
+      if (!section)
+       return FALSE;
+
+      if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         return FALSE;
+       }
+
+      if (_bfd_vms_slurp_object_records (abfd) != TRUE)
+       return FALSE;
+
+      section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
+      section->size = bfd_tell (abfd) - section->filepos;
+
+      if (!bfd_set_section_flags (abfd, section, bfd_flags))
+       return FALSE;
+
+      abfd->flags |= HAS_SYMS;
+    }
+
+  return TRUE;
+}
+\f
+/* Object file reading.  */
+
+/* Object file input functions.  */
+
+/* Get next record from object file to vms_buf.
+   Set PRIV(buf_size) and return it
+
+   This is a little tricky since it should be portable.
+
+   The openVMS object file has 'variable length' which means that
+   read() returns data in chunks of (hopefully) correct and expected
+   size.  The linker (and other tools on VMS) depend on that. Unix
+   doesn't know about 'formatted' files, so reading and writing such
+   an object file in a Unix environment is not trivial.
+
+   With the tool 'file' (available on all VMS FTP sites), one
+   can view and change the attributes of a file.  Changing from
+   'variable length' to 'fixed length, 512 bytes' reveals the
+   record size at the first 2 bytes of every record.  The same
+   may happen during the transfer of object files from VMS to Unix,
+   at least with UCX, the DEC implementation of TCP/IP.
+
+   The VMS format repeats the size at bytes 2 & 3 of every record.
+
+   On the first call (file_format == FF_UNKNOWN) we check if
+   the first and the third byte pair (!) of the record match.
+   If they do it's an object file in an Unix environment or with
+   wrong attributes (FF_FOREIGN), else we should be in a VMS
+   environment where read() returns the record size (FF_NATIVE).
+
+   Reading is always done in 2 steps:
+    1. first just the record header is read and the size extracted,
+    2. then the read buffer is adjusted and the remaining bytes are
+       read in.
+
+   All file I/O is done on even file positions.  */
+
+#define VMS_OBJECT_ADJUSTMENT  2
+
+static void
+maybe_adjust_record_pointer_for_object (bfd *abfd)
+{
+  /* Set the file format once for all on the first invocation.  */
+  if (PRIV (recrd.file_format) == FF_UNKNOWN)
+    {
+      if (PRIV (recrd.rec)[0] == PRIV (recrd.rec)[4]
+         && PRIV (recrd.rec)[1] == PRIV (recrd.rec)[5])
+       PRIV (recrd.file_format) = FF_FOREIGN;
+      else
+       PRIV (recrd.file_format) = FF_NATIVE;
+    }
+
+  /* The adjustment is needed only in an Unix environment.  */
+  if (PRIV (recrd.file_format) == FF_FOREIGN)
+    PRIV (recrd.rec) += VMS_OBJECT_ADJUSTMENT;
+}
+
+/* Implement step #1 of the object record reading procedure.
+   Return the record type or -1 on failure.  */
+
+static int
+_bfd_vms_get_object_record (bfd *abfd)
+{
+  unsigned int test_len;
+  int type;
+  int off = 0;
+
+  vms_debug2 ((8, "_bfd_vms_get_obj_record\n"));
+
+  test_len = 6;
+
+  /* Skip odd alignment byte.  */
+  if (bfd_tell (abfd) & 1)
+    {
+      if (bfd_bread (PRIV (recrd.buf), 1, abfd) != 1)
+        {
+          bfd_set_error (bfd_error_file_truncated);
+          return -1;
+        }
+      /* Alignment byte may be present or not.  This is not easy to
+         detect but all object record types are not 0 (on Alpha VMS).
+         We also hope that pad byte is 0.  */
+      if (PRIV (recrd.buf)[0])
+        off = 1;
+    }
+
+  /* Read the record header  */
+  if (bfd_bread (PRIV (recrd.buf) + off, test_len - off, abfd)
+      != test_len - off)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      return -1;
+    }
+
+  /* Reset the record pointer.  */
+  PRIV (recrd.rec) = PRIV (recrd.buf);
+  maybe_adjust_record_pointer_for_object (abfd);
+
+  if (vms_get_remaining_object_record (abfd, test_len) <= 0)
+    return -1;
+
+  type = bfd_getl16 (PRIV (recrd.rec));
+
+  vms_debug2 ((8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
+               PRIV (recrd.rec), PRIV (recrd.rec_size), type));
+
+  return type;
+}
+
+/* Implement step #2 of the object record reading procedure.
+   Return the size of the record or 0 on failure.  */
+
+static int
+vms_get_remaining_object_record (bfd *abfd, int read_so_far)
+{
+  unsigned int to_read;
+
+  vms_debug2 ((8, "vms_get_remaining_obj_record\n"));
+
+  /* Extract record size.  */
+  PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2);
+
+  if (PRIV (recrd.rec_size) <= 0)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      return 0;
+    }
+
+  /* That's what the linker manual says.  */
+  if (PRIV (recrd.rec_size) > EOBJ__C_MAXRECSIZ)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      return 0;
+    }
+
+  /* Take into account object adjustment.  */
+  to_read = PRIV (recrd.rec_size);
+  if (PRIV (recrd.file_format) == FF_FOREIGN)
+    to_read += VMS_OBJECT_ADJUSTMENT;
+
+  /* Adjust the buffer.  */
+  if (to_read > PRIV (recrd.buf_size))
+    {
+      PRIV (recrd.buf)
+        = (unsigned char *) bfd_realloc (PRIV (recrd.buf), to_read);
+      if (PRIV (recrd.buf) == NULL)
+        return 0;
+      PRIV (recrd.buf_size) = to_read;
+    }
+
+  /* Read the remaining record.  */
+  to_read -= read_so_far;
+
+  vms_debug2 ((8, "vms_get_remaining_obj_record: to_read %d\n", to_read));
+
+  if (bfd_bread (PRIV (recrd.buf) + read_so_far, to_read, abfd) != to_read)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      return 0;
+    }
+
+  /* Reset the record pointer.  */
+  PRIV (recrd.rec) = PRIV (recrd.buf);
+  maybe_adjust_record_pointer_for_object (abfd);
+
+  vms_debug2 ((8, "vms_get_remaining_obj_record: size %d\n",
+               PRIV (recrd.rec_size)));
+
+  return PRIV (recrd.rec_size);
+}
+
+/* Read and process emh record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_ehdr (bfd *abfd)
+{
+  unsigned char *ptr;
+  unsigned char *vms_rec;
+  int subtype;
+
+  vms_rec = PRIV (recrd.rec);
+
+  vms_debug2 ((2, "HDR/EMH\n"));
+
+  subtype = bfd_getl16 (vms_rec + 4);
+
+  vms_debug2 ((3, "subtype %d\n", subtype));
+
+  switch (subtype)
+    {
+    case EMH__C_MHD:
+      /* Module header.  */
+      PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
+      PRIV (hdr_data).hdr_l_arch1  = bfd_getl32 (vms_rec + 8);
+      PRIV (hdr_data).hdr_l_arch2  = bfd_getl32 (vms_rec + 12);
+      PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
+      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20);
+      ptr = vms_rec + 20 + vms_rec[20] + 1;
+      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
+      ptr += *ptr + 1;
+      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
+      break;
+
+    case EMH__C_LNM:
+      PRIV (hdr_data).hdr_c_lnm =
+        _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      break;
+
+    case EMH__C_SRC:
+      PRIV (hdr_data).hdr_c_src =
+        _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      break;
+
+    case EMH__C_TTL:
+      PRIV (hdr_data).hdr_c_ttl =
+        _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+      break;
+
+    case EMH__C_CPR:
+    case EMH__C_MTC:
+    case EMH__C_GTX:
+      break;
+
+    default:
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/* Typical sections for evax object files.  */
+
+#define EVAX_ABS_NAME          "$ABS$"
+#define EVAX_CODE_NAME         "$CODE$"
+#define EVAX_LINK_NAME         "$LINK$"
+#define EVAX_DATA_NAME         "$DATA$"
+#define EVAX_BSS_NAME          "$BSS$"
+#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
+#define EVAX_READONLY_NAME     "$READONLY$"
+#define EVAX_LITERAL_NAME      "$LITERAL$"
+#define EVAX_LITERALS_NAME     "$LITERALS"
+#define EVAX_COMMON_NAME       "$COMMON$"
+#define EVAX_LOCAL_NAME                "$LOCAL$"
+
+struct sec_flags_struct
+{
+  const char *name;            /* Name of section.  */
+  int vflags_always;
+  flagword flags_always;       /* Flags we set always.  */
+  int vflags_hassize;
+  flagword flags_hassize;      /* Flags we set if the section has a size > 0.  */
+};
+
+/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible.  */
+
+static struct sec_flags_struct evax_section_flags[] =
+  {
+    { EVAX_ABS_NAME,
+      (EGPS__V_SHR),
+      (SEC_DATA),
+      (EGPS__V_SHR),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+    { EVAX_CODE_NAME,
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE),
+      (SEC_CODE),
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE),
+      (SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+    { EVAX_LITERAL_NAME,
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD),
+      (SEC_DATA | SEC_READONLY),
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+    { EVAX_LINK_NAME,
+      (EGPS__V_REL | EGPS__V_RD),
+      (SEC_DATA | SEC_READONLY),
+      (EGPS__V_REL | EGPS__V_RD),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+    { EVAX_DATA_NAME,
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD),
+      (SEC_DATA),
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+    { EVAX_BSS_NAME,
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD),
+      (SEC_NO_FLAGS),
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD),
+      (SEC_ALLOC) },
+    { EVAX_READONLYADDR_NAME,
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD),
+      (SEC_DATA | SEC_READONLY),
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+    { EVAX_READONLY_NAME,
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD),
+      (SEC_DATA | SEC_READONLY),
+      (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+    { EVAX_LOCAL_NAME,
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
+      (SEC_DATA),
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
+    { EVAX_LITERALS_NAME,
+      (EGPS__V_PIC | EGPS__V_OVR),
+      (SEC_DATA | SEC_READONLY),
+      (EGPS__V_PIC | EGPS__V_OVR),
+      (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
+    { NULL,
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
+      (SEC_DATA),
+      (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT),
+      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }
+  };
+
+/* Retrieve bfd section flags by name and size.  */
+
+static flagword
+vms_secflag_by_name (bfd *abfd ATTRIBUTE_UNUSED,
+                    struct sec_flags_struct *section_flags,
+                    char *name,
+                    int hassize)
+{
+  int i = 0;
+
+  while (section_flags[i].name != NULL)
+    {
+      if (strcmp (name, section_flags[i].name) == 0)
+        {
+         if (hassize)
+           return section_flags[i].flags_hassize;
+         else
+           return section_flags[i].flags_always;
+       }
+      i++;
+    }
+  if (hassize)
+    return section_flags[i].flags_hassize;
+  return section_flags[i].flags_always;
+}
+
+/* Retrieve vms section flags by name and size.  */
+
+static flagword
+vms_esecflag_by_name (struct sec_flags_struct *section_flags,
+                     char *name,
+                     int hassize)
+{
+  int i = 0;
+
+  while (section_flags[i].name != NULL)
+    {
+      if (strcmp (name, section_flags[i].name) == 0)
+       {
+         if (hassize)
+           return section_flags[i].vflags_hassize;
+         else
+           return section_flags[i].vflags_always;
+       }
+      i++;
+    }
+  if (hassize)
+    return section_flags[i].vflags_hassize;
+  return section_flags[i].vflags_always;
+}
+
+/* Input routines.  */
+
+static struct vms_symbol_entry *
+add_symbol (bfd *abfd, const unsigned char *ascic)
+{
+  struct vms_symbol_entry *entry;
+  int len;
+
+  len = *ascic++;
+  entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len);
+  if (entry == NULL)
+    return NULL;
+  entry->namelen = len;
+  memcpy (entry->name, ascic, len);
+  entry->name[len] = 0;
+  entry->owner = abfd;
+
+  if (PRIV (gsd_sym_count) >= PRIV (max_sym_count))
+    {
+      if (PRIV (max_sym_count) == 0)
+        {
+          PRIV (max_sym_count) = 128;
+          PRIV (syms) = bfd_malloc
+            (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *));
+        }
+      else
+        {
+          PRIV (max_sym_count) *= 2;
+          PRIV (syms) = bfd_realloc
+            (PRIV (syms),
+             (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *)));
+        }
+      if (PRIV (syms) == NULL)
+        return NULL;
+    }
+
+  PRIV (syms)[PRIV (gsd_sym_count)++] = entry;
+  return entry;
+}
+
+/* Read and process EGSD.  Return FALSE on failure.  */
+
+static bfd_boolean
+_bfd_vms_slurp_egsd (bfd * abfd)
+{
+  int gsd_type, gsd_size;
+  asection *section;
+  unsigned char *vms_rec;
+  flagword new_flags, old_flags;
+  char *name;
+  unsigned long base_addr;
+  unsigned long align_addr;
+
+  vms_debug2 ((2, "EGSD\n"));
+
+  PRIV (recrd.rec) += 8;       /* Skip type, size, align pad.  */
+  PRIV (recrd.rec_size) -= 8;
+
+  /* Calculate base address for each section.  */
+  base_addr = 0L;
+
+  while (PRIV (recrd.rec_size) > 0)
+    {
+      vms_rec = PRIV (recrd.rec);
+
+      gsd_type = bfd_getl16 (vms_rec);
+      gsd_size = bfd_getl16 (vms_rec + 2);
+
+      vms_debug2 ((3, "egsd_type %d\n", gsd_type));
+
+      switch (gsd_type)
+       {
+       case EGSD__C_PSC:
+         {
+           /* Program section definition.  */
+            struct vms_egps *egps = (struct vms_egps *)vms_rec;
+           name = _bfd_vms_save_counted_string (&egps->namlng);
+           section = bfd_make_section (abfd, name);
+           if (!section)
+             return FALSE;
+           old_flags = bfd_getl16 (egps->flags);
+            vms_section_data (section)->flags = old_flags;
+            vms_section_data (section)->no_flags = 0;
+           section->size = bfd_getl32 (egps->alloc);
+           new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
+                                            section->size > 0);
+            if (!(old_flags & EGPS__V_NOMOD))
+              {
+                new_flags |= SEC_HAS_CONTENTS;
+                if (old_flags & EGPS__V_REL)
+                  new_flags |= SEC_RELOC;
+              }
+           if (!bfd_set_section_flags (abfd, section, new_flags))
+             return FALSE;
+           section->alignment_power = egps->align;
+           align_addr = (1 << section->alignment_power);
+           if ((base_addr % align_addr) != 0)
+             base_addr += (align_addr - (base_addr % align_addr));
+           section->vma = (bfd_vma)base_addr;
+           base_addr += section->size;
+           section->filepos = (unsigned int)-1;
+#if VMS_DEBUG
+           vms_debug (4, "EGSD P-section %d (%s, flags %04x) ",
+                      section->index, name, old_flags);
+           vms_debug (4, "%lu bytes at 0x%08lx (mem %p)\n",
+                      (unsigned long)section->size,
+                       (unsigned long)section->vma, section->contents);
+#endif
+         }
+         break;
+
+       case EGSD__C_SYM:
+         {
+            int nameoff;
+            struct vms_symbol_entry *entry;
+            struct vms_egsy *egsy = (struct vms_egsy *) vms_rec;
+
+           old_flags = bfd_getl16 (egsy->flags);
+           if (old_flags & EGSY__V_DEF)
+              nameoff = ESDF__B_NAMLNG;
+            else
+              nameoff = ESRF__B_NAMLNG;
+
+            entry = add_symbol (abfd, vms_rec + nameoff);
+            if (entry == NULL)
+              return FALSE;
+
+            /* Allow only duplicate reference.  */
+            if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF))
+              abort ();
+
+            if (entry->typ == 0)
+              {
+                entry->typ = gsd_type;
+                entry->data_type = egsy->datyp;
+                entry->flags = old_flags;
+              }
+
+           if (old_flags & EGSY__V_DEF)
+              {
+                struct vms_esdf *esdf = (struct vms_esdf *)vms_rec;
+
+               entry->value = bfd_getl64 (esdf->value);
+               entry->section = bfd_getl32 (esdf->psindx);
+
+                if (old_flags & EGSY__V_NORM)
+                  {
+                    PRIV (norm_sym_count)++;
+
+                    entry->code_value = bfd_getl64 (esdf->code_address);
+                    entry->code_section = bfd_getl32 (esdf->ca_psindx);
+                  }
+              }
+         }
+         break;
+
+       case EGSD__C_SYMG:
+         {
+            int nameoff;
+            struct vms_symbol_entry *entry;
+            struct vms_egst *egst = (struct vms_egst *)vms_rec;
+
+           old_flags = bfd_getl16 (egst->header.flags);
+           if (old_flags & EGSY__V_DEF)
+              nameoff = ESDF__B_NAMLNG;
+            else
+              nameoff = ESRF__B_NAMLNG;
+
+            entry = add_symbol (abfd, &egst->namlng);
+
+            if (entry == NULL)
+              return FALSE;
+
+            entry->typ = gsd_type;
+            entry->data_type = egst->header.datyp;
+            entry->flags = old_flags;
+
+            entry->symbol_vector = bfd_getl32 (egst->value);
+
+            entry->section = bfd_getl32 (egst->psindx);
+            entry->value = bfd_getl64 (egst->lp_2);
+
+            if (old_flags & EGSY__V_NORM)
+              {
+                PRIV (norm_sym_count)++;
+
+                entry->code_value = bfd_getl64 (egst->lp_1);
+                entry->code_section = 0;
+              }
+          }
+         break;
+
+       case EGSD__C_IDC:
+       case EGSD__C_SYMM:
+       case EGSD__C_SYMV:
+       default:
+         (*_bfd_error_handler) (_("Unknown EGSD subtype %d"), gsd_type);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+
+      PRIV (recrd.rec_size) -= gsd_size;
+      PRIV (recrd.rec) += gsd_size;
+    }
+
+  if (PRIV (gsd_sym_count) > 0)
+    abfd->flags |= HAS_SYMS;
+
+  return TRUE;
+}
+
+/* Stack routines for vms ETIR commands.  */
+
+/* Push value and section index.  */
+
+static void
+_bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc)
+{
+  vms_debug2 ((4, "<push %08lx (0x%08x) at %d>\n",
+               (unsigned long)val, reloc, PRIV (stackptr)));
+
+  PRIV (stack[PRIV (stackptr)]).value = val;
+  PRIV (stack[PRIV (stackptr)]).reloc = reloc;
+  PRIV (stackptr)++;
+  if (PRIV (stackptr) >= STACKSIZE)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
+      exit (1);
+    }
+}
+
+/* Pop value and section index.  */
+
+static void
+_bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel)
+{
+  if (PRIV (stackptr) == 0)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
+      exit (1);
+    }
+  PRIV (stackptr)--;
+  *val = PRIV (stack[PRIV (stackptr)]).value;
+  *rel = PRIV (stack[PRIV (stackptr)]).reloc;
+
+  vms_debug2 ((4, "<pop %08lx (0x%08x)>\n", (unsigned long)*val, *rel));
+}
+
+/* Routines to fill sections contents during tir/etir read.  */
+
+/* Initialize image buffer pointer to be filled.  */
+
+static void
+image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info)
+{
+  asection *sec;
+
+  vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect));
+
+  sec = PRIV (sections)[sect];
+
+  if (info)
+    {
+      /* Reading contents to an output bfd.  */
+
+      if (sec->output_section == NULL)
+        {
+          /* Section discarded.  */
+          vms_debug2 ((5, " section %s discarded\n", sec->name));
+
+          /* This is not used.  */
+          PRIV (image_section) = NULL;
+          PRIV (image_offset) = 0;
+          return;
+        }
+      PRIV (image_offset) = sec->output_offset + vma;
+      PRIV (image_section) = sec->output_section;
+    }
+  else
+    {
+      PRIV (image_offset) = vma;
+      PRIV (image_section) = sec;
+    }
+}
+
+/* Increment image buffer pointer by offset.  */
+
+static void
+image_inc_ptr (bfd *abfd, bfd_vma offset)
+{
+  vms_debug2 ((4, "image_inc_ptr (%u)\n", (unsigned)offset));
+
+  PRIV (image_offset) += offset;
+}
+
+/* Save current DST location counter under specified index.  */
+
+static void
+dst_define_location (bfd *abfd, unsigned int loc)
+{
+  vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc));
+
+  /* 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_offset);
+}
+
+/* Restore saved DST location counter from specified index.  */
+
+static void
+dst_restore_location (bfd *abfd, unsigned int loc)
+{
+  vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc));
+
+  PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
+}
+
+/* Retrieve saved DST location counter from specified index.  */
+
+static unsigned int
+dst_retrieve_location (bfd *abfd, unsigned int loc)
+{
+  vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc));
+
+  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 *section = PRIV (image_section);
+
+  section->size += size;
+
+  /* Grow the section as necessary */
+  if (section->size <= section->rawsize)
+    return;
+  do
+    {
+      if (section->rawsize == 0)
+        section->rawsize = 1024;
+      else
+        section->rawsize *= 2;
+    }
+  while (section->size > section->rawsize);
+  section->contents = bfd_realloc (section->contents, section->rawsize);
+}
+
+/* Write multiple bytes to section image.  */
+
+static bfd_boolean
+image_write (bfd *abfd, unsigned char *ptr, int size)
+{
+#if VMS_DEBUG
+  _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
+                  (long)PRIV (image_offset));
+  _bfd_hexdump (9, ptr, size, 0);
+#endif
+
+  if (PRIV (image_autoextend))
+    dst_check_allocation (abfd, size);
+
+  if (PRIV (image_section)->contents != NULL)
+    {
+      asection *sec = PRIV (image_section);
+      file_ptr off = PRIV (image_offset);
+
+      /* Check bounds.  */
+      if (off > (file_ptr)sec->size
+          || size > (file_ptr)sec->size
+          || off + size > (file_ptr)sec->size)
+        {
+          bfd_set_error (bfd_error_bad_value);
+          return FALSE;
+        }
+
+      memcpy (sec->contents + off, ptr, size);
+    }
+
+  PRIV (image_offset) += size;
+  return TRUE;
+}
+
+/* Write byte to section image.  */
+
+static bfd_boolean
+image_write_b (bfd * abfd, unsigned int value)
+{
+  unsigned char data[1];
+
+  vms_debug2 ((6, "image_write_b (%02x)\n", (int) value));
+
+  *data = value;
+
+  return image_write (abfd, data, sizeof (data));
+}
+
+/* Write 2-byte word to image.  */
+
+static bfd_boolean
+image_write_w (bfd * abfd, unsigned int value)
+{
+  unsigned char data[2];
+
+  vms_debug2 ((6, "image_write_w (%04x)\n", (int) value));
+
+  bfd_putl16 (value, data);
+  return image_write (abfd, data, sizeof (data));
+}
+
+/* Write 4-byte long to image.  */
+
+static bfd_boolean
+image_write_l (bfd * abfd, unsigned long value)
+{
+  unsigned char data[4];
+
+  vms_debug2 ((6, "image_write_l (%08lx)\n", value));
+
+  bfd_putl32 (value, data);
+  return image_write (abfd, data, sizeof (data));
+}
+
+/* Write 8-byte quad to image.  */
+
+static bfd_boolean
+image_write_q (bfd * abfd, bfd_vma value)
+{
+  unsigned char data[8];
+
+  vms_debug2 ((6, "image_write_q (%08lx)\n", (unsigned long)value));
+
+  bfd_putl64 (value, data);
+  return image_write (abfd, data, sizeof (data));
+}
+\f
+static const char *
+_bfd_vms_etir_name (int cmd)
+{
+  switch (cmd)
+    {
+    case ETIR__C_STA_GBL: return "ETIR__C_STA_GBL";
+    case ETIR__C_STA_LW: return "ETIR__C_STA_LW";
+    case ETIR__C_STA_QW: return "ETIR__C_STA_QW";
+    case ETIR__C_STA_PQ: return "ETIR__C_STA_PQ";
+    case ETIR__C_STA_LI: return "ETIR__C_STA_LI";
+    case ETIR__C_STA_MOD: return "ETIR__C_STA_MOD";
+    case ETIR__C_STA_CKARG: return "ETIR__C_STA_CKARG";
+    case ETIR__C_STO_B: return "ETIR__C_STO_B";
+    case ETIR__C_STO_W: return "ETIR__C_STO_W";
+    case ETIR__C_STO_GBL: return "ETIR__C_STO_GBL";
+    case ETIR__C_STO_CA: return "ETIR__C_STO_CA";
+    case ETIR__C_STO_RB: return "ETIR__C_STO_RB";
+    case ETIR__C_STO_AB: return "ETIR__C_STO_AB";
+    case ETIR__C_STO_OFF: return "ETIR__C_STO_OFF";
+    case ETIR__C_STO_IMM: return "ETIR__C_STO_IMM";
+    case ETIR__C_STO_IMMR: return "ETIR__C_STO_IMMR";
+    case ETIR__C_STO_LW: return "ETIR__C_STO_LW";
+    case ETIR__C_STO_QW: return "ETIR__C_STO_QW";
+    case ETIR__C_STO_GBL_LW: return "ETIR__C_STO_GBL_LW";
+    case ETIR__C_STO_LP_PSB: return "ETIR__C_STO_LP_PSB";
+    case ETIR__C_STO_HINT_GBL: return "ETIR__C_STO_HINT_GBL";
+    case ETIR__C_STO_HINT_PS: return "ETIR__C_STO_HINT_PS";
+    case ETIR__C_OPR_ADD: return "ETIR__C_OPR_ADD";
+    case ETIR__C_OPR_SUB: return "ETIR__C_OPR_SUB";
+    case ETIR__C_OPR_INSV: return "ETIR__C_OPR_INSV";
+    case ETIR__C_OPR_USH: return "ETIR__C_OPR_USH";
+    case ETIR__C_OPR_ROT: return "ETIR__C_OPR_ROT";
+    case ETIR__C_OPR_REDEF: return "ETIR__C_OPR_REDEF";
+    case ETIR__C_OPR_DFLIT: return "ETIR__C_OPR_DFLIT";
+    case ETIR__C_STC_LP: return "ETIR__C_STC_LP";
+    case ETIR__C_STC_GBL: return "ETIR__C_STC_GBL";
+    case ETIR__C_STC_GCA: return "ETIR__C_STC_GCA";
+    case ETIR__C_STC_PS: return "ETIR__C_STC_PS";
+    case ETIR__C_STC_NBH_PS: return "ETIR__C_STC_NBH_PS";
+    case ETIR__C_STC_NOP_GBL: return "ETIR__C_STC_NOP_GBL";
+    case ETIR__C_STC_NOP_PS: return "ETIR__C_STC_NOP_PS";
+    case ETIR__C_STC_BSR_GBL: return "ETIR__C_STC_BSR_GBL";
+    case ETIR__C_STC_BSR_PS: return "ETIR__C_STC_BSR_PS";
+    case ETIR__C_STC_LDA_GBL: return "ETIR__C_STC_LDA_GBL";
+    case ETIR__C_STC_LDA_PS: return "ETIR__C_STC_LDA_PS";
+    case ETIR__C_STC_BOH_GBL: return "ETIR__C_STC_BOH_GBL";
+    case ETIR__C_STC_BOH_PS: return "ETIR__C_STC_BOH_PS";
+    case ETIR__C_STC_NBH_GBL: return "ETIR__C_STC_NBH_GBL";
+    case ETIR__C_STC_LP_PSB: return "ETIR__C_STC_LP_PSB";
+    case ETIR__C_CTL_SETRB: return "ETIR__C_CTL_SETRB";
+    case ETIR__C_CTL_AUGRB: return "ETIR__C_CTL_AUGRB";
+    case ETIR__C_CTL_DFLOC: return "ETIR__C_CTL_DFLOC";
+    case ETIR__C_CTL_STLOC: return "ETIR__C_CTL_STLOC";
+    case ETIR__C_CTL_STKDL: return "ETIR__C_CTL_STKDL";
+
+    default:
+      /* These names have not yet been added to this switch statement.  */
+      (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
+    }
+
+  return NULL;
+}
+#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
+
+static void
+_bfd_vms_get_value (bfd *abfd, const unsigned char *ascic,
+                    struct bfd_link_info *info,
+                    bfd_vma *vma,
+                    struct alpha_vms_link_hash_entry **hp)
+{
+  char name[257];
+  int len;
+  int i;
+  struct alpha_vms_link_hash_entry *h;
+
+  /* Not linking.  Do not try to resolve the symbol.  */
+  if (info == NULL)
+    {
+      *vma = 0;
+      *hp = NULL;
+      return;
+    }
+
+  len = *ascic;
+  for (i = 0; i < len; i++)
+    name[i] = ascic[i + 1];
+  name[i] = 0;
+
+  h = (struct alpha_vms_link_hash_entry *)
+    bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
+
+  *hp = h;
+
+  if (h != NULL
+      && (h->root.type == bfd_link_hash_defined
+          || h->root.type == bfd_link_hash_defweak))
+    *vma = h->root.u.def.value
+      + h->root.u.def.section->output_offset
+      + h->root.u.def.section->output_section->vma;
+  else if (h && h->root.type == bfd_link_hash_undefweak)
+    *vma = 0;
+  else
+    {
+      if (!(*info->callbacks->undefined_symbol)
+          (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE))
+        abort ();
+      *vma = 0;
+    }
+}
+
+#define RELC_NONE 0
+#define RELC_REL  1
+#define RELC_SHR_BASE 0x10000
+#define RELC_SEC_BASE 0x20000
+#define RELC_MASK     0x0ffff
+
+static unsigned int
+alpha_vms_sym_to_ctxt (struct alpha_vms_link_hash_entry *h)
+{
+  /* Handle undefined symbols.  */
+  if (h == NULL || h->sym == NULL)
+    return RELC_NONE;
+
+  if (h->sym->typ == EGSD__C_SYMG)
+    {
+      if (h->sym->flags & EGSY__V_REL)
+        return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
+      else
+        {
+          /* Can this happen ?  I'd like to see an example.  */
+          abort ();
+        }
+    }
+  if (h->sym->typ == EGSD__C_SYM)
+    {
+      if (h->sym->flags & EGSY__V_REL)
+        return RELC_REL;
+      else
+        return RELC_NONE;
+    }
+  abort ();
+}
+
+static bfd_vma
+alpha_vms_get_sym_value (unsigned int sect, bfd_vma addr,
+                         struct alpha_vms_link_hash_entry *h)
+{
+  asection *s;
+
+  BFD_ASSERT (h && (h->root.type == bfd_link_hash_defined
+                    || h->root.type == bfd_link_hash_defweak));
+
+  s = PRIV2 (h->root.u.def.section->owner, sections)[sect];
+  return s->output_section->vma + s->output_offset + addr;
+}
+
+static bfd_vma
+alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info,
+                       unsigned int rel, bfd_vma vma)
+{
+  asection *sec = PRIV (sections)[rel & RELC_MASK];
+
+  if (info)
+    {
+      if (sec->output_section == NULL)
+        abort ();
+      return vma + sec->output_section->vma + sec->output_offset;
+    }
+  else
+    return vma + sec->vma;
+}
+
+static bfd_boolean
+_bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
+{
+  unsigned char *ptr;
+  unsigned int length;
+  unsigned char *maxptr;
+  bfd_vma op1;
+  bfd_vma op2;
+  unsigned int rel1;
+  unsigned int rel2;
+  struct alpha_vms_link_hash_entry *h;
+
+  PRIV (recrd.rec) += ETIR__C_HEADER_SIZE;
+  PRIV (recrd.rec_size) -= ETIR__C_HEADER_SIZE;
+
+  ptr = PRIV (recrd.rec);
+  length = PRIV (recrd.rec_size);
+  maxptr = ptr + length;
+
+  vms_debug2 ((2, "ETIR: %d bytes\n", length));
+
+  while (ptr < maxptr)
+    {
+      int cmd = bfd_getl16 (ptr);
+      int cmd_length = bfd_getl16 (ptr + 2);
+
+      ptr += 4;
+
+#if VMS_DEBUG
+      _bfd_vms_debug (4, "etir: %s(%d)\n",
+                      _bfd_vms_etir_name (cmd), cmd);
+      _bfd_hexdump (8, ptr, cmd_length - 4, (long) ptr);
+#endif
+
+      switch (cmd)
+        {
+          /* Stack global
+             arg: cs   symbol name
+
+             stack 32 bit value of symbol (high bits set to 0).  */
+        case ETIR__C_STA_GBL:
+          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+          _bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h));
+          break;
+
+          /* Stack longword
+             arg: lw   value
+
+             stack 32 bit value, sign extend to 64 bit.  */
+        case ETIR__C_STA_LW:
+          _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE);
+          break;
+
+          /* Stack quadword
+             arg: qw   value
+
+             stack 64 bit value of symbol.  */
+        case ETIR__C_STA_QW:
+          _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE);
+          break;
+
+          /* Stack psect base plus quadword offset
+             arg: lw   section index
+             qw        signed quadword offset (low 32 bits)
+
+             Stack qw argument and section index
+             (see ETIR__C_STO_OFF, ETIR__C_CTL_SETRB).  */
+        case ETIR__C_STA_PQ:
+          {
+            int psect;
+
+            psect = bfd_getl32 (ptr);
+            if ((unsigned int) psect >= PRIV (section_count))
+              {
+                (*_bfd_error_handler) (_("bad section index in %s"),
+                                       _bfd_vms_etir_name (cmd));
+                bfd_set_error (bfd_error_bad_value);
+                return FALSE;
+              }
+            op1 = bfd_getl64 (ptr + 4);
+            _bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE);
+          }
+          break;
+
+        case ETIR__C_STA_LI:
+        case ETIR__C_STA_MOD:
+        case ETIR__C_STA_CKARG:
+          (*_bfd_error_handler) (_("unsupported STA cmd %s"),
+                                 _bfd_vms_etir_name (cmd));
+          return FALSE;
+          break;
+
+          /* Store byte: pop stack, write byte
+             arg: -.  */
+        case ETIR__C_STO_B:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          image_write_b (abfd, (unsigned int) op1 & 0xff);
+          break;
+
+          /* Store word: pop stack, write word
+             arg: -.  */
+        case ETIR__C_STO_W:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          image_write_w (abfd, (unsigned int) op1 & 0xffff);
+          break;
+
+          /* Store longword: pop stack, write longword
+             arg: -.  */
+        case ETIR__C_STO_LW:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 & RELC_SEC_BASE)
+            {
+              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+              rel1 = RELC_REL;
+            }
+          else if (rel1 & RELC_SHR_BASE)
+            {
+              alpha_vms_add_lw_fixup (info, rel1 & RELC_MASK, op1);
+              rel1 = RELC_NONE;
+            }
+          if (rel1 != RELC_NONE)
+            {
+              if (rel1 != RELC_REL)
+                abort ();
+              alpha_vms_add_lw_reloc (info);
+            }
+          image_write_l (abfd, op1);
+          break;
+
+          /* Store quadword: pop stack, write quadword
+             arg: -.  */
+        case ETIR__C_STO_QW:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 & RELC_SEC_BASE)
+            {
+              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+              rel1 = RELC_REL;
+            }
+          else if (rel1 & RELC_SHR_BASE)
+            abort ();
+          if (rel1 != RELC_NONE)
+            {
+              if (rel1 != RELC_REL)
+                abort ();
+              alpha_vms_add_qw_reloc (info);
+            }
+          image_write_q (abfd, op1);
+          break;
+
+          /* Store immediate repeated: pop stack for repeat count
+             arg: lw   byte count
+             da        data.  */
+        case ETIR__C_STO_IMMR:
+          {
+            int size;
+
+            size = bfd_getl32 (ptr);
+            _bfd_vms_pop (abfd, &op1, &rel1);
+            if (rel1 != RELC_NONE)
+              goto bad_context;
+            while (op1-- > 0)
+              image_write (abfd, ptr + 4, size);
+          }
+          break;
+
+          /* Store global: write symbol value
+             arg: cs   global symbol name.  */
+        case ETIR__C_STO_GBL:
+          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+          if (h && h->sym)
+            {
+              if (h->sym->typ == EGSD__C_SYMG)
+                {
+                  alpha_vms_add_fixup_qr
+                    (info, abfd, h->sym->owner, h->sym->symbol_vector);
+                  op1 = 0;
+                }
+              else
+                {
+                  op1 = alpha_vms_get_sym_value (h->sym->section,
+                                                 h->sym->value, h);
+                  alpha_vms_add_qw_reloc (info);
+                }
+            }
+          image_write_q (abfd, op1);
+          break;
+
+          /* Store code address: write address of entry point
+             arg: cs   global symbol name (procedure).  */
+        case ETIR__C_STO_CA:
+          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+          if (h && h->sym)
+            {
+              if (h->sym->flags & EGSY__V_NORM)
+                {
+                  /* That's really a procedure.  */
+                  if (h->sym->typ == EGSD__C_SYMG)
+                    {
+                      alpha_vms_add_fixup_ca (info, abfd, h->sym->owner);
+                      op1 = h->sym->symbol_vector;
+                    }
+                  else
+                    {
+                      op1 = alpha_vms_get_sym_value (h->sym->code_section,
+                                                     h->sym->code_value, h);
+                      alpha_vms_add_qw_reloc (info);
+                    }
+                }
+              else
+                {
+                  /* Symbol is not a procedure.  */
+                  abort ();
+                }
+            }
+          image_write_q (abfd, op1);
+          break;
+
+          /* Store offset to psect: pop stack, add low 32 bits to base of psect
+             arg: none.  */
+        case ETIR__C_STO_OFF:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+
+          if (!(rel1 & RELC_SEC_BASE))
+            abort ();
+
+          op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+          rel1 = RELC_REL;
+          image_write_q (abfd, op1);
+          break;
+
+          /* Store immediate
+             arg: lw   count of bytes
+             da        data.  */
+        case ETIR__C_STO_IMM:
+          {
+            int size;
+
+            size = bfd_getl32 (ptr);
+            image_write (abfd, ptr + 4, size);
+          }
+          break;
+
+          /* This code is 'reserved to digital' according to the openVMS
+             linker manual, however it is generated by the DEC C compiler
+             and defined in the include file.
+             FIXME, since the following is just a guess
+             store global longword: store 32bit value of symbol
+             arg: cs   symbol name.  */
+        case ETIR__C_STO_GBL_LW:
+          _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+#if 0
+          abort ();
+#endif
+          image_write_l (abfd, op1);
+          break;
+
+        case ETIR__C_STO_RB:
+        case ETIR__C_STO_AB:
+        case ETIR__C_STO_LP_PSB:
+          (*_bfd_error_handler) (_("%s: not supported"),
+                                 _bfd_vms_etir_name (cmd));
+          return FALSE;
+          break;
+        case ETIR__C_STO_HINT_GBL:
+        case ETIR__C_STO_HINT_PS:
+          (*_bfd_error_handler) (_("%s: not implemented"),
+                                 _bfd_vms_etir_name (cmd));
+          return FALSE;
+          break;
+
+          /* 200 Store-conditional Linkage Pair
+             arg: none.  */
+        case ETIR__C_STC_LP:
+
+          /* 202 Store-conditional Address at global address
+             lw        linkage index
+             cs        global name.  */
+
+        case ETIR__C_STC_GBL:
+
+          /* 203 Store-conditional Code Address at global address
+             lw        linkage index
+             cs        procedure name.  */
+        case ETIR__C_STC_GCA:
+
+          /* 204 Store-conditional Address at psect + offset
+             lw        linkage index
+             lw        psect index
+             qw        offset.  */
+        case ETIR__C_STC_PS:
+          (*_bfd_error_handler) (_("%s: not supported"),
+                                 _bfd_vms_etir_name (cmd));
+          return FALSE;
+          break;
+
+          /* 201 Store-conditional Linkage Pair with Procedure Signature
+             lw        linkage index
+             cs        procedure name
+             by        signature length
+             da        signature.  */
+
+        case ETIR__C_STC_LP_PSB:
+          _bfd_vms_get_value (abfd, ptr + 4, info, &op1, &h);
+          if (h && h->sym)
+            {
+              if (h->sym->typ == EGSD__C_SYMG)
+                {
+                  alpha_vms_add_fixup_lp (info, abfd, h->sym->owner);
+                  op1 = h->sym->symbol_vector;
+                  op2 = 0;
+                }
+              else
+                {
+                  op1 = alpha_vms_get_sym_value (h->sym->code_section,
+                                                 h->sym->code_value, h);
+                  op2 = alpha_vms_get_sym_value (h->sym->section,
+                                                h->sym->value, h);
+                }
+            }
+          else
+            {
+              /* Undefined symbol.  */
+              op1 = 0;
+              op2 = 0;
+            }
+          image_write_q (abfd, op1);
+          image_write_q (abfd, op2);
+          break;
+
+          /* 205 Store-conditional NOP at address of global
+             arg: none.  */
+        case ETIR__C_STC_NOP_GBL:
+          /* ALPHA_R_NOP */
+
+          /* 207 Store-conditional BSR at global address
+             arg: none.  */
+
+        case ETIR__C_STC_BSR_GBL:
+          /* ALPHA_R_BSR */
+
+          /* 209 Store-conditional LDA at global address
+             arg: none.  */
+
+        case ETIR__C_STC_LDA_GBL:
+          /* ALPHA_R_LDA */
+
+          /* 211 Store-conditional BSR or Hint at global address
+             arg: none.  */
+
+        case ETIR__C_STC_BOH_GBL:
+          /* Currentl ignored.  */
+          break;
+
+          /* 213 Store-conditional NOP,BSR or HINT at global address
+             arg: none.  */
+
+        case ETIR__C_STC_NBH_GBL:
+
+          /* 206 Store-conditional NOP at pect + offset
+             arg: none.  */
+
+        case ETIR__C_STC_NOP_PS:
+
+          /* 208 Store-conditional BSR at pect + offset
+             arg: none.  */
+
+        case ETIR__C_STC_BSR_PS:
+
+          /* 210 Store-conditional LDA at psect + offset
+             arg: none.  */
+
+        case ETIR__C_STC_LDA_PS:
+
+          /* 212 Store-conditional BSR or Hint at pect + offset
+             arg: none.  */
+
+        case ETIR__C_STC_BOH_PS:
+
+          /* 214 Store-conditional NOP, BSR or HINT at psect + offset
+             arg: none.  */
+        case ETIR__C_STC_NBH_PS:
+          (*_bfd_error_handler) ("%s: not supported",
+                                 _bfd_vms_etir_name (cmd));
+          return FALSE;
+          break;
+
+          /* Det relocation base: pop stack, set image location counter
+             arg: none.  */
+        case ETIR__C_CTL_SETRB:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (!(rel1 & RELC_SEC_BASE))
+            abort ();
+          image_set_ptr (abfd, op1, rel1 & RELC_MASK, info);
+          break;
+
+          /* Augment relocation base: increment image location counter by offset
+             arg: lw   offset value.  */
+        case ETIR__C_CTL_AUGRB:
+          op1 = bfd_getl32 (ptr);
+          image_inc_ptr (abfd, op1);
+          break;
+
+          /* Define location: pop index, save location counter under index
+             arg: none.  */
+        case ETIR__C_CTL_DFLOC:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          dst_define_location (abfd, op1);
+          break;
+
+          /* Set location: pop index, restore location counter from index
+             arg: none.  */
+        case ETIR__C_CTL_STLOC:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          dst_restore_location (abfd, op1);
+          break;
+
+          /* Stack defined location: pop index, push location counter from index
+             arg: none.  */
+        case ETIR__C_CTL_STKDL:
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_NOP:      /* No-op.  */
+          break;
+
+        case ETIR__C_OPR_ADD:      /* Add.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 == RELC_NONE && rel2 != RELC_NONE)
+            rel1 = rel2;
+          else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, op1 + op2, rel1);
+          break;
+
+        case ETIR__C_OPR_SUB:      /* Subtract.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 == RELC_NONE && rel2 != RELC_NONE)
+            rel1 = rel2;
+          else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE))
+            {
+              op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+              op2 = alpha_vms_fix_sec_rel (abfd, info, rel2, op2);
+              rel1 = RELC_NONE;
+            }
+          else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, op2 - op1, rel1);
+          break;
+
+        case ETIR__C_OPR_MUL:      /* Multiply.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, op1 * op2, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_DIV:      /* Divide.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+            goto bad_context;
+          if (op2 == 0)
+            _bfd_vms_push (abfd, 0, RELC_NONE);
+          else
+            _bfd_vms_push (abfd, op2 / op1, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_AND:      /* Logical AND.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, op1 & op2, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_IOR:      /* Logical inclusive OR.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, op1 | op2, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_EOR:      /* Logical exclusive OR.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, op1 ^ op2, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_NEG:      /* Negate.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, -op1, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_COM:      /* Complement.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (rel1 != RELC_NONE)
+            goto bad_context;
+          _bfd_vms_push (abfd, ~op1, RELC_NONE);
+          break;
+
+        case ETIR__C_OPR_ASH:      /* Arithmetic shift.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          _bfd_vms_pop (abfd, &op2, &rel2);
+          if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+            {
+            bad_context:
+              (*_bfd_error_handler) (_("invalid use of %s with contexts"),
+                                     _bfd_vms_etir_name (cmd));
+              return FALSE;
+            }
+          if ((int)op2 < 0)            /* Shift right.  */
+            op1 >>= -(int)op2;
+          else                 /* Shift left.  */
+            op1 <<= (int)op2;
+          _bfd_vms_push (abfd, op1, RELC_NONE); /* FIXME: sym.  */
+          break;
+
+        case ETIR__C_OPR_INSV:      /* Insert field.   */
+        case ETIR__C_OPR_USH:       /* Unsigned shift.   */
+        case ETIR__C_OPR_ROT:       /* Rotate.  */
+        case ETIR__C_OPR_REDEF:     /* Redefine symbol to current location.  */
+        case ETIR__C_OPR_DFLIT:     /* Define a literal.  */
+          (*_bfd_error_handler) (_("%s: not supported"),
+                                 _bfd_vms_etir_name (cmd));
+          return FALSE;
+          break;
+
+        case ETIR__C_OPR_SEL:      /* Select.  */
+          _bfd_vms_pop (abfd, &op1, &rel1);
+          if (op1 & 0x01L)
+            _bfd_vms_pop (abfd, &op1, &rel1);
+          else
+            {
+              _bfd_vms_pop (abfd, &op1, &rel1);
+              _bfd_vms_pop (abfd, &op2, &rel2);
+              _bfd_vms_push (abfd, op1, rel1);
+            }
+          break;
+
+        default:
+          (*_bfd_error_handler) (_("reserved cmd %d"), cmd);
+          return FALSE;
+          break;
+        }
+
+      ptr += cmd_length - 4;
+    }
+
+  return TRUE;
+}
+
+/* Process EDBG/ETBT record.
+   Return TRUE on success, FALSE on error  */
+
+static bfd_boolean
+vms_slurp_debug (bfd *abfd)
+{
+  asection *section = PRIV (dst_section);
+
+  if (section == NULL)
+    {
+      /* We have no way to find out beforehand how much debug info there
+        is in an object file, so pick an initial amount and grow it as
+        needed later.  */
+      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC
+        | SEC_IN_MEMORY;
+
+      section = bfd_make_section (abfd, "$DST$");
+      if (!section)
+       return FALSE;
+      if (!bfd_set_section_flags (abfd, section, flags))
+       return FALSE;
+      PRIV (dst_section) = section;
+    }
+
+  PRIV (image_section) = section;
+  PRIV (image_offset) = section->size;
+  PRIV (image_autoextend) = FALSE;
+
+  if (!_bfd_vms_slurp_etir (abfd, NULL))
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Process EDBG record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_edbg (bfd *abfd)
+{
+  vms_debug2 ((2, "EDBG\n"));
+
+  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+
+  return vms_slurp_debug (abfd);
+}
+
+/* Process ETBT record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_etbt (bfd *abfd)
+{
+  vms_debug2 ((2, "ETBT\n"));
+
+  abfd->flags |= HAS_LINENO;
+
+  return vms_slurp_debug (abfd);
+}
+
+/* Process EEOM record.
+   Return TRUE on success, FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_eeom (bfd *abfd)
+{
+  struct vms_eeom *eeom = (struct vms_eeom *) PRIV (recrd.rec);
+
+  vms_debug2 ((2, "EEOM\n"));
+
+  PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps);
+  PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod);
+  if (PRIV (eom_data).eom_w_comcod > 1)
+    {
+      (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
+  PRIV (eom_data).eom_has_transfer = FALSE;
+  if (PRIV (recrd.rec_size) > 10)
+    {
+      PRIV (eom_data).eom_has_transfer = TRUE;
+      PRIV (eom_data).eom_b_tfrflg = eeom->tfrflg;
+      PRIV (eom_data).eom_l_psindx = bfd_getl32 (eeom->psindx);
+      PRIV (eom_data).eom_l_tfradr = bfd_getl32 (eeom->tfradr);
+
+      abfd->start_address = PRIV (eom_data).eom_l_tfradr;
+    }
+  return TRUE;
+}
+
+/* Slurp an ordered set of VMS object records.  Return FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_slurp_object_records (bfd * abfd)
+{
+  int err, new_type, type = -1;
+
+  do
+    {
+      vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd)));
+
+      new_type = _bfd_vms_get_object_record (abfd);
+      if (new_type < 0)
+       {
+         vms_debug2 ((2, "next_record failed\n"));
+         return FALSE;
+       }
+
+      type = new_type;
+
+      switch (type)
+       {
+        case EOBJ__C_EMH:
+          err = _bfd_vms_slurp_ehdr (abfd);
+          break;
+        case EOBJ__C_EEOM:
+          err = _bfd_vms_slurp_eeom (abfd);
+          break;
+        case EOBJ__C_EGSD:
+          err = _bfd_vms_slurp_egsd (abfd);
+          break;
+        case EOBJ__C_ETIR:
+          err = TRUE; /* _bfd_vms_slurp_etir (abfd); */
+          break;
+        case EOBJ__C_EDBG:
+          err = _bfd_vms_slurp_edbg (abfd);
+          break;
+        case EOBJ__C_ETBT:
+          err = _bfd_vms_slurp_etbt (abfd);
+          break;
+        default:
+          err = FALSE;
+       }
+      if (err != TRUE)
+       {
+         vms_debug2 ((2, "slurp type %d failed\n", type));
+         return FALSE;
+       }
+    }
+  while (type != EOBJ__C_EEOM);
+
+  return TRUE;
+}
+
+/* Initialize private data  */
+static bfd_boolean
+vms_initialize (bfd * abfd)
+{
+  bfd_size_type amt;
+
+  amt = sizeof (struct vms_private_data_struct);
+  abfd->tdata.any = bfd_zalloc (abfd, amt);
+  if (abfd->tdata.any == NULL)
+    return FALSE;
+
+  PRIV (recrd.file_format) = FF_UNKNOWN;
+
+  amt = sizeof (struct stack_struct) * STACKSIZE;
+  PRIV (stack) = bfd_alloc (abfd, amt);
+  if (PRIV (stack) == NULL)
+    goto error_ret1;
+
+  return TRUE;
+
+ error_ret1:
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  return FALSE;
+}
+
+/* Check the format for a file being read.
+   Return a (bfd_target *) if it's an object file or zero if not.  */
+
+static const struct bfd_target *
+alpha_vms_object_p (bfd *abfd)
+{
+  PTR tdata_save = abfd->tdata.any;
+  unsigned int test_len;
+  unsigned char *buf;
+
+  vms_debug2 ((1, "vms_object_p(%p)\n", abfd));
+
+  /* Allocate alpha-vms specific data.  */
+  if (!vms_initialize (abfd))
+    goto error_ret;
+
+  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
+    goto err_wrong_format;
+
+  /* The first challenge with VMS is to discover the kind of the file.
+
+     Image files (executable or shared images) are stored as a raw
+     stream of bytes (like on UNIX), but there is no magic number.
+
+     Object files are written with RMS (record management service), ie
+     each records are preceeded by its length (on a word - 2 bytes), and
+     padded for word-alignment.  That would be simple but when files
+     are transfered to a UNIX filesystem (using ftp), records are lost.
+     Only the raw content of the records are transfered.  Fortunately,
+     the Alpha Object file format also store the length of the record
+     in the records.  Is that clear ?  */
+
+  /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
+     2 bytes size repeated) and 12 bytes for images (4 bytes major id,
+     4 bytes minor id, 4 bytes length).  */
+  test_len = 12;
+
+  /* Size the main buffer.  */
+  buf = (unsigned char *) bfd_malloc (test_len);
+  if (buf == NULL)
+    goto error_ret;
+  PRIV (recrd.buf) = buf;
+  PRIV (recrd.buf_size) = test_len;
+
+  /* Initialize the record pointer.  */
+  PRIV (recrd.rec) = buf;
+
+  if (bfd_bread (buf, test_len, abfd) != test_len)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      goto error_ret;
+    }
+
+  /* Is it an image?  */
+  if ((bfd_getl32 (buf) == EIHD__K_MAJORID)
+      && (bfd_getl32 (buf + 4) == EIHD__K_MINORID))
+    {
+      unsigned int to_read;
+      unsigned int read_so_far;
+      unsigned int remaining;
+      unsigned int eisd_offset, eihs_offset;
+
+      /* Extract the header size.  */
+      PRIV (recrd.rec_size) = bfd_getl32 (buf + EIHD__L_SIZE);
+
+      if (PRIV (recrd.rec_size) > PRIV (recrd.buf_size))
+        {
+          buf = bfd_realloc_or_free (buf, PRIV (recrd.rec_size));
+
+          if (buf == NULL)
+            {
+              PRIV (recrd.buf) = NULL;
+              bfd_set_error (bfd_error_no_memory);
+              goto error_ret;
+            }
+          PRIV (recrd.buf) = buf;
+          PRIV (recrd.buf_size) = PRIV (recrd.rec_size);
+        }
+
+      /* Read the remaining record.  */
+      remaining = PRIV (recrd.rec_size) - test_len;
+      to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining);
+      read_so_far = test_len;
+
+      while (remaining > 0)
+        {
+          if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read)
+            {
+              bfd_set_error (bfd_error_file_truncated);
+              goto err_wrong_format;
+            }
+
+          read_so_far += to_read;
+          remaining -= to_read;
+
+          to_read = MIN (VMS_BLOCK_SIZE, remaining);
+        }
+
+      /* Reset the record pointer.  */
+      PRIV (recrd.rec) = buf;
+
+      vms_debug2 ((2, "file type is image\n"));
+
+      if (_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset) != TRUE)
+        goto err_wrong_format;
+
+      if (_bfd_vms_slurp_eisd (abfd, eisd_offset) != TRUE)
+        goto err_wrong_format;
+
+      /* EIHS is optional.  */
+      if (eihs_offset != 0 && _bfd_vms_slurp_eihs (abfd, eihs_offset) != TRUE)
+        goto err_wrong_format;
+    }
+  else
+    {
+      int type;
+
+      /* Assume it's a module and adjust record pointer if necessary.  */
+      maybe_adjust_record_pointer_for_object (abfd);
+
+      /* But is it really a module?  */
+      if (bfd_getl16 (PRIV (recrd.rec)) <= EOBJ__C_MAXRECTYP
+          && bfd_getl16 (PRIV (recrd.rec) + 2) <= EOBJ__C_MAXRECSIZ)
+        {
+          if (vms_get_remaining_object_record (abfd, test_len) <= 0)
+            goto err_wrong_format;
+
+          vms_debug2 ((2, "file type is module\n"));
+
+          type = bfd_getl16 (PRIV (recrd.rec));
+          if (type != EOBJ__C_EMH || _bfd_vms_slurp_ehdr (abfd) != TRUE)
+            goto err_wrong_format;
+
+          if (_bfd_vms_slurp_object_records (abfd) != TRUE)
+            goto err_wrong_format;
+        }
+      else
+        goto err_wrong_format;
+    }
+
+  /* Set arch_info to alpha.   */
+
+  if (! bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0))
+    goto err_wrong_format;
+
+  return abfd->xvec;
+
+ err_wrong_format:
+  bfd_set_error (bfd_error_wrong_format);
+
+ error_ret:
+  if (PRIV (recrd.buf))
+    free (PRIV (recrd.buf));
+  if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+    bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = tdata_save;
+  return NULL;
+}
+\f
+/* Image write.  */
+
+static void
+vector_grow1 (struct vector_type *vec, size_t elsz)
+{
+  if (vec->nbr_el + 1 < vec->max_el)
+    return;
+
+  if (vec->max_el == 0)
+    {
+      vec->max_el = 16;
+      vec->els = bfd_malloc2 (vec->max_el, elsz);
+    }
+  else
+    {
+      vec->max_el *= 2;
+      vec->els = bfd_realloc2 (vec->els, vec->max_el, elsz);
+    }
+}
+
+/* Bump ABFD file position to next block.  */
+
+static void
+alpha_vms_file_position_block (bfd *abfd)
+{
+  /* Next block.  */
+  PRIV (file_pos) += VMS_BLOCK_SIZE - 1;
+  PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE);
+}
+
+static void
+alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
+                         struct vms_eisd *dst)
+{
+  bfd_putl32 (src->u.eisd.majorid, dst->majorid);
+  bfd_putl32 (src->u.eisd.minorid, dst->minorid);
+  bfd_putl32 (src->u.eisd.eisdsize, dst->eisdsize);
+  if (src->u.eisd.eisdsize <= EISD__K_LENEND)
+    return;
+  bfd_putl32 (src->u.eisd.secsize, dst->secsize);
+  bfd_putl64 (src->u.eisd.virt_addr, dst->virt_addr);
+  bfd_putl32 (src->u.eisd.flags, dst->flags);
+  bfd_putl32 (src->u.eisd.vbn, dst->vbn);
+  dst->pfc = src->u.eisd.pfc;
+  dst->matchctl = src->u.eisd.matchctl;
+  dst->type = src->u.eisd.type;
+  dst->fill_1 = 0;
+  if (src->u.eisd.flags & EISD__M_GBL)
+    {
+      bfd_putl32 (src->u.gbl_eisd.ident, dst->ident);
+      memcpy (dst->gblnam, src->u.gbl_eisd.gblnam,
+              src->u.gbl_eisd.gblnam[0] + 1);
+    }
+}
+
+/* Append EISD to the list of extra eisd for ABFD.  */
+
+static void
+alpha_vms_append_extra_eisd (bfd *abfd, struct vms_internal_eisd_map *eisd)
+{
+  eisd->next = NULL;
+  if (PRIV (gbl_eisd_head) == NULL)
+    PRIV (gbl_eisd_head) = eisd;
+  else
+    PRIV (gbl_eisd_tail)->next = eisd;
+  PRIV (gbl_eisd_tail) = eisd;
+}
+
+static bfd_boolean
+alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
+{
+  struct vms_internal_eisd_map *eisd;
+  int namlen;
+
+  namlen = strlen (PRIV2 (shrimg, hdr_data.hdr_t_name));
+  if (namlen + 5 > EISD__K_GBLNAMLEN)
+    {
+      /* Won't fit.  */
+      return FALSE;
+    }
+
+  eisd = bfd_alloc (abfd, sizeof (*eisd));
+  if (eisd == NULL)
+    return FALSE;
+
+  /* Fill the fields.  */
+  eisd->u.gbl_eisd.common.majorid = EISD__K_MAJORID;
+  eisd->u.gbl_eisd.common.minorid = EISD__K_MINORID;
+  eisd->u.gbl_eisd.common.eisdsize = (EISD__K_LEN + 4 + namlen + 5 + 3) & ~3;
+  eisd->u.gbl_eisd.common.secsize = VMS_BLOCK_SIZE;    /* Must not be 0.  */
+  eisd->u.gbl_eisd.common.virt_addr = 0;
+  eisd->u.gbl_eisd.common.flags = EISD__M_GBL;
+  eisd->u.gbl_eisd.common.vbn = 0;
+  eisd->u.gbl_eisd.common.pfc = 0;
+  eisd->u.gbl_eisd.common.matchctl = PRIV2 (shrimg, matchctl);
+  eisd->u.gbl_eisd.common.type = EISD__K_SHRPIC;
+
+  eisd->u.gbl_eisd.ident = PRIV2 (shrimg, ident);
+  eisd->u.gbl_eisd.gblnam[0] = namlen + 4;
+  memcpy (eisd->u.gbl_eisd.gblnam + 1, PRIV2 (shrimg, hdr_data.hdr_t_name),
+          namlen);
+  memcpy (eisd->u.gbl_eisd.gblnam + 1 + namlen, "_001", 4);
+
+  /* Append it to the list.  */
+  alpha_vms_append_extra_eisd (abfd, eisd);
+
+  return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
+{
+  struct vms_internal_eisd_map *eisd;
+
+  /* Only for allocating section.  */
+  if (!(sec->flags & SEC_ALLOC))
+    return TRUE;
+
+  BFD_ASSERT (vms_section_data (sec)->eisd == NULL);
+  eisd = bfd_alloc (abfd, sizeof (*eisd));
+  if (eisd == NULL)
+    return FALSE;
+  vms_section_data (sec)->eisd = eisd;
+
+  /* Fill the fields.  */
+  eisd->u.eisd.majorid = EISD__K_MAJORID;
+  eisd->u.eisd.minorid = EISD__K_MINORID;
+  eisd->u.eisd.eisdsize = EISD__K_LEN;
+  eisd->u.eisd.secsize =
+    (sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
+  eisd->u.eisd.virt_addr = sec->vma;
+  eisd->u.eisd.flags = 0;
+  eisd->u.eisd.vbn = 0; /* To be later defined.  */
+  eisd->u.eisd.pfc = 0; /* Default.  */
+  eisd->u.eisd.matchctl = EISD__K_MATALL;
+  eisd->u.eisd.type = EISD__K_NORMAL;
+
+  if (sec->flags & SEC_CODE)
+    eisd->u.eisd.flags |= EISD__M_EXE;
+  if (!(sec->flags & SEC_READONLY))
+    eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
+
+  if (!(sec->flags & SEC_LOAD))
+    {
+      eisd->u.eisd.flags |= EISD__M_DZRO;
+      eisd->u.eisd.flags &= ~EISD__M_CRF;
+    }
+  if (sec->flags & SEC_LINKER_CREATED)
+    {
+      if (strcmp (sec->name, "$FIXUP$") == 0)
+        eisd->u.eisd.flags |= EISD__M_FIXUPVEC;
+    }
+
+  /* Append it to the list.  */
+  eisd->next = NULL;
+  if (PRIV (eisd_head) == NULL)
+    PRIV (eisd_head) = eisd;
+  else
+    PRIV (eisd_tail)->next = eisd;
+  PRIV (eisd_tail) = eisd;
+
+  return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_write_exec (bfd *abfd)
+{
+  struct vms_eihd eihd;
+  struct vms_eiha *eiha;
+  struct vms_eihi *eihi;
+  struct vms_eihs *eihs = NULL;
+  asection *sec;
+  struct vms_internal_eisd_map *first_eisd;
+  struct vms_internal_eisd_map *eisd;
+  asection *dst;
+
+  PRIV (file_pos) = EIHD__C_LENGTH;
+
+  memset (&eihd, 0, sizeof (eihd));
+  memset (eihd.fill_2, 0xff, sizeof (eihd.fill_2));
+
+  bfd_putl32 (EIHD__K_MAJORID, eihd.majorid);
+  bfd_putl32 (EIHD__K_MINORID, eihd.minorid);
+
+  bfd_putl32 (sizeof (eihd), eihd.size);
+  bfd_putl32 (0, eihd.isdoff);
+  bfd_putl32 (0, eihd.activoff);
+  bfd_putl32 (0, eihd.symdbgoff);
+  bfd_putl32 (0, eihd.imgidoff);
+  bfd_putl32 (0, eihd.patchoff);
+  bfd_putl64 (0, eihd.iafva);
+  bfd_putl32 (0, eihd.version_array_off);
+
+  bfd_putl32 (EIHD__K_EXE, eihd.imgtype);
+  bfd_putl32 (0, eihd.subtype);
+
+  bfd_putl32 (0, eihd.imgiocnt);
+  bfd_putl32 (-1, eihd.privreqs);
+  bfd_putl32 (-1, eihd.privreqs + 4);
+
+  bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
+              eihd.hdrblkcnt);
+  bfd_putl32 (0, eihd.lnkflags);
+  bfd_putl32 (0, eihd.ident);
+  bfd_putl32 (0, eihd.sysver);
+
+  eihd.matchctl = 0;
+  bfd_putl32 (0, eihd.symvect_size);
+  bfd_putl32 (16, eihd.virt_mem_block_size);
+  bfd_putl32 (0, eihd.ext_fixup_off);
+  bfd_putl32 (0, eihd.noopt_psect_off);
+  bfd_putl32 (-1, eihd.alias);
+
+  /* Alloc EIHA.  */
+  eiha = (struct vms_eiha *)((char *) &eihd + PRIV (file_pos));
+  bfd_putl32 (PRIV (file_pos), eihd.activoff);
+  PRIV (file_pos) += sizeof (struct vms_eiha);
+
+  bfd_putl32 (sizeof (struct vms_eiha), eiha->size);
+  bfd_putl32 (0, eiha->spare);
+  bfd_putl32 (0x00000340, eiha->tfradr1);      /* SYS$IMGACT */
+  bfd_putl32 (0xffffffff, eiha->tfradr1_h);
+  bfd_putl64 (bfd_get_start_address (abfd), eiha->tfradr2);
+  bfd_putl64 (0, eiha->tfradr3);
+  bfd_putl64 (0, eiha->tfradr4);
+  bfd_putl64 (0, eiha->inishr);
+
+  /* Alloc EIHI.  */
+  eihi = (struct vms_eihi *)((char *) &eihd + PRIV (file_pos));
+  bfd_putl32 (PRIV (file_pos), eihd.imgidoff);
+  PRIV (file_pos) += sizeof (struct vms_eihi);
+
+  bfd_putl32 (EIHI__K_MAJORID, eihi->majorid);
+  bfd_putl32 (EIHI__K_MINORID, eihi->minorid);
+  {
+    char *module;
+    unsigned int len;
+
+    module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
+    len = strlen (module);
+    if (len > sizeof (eihi->imgnam) - 1)
+      len = sizeof (eihi->imgnam) - 1;
+    eihi->imgnam[0] = len;
+    memcpy (eihi->imgnam + 1, module, len);
+    free (module);
+  }
+  bfd_putl32 (0, eihi->linktime + 0);
+  bfd_putl32 (0, eihi->linktime + 4);
+  eihi->imgid[0] = 0;
+  eihi->linkid[0] = 0;
+  eihi->imgbid[0] = 0;
+
+  /* Alloc EIHS.  */
+  dst = bfd_get_section_by_name (abfd, "$DST$");
+  if (dst == NULL || dst->size == 0)
+    dst = bfd_get_section_by_name (abfd, "$TBT$");
+  if (dst != NULL && dst->size != 0)
+    {
+      eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos));
+      bfd_putl32 (PRIV (file_pos), eihd.symdbgoff);
+      PRIV (file_pos) += sizeof (struct vms_eihs);
+
+      bfd_putl32 (EIHS__K_MAJORID, eihs->majorid);
+      bfd_putl32 (EIHS__K_MINORID, eihs->minorid);
+      bfd_putl32 (0, eihs->dstvbn);
+      bfd_putl32 (0, eihs->dstsize);
+      bfd_putl32 (0, eihs->gstvbn);
+      bfd_putl32 (0, eihs->gstsize);
+      bfd_putl32 (0, eihs->dmtvbn);
+      bfd_putl32 (0, eihs->dmtsize);
+    }
+
+  /* One per section.  */
+  for (sec = abfd->sections; sec; sec = sec->next)
+    {
+      if (!alpha_vms_create_eisd_for_section (abfd, sec))
+        return FALSE;
+    }
+
+  /* Merge section EIDS which extra ones.  */
+  if (PRIV (eisd_tail))
+    PRIV (eisd_tail)->next = PRIV (gbl_eisd_head);
+  else
+    PRIV (eisd_head) = PRIV (gbl_eisd_head);
+  if (PRIV (gbl_eisd_tail))
+    PRIV (eisd_tail) = PRIV (gbl_eisd_tail);
+
+  first_eisd = PRIV (eisd_head);
+
+  /* Add end of eisd.  */
+  if (first_eisd)
+    {
+      eisd = bfd_zalloc (abfd, sizeof (*eisd));
+      if (eisd == NULL)
+        return FALSE;
+      eisd->u.eisd.majorid = 0;
+      eisd->u.eisd.minorid = 0;
+      eisd->u.eisd.eisdsize = 0;
+      alpha_vms_append_extra_eisd (abfd, eisd);
+    }
+
+  /* Place EISD in the file.  */
+  for (eisd = first_eisd; eisd; eisd = eisd->next)
+    {
+      file_ptr room = VMS_BLOCK_SIZE - (PRIV (file_pos) % VMS_BLOCK_SIZE);
+
+      /* First block is a little bit special: there is a word at the end.  */
+      if (PRIV (file_pos) < VMS_BLOCK_SIZE && room > 2)
+        room -= 2;
+      if (room < eisd->u.eisd.eisdsize + EISD__K_LENEND)
+        alpha_vms_file_position_block (abfd);
+
+      eisd->file_pos = PRIV (file_pos);
+      PRIV (file_pos) += eisd->u.eisd.eisdsize;
+
+      if (eisd->u.eisd.flags & EISD__M_FIXUPVEC)
+        bfd_putl64 (eisd->u.eisd.virt_addr, eihd.iafva);
+    }
+
+  if (first_eisd != NULL)
+    {
+      bfd_putl32 (first_eisd->file_pos, eihd.isdoff);
+      /* Real size of end of eisd marker.  */
+      PRIV (file_pos) += EISD__K_LENEND;
+    }
+
+  bfd_putl32 (PRIV (file_pos), eihd.size);
+  bfd_putl32 ((PRIV (file_pos) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
+              eihd.hdrblkcnt);
+
+  /* Place sections.  */
+  for (sec = abfd->sections; sec; sec = sec->next)
+    {
+      if (!(sec->flags & SEC_HAS_CONTENTS))
+        continue;
+
+      eisd = vms_section_data (sec)->eisd;
+
+      /* Align on a block.  */
+      alpha_vms_file_position_block (abfd);
+      sec->filepos = PRIV (file_pos);
+
+      if (eisd != NULL)
+        eisd->u.eisd.vbn = (sec->filepos / VMS_BLOCK_SIZE) + 1;
+
+      PRIV (file_pos) += sec->size;
+    }
+
+  if (eihs != NULL && dst != NULL)
+    {
+      bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn);
+      bfd_putl32 (dst->size, eihs->dstsize);
+    }
+
+  /* Write EISD in hdr.  */
+  for (eisd = first_eisd; eisd && eisd->file_pos < VMS_BLOCK_SIZE;
+       eisd = eisd->next)
+    alpha_vms_swap_eisd_out
+      (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos));
+
+  /* Write first block.  */
+  if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
+    return FALSE;
+
+  /* Write remaining eisd.  */
+  if (eisd != NULL)
+    {
+      unsigned char blk[VMS_BLOCK_SIZE];
+      struct vms_internal_eisd_map *next_eisd;
+
+      memset (blk, 0xff, sizeof (blk));
+      while (eisd != NULL)
+        {
+          alpha_vms_swap_eisd_out
+            (eisd,
+             (struct vms_eisd *)(blk + (eisd->file_pos % VMS_BLOCK_SIZE)));
+
+          next_eisd = eisd->next;
+          if (next_eisd == NULL
+              || (next_eisd->file_pos / VMS_BLOCK_SIZE
+                  != eisd->file_pos / VMS_BLOCK_SIZE))
+            {
+              if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk))
+                return FALSE;
+
+              memset (blk, 0xff, sizeof (blk));
+            }
+          eisd = next_eisd;
+        }
+    }
+
+  /* Write sections.  */
+  for (sec = abfd->sections; sec; sec = sec->next)
+    {
+      unsigned char blk[VMS_BLOCK_SIZE];
+      bfd_size_type len;
+
+      if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS))
+        continue;
+      if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size)
+        return FALSE;
+
+      /* Pad.  */
+      len = VMS_BLOCK_SIZE - sec->size % VMS_BLOCK_SIZE;
+      if (len != VMS_BLOCK_SIZE)
+        {
+          memset (blk, 0, len);
+          if (bfd_bwrite (blk, len, abfd) != len)
+            return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+\f
+/* Object write.  */
+
+/* This hash routine borrowed from GNU-EMACS, and strengthened
+   slightly.  ERY.  */
+
+static int
+hash_string (const char *ptr)
+{
+  const unsigned char *p = (unsigned char *) ptr;
+  const unsigned char *end = p + strlen (ptr);
+  unsigned char c;
+  int hash = 0;
+
+  while (p != end)
+    {
+      c = *p++;
+      hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
+    }
+  return hash;
+}
+
+/* Generate a length-hashed VMS symbol name (limited to maxlen chars).  */
+
+static char *
+_bfd_vms_length_hash_symbol (bfd *abfd, const char *in, int maxlen)
+{
+  unsigned long result;
+  int in_len;
+  char *new_name;
+  const char *old_name;
+  int i;
+  static char outbuf[EOBJ__C_SYMSIZ + 1];
+  char *out = outbuf;
+
+#if VMS_DEBUG
+  vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
+#endif
+
+  if (maxlen > EOBJ__C_SYMSIZ)
+    maxlen = EOBJ__C_SYMSIZ;
+
+  /* Save this for later.  */
+  new_name = out;
+
+  /* We may need to truncate the symbol, save the hash for later.  */
+  in_len = strlen (in);
+
+  result = (in_len > maxlen) ? hash_string (in) : 0;
+
+  old_name = in;
+
+  /* Do the length checking.  */
+  if (in_len <= maxlen)
+    i = in_len;
+  else
+    {
+      if (PRIV (flag_hash_long_names))
+       i = maxlen - 9;
+      else
+       i = maxlen;
+    }
+
+  strncpy (out, in, (size_t) i);
+  in += i;
+  out += i;
+
+  if ((in_len > maxlen)
+      && PRIV (flag_hash_long_names))
+    sprintf (out, "_%08lx", result);
+  else
+    *out = 0;
+
+#if VMS_DEBUG
+  vms_debug (4, "--> [%d]\"%s\"\n", (int)strlen (outbuf), outbuf);
+#endif
+
+  if (in_len > maxlen
+       && PRIV (flag_hash_long_names)
+       && PRIV (flag_show_after_trunc))
+    printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
+
+  return outbuf;
+}
+
+/* Write section and symbol directory of bfd abfd.  Return FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_write_egsd (bfd *abfd)
+{
+  asection *section;
+  asymbol *symbol;
+  unsigned int symnum;
+  int last_index = -1;
+  char dummy_name[10];
+  char *sname;
+  flagword new_flags, old_flags;
+  int abs_section_index = 0;
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  vms_debug2 ((2, "vms_write_gsd\n"));
+
+  /* Output sections.  */
+  section = abfd->sections;
+  vms_debug2 ((3, "%d sections found\n", abfd->section_count));
+
+  /* Egsd is quadword aligned.  */
+  _bfd_vms_output_alignment (recwr, 8);
+
+  _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+  _bfd_vms_output_long (recwr, 0);
+
+  while (section != 0)
+    {
+      vms_debug2 ((3, "Section #%d %s, %d bytes\n",
+                   section->index, section->name, (int)section->size));
+
+      /* Don't write out the VMS debug info section since it is in the
+         ETBT and EDBG sections in etir. */
+      if (!strcmp (section->name, ".vmsdebug"))
+        goto done;
+
+      /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
+      if (_bfd_vms_output_check (recwr, 64) < 0)
+       {
+         _bfd_vms_output_end (abfd, recwr);
+         _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+         _bfd_vms_output_long (recwr, 0);
+       }
+
+      /* Create dummy sections to keep consecutive indices.  */
+      while (section->index - last_index > 1)
+       {
+         vms_debug2 ((3, "index %d, last %d\n", section->index, last_index));
+         _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+         _bfd_vms_output_short (recwr, 0);
+         _bfd_vms_output_short (recwr, 0);
+         _bfd_vms_output_long (recwr, 0);
+         sprintf (dummy_name, ".DUMMY%02d", last_index);
+         _bfd_vms_output_counted (recwr, dummy_name);
+         _bfd_vms_output_end_subrec (recwr);
+         last_index++;
+       }
+
+      /* Don't know if this is necessary for the linker but for now it keeps
+        vms_slurp_gsd happy  */
+      sname = (char *)section->name;
+      if (*sname == '.')
+       {
+         sname++;
+         if ((*sname == 't') && (strcmp (sname, "text") == 0))
+           sname = EVAX_CODE_NAME;
+         else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
+           sname = EVAX_DATA_NAME;
+         else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
+           sname = EVAX_BSS_NAME;
+         else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
+           sname = EVAX_LINK_NAME;
+         else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
+           sname = EVAX_READONLY_NAME;
+         else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
+           sname = EVAX_LITERAL_NAME;
+         else if ((*sname == 'l') && (strcmp (sname, "literals") == 0))
+           {
+             sname = EVAX_LITERALS_NAME;
+             abs_section_index = section->index;
+           }
+         else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
+           sname = EVAX_COMMON_NAME;
+         else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
+           sname = EVAX_LOCAL_NAME;
+       }
+      else
+       sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ__C_SECSIZ);
+
+      _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+      _bfd_vms_output_short (recwr, section->alignment_power & 0xff);
+
+      if (bfd_is_com_section (section))
+       new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD
+                    | EGPS__V_WRT | EGPS__V_NOMOD | EGPS__V_COM);
+      else
+       new_flags = vms_esecflag_by_name (evax_section_flags, sname,
+                                         section->size > 0);
+
+      /* Modify them as directed.  */
+      if (section->flags & SEC_READONLY)
+       new_flags &= ~EGPS__V_WRT;
+
+      new_flags &= ~vms_section_data (section)->no_flags;
+      new_flags |= vms_section_data (section)->flags;
+
+      vms_debug2 ((3, "sec flags %x\n", section->flags));
+      vms_debug2 ((3, "new_flags %x, _raw_size %lu\n",
+                   new_flags, (unsigned long)section->size));
+
+      _bfd_vms_output_short (recwr, new_flags);
+      _bfd_vms_output_long (recwr, (unsigned long) section->size);
+      _bfd_vms_output_counted (recwr, sname);
+      _bfd_vms_output_end_subrec (recwr);
+
+      last_index = section->index;
+done:
+      section = section->next;
+    }
+
+  /* Output symbols.  */
+  vms_debug2 ((3, "%d symbols found\n", abfd->symcount));
+
+  bfd_set_start_address (abfd, (bfd_vma) -1);
+
+  for (symnum = 0; symnum < abfd->symcount; symnum++)
+    {
+      char *hash;
+
+      symbol = abfd->outsymbols[symnum];
+      if (*(symbol->name) == '_')
+       {
+         if (strcmp (symbol->name, "__main") == 0)
+           bfd_set_start_address (abfd, (bfd_vma)symbol->value);
+       }
+      old_flags = symbol->flags;
+
+      if (old_flags & BSF_FILE)
+       continue;
+
+      if ((old_flags & BSF_GLOBAL) == 0                   /* Not xdef...  */
+         && !bfd_is_und_section (symbol->section) /* and not xref... */
+         && !((old_flags & BSF_SECTION_SYM) != 0  /* and not LIB$INITIALIZE.  */
+              && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
+       continue;
+
+      /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  */
+      if (_bfd_vms_output_check (recwr, 80) < 0)
+       {
+         _bfd_vms_output_end (abfd, recwr);
+         _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+         _bfd_vms_output_long (recwr, 0);
+       }
+
+      _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYM);
+
+      /* Data type, alignment.  */
+      _bfd_vms_output_short (recwr, 0);
+
+      new_flags = 0;
+
+      if (old_flags & BSF_WEAK)
+       new_flags |= EGSY__V_WEAK;
+      if (bfd_is_com_section (symbol->section))                /* .comm  */
+       new_flags |= (EGSY__V_WEAK | EGSY__V_COMM);
+
+      if (old_flags & BSF_FUNCTION)
+       {
+         new_flags |= EGSY__V_NORM;
+         new_flags |= EGSY__V_REL;
+       }
+      if (old_flags & BSF_GLOBAL)
+       {
+         new_flags |= EGSY__V_DEF;
+         if (!bfd_is_abs_section (symbol->section))
+           new_flags |= EGSY__V_REL;
+       }
+      _bfd_vms_output_short (recwr, new_flags);
+
+      if (old_flags & BSF_GLOBAL)
+       {
+         /* Symbol definition.  */
+         bfd_vma code_address = 0;
+         unsigned long ca_psindx = 0;
+         unsigned long psindx;
+
+         if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
+           {
+             asymbol *sym;
+
+              sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
+             code_address = sym->value;
+             ca_psindx = sym->section->index;
+           }
+         if (bfd_is_abs_section (symbol->section))
+           psindx = abs_section_index;
+         else
+           psindx = symbol->section->index;
+
+         _bfd_vms_output_quad (recwr, symbol->value);
+         _bfd_vms_output_quad (recwr, code_address);
+         _bfd_vms_output_long (recwr, ca_psindx);
+         _bfd_vms_output_long (recwr, psindx);
+       }
+      hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ__C_SYMSIZ);
+      _bfd_vms_output_counted (recwr, hash);
+
+      _bfd_vms_output_end_subrec (recwr);
+
+    }
+
+  _bfd_vms_output_alignment (recwr, 8);
+  _bfd_vms_output_end (abfd, recwr);
+
+  return TRUE;
+}
+
+/* Write object header for bfd abfd.  Return FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_write_ehdr (bfd *abfd)
+{
+  asymbol *symbol;
+  unsigned int symnum;
+  int had_case = 0;
+  int had_file = 0;
+  char version [256];
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd));
+
+  _bfd_vms_output_alignment (recwr, 2);
+
+  /* EMH.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_MHD);
+  _bfd_vms_output_short (recwr, EOBJ__C_STRLVL);
+  _bfd_vms_output_long (recwr, 0);
+  _bfd_vms_output_long (recwr, 0);
+  _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE);
+
+  /* Create module name from filename.  */
+  if (bfd_get_filename (abfd) != 0)
+    {
+      char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
+      _bfd_vms_output_counted (recwr, module);
+      free (module);
+    }
+  else
+    _bfd_vms_output_counted (recwr, "NONAME");
+
+  _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
+  _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH);
+  _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
+  _bfd_vms_output_end (abfd, recwr);
+
+  /* LMN.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_LNM);
+  snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
+  _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version));
+  _bfd_vms_output_end (abfd, recwr);
+
+  /* SRC.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_SRC);
+
+  for (symnum = 0; symnum < abfd->symcount; symnum++)
+    {
+      symbol = abfd->outsymbols[symnum];
+
+      if (symbol->flags & BSF_FILE)
+       {
+         if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
+           {
+             PRIV (flag_hash_long_names) = symbol->name[6] - '0';
+             PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
+
+             if (had_file)
+               break;
+             had_case = 1;
+             continue;
+           }
+
+         _bfd_vms_output_dump (recwr, (unsigned char *) symbol->name,
+                               (int) strlen (symbol->name));
+         if (had_case)
+           break;
+         had_file = 1;
+       }
+    }
+
+  if (symnum == abfd->symcount)
+    _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("noname"));
+
+  _bfd_vms_output_end (abfd, recwr);
+
+  /* TTL.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_TTL);
+  _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("TTL"));
+  _bfd_vms_output_end (abfd, recwr);
+
+  /* CPR.  */
+  _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+  _bfd_vms_output_short (recwr, EMH__C_CPR);
+  _bfd_vms_output_dump (recwr,
+                        (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
+                        39);
+  _bfd_vms_output_end (abfd, recwr);
+
+  return TRUE;
+}
+
+/* Part 4.6, relocations.  */
+
+\f
+/* WRITE ETIR SECTION
+
+   This is still under construction and therefore not documented.  */
+
+/* Close the etir/etbt record.  */
+
+static void
+end_etir_record (bfd * abfd)
+{
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  _bfd_vms_output_end (abfd, recwr);
+}
+
+static void
+start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
+{
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  if (section->name[0] == '.' && section->name[1] == 'v'
+      && !strcmp (section->name, ".vmsdebug"))
+    {
+      _bfd_vms_output_begin (recwr, EOBJ__C_ETBT);
+
+      if (offset == 0)
+        {
+          /* Push start offset.  */
+          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+          _bfd_vms_output_long (recwr, (unsigned long) 0);
+          _bfd_vms_output_end_subrec (recwr);
+
+          /* Set location.  */
+          _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_DFLOC);
+          _bfd_vms_output_end_subrec (recwr);
+        }
+    }
+  else
+    {
+      _bfd_vms_output_begin (recwr, EOBJ__C_ETIR);
+
+      if (offset == 0)
+        {
+          /* Push start offset.  */
+          _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+          _bfd_vms_output_long (recwr, (unsigned long) section->index);
+          _bfd_vms_output_quad (recwr, offset);
+          _bfd_vms_output_end_subrec (recwr);
+
+          /* Start = pop ().  */
+          _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_SETRB);
+          _bfd_vms_output_end_subrec (recwr);
+        }
+    }
+}
+
+/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
+   address VADDR in section specified by SEC_INDEX and NAME.  */
+
+static void
+sto_imm (bfd *abfd, asection *section,
+         bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
+{
+  bfd_size_type size;
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+#if VMS_DEBUG
+  _bfd_vms_debug (8, "sto_imm %d bytes\n", (int) ssize);
+  _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
+#endif
+
+  while (ssize > 0)
+    {
+      /* Try all the rest.  */
+      size = ssize;
+
+      if (_bfd_vms_output_check (recwr, size) < 0)
+       {
+         /* Doesn't fit, split !  */
+         end_etir_record (abfd);
+
+          start_etir_or_etbt_record (abfd, section, vaddr);
+
+         size = _bfd_vms_output_check (recwr, 0);      /* get max size */
+         if (size > ssize)                     /* more than what's left ? */
+           size = ssize;
+       }
+
+      _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_IMM);
+      _bfd_vms_output_long (recwr, (unsigned long) (size));
+      _bfd_vms_output_dump (recwr, cptr, size);
+      _bfd_vms_output_end_subrec (recwr);
+
+#if VMS_DEBUG
+      _bfd_vms_debug (10, "dumped %d bytes\n", (int) size);
+      _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
+#endif
+
+      vaddr += size;
+      cptr += size;
+      ssize -= size;
+    }
+}
+
+static void
+etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
+{
+  if (_bfd_vms_output_check (&PRIV (recwr), checklen) < 0)
+    {
+      /* Not enough room in this record.  Close it and open a new one.  */
+      end_etir_record (abfd);
+      start_etir_or_etbt_record (abfd, section, vaddr);
+    }
+}
+
+/* Return whether RELOC must be deferred till the end.  */
+
+static bfd_boolean
+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 TRUE;
+
+    default:
+      return FALSE;
+    }
+}
+
+/* Write section contents for bfd abfd.  Return FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
+{
+  asection *section;
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  vms_debug2 ((2, "vms_write_tir (%p, %d)\n", abfd, objtype));
+
+  _bfd_vms_output_alignment (recwr, 4);
+
+  PRIV (vms_linkage_index) = 1;
+
+  for (section = abfd->sections; section; section = section->next)
+    {
+      vms_debug2 ((4, "writing %d. section '%s' (%d bytes)\n",
+                   section->index, section->name, (int) (section->size)));
+
+      if (!(section->flags & SEC_HAS_CONTENTS)
+         || bfd_is_com_section (section))
+       continue;
+
+      if (!section->contents)
+       {
+         bfd_set_error (bfd_error_no_contents);
+         return FALSE;
+       }
+
+      start_etir_or_etbt_record (abfd, section, 0);
+
+      if (section->flags & SEC_RELOC)
+       {
+         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 VMS_DEBUG
+         else
+           {
+             int i = section->reloc_count;
+             arelent **rptr = section->orelocation;
+             _bfd_vms_debug (4, "%d relocations:\n", i);
+             while (i-- > 0)
+               {
+                 _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,
+                                 (unsigned long)(*rptr)->address,
+                                  (unsigned long)(*rptr)->addend,
+                                 bfd_get_reloc_size ((*rptr)->howto),
+                                  ( *rptr)->howto->name);
+                 rptr++;
+               }
+           }
+#endif
+
+       new_pass:
+         for (irel = 0; irel < section->reloc_count; irel++)
+           {
+             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;
+             bfd_boolean 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, section, size, curr_data, curr_addr);
+                 curr_data += size;
+                 curr_addr += size;
+               }
+
+             size = bfd_get_reloc_size (rptr->howto);
+
+             switch (rptr->howto->type)
+               {
+               case ALPHA_R_IGNORE:
+                 break;
+
+               case ALPHA_R_REFLONG:
+                 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__C_SYMSIZ);
+                     etir_output_check (abfd, section, curr_addr, slen);
+                     if (addend)
+                       {
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
+                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_end_subrec (recwr);
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+                         _bfd_vms_output_long (recwr, (unsigned long) addend);
+                         _bfd_vms_output_end_subrec (recwr);
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD);
+                         _bfd_vms_output_end_subrec (recwr);
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
+                         _bfd_vms_output_end_subrec (recwr);
+                       }
+                     else
+                       {
+                         _bfd_vms_output_begin_subrec
+                            (recwr, ETIR__C_STO_GBL_LW);
+                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_end_subrec (recwr);
+                       }
+                   }
+                 else if (bfd_is_abs_section (sym->section))
+                   {
+                     etir_output_check (abfd, section, curr_addr, 16);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+                     _bfd_vms_output_long (recwr, (unsigned long) sym->value);
+                     _bfd_vms_output_end_subrec (recwr);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
+                     _bfd_vms_output_end_subrec (recwr);
+                   }
+                 else
+                   {
+                     etir_output_check (abfd, section, curr_addr, 32);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+                     _bfd_vms_output_long (recwr, (unsigned long) sec->index);
+                     _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
+                     _bfd_vms_output_end_subrec (recwr);
+                     /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
+                        says that we should have a ETIR__C_STO_OFF here.
+                        But the relocation would not be BFD_RELOC_32 then.
+                        This case is very likely unreachable.  */
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
+                     _bfd_vms_output_end_subrec (recwr);
+                   }
+                 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__C_SYMSIZ);
+                     etir_output_check (abfd, section, curr_addr, slen);
+                     if (addend)
+                       {
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
+                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_end_subrec (recwr);
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
+                         _bfd_vms_output_quad (recwr, addend);
+                         _bfd_vms_output_end_subrec (recwr);
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD);
+                         _bfd_vms_output_end_subrec (recwr);
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW);
+                         _bfd_vms_output_end_subrec (recwr);
+                       }
+                     else
+                       {
+                         _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL);
+                         _bfd_vms_output_counted (recwr, hash);
+                         _bfd_vms_output_end_subrec (recwr);
+                       }
+                   }
+                 else if (bfd_is_abs_section (sym->section))
+                   {
+                     etir_output_check (abfd, section, curr_addr, 16);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
+                     _bfd_vms_output_quad (recwr, sym->value);
+                     _bfd_vms_output_end_subrec (recwr);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW);
+                     _bfd_vms_output_end_subrec (recwr);
+                   }
+                 else
+                   {
+                     etir_output_check (abfd, section, curr_addr, 32);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+                     _bfd_vms_output_long (recwr, (unsigned long) sec->index);
+                     _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
+                     _bfd_vms_output_end_subrec (recwr);
+                     _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_OFF);
+                     _bfd_vms_output_end_subrec (recwr);
+                   }
+                 break;
+
+               case ALPHA_R_HINT:
+                 sto_imm (abfd, section, size, curr_data, curr_addr);
+                 break;
+
+               case ALPHA_R_LINKAGE:
+                 etir_output_check (abfd, section, curr_addr, 64);
+                 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) PRIV (vms_linkage_index));
+                 PRIV (vms_linkage_index) += 2;
+                 hash = _bfd_vms_length_hash_symbol
+                    (abfd, sym->name, EOBJ__C_SYMSIZ);
+                 _bfd_vms_output_counted (recwr, hash);
+                 _bfd_vms_output_byte (recwr, 0);
+                 _bfd_vms_output_end_subrec (recwr);
+                 break;
+
+               case ALPHA_R_CODEADDR:
+                 slen = strlen ((char *) sym->name);
+                 hash = _bfd_vms_length_hash_symbol
+                    (abfd, sym->name, EOBJ__C_SYMSIZ);
+                 etir_output_check (abfd, section, curr_addr, slen);
+                 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
+                 _bfd_vms_output_counted (recwr, hash);
+                 _bfd_vms_output_end_subrec (recwr);
+                 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_subrec (recwr, ETIR__C_STC_NOP_GBL);
+                 _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (recwr, rptr->address);
+                 _bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (recwr, rptr->addend);
+                 _bfd_vms_output_counted
+                   (recwr, _bfd_vms_length_hash_symbol
+                     (abfd, udata->origname, EOBJ__C_SYMSIZ));
+                 _bfd_vms_output_end_subrec (recwr);
+                 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_subrec (recwr, ETIR__C_STC_LDA_GBL);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->lkindex + 1);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (recwr, rptr->address);
+                 _bfd_vms_output_long (recwr, (unsigned long) 0x237B0000);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->bsym->section->index);
+                 _bfd_vms_output_quad (recwr, rptr->addend);
+                 _bfd_vms_output_counted
+                   (recwr, _bfd_vms_length_hash_symbol
+                     (abfd, udata->origname, EOBJ__C_SYMSIZ));
+                 _bfd_vms_output_end_subrec (recwr);
+                 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_subrec (recwr, ETIR__C_STC_BOH_GBL);
+                 _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (recwr, rptr->address);
+                 _bfd_vms_output_long (recwr, (unsigned long) 0xD3400000);
+                 _bfd_vms_output_long
+                   (recwr, (unsigned long) udata->enbsym->section->index);
+                 _bfd_vms_output_quad (recwr, rptr->addend);
+                 _bfd_vms_output_counted
+                   (recwr, _bfd_vms_length_hash_symbol
+                     (abfd, udata->origname, EOBJ__C_SYMSIZ));
+                 _bfd_vms_output_end_subrec (recwr);
+                 break;
+
+               default:
+                 (*_bfd_error_handler) (_("Unhandled relocation %s"),
+                                        rptr->howto->name);
+                 break;
+               }
+
+             curr_data += size;
+             curr_addr += size;
+           } /* End of relocs loop.  */
+
+         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, section, size, curr_data, curr_addr);
+             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, section->size, section->contents, 0);
+
+      end_etir_record (abfd);
+    }
+
+  _bfd_vms_output_alignment (recwr, 2);
+  return TRUE;
+}
+
+/* Write eom record for bfd abfd.  Return FALSE on error.  */
+
+static bfd_boolean
+_bfd_vms_write_eeom (bfd *abfd)
+{
+  struct vms_rec_wr *recwr = &PRIV (recwr);
+
+  vms_debug2 ((2, "vms_write_eeom\n"));
+
+  _bfd_vms_output_begin (recwr, EOBJ__C_EEOM);
+  _bfd_vms_output_long (recwr, (unsigned long) (PRIV (vms_linkage_index) >> 1));
+  _bfd_vms_output_byte (recwr, 0);     /* Completion code.  */
+  _bfd_vms_output_byte (recwr, 0);     /* Fill byte.  */
+
+  if (bfd_get_start_address (abfd) != (bfd_vma)-1)
+    {
+      asection *section;
+
+      section = bfd_get_section_by_name (abfd, ".link");
+      if (section == 0)
+       {
+         bfd_set_error (bfd_error_nonrepresentable_section);
+         return FALSE;
+       }
+      _bfd_vms_output_short (recwr, 0);
+      _bfd_vms_output_long (recwr, (unsigned long) (section->index));
+      _bfd_vms_output_long (recwr,
+                            (unsigned long) bfd_get_start_address (abfd));
+      _bfd_vms_output_long (recwr, 0);
+    }
+
+  _bfd_vms_output_end (abfd, recwr);
+  return TRUE;
+}
+
+/* Write cached information into a file being written, at bfd_close.  */
+
+static bfd_boolean
+alpha_vms_write_object_contents (bfd *abfd)
+{
+  vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd));
+
+  if (abfd->flags & (EXEC_P | DYNAMIC))
+    {
+      return alpha_vms_write_exec (abfd);
+    }
+  else
+    {
+      if (abfd->section_count > 0)                     /* we have sections */
+        {
+          if (_bfd_vms_write_ehdr (abfd) != TRUE)
+            return FALSE;
+          if (_bfd_vms_write_egsd (abfd) != TRUE)
+            return FALSE;
+          if (_bfd_vms_write_etir (abfd, EOBJ__C_ETIR) != TRUE)
+            return FALSE;
+          if (_bfd_vms_write_eeom (abfd) != TRUE)
+            return FALSE;
+        }
+    }
+  return TRUE;
+}
+\f
+/* Debug stuff: nearest line.  */
+
+#define SET_MODULE_PARSED(m) \
+  do { if ((m)->name == NULL) (m)->name = ""; } while (0)
+#define IS_MODULE_PARSED(m) ((m)->name != NULL)
+
+/* Build a new module for the specified BFD.  */
+
+static struct module *
+new_module (bfd *abfd)
+{
+  struct module *module
+    = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
+  module->file_table_count = 16; /* Arbitrary.  */
+  module->file_table
+    = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
+  return module;
+}
+
+/* Parse debug info for a module and internalize it.  */
+
+static void
+parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
+             int length)
+{
+  unsigned char *maxptr = ptr + length;
+  unsigned char *src_ptr, *pcl_ptr;
+  unsigned int prev_linum = 0, curr_linenum = 0;
+  bfd_vma prev_pc = 0, curr_pc = 0;
+  struct srecinfo *curr_srec, *srec;
+  struct lineinfo *curr_line, *line;
+  struct funcinfo *funcinfo;
+
+  /* Initialize tables with zero element.  */
+  curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
+  module->srec_table = curr_srec;
+
+  curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
+  module->line_table = curr_line;
+
+  while (length == -1 || ptr < maxptr)
+    {
+      /* The first byte is not counted in the recorded length.  */
+      int rec_length = bfd_getl16 (ptr) + 1;
+      int rec_type = bfd_getl16 (ptr + 2);
+
+      vms_debug2 ((2, "DST record: leng %d, type %d\n", rec_length, rec_type));
+
+      if (length == -1 && rec_type == DST__K_MODEND)
+        break;
+
+      switch (rec_type)
+       {
+       case DST__K_MODBEG:
+         module->name
+           = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
+
+         curr_pc = 0;
+         prev_pc = 0;
+         curr_linenum = 0;
+         prev_linum = 0;
+
+          vms_debug2 ((3, "module: %s\n", module->name));
+         break;
+
+       case DST__K_MODEND:
+         break;
+
+       case DST__K_RTNBEG:
+         funcinfo = (struct funcinfo *)
+           bfd_zalloc (abfd, sizeof (struct funcinfo));
+          funcinfo->name
+           = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
+         funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
+         funcinfo->next = module->func_table;
+         module->func_table = funcinfo;
+
+          vms_debug2 ((3, "routine: %s at 0x%lx\n",
+                       funcinfo->name, (unsigned long) funcinfo->low));
+         break;
+
+       case DST__K_RTNEND:
+         module->func_table->high = module->func_table->low
+           + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
+
+         if (module->func_table->high > module->high)
+           module->high = module->func_table->high;
+
+          vms_debug2 ((3, "end routine\n"));
+         break;
+
+       case DST__K_PROLOG:
+          vms_debug2 ((3, "prologue\n"));
+         break;
+
+       case DST__K_EPILOG:
+          vms_debug2 ((3, "epilog\n"));
+         break;
+
+       case DST__K_BLKBEG:
+          vms_debug2 ((3, "block\n"));
+         break;
+
+       case DST__K_BLKEND:
+          vms_debug2 ((3, "end block\n"));
+         break;
+
+       case DST__K_SOURCE:
+         src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
+
+         vms_debug2 ((3, "source info\n"));
+
+         while (src_ptr < ptr + rec_length)
+           {
+             int cmd = src_ptr[0], cmd_length, data;
+
+             switch (cmd)
+               {
+               case DST__K_SRC_DECLFILE:
+                 {
+                   unsigned int fileid
+                     = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
+                   char *filename
+                     = _bfd_vms_save_counted_string (src_ptr
+                         + DST_S_B_SRC_DF_FILENAME);
+
+                   while (fileid >= module->file_table_count)
+                     {
+                       module->file_table_count *= 2;
+                       module->file_table
+                         = bfd_realloc (module->file_table,
+                                        module->file_table_count
+                                          * sizeof (struct fileinfo));
+                     }
+
+                   module->file_table [fileid].name = filename;
+                   module->file_table [fileid].srec = 1;
+                   cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
+                   vms_debug2 ((4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
+                                 fileid, module->file_table [fileid].name));
+                 }
+                 break;
+
+               case DST__K_SRC_DEFLINES_B:
+                 /* Perform the association and set the next higher index
+                    to the limit.  */
+                 data = src_ptr[DST_S_B_SRC_UNSBYTE];
+                 srec = (struct srecinfo *)
+                   bfd_zalloc (abfd, sizeof (struct srecinfo));
+                 srec->line = curr_srec->line + data;
+                 srec->srec = curr_srec->srec + data;
+                 srec->sfile = curr_srec->sfile;
+                 curr_srec->next = srec;
+                 curr_srec = srec;
+                 cmd_length = 2;
+                 vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_B: %d\n", data));
+                 break;
+
+               case DST__K_SRC_DEFLINES_W:
+                 /* Perform the association and set the next higher index
+                    to the limit.  */
+                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+                 srec = (struct srecinfo *)
+                   bfd_zalloc (abfd, sizeof (struct srecinfo));
+                 srec->line = curr_srec->line + data;
+                 srec->srec = curr_srec->srec + data,
+                 srec->sfile = curr_srec->sfile;
+                 curr_srec->next = srec;
+                 curr_srec = srec;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_W: %d\n", data));
+                 break;
+
+               case DST__K_SRC_INCRLNUM_B:
+                 data = src_ptr[DST_S_B_SRC_UNSBYTE];
+                 curr_srec->line += data;
+                 cmd_length = 2;
+                 vms_debug2 ((4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data));
+                 break;
+
+               case DST__K_SRC_SETFILE:
+                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+                 curr_srec->sfile = data;
+                 curr_srec->srec = module->file_table[data].srec;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST_S_C_SRC_SETFILE: %d\n", data));
+                 break;
+
+               case DST__K_SRC_SETLNUM_L:
+                 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
+                 curr_srec->line = data;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_L: %d\n", data));
+                 break;
+
+               case DST__K_SRC_SETLNUM_W:
+                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+                 curr_srec->line = data;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_W: %d\n", data));
+                 break;
+
+               case DST__K_SRC_SETREC_L:
+                 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
+                 curr_srec->srec = data;
+                 module->file_table[curr_srec->sfile].srec = data;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST_S_C_SRC_SETREC_L: %d\n", data));
+                 break;
+
+               case DST__K_SRC_SETREC_W:
+                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+                 curr_srec->srec = data;
+                 module->file_table[curr_srec->sfile].srec = data;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST_S_C_SRC_SETREC_W: %d\n", data));
+                 break;
+
+               case DST__K_SRC_FORMFEED:
+                 cmd_length = 1;
+                 vms_debug2 ((4, "DST_S_C_SRC_FORMFEED\n"));
+                 break;
+
+               default:
+                 (*_bfd_error_handler) (_("unknown source command %d"),
+                                        cmd);
+                 cmd_length = 2;
+                 break;
+               }
+
+             src_ptr += cmd_length;
+           }
+         break;
+
+       case DST__K_LINE_NUM:
+         pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
+
+         vms_debug2 ((3, "line info\n"));
+
+         while (pcl_ptr < ptr + rec_length)
+           {
+             /* The command byte is signed so we must sign-extend it.  */
+             int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
+
+             switch (cmd)
+               {
+               case DST__K_DELTA_PC_W:
+                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+                 curr_pc += data;
+                 curr_linenum += 1;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST__K_DELTA_PC_W: %d\n", data));
+                 break;
+
+               case DST__K_DELTA_PC_L:
+                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+                 curr_pc += data;
+                 curr_linenum += 1;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST__K_DELTA_PC_L: %d\n", data));
+                 break;
+
+               case DST__K_INCR_LINUM:
+                 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+                 curr_linenum += data;
+                 cmd_length = 2;
+                 vms_debug2 ((4, "DST__K_INCR_LINUM: %d\n", data));
+                 break;
+
+               case DST__K_INCR_LINUM_W:
+                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+                 curr_linenum += data;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST__K_INCR_LINUM_W: %d\n", data));
+                 break;
+
+               case DST__K_INCR_LINUM_L:
+                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+                 curr_linenum += data;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST__K_INCR_LINUM_L: %d\n", data));
+                 break;
+
+               case DST__K_SET_LINUM_INCR:
+                 (*_bfd_error_handler)
+                   (_("DST__K_SET_LINUM_INCR not implemented"));
+                 cmd_length = 2;
+                 break;
+
+               case DST__K_SET_LINUM_INCR_W:
+                 (*_bfd_error_handler)
+                   (_("DST__K_SET_LINUM_INCR_W not implemented"));
+                 cmd_length = 3;
+                 break;
+
+               case DST__K_RESET_LINUM_INCR:
+                 (*_bfd_error_handler)
+                   (_("DST__K_RESET_LINUM_INCR not implemented"));
+                 cmd_length = 1;
+                 break;
+
+               case DST__K_BEG_STMT_MODE:
+                 (*_bfd_error_handler)
+                   (_("DST__K_BEG_STMT_MODE not implemented"));
+                 cmd_length = 1;
+                 break;
+
+               case DST__K_END_STMT_MODE:
+                 (*_bfd_error_handler)
+                   (_("DST__K_END_STMT_MODE not implemented"));
+                 cmd_length = 1;
+                 break;
+
+               case DST__K_SET_LINUM_B:
+                 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+                 curr_linenum = data;
+                 cmd_length = 2;
+                 vms_debug2 ((4, "DST__K_SET_LINUM_B: %d\n", data));
+                 break;
+
+               case DST__K_SET_LINUM:
+                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+                 curr_linenum = data;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST__K_SET_LINE_NUM: %d\n", data));
+                 break;
+
+               case DST__K_SET_LINUM_L:
+                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+                 curr_linenum = data;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST__K_SET_LINUM_L: %d\n", data));
+                 break;
+
+               case DST__K_SET_PC:
+                 (*_bfd_error_handler)
+                   (_("DST__K_SET_PC not implemented"));
+                 cmd_length = 2;
+                 break;
+
+               case DST__K_SET_PC_W:
+                 (*_bfd_error_handler)
+                   (_("DST__K_SET_PC_W not implemented"));
+                 cmd_length = 3;
+                 break;
+
+               case DST__K_SET_PC_L:
+                 (*_bfd_error_handler)
+                   (_("DST__K_SET_PC_L not implemented"));
+                 cmd_length = 5;
+                 break;
+
+               case DST__K_SET_STMTNUM:
+                 (*_bfd_error_handler)
+                   (_("DST__K_SET_STMTNUM not implemented"));
+                 cmd_length = 2;
+                 break;
+
+               case DST__K_TERM:
+                 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+                 curr_pc += data;
+                 cmd_length = 2;
+                 vms_debug2 ((4, "DST__K_TERM: %d\n", data));
+                 break;
+
+               case DST__K_TERM_W:
+                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+                 curr_pc += data;
+                 cmd_length = 3;
+                 vms_debug2 ((4, "DST__K_TERM_W: %d\n", data));
+                 break;
+
+               case DST__K_TERM_L:
+                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+                 curr_pc += data;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST__K_TERM_L: %d\n", data));
+                 break;
+
+               case DST__K_SET_ABS_PC:
+                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+                 curr_pc = data;
+                 cmd_length = 5;
+                 vms_debug2 ((4, "DST__K_SET_ABS_PC: 0x%x\n", data));
+                 break;
+
+               default:
+                 if (cmd <= 0)
+                   {
+                     curr_pc -= cmd;
+                     curr_linenum += 1;
+                     cmd_length = 1;
+                     vms_debug2 ((4, "bump pc to 0x%lx and line to %d\n",
+                                   (unsigned long)curr_pc, curr_linenum));
+                   }
+                 else
+                   {
+                     (*_bfd_error_handler) (_("unknown line command %d"),
+                                            cmd);
+                     cmd_length = 2;
+                   }
+                 break;
+               }
+
+             if ((curr_linenum != prev_linum && curr_pc != prev_pc)
+                 || cmd <= 0
+                 || cmd == DST__K_DELTA_PC_L
+                 || cmd == DST__K_DELTA_PC_W)
+               {
+                 line = (struct lineinfo *)
+                   bfd_zalloc (abfd, sizeof (struct lineinfo));
+                 line->address = curr_pc;
+                 line->line = curr_linenum;
+
+                 curr_line->next = line;
+                 curr_line = line;
+
+                 prev_linum = curr_linenum;
+                 prev_pc = curr_pc;
+                 vms_debug2 ((4, "-> correlate pc 0x%lx with line %d\n",
+                               (unsigned long)curr_pc, curr_linenum));
+               }
+
+             pcl_ptr += cmd_length;
+           }
+         break;
+
+       case 0x17: /* Undocumented type used by DEC C to declare equates.  */
+         vms_debug2 ((3, "undocumented type 0x17\n"));
+         break;
+
+       default:
+         vms_debug2 ((3, "ignoring record\n"));
+         break;
+
+       }
+
+      ptr += rec_length;
+    }
+
+  /* Finalize tables with EOL marker.  */
+  srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
+  srec->line = (unsigned int) -1;
+  srec->srec = (unsigned int) -1;
+  curr_srec->next = srec;
+
+  line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
+  line->line = (unsigned int) -1;
+  line->address = (bfd_vma) -1;
+  curr_line->next = line;
+
+  /* Advertise that this module has been parsed.  This is needed
+     because parsing can be either performed at module creation
+     or deferred until debug info is consumed.  */
+  SET_MODULE_PARSED (module);
+}
+
+/* Build the list of modules for the specified BFD.  */
+
+static struct module *
+build_module_list (bfd *abfd)
+{
+  struct module *module, *list = NULL;
+  asection *dmt;
+
+  if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
+    {
+      /* We have a DMT section so this must be an image.  Parse the
+        section and build the list of modules.  This is sufficient
+        since we can compute the start address and the end address
+        of every module from the section contents.  */
+      bfd_size_type size = bfd_get_section_size (dmt);
+      unsigned char *ptr, *end;
+
+      ptr = (unsigned char *) bfd_alloc (abfd, size);
+      if (! ptr)
+       return NULL;
+
+      if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
+       return NULL;
+
+      vms_debug2 ((2, "DMT\n"));
+
+      end = ptr + size;
+
+      while (ptr < end)
+       {
+         /* Each header declares a module with its start offset and size
+            of debug info in the DST section, as well as the count of
+            program sections (i.e. address spans) it contains.  */
+         int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
+         int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
+         int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
+         ptr += DBG_S_C_DMT_HEADER_SIZE;
+
+         vms_debug2 ((3, "module: modbeg = %d, size = %d, count = %d\n",
+                       modbeg, msize, count));
+
+         /* We create a 'module' structure for each program section since
+            we only support contiguous addresses in a 'module' structure.
+            As a consequence, the actual debug info in the DST section is
+            shared and can be parsed multiple times; that doesn't seem to
+            cause problems in practice.  */
+         while (count-- > 0)
+           {
+             int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
+             int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
+             module = new_module (abfd);
+             module->modbeg = modbeg;
+             module->size = msize;
+             module->low = start;
+             module->high = start + length;
+             module->next = list;
+             list = module;
+             ptr += DBG_S_C_DMT_PSECT_SIZE;
+
+             vms_debug2 ((4, "section: start = 0x%x, length = %d\n",
+                           start, length));
+           }
+       }
+    }
+  else
+    {
+      /* We don't have a DMT section so this must be an object.  Parse
+        the module right now in order to compute its start address and
+        end address.  */
+      module = new_module (abfd);
+      parse_module (abfd, module, PRIV (dst_section)->contents, -1);
+      list = module;
+    }
+
+  return list;
+}
+
+/* Calculate and return the name of the source file and the line nearest
+   to the wanted location in the specified module.  */
+
+static bfd_boolean
+module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
+                         const char **file, const char **func,
+                         unsigned int *line)
+{
+  struct funcinfo *funcinfo;
+  struct lineinfo *lineinfo;
+  struct srecinfo *srecinfo;
+  bfd_boolean ret = FALSE;
+
+  /* Parse this module if that was not done at module creation.  */
+  if (! IS_MODULE_PARSED (module))
+    {
+      unsigned int size = module->size;
+      unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
+      unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
+
+      if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
+         || bfd_bread (buffer, size, abfd) != size)
+       {
+         bfd_set_error (bfd_error_no_debug_section);
+         return FALSE;
+       }
+
+      parse_module (abfd, module, buffer, size);
+      free (buffer);
+    }
+
+  /* Find out the function (if any) that contains the address.  */
+  for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
+    if (addr >= funcinfo->low && addr <= funcinfo->high)
+      {
+        *func = funcinfo->name;
+       ret = TRUE;
+       break;
+      }
+
+  /* Find out the source file and the line nearest to the address.  */
+  for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
+    if (lineinfo->next && addr < lineinfo->next->address)
+      {
+       for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
+         if (srecinfo->next && lineinfo->line < srecinfo->next->line)
+           {
+             if (srecinfo->sfile > 0)
+               {
+                 *file = module->file_table[srecinfo->sfile].name;
+                 *line = srecinfo->srec + lineinfo->line - srecinfo->line;
+               }
+             else
+               {
+                 *file = module->name;
+                 *line = lineinfo->line;
+               }
+             return TRUE;
+           }
+
+       break;
+      }
+
+  return ret;
+}
+
+/* Provided a BFD, a section and an offset into the section, calculate and
+   return the name of the source file and the line nearest to the wanted
+   location.  */
+
+static bfd_boolean
+_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
+                               asymbol **symbols ATTRIBUTE_UNUSED,
+                               bfd_vma offset, const char **file,
+                               const char **func, unsigned int *line)
+{
+  struct module *module;
+
+  /* What address are we looking for?  */
+  bfd_vma addr = section->vma + offset;
+
+  *file = NULL;
+  *func = NULL;
+  *line = 0;
+
+  if (PRIV (dst_section) == NULL || !(abfd->flags & (EXEC_P | DYNAMIC)))
+    return FALSE;
+
+  if (PRIV (modules) == NULL)
+    {
+      PRIV (modules) = build_module_list (abfd);
+      if (PRIV (modules) == NULL)
+        return FALSE;
+    }
+
+  for (module = PRIV (modules); module; module = module->next)
+    if (addr >= module->low && addr <= module->high)
+      return module_find_nearest_line (abfd, module, addr, file, func, line);
+
+  return FALSE;
+}
+\f
+/* Canonicalizations.  */
+/* Set name, value, section and flags of SYM from E.  */
+
+static bfd_boolean
+alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym)
+{
+  flagword flags;
+  symvalue value;
+  asection *sec;
+  const char *name;
+
+  name = e->name;
+  value = 0;
+  flags = BSF_NO_FLAGS;
+  sec = NULL;
+
+  switch (e->typ)
+    {
+    case EGSD__C_SYM:
+      if (e->flags & EGSY__V_WEAK)
+        flags |= BSF_WEAK;
+
+      if (e->flags & EGSY__V_DEF)
+        {
+          /* Symbol definition.  */
+          flags |= BSF_GLOBAL;
+          if (e->flags & EGSY__V_NORM)
+            flags |= BSF_FUNCTION;
+          value = e->value;
+          sec = PRIV (sections)[e->section];
+        }
+      else
+        {
+          /* Symbol reference.  */
+          sec = bfd_und_section_ptr;
+        }
+      break;
+
+    case EGSD__C_SYMG:
+      /* A universal symbol is by definition global...  */
+      flags |= BSF_GLOBAL;
+
+      /* ...and dynamic in shared libraries.  */
+      if (abfd->flags & DYNAMIC)
+        flags |= BSF_DYNAMIC;
+
+      if (e->flags & EGSY__V_WEAK)
+        flags |= BSF_WEAK;
+
+      if (!(e->flags & EGSY__V_DEF))
+        abort ();
+
+      if (e->flags & EGSY__V_NORM)
+        flags |= BSF_FUNCTION;
+
+      value = e->symbol_vector;
+
+      /* Adding this offset is necessary in order for GDB to
+         read the DWARF-2 debug info from shared libraries.  */
+      if ((abfd->flags & DYNAMIC) && strstr (name, "$DWARF2.DEBUG") != 0)
+        value += PRIV (symvva);
+
+      sec = bfd_abs_section_ptr;
+#if 0
+      /* Find containing section.  */
+      {
+        bfd_vma sbase = 0;
+        asection *s;
+
+        for (s = abfd->sections; s; s = s->next)
+          {
+            if (value >= s->vma
+                && s->vma > sbase
+                && !(s->flags & SEC_COFF_SHARED_LIBRARY)
+                && (s->size > 0 || !(e->flags & EGSY__V_REL)))
+              {
+                sbase = s->vma;
+                sec = s;
+              }
+          }
+        value -= sbase;
+      }
+#endif
+
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  sym->name = name;
+  sym->section = sec;
+  sym->flags = flags;
+  sym->value = value;
+  return TRUE;
+}
+
+
+/* Return the number of bytes required to store a vector of pointers
+   to asymbols for all the symbols in the BFD abfd, including a
+   terminal NULL pointer. If there are no symbols in the BFD,
+   then return 0.  If an error occurs, return -1.  */
+
+static long
+alpha_vms_get_symtab_upper_bound (bfd *abfd)
+{
+  vms_debug2 ((1, "alpha_vms_get_symtab_upper_bound (%p), %d symbols\n",
+               abfd, PRIV (gsd_sym_count)));
+
+  return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
+}
+
+/* Read the symbols from the BFD abfd, and fills in the vector
+   location with pointers to the symbols and a trailing NULL.
+
+   Return number of symbols read.   */
+
+static long
+alpha_vms_canonicalize_symtab (bfd *abfd, asymbol **symbols)
+{
+  unsigned int i;
+
+  vms_debug2 ((1, "alpha_vms_canonicalize_symtab (%p, <ret>)\n", abfd));
+
+  if (PRIV (csymbols) == NULL)
+    {
+      PRIV (csymbols) = (asymbol **) bfd_alloc
+        (abfd, PRIV (gsd_sym_count) * sizeof (asymbol *));
+
+      /* Traverse table and fill symbols vector.  */
+      for (i = 0; i < PRIV (gsd_sym_count); i++)
+        {
+          struct vms_symbol_entry *e = PRIV (syms)[i];
+          asymbol *sym;
+
+          sym = bfd_make_empty_symbol (abfd);
+          if (sym == NULL || !alpha_vms_convert_symbol (abfd, e, sym))
+            {
+              bfd_release (abfd, PRIV (csymbols));
+              PRIV (csymbols) = NULL;
+              return -1;
+            }
+
+          PRIV (csymbols)[i] = sym;
+        }
+    }
+
+  if (symbols != NULL)
+    {
+      for (i = 0; i < PRIV (gsd_sym_count); i++)
+        symbols[i] = PRIV (csymbols)[i];
+      symbols[i] = NULL;
+    }
+
+  return PRIV (gsd_sym_count);
+}
+
+/* Read and convert relocations from ETIR.  We do it once for all sections.  */
+
+static bfd_boolean
+alpha_vms_slurp_relocs (bfd *abfd)
+{
+  int cur_psect = -1;
+
+  vms_debug2 ((3, "alpha_vms_slurp_relocs\n"));
+
+  /* We slurp relocs only once, for all sections.  */
+  if (PRIV (reloc_done))
+      return TRUE;
+  PRIV (reloc_done) = TRUE;
+
+  if (alpha_vms_canonicalize_symtab (abfd, NULL) < 0)
+    return FALSE;
+
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+    return FALSE;
+
+  while (1)
+    {
+      unsigned char *begin;
+      unsigned char *end;
+      unsigned char *ptr;
+      bfd_reloc_code_real_type reloc_code;
+      int type;
+      bfd_vma vaddr = 0;
+
+      int length;
+
+      bfd_vma cur_address;
+      int cur_psidx = -1;
+      unsigned char *cur_sym = NULL;
+      int prev_cmd = -1;
+      bfd_vma cur_addend = 0;
+
+      /* Skip non-ETIR records.  */
+      type = _bfd_vms_get_object_record (abfd);
+      if (type == EOBJ__C_EEOM)
+        break;
+      if (type != EOBJ__C_ETIR)
+        continue;
+
+      begin = PRIV (recrd.rec) + 4;
+      end = PRIV (recrd.rec) + PRIV (recrd.rec_size);
+
+      for (ptr = begin; ptr < end; ptr += length)
+        {
+          int cmd;
+
+          cmd = bfd_getl16 (ptr);
+          length = bfd_getl16 (ptr + 2);
+
+          cur_address = vaddr;
+
+          vms_debug2 ((4, "alpha_vms_slurp_relocs: etir %s\n",
+                       _bfd_vms_etir_name (cmd)));
+
+          switch (cmd)
+            {
+            case ETIR__C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+                                  /* ALPHA_R_REFQUAD und_section, step 1 */
+              cur_sym = ptr + 4;
+              prev_cmd = cmd;
+              continue;
+
+            case ETIR__C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+              cur_psidx = bfd_getl32 (ptr + 4);
+              cur_addend = bfd_getl64 (ptr + 8);
+              prev_cmd = cmd;
+              continue;
+
+            case ETIR__C_CTL_SETRB:
+              if (prev_cmd != ETIR__C_STA_PQ)
+                {
+                  (*_bfd_error_handler)
+                    (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd),
+                     _bfd_vms_etir_name (cmd));
+                  return FALSE;
+                }
+              cur_psect = cur_psidx;
+              vaddr = cur_addend;
+              cur_psidx = -1;
+              cur_addend = 0;
+              continue;
+
+            case ETIR__C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
+                                 /* ALPHA_R_REFLONG und_section, step 2 */
+              if (prev_cmd != -1)
+                {
+                  if (prev_cmd != ETIR__C_STA_GBL)
+                    {
+                      (*_bfd_error_handler)
+                        (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
+                         _bfd_vms_etir_name (ETIR__C_STA_LW));
+                      return FALSE;
+                    }
+                }
+              cur_addend = bfd_getl32 (ptr + 4);
+              prev_cmd = cmd;
+              continue;
+
+            case ETIR__C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
+                                /* ALPHA_R_REFQUAD und_section, step 2 */
+              if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL)
+                {
+                  (*_bfd_error_handler)
+                    (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
+                     _bfd_vms_etir_name (ETIR__C_STA_QW));
+                  return FALSE;
+                }
+              cur_addend = bfd_getl64 (ptr + 4);
+              prev_cmd = cmd;
+              continue;
+
+            case ETIR__C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+                                /* ALPHA_R_REFLONG abs_section, step 2 */
+                                 /* ALPHA_R_REFLONG others, step 2 */
+              if (prev_cmd != ETIR__C_OPR_ADD
+                  && prev_cmd != ETIR__C_STA_LW
+                  && prev_cmd != ETIR__C_STA_PQ)
+                {
+                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+                                         _bfd_vms_etir_name (prev_cmd),
+                                         _bfd_vms_etir_name (ETIR__C_STO_LW));
+                  return FALSE;
+                }
+              reloc_code = BFD_RELOC_32;
+              break;
+
+            case ETIR__C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+                                /* ALPHA_R_REFQUAD abs_section, step 2 */
+              if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW)
+                {
+                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+                                         _bfd_vms_etir_name (prev_cmd),
+                                         _bfd_vms_etir_name (ETIR__C_STO_QW));
+                  return FALSE;
+                }
+              reloc_code = BFD_RELOC_64;
+              break;
+
+            case ETIR__C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+              if (prev_cmd != ETIR__C_STA_PQ)
+                {
+                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+                                         _bfd_vms_etir_name (prev_cmd),
+                                         _bfd_vms_etir_name (ETIR__C_STO_OFF));
+                  return FALSE;
+                }
+              reloc_code = BFD_RELOC_64;
+              break;
+
+            case ETIR__C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+                                  /* ALPHA_R_REFQUAD und_section, step 3 */
+              if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW)
+                {
+                  (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+                                         _bfd_vms_etir_name (prev_cmd),
+                                         _bfd_vms_etir_name (ETIR__C_OPR_ADD));
+                  return FALSE;
+                }
+              prev_cmd = ETIR__C_OPR_ADD;
+              continue;
+
+            case ETIR__C_STO_CA: /* ALPHA_R_CODEADDR */
+              reloc_code = BFD_RELOC_ALPHA_CODEADDR;
+              cur_sym = ptr + 4;
+              break;
+
+            case ETIR__C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
+              reloc_code = BFD_RELOC_64;
+              cur_sym = ptr + 4;
+              break;
+
+            case ETIR__C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
+              reloc_code = BFD_RELOC_32;
+              cur_sym = ptr + 4;
+              break;
+
+            case ETIR__C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
+              reloc_code = BFD_RELOC_ALPHA_LINKAGE;
+              cur_sym = ptr + 8;
+              break;
+
+            case ETIR__C_STC_NOP_GBL: /* ALPHA_R_NOP */
+              reloc_code = BFD_RELOC_ALPHA_NOP;
+              goto call_reloc;
+
+            case ETIR__C_STC_BSR_GBL: /* ALPHA_R_BSR */
+              reloc_code = BFD_RELOC_ALPHA_BSR;
+              goto call_reloc;
+
+            case ETIR__C_STC_LDA_GBL: /* ALPHA_R_LDA */
+              reloc_code = BFD_RELOC_ALPHA_LDA;
+              goto call_reloc;
+
+            case ETIR__C_STC_BOH_GBL: /* ALPHA_R_BOH */
+              reloc_code = BFD_RELOC_ALPHA_BOH;
+              goto call_reloc;
+
+            call_reloc:
+              cur_sym = ptr + 4 + 32;
+              cur_address = bfd_getl64 (ptr + 4 + 8);
+              cur_addend = bfd_getl64 (ptr + 4 + 24);
+              break;
+
+            case ETIR__C_STO_IMM:
+              vaddr += bfd_getl32 (ptr + 4);
+              continue;
+
+            default:
+              (*_bfd_error_handler) (_("Unknown reloc %s"),
+                                     _bfd_vms_etir_name (cmd));
+              return FALSE;
+            }
+
+          {
+            asection *sec;
+            struct vms_section_data_struct *vms_sec;
+            arelent *reloc;
+
+            /* Get section to which the relocation applies.  */
+            if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
+              {
+                (*_bfd_error_handler) (_("Invalid section index in ETIR"));
+                return FALSE;
+              }
+            sec = PRIV (sections)[cur_psect];
+            vms_sec = vms_section_data (sec);
+
+            /* Allocate a reloc entry.  */
+            if (sec->reloc_count >= vms_sec->reloc_max)
+              {
+                if (vms_sec->reloc_max == 0)
+                  {
+                    vms_sec->reloc_max = 64;
+                    sec->relocation = bfd_zmalloc
+                      (vms_sec->reloc_max * sizeof (arelent));
+                }
+                else
+                  {
+                    vms_sec->reloc_max *= 2;
+                    sec->relocation = bfd_realloc
+                      (sec->relocation, vms_sec->reloc_max * sizeof (arelent));
+                  }
+              }
+            reloc = &sec->relocation[sec->reloc_count];
+            sec->reloc_count++;
+
+            reloc->howto = bfd_reloc_type_lookup (abfd, reloc_code);
+
+            if (cur_sym != NULL)
+              {
+                unsigned int j;
+                unsigned int symlen = *cur_sym;
+                asymbol **sym;
+
+                /* Linear search.  */
+                symlen = *cur_sym;
+                cur_sym++;
+                sym = NULL;
+
+                for (j = 0; j < PRIV (gsd_sym_count); j++)
+                  if (PRIV (syms)[j]->namelen == symlen
+                      && memcmp (PRIV (syms)[j]->name, cur_sym, symlen) == 0)
+                    {
+                      sym = &PRIV (csymbols)[j];
+                      break;
+                    }
+                if (sym == NULL)
+                  {
+                    (*_bfd_error_handler) (_("Unknown symbol in command %s"),
+                                           _bfd_vms_etir_name (cmd));
+                    reloc->sym_ptr_ptr = NULL;
+                  }
+                else
+                  reloc->sym_ptr_ptr = sym;
+              }
+            else if (cur_psidx >= 0)
+              reloc->sym_ptr_ptr =
+                PRIV (sections)[cur_psidx]->symbol_ptr_ptr;
+            else
+              reloc->sym_ptr_ptr = NULL;
+
+            reloc->address = cur_address;
+            reloc->addend = cur_addend;
+
+            vaddr += bfd_get_reloc_size (reloc->howto);
+          }
+
+          cur_addend = 0;
+          prev_cmd = -1;
+          cur_sym = NULL;
+          cur_psidx = -1;
+        }
+    }
+  vms_debug2 ((3, "alpha_vms_slurp_relocs: result = TRUE\n"));
+
+  return TRUE;
+}
+
+/* Return the number of bytes required to store the relocation
+   information associated with the given section.  */
+
+static long
+alpha_vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
+{
+  alpha_vms_slurp_relocs (abfd);
+
+  return (section->reloc_count + 1) * sizeof (arelent *);
+}
+
+/* Convert relocations from VMS (external) form into BFD internal
+   form.  Return the number of relocations.  */
+
+static long
+alpha_vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
+                              asymbol **symbols ATTRIBUTE_UNUSED)
+{
+  arelent *tblptr;
+  int count;
+
+  if (!alpha_vms_slurp_relocs (abfd))
+    return -1;
+
+  count = section->reloc_count;
+  tblptr = section->relocation;
+
+  while (count--)
+    *relptr++ = tblptr++;
+
+  *relptr = (arelent *) NULL;
+  return section->reloc_count;
+}
+\f
+/* This is just copied from ecoff-alpha, needs to be fixed probably.  */
+
+/* How to process the various reloc types.  */
+
+static bfd_reloc_status_type
+reloc_nil (bfd * abfd ATTRIBUTE_UNUSED,
+          arelent *reloc ATTRIBUTE_UNUSED,
+          asymbol *sym ATTRIBUTE_UNUSED,
+          void * data ATTRIBUTE_UNUSED,
+          asection *sec ATTRIBUTE_UNUSED,
+          bfd *output_bfd ATTRIBUTE_UNUSED,
+          char **error_message ATTRIBUTE_UNUSED)
+{
+#if VMS_DEBUG
+  vms_debug (1, "reloc_nil (abfd %p, output_bfd %p)\n", abfd, output_bfd);
+  vms_debug (2, "In section %s, symbol %s\n",
+       sec->name, sym->name);
+  vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
+               reloc->sym_ptr_ptr[0]->name,
+               (unsigned long)reloc->address,
+               (unsigned long)reloc->addend, reloc->howto->name);
+  vms_debug (2, "data at %p\n", data);
+  /*  _bfd_hexdump (2, data, bfd_get_reloc_size (reloc->howto), 0); */
+#endif
+
+  return bfd_reloc_ok;
+}
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+   from smaller values.  Start with zero, widen, *then* decrement.  */
+#define MINUS_ONE      (((bfd_vma)0) - 1)
+
+static reloc_howto_type alpha_howto_table[] =
+{
+  HOWTO (ALPHA_R_IGNORE,       /* Type.  */
+        0,                     /* Rightshift.  */
+        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        8,                     /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "IGNORE",              /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        0,                     /* Source mask */
+        0,                     /* Dest mask.  */
+        TRUE),                 /* PC rel offset.  */
+
+  /* A 64 bit reference to a symbol.  */
+  HOWTO (ALPHA_R_REFQUAD,      /* Type.  */
+        0,                     /* Rightshift.  */
+        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        64,                    /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_bitfield, /* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "REFQUAD",             /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        MINUS_ONE,             /* Source mask.  */
+        MINUS_ONE,             /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* A 21 bit branch.  The native assembler generates these for
+     branches within the text segment, and also fills in the PC
+     relative offset in the instruction.  */
+  HOWTO (ALPHA_R_BRADDR,       /* Type.  */
+        2,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        21,                    /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed, /* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "BRADDR",              /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        0x1fffff,              /* Source mask.  */
+        0x1fffff,              /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* A hint for a jump to a register.  */
+  HOWTO (ALPHA_R_HINT,         /* Type.  */
+        2,                     /* Rightshift.  */
+        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        14,                    /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "HINT",                /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        0x3fff,                /* Source mask.  */
+        0x3fff,                /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* 16 bit PC relative offset.  */
+  HOWTO (ALPHA_R_SREL16,       /* Type.  */
+        0,                     /* Rightshift.  */
+        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed, /* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "SREL16",              /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        0xffff,                /* Source mask.  */
+        0xffff,                /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* 32 bit PC relative offset.  */
+  HOWTO (ALPHA_R_SREL32,       /* Type.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed, /* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "SREL32",              /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* A 64 bit PC relative offset.  */
+  HOWTO (ALPHA_R_SREL64,       /* Type.  */
+        0,                     /* Rightshift.  */
+        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        64,                    /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed, /* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "SREL64",              /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        MINUS_ONE,             /* Source mask.  */
+        MINUS_ONE,             /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* Push a value on the reloc evaluation stack.  */
+  HOWTO (ALPHA_R_OP_PUSH,      /* Type.  */
+        0,                     /* Rightshift.  */
+        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "OP_PUSH",             /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Source mask.  */
+        0,                     /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* Store the value from the stack at the given address.  Store it in
+     a bitfield of size r_size starting at bit position r_offset.  */
+  HOWTO (ALPHA_R_OP_STORE,     /* Type.  */
+        0,                     /* Rightshift.  */
+        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        64,                    /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "OP_STORE",            /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Source mask.  */
+        MINUS_ONE,             /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* Subtract the reloc address from the value on the top of the
+     relocation stack.  */
+  HOWTO (ALPHA_R_OP_PSUB,      /* Type.  */
+        0,                     /* Rightshift.  */
+        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "OP_PSUB",             /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Source mask.  */
+        0,                     /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* Shift the value on the top of the relocation stack right by the
+     given value.  */
+  HOWTO (ALPHA_R_OP_PRSHIFT,   /* Type.  */
+        0,                     /* Rightshift.  */
+        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "OP_PRSHIFT",          /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Source mask.  */
+        0,                     /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* Hack. Linkage is done by linker.  */
+  HOWTO (ALPHA_R_LINKAGE,      /* Type.  */
+        0,                     /* Rightshift.  */
+        8,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        256,                   /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "LINKAGE",             /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0,                     /* Source mask.  */
+        0,                     /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* A 32 bit reference to a symbol.  */
+  HOWTO (ALPHA_R_REFLONG,      /* Type.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_bitfield, /* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "REFLONG",             /* Name.  */
+        TRUE,                  /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  /* A 64 bit reference to a procedure, written as 32 bit value.  */
+  HOWTO (ALPHA_R_CODEADDR,     /* Type.  */
+        0,                     /* Rightshift.  */
+        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        64,                    /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_signed,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "CODEADDR",            /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  HOWTO (ALPHA_R_NOP,          /* Type.  */
+        0,                     /* Rightshift.  */
+        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH
+           because the calculations for the 3 relocations are the same.
+           See B.4.5.2 of the OpenVMS Linker Utility Manual.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.   */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "NOP",                 /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  HOWTO (ALPHA_R_BSR,          /* Type.  */
+        0,                     /* Rightshift.  */
+        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "BSR",                 /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  HOWTO (ALPHA_R_LDA,          /* Type.  */
+        0,                     /* Rightshift.  */
+        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
+        FALSE,                 /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "LDA",                 /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+
+  HOWTO (ALPHA_R_BOH,          /* Type.  */
+        0,                     /* Rightshift.  */
+        3,                     /* Size (0 = byte, 1 = short, 2 = long, 3 = nil).  */
+        0,                     /* Bitsize.  */
+        TRUE,                  /* PC relative.  */
+        0,                     /* Bitpos.  */
+        complain_overflow_dont,/* Complain_on_overflow.  */
+        reloc_nil,             /* Special_function.  */
+        "BOH",                 /* Name.  */
+        FALSE,                 /* Partial_inplace.  */
+        0xffffffff,            /* Source mask.  */
+        0xffffffff,            /* Dest mask.  */
+        FALSE),                /* PC rel offset.  */
+};
+
+/* Return a pointer to a howto structure which, when invoked, will perform
+   the relocation code on data from the architecture noted.  */
+
+static const struct reloc_howto_struct *
+alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+                                 bfd_reloc_code_real_type code)
+{
+  int alpha_type;
+
+  vms_debug2 ((1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code));
+
+  switch (code)
+    {
+      case BFD_RELOC_16:               alpha_type = ALPHA_R_SREL16;    break;
+      case BFD_RELOC_32:               alpha_type = ALPHA_R_REFLONG;   break;
+      case BFD_RELOC_64:               alpha_type = ALPHA_R_REFQUAD;   break;
+      case BFD_RELOC_CTOR:             alpha_type = ALPHA_R_REFQUAD;   break;
+      case BFD_RELOC_23_PCREL_S2:      alpha_type = ALPHA_R_BRADDR;    break;
+      case BFD_RELOC_ALPHA_HINT:       alpha_type = ALPHA_R_HINT;      break;
+      case BFD_RELOC_16_PCREL:         alpha_type = ALPHA_R_SREL16;    break;
+      case BFD_RELOC_32_PCREL:         alpha_type = ALPHA_R_SREL32;    break;
+      case BFD_RELOC_64_PCREL:         alpha_type = ALPHA_R_SREL64;    break;
+      case BFD_RELOC_ALPHA_LINKAGE:    alpha_type = ALPHA_R_LINKAGE;   break;
+      case BFD_RELOC_ALPHA_CODEADDR:   alpha_type = ALPHA_R_CODEADDR;  break;
+      case BFD_RELOC_ALPHA_NOP:                alpha_type = ALPHA_R_NOP;       break;
+      case BFD_RELOC_ALPHA_BSR:                alpha_type = ALPHA_R_BSR;       break;
+      case BFD_RELOC_ALPHA_LDA:                alpha_type = ALPHA_R_LDA;       break;
+      case BFD_RELOC_ALPHA_BOH:                alpha_type = ALPHA_R_BOH;       break;
+      default:
+       (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
+       return NULL;
+    }
+  vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name));
+  return & alpha_howto_table[alpha_type];
+}
+
+static reloc_howto_type *
+alpha_vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                 const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
+       i++)
+    if (alpha_howto_table[i].name != NULL
+       && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
+      return &alpha_howto_table[i];
+
+  return NULL;
+}
+\f
+static long
+alpha_vms_get_synthetic_symtab (bfd *abfd,
+                                long symcount ATTRIBUTE_UNUSED,
+                                asymbol **usyms ATTRIBUTE_UNUSED,
+                                long dynsymcount ATTRIBUTE_UNUSED,
+                                asymbol **dynsyms ATTRIBUTE_UNUSED,
+                                asymbol **ret)
+{
+  asymbol *syms;
+  unsigned int i;
+  unsigned int n = 0;
+
+  syms = (asymbol *) bfd_malloc (PRIV (norm_sym_count) * sizeof (asymbol));
+  *ret = syms;
+  if (syms == NULL)
+    return -1;
+
+  for (i = 0; i < PRIV (gsd_sym_count); i++)
+    {
+      struct vms_symbol_entry *e = PRIV (syms)[i];
+      asymbol *sym;
+      flagword flags;
+      symvalue value;
+      asection *sec;
+      const char *name;
+      char *sname;
+      int l;
+
+      name = e->name;
+      value = 0;
+      flags = BSF_LOCAL | BSF_SYNTHETIC;
+      sec = NULL;
+
+      switch (e->typ)
+        {
+        case EGSD__C_SYM:
+          if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
+            {
+              value = e->code_value;
+              sec = PRIV (sections)[e->code_section];
+            }
+          else
+            continue;
+          break;
+
+        case EGSD__C_SYMG:
+          if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
+            {
+              bfd_vma sbase = 0;
+              asection *s;
+
+              value = e->code_value;
+
+              /* Find containing section.  */
+              for (s = abfd->sections; s; s = s->next)
+                {
+                  if (value >= s->vma
+                      && s->vma > sbase
+                      && !(s->flags & SEC_COFF_SHARED_LIBRARY)
+                      && (s->size > 0 || !(e->flags & EGSY__V_REL)))
+                    {
+                      sbase = s->vma;
+                      sec = s;
+                    }
+                }
+              value -= sbase;
+            }
+          else
+            continue;
+          break;
+
+        default:
+          abort ();
+        }
+
+      l = strlen (name);
+      sname = bfd_alloc (abfd, l + 5);
+      if (sname == NULL)
+        return FALSE;
+      memcpy (sname, name, l);
+      memcpy (sname + l, "..en", 5);
+
+      sym = &syms[n++];
+      sym->name = sname;
+      sym->section = sec;
+      sym->flags = flags;
+      sym->value = value;
+      sym->udata.p = NULL;
+    }
+
+  return n;
+}
+\f
+/* Private dump.  */
+
+static const char *
+vms_time_to_str (unsigned char *buf)
+{
+  time_t t = vms_rawtime_to_time_t (buf);
+  char *res = ctime (&t);
+
+  if (!res)
+    res = "*invalid time*";
+  else
+    res[24] = 0;
+  return res;
+}
+
+static void
+evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
+{
+  struct vms_emh_common *emh = (struct vms_emh_common *)rec;
+  unsigned int subtype;
+
+  subtype = (unsigned)bfd_getl16 (emh->subtyp);
+
+  fprintf (file, _("  EMH %u (len=%u): "), subtype, rec_len);
+
+  switch (subtype)
+    {
+    case EMH__C_MHD:
+      {
+        struct vms_emh_mhd *mhd = (struct vms_emh_mhd *)rec;
+        const char *name;
+
+        fprintf (file, _("Module header\n"));
+        fprintf (file, _("   structure level: %u\n"), mhd->strlvl);
+        fprintf (file, _("   max record size: %u\n"),
+                 (unsigned)bfd_getl32 (mhd->recsiz));
+        name = (char *)(mhd + 1);
+        fprintf (file, _("   module name    : %.*s\n"), name[0], name + 1);
+        name += name[0] + 1;
+        fprintf (file, _("   module version : %.*s\n"), name[0], name + 1);
+        name += name[0] + 1;
+        fprintf (file, _("   compile date   : %.17s\n"), name);
+      }
+      break;
+    case EMH__C_LNM:
+      {
+        fprintf (file, _("Language Processor Name\n"));
+        fprintf (file, _("   language name: %.*s\n"),
+                 (int)(rec_len - sizeof (struct vms_emh_common)),
+                 (char *)rec + sizeof (struct vms_emh_common));
+      }
+      break;
+    case EMH__C_SRC:
+      {
+        fprintf (file, _("Source Files Header\n"));
+        fprintf (file, _("   file: %.*s\n"),
+                 (int)(rec_len - sizeof (struct vms_emh_common)),
+                 (char *)rec + sizeof (struct vms_emh_common));
+      }
+      break;
+    case EMH__C_TTL:
+      {
+        fprintf (file, _("Title Text Header\n"));
+        fprintf (file, _("   title: %.*s\n"),
+                 (int)(rec_len - sizeof (struct vms_emh_common)),
+                 (char *)rec + sizeof (struct vms_emh_common));
+      }
+      break;
+    case EMH__C_CPR:
+      {
+        fprintf (file, _("Copyright Header\n"));
+        fprintf (file, _("   copyright: %.*s\n"),
+                 (int)(rec_len - sizeof (struct vms_emh_common)),
+                 (char *)rec + sizeof (struct vms_emh_common));
+      }
+      break;
+    default:
+      fprintf (file, _("unhandled emh subtype %u\n"), subtype);
+      break;
+    }
+}
+
+static void
+evax_bfd_print_eeom (FILE *file, unsigned char *rec, unsigned int rec_len)
+{
+  struct vms_eeom *eeom = (struct vms_eeom *)rec;
+
+  fprintf (file, _("  EEOM (len=%u):\n"), rec_len);
+  fprintf (file, _("   number of cond linkage pairs: %u\n"),
+           (unsigned)bfd_getl32 (eeom->total_lps));
+  fprintf (file, _("   completion code: %u\n"),
+           (unsigned)bfd_getl16 (eeom->comcod));
+  if (rec_len > 10)
+    {
+      fprintf (file, _("   transfer addr flags: 0x%02x\n"), eeom->tfrflg);
+      fprintf (file, _("   transfer addr psect: %u\n"),
+               (unsigned)bfd_getl32 (eeom->psindx));
+      fprintf (file, _("   transfer address   : 0x%08x\n"),
+               (unsigned)bfd_getl32 (eeom->tfradr));
+    }
+}
+
+static void
+exav_bfd_print_egsy_flags (unsigned int flags, FILE *file)
+{
+  if (flags & EGSY__V_WEAK)
+    fputs (_(" WEAK"), file);
+  if (flags & EGSY__V_DEF)
+    fputs (_(" DEF"), file);
+  if (flags & EGSY__V_UNI)
+    fputs (_(" UNI"), file);
+  if (flags & EGSY__V_REL)
+    fputs (_(" REL"), file);
+  if (flags & EGSY__V_COMM)
+    fputs (_(" COMM"), file);
+  if (flags & EGSY__V_VECEP)
+    fputs (_(" VECEP"), file);
+  if (flags & EGSY__V_NORM)
+    fputs (_(" NORM"), file);
+  if (flags & EGSY__V_QUAD_VAL)
+    fputs (_(" QVAL"), file);
+}
+
+static void
+evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len)
+{
+  unsigned int off = sizeof (struct vms_egsd);
+  unsigned int n;
+
+  fprintf (file, _("  EGSD (len=%u):\n"), rec_len);
+
+  n = 0;
+  for (off = sizeof (struct vms_egsd); off < rec_len; )
+    {
+      struct vms_egsd_entry *e = (struct vms_egsd_entry *)(rec + off);
+      unsigned int type;
+      unsigned int len;
+
+      type = (unsigned)bfd_getl16 (e->gsdtyp);
+      len = (unsigned)bfd_getl16 (e->gsdsiz);
+
+      fprintf (file, _("  EGSD entry %2u (type: %u, len: %u): "),
+               n, type, len);
+      n++;
+
+      switch (type)
+        {
+        case EGSD__C_PSC:
+          {
+            struct vms_egps *egps = (struct vms_egps *)e;
+            unsigned int flags = bfd_getl16 (egps->flags);
+            unsigned int l;
+
+            fprintf (file, _("PSC - Program section definition\n"));
+            fprintf (file, _("   alignment  : 2**%u\n"), egps->align);
+            fprintf (file, _("   flags      : 0x%04x"), flags);
+            if (flags & EGPS__V_PIC)
+              fputs (_(" PIC"), file);
+            if (flags & EGPS__V_LIB)
+              fputs (_(" LIB"), file);
+            if (flags & EGPS__V_OVR)
+              fputs (_(" OVR"), file);
+            if (flags & EGPS__V_REL)
+              fputs (_(" REL"), file);
+            if (flags & EGPS__V_GBL)
+              fputs (_(" GBL"), file);
+            if (flags & EGPS__V_SHR)
+              fputs (_(" SHR"), file);
+            if (flags & EGPS__V_EXE)
+              fputs (_(" EXE"), file);
+            if (flags & EGPS__V_RD)
+              fputs (_(" RD"), file);
+            if (flags & EGPS__V_WRT)
+              fputs (_(" WRT"), file);
+            if (flags & EGPS__V_VEC)
+              fputs (_(" VEC"), file);
+            if (flags & EGPS__V_NOMOD)
+              fputs (_(" NOMOD"), file);
+            if (flags & EGPS__V_COM)
+              fputs (_(" COM"), file);
+            if (flags & EGPS__V_ALLOC_64BIT)
+              fputs (_(" 64B"), file);
+            fputc ('\n', file);
+            l = bfd_getl32 (egps->alloc);
+            fprintf (file, _("   alloc (len): %u (0x%08x)\n"), l, l);
+            fprintf (file, _("   name       : %.*s\n"),
+                     egps->namlng, egps->name);
+          }
+          break;
+        case EGSD__C_SYM:
+          {
+            struct vms_egsy *egsy = (struct vms_egsy *)e;
+            unsigned int flags = bfd_getl16 (egsy->flags);
+
+            if (flags & EGSY__V_DEF)
+              {
+                struct vms_esdf *esdf = (struct vms_esdf *)e;
+
+                fprintf (file, _("SYM - Global symbol definition\n"));
+                fprintf (file, _("   flags: 0x%04x"), flags);
+                exav_bfd_print_egsy_flags (flags, file);
+                fputc ('\n', file);
+                fprintf (file, _("   psect offset: 0x%08x\n"),
+                         (unsigned)bfd_getl32 (esdf->value));
+                if (flags & EGSY__V_NORM)
+                  {
+                    fprintf (file, _("   code address: 0x%08x\n"),
+                             (unsigned)bfd_getl32 (esdf->code_address));
+                    fprintf (file, _("   psect index for entry point : %u\n"),
+                             (unsigned)bfd_getl32 (esdf->ca_psindx));
+                  }
+                fprintf (file, _("   psect index : %u\n"),
+                         (unsigned)bfd_getl32 (esdf->psindx));
+                fprintf (file, _("   name        : %.*s\n"),
+                         esdf->namlng, esdf->name);
+              }
+            else
+              {
+                struct vms_esrf *esrf = (struct vms_esrf *)e;
+
+                fprintf (file, _("SYM - Global symbol reference\n"));
+                fprintf (file, _("   name       : %.*s\n"),
+                         esrf->namlng, esrf->name);
+              }
+          }
+          break;
+        case EGSD__C_SYMG:
+          {
+            struct vms_egst *egst = (struct vms_egst *)e;
+            unsigned int flags = bfd_getl16 (egst->header.flags);
+
+            fprintf (file, _("SYMG - Universal symbol definition\n"));
+            fprintf (file, _("   flags: 0x%04x"), flags);
+            exav_bfd_print_egsy_flags (flags, file);
+            fputc ('\n', file);
+            fprintf (file, _("   symbol vector offset: 0x%08x\n"),
+                     (unsigned)bfd_getl32 (egst->value));
+            fprintf (file, _("   entry point: 0x%08x\n"),
+                     (unsigned)bfd_getl32 (egst->lp_1));
+            fprintf (file, _("   proc descr : 0x%08x\n"),
+                     (unsigned)bfd_getl32 (egst->lp_2));
+            fprintf (file, _("   psect index: %u\n"),
+                     (unsigned)bfd_getl32 (egst->psindx));
+            fprintf (file, _("   name       : %.*s\n"),
+                     egst->namlng, egst->name);
+          }
+          break;
+        case EGSD__C_SYMV:
+          {
+            struct vms_esdfv *esdfv = (struct vms_esdfv *)e;
+            unsigned int flags = bfd_getl16 (esdfv->flags);
+
+            fprintf (file, _("SYMV - Vectored symbol definition\n"));
+            fprintf (file, _("   flags: 0x%04x"), flags);
+            exav_bfd_print_egsy_flags (flags, file);
+            fputc ('\n', file);
+            fprintf (file, _("   vector      : 0x%08x\n"),
+                     (unsigned)bfd_getl32 (esdfv->vector));
+            fprintf (file, _("   psect offset: %u\n"),
+                     (unsigned)bfd_getl32 (esdfv->value));
+            fprintf (file, _("   psect index : %u\n"),
+                     (unsigned)bfd_getl32 (esdfv->psindx));
+            fprintf (file, _("   name        : %.*s\n"),
+                     esdfv->namlng, esdfv->name);
+          }
+          break;
+        case EGSD__C_SYMM:
+          {
+            struct vms_esdfm *esdfm = (struct vms_esdfm *)e;
+            unsigned int flags = bfd_getl16 (esdfm->flags);
+
+            fprintf (file, _("SYMM - Global symbol definition with version\n"));
+            fprintf (file, _("   flags: 0x%04x"), flags);
+            exav_bfd_print_egsy_flags (flags, file);
+            fputc ('\n', file);
+            fprintf (file, _("   version mask: 0x%08x\n"),
+                     (unsigned)bfd_getl32 (esdfm->version_mask));
+            fprintf (file, _("   psect offset: %u\n"),
+                     (unsigned)bfd_getl32 (esdfm->value));
+            fprintf (file, _("   psect index : %u\n"),
+                     (unsigned)bfd_getl32 (esdfm->psindx));
+            fprintf (file, _("   name        : %.*s\n"),
+                     esdfm->namlng, esdfm->name);
+          }
+          break;
+        default:
+          fprintf (file, _("unhandled egsd entry type %u\n"), type);
+          break;
+        }
+      off += len;
+    }
+}
+
+static void
+evax_bfd_print_hex (FILE *file, const char *pfx,
+                    const unsigned char *buf, unsigned int len)
+{
+  unsigned int i;
+  unsigned int n;
+
+  n = 0;
+  for (i = 0; i < len; i++)
+    {
+      if (n == 0)
+        fputs (pfx, file);
+      fprintf (file, " %02x", buf[i]);
+      n++;
+      if (n == 16)
+        {
+          n = 0;
+          fputc ('\n', file);
+        }
+    }
+  if (n != 0)
+    fputc ('\n', file);
+}
+
+static void
+evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps)
+{
+  fprintf (file, _("    linkage index: %u, replacement insn: 0x%08x\n"),
+           (unsigned)bfd_getl32 (buf),
+           (unsigned)bfd_getl32 (buf + 16));
+  fprintf (file, _("    psect idx 1: %u, offset 1: 0x%08x %08x\n"),
+           (unsigned)bfd_getl32 (buf + 4),
+           (unsigned)bfd_getl32 (buf + 12),
+           (unsigned)bfd_getl32 (buf + 8));
+  fprintf (file, _("    psect idx 2: %u, offset 2: 0x%08x %08x\n"),
+           (unsigned)bfd_getl32 (buf + 20),
+           (unsigned)bfd_getl32 (buf + 28),
+           (unsigned)bfd_getl32 (buf + 24));
+  if (is_ps)
+    fprintf (file, _("    psect idx 3: %u, offset 3: 0x%08x %08x\n"),
+             (unsigned)bfd_getl32 (buf + 32),
+             (unsigned)bfd_getl32 (buf + 40),
+             (unsigned)bfd_getl32 (buf + 36));
+  else
+    fprintf (file, _("    global name: %.*s\n"), buf[32], buf + 33);
+}
+
+static void
+evax_bfd_print_etir (FILE *file, const char *name,
+                     unsigned char *rec, unsigned int rec_len)
+{
+  unsigned int off = sizeof (struct vms_egsd);
+  unsigned int sec_len;
+
+  fprintf (file, _("  %s (len=%u+%u):\n"), name,
+           (unsigned)(rec_len - sizeof (struct vms_eobjrec)),
+           (unsigned)sizeof (struct vms_eobjrec));
+
+  for (off = sizeof (struct vms_eobjrec); off < rec_len; )
+    {
+      struct vms_etir *etir = (struct vms_etir *)(rec + off);
+      unsigned char *buf;
+      unsigned int type;
+      unsigned int size;
+
+      type = bfd_getl16 (etir->rectyp);
+      size = bfd_getl16 (etir->size);
+      buf = rec + off + sizeof (struct vms_etir);
+
+      fprintf (file, _("   (type: %3u, size: 4+%3u): "), type, size - 4);
+      switch (type)
+        {
+        case ETIR__C_STA_GBL:
+          fprintf (file, _("STA_GBL (stack global) %.*s\n"),
+                   buf[0], buf + 1);
+          break;
+        case ETIR__C_STA_LW:
+          fprintf (file, _("STA_LW (stack longword) 0x%08x\n"),
+                   (unsigned)bfd_getl32 (buf));
+          break;
+        case ETIR__C_STA_QW:
+          fprintf (file, _("STA_QW (stack quadword) 0x%08x %08x\n"),
+                   (unsigned)bfd_getl32 (buf + 4),
+                   (unsigned)bfd_getl32 (buf + 0));
+          break;
+        case ETIR__C_STA_PQ:
+          fprintf (file, _("STA_PQ (stack psect base + offset)\n"));
+          fprintf (file, _("    psect: %u, offset: 0x%08x %08x\n"),
+                   (unsigned)bfd_getl32 (buf + 0),
+                   (unsigned)bfd_getl32 (buf + 8),
+                   (unsigned)bfd_getl32 (buf + 4));
+          break;
+        case ETIR__C_STA_LI:
+          fprintf (file, _("STA_LI (stack literal)\n"));
+          break;
+        case ETIR__C_STA_MOD:
+          fprintf (file, _("STA_MOD (stack module)\n"));
+          break;
+        case ETIR__C_STA_CKARG:
+          fprintf (file, _("STA_CKARG (compare procedure argument)\n"));
+          break;
+
+        case ETIR__C_STO_B:
+          fprintf (file, _("STO_B (store byte)\n"));
+          break;
+        case ETIR__C_STO_W:
+          fprintf (file, _("STO_W (store word)\n"));
+          break;
+        case ETIR__C_STO_LW:
+          fprintf (file, _("STO_LW (store longword)\n"));
+          break;
+        case ETIR__C_STO_QW:
+          fprintf (file, _("STO_QW (store quadword)\n"));
+          break;
+        case ETIR__C_STO_IMMR:
+          {
+            unsigned int len = bfd_getl32 (buf);
+            fprintf (file,
+                     _("STO_IMMR (store immediate repeat) %u bytes\n"),
+                     len);
+            evax_bfd_print_hex (file, "   ", buf + 4, len);
+            sec_len += len;
+          }
+          break;
+        case ETIR__C_STO_GBL:
+          fprintf (file, _("STO_GBL (store global) %.*s\n"),
+                   buf[0], buf + 1);
+          break;
+        case ETIR__C_STO_CA:
+          fprintf (file, _("STO_CA (store code address) %.*s\n"),
+                   buf[0], buf + 1);
+          break;
+        case ETIR__C_STO_RB:
+          fprintf (file, _("STO_RB (store relative branch)\n"));
+          break;
+        case ETIR__C_STO_AB:
+          fprintf (file, _("STO_AB (store absolute branch)\n"));
+          break;
+        case ETIR__C_STO_OFF:
+          fprintf (file, _("STO_OFF (store offset to psect)\n"));
+          break;
+        case ETIR__C_STO_IMM:
+          {
+            unsigned int len = bfd_getl32 (buf);
+            fprintf (file,
+                     _("STO_IMM (store immediate) %u bytes\n"),
+                     len);
+            evax_bfd_print_hex (file, "   ", buf + 4, len);
+            sec_len += len;
+          }
+          break;
+        case ETIR__C_STO_LP_PSB:
+          fprintf (file, _("STO_OFF (store LP with procedure signature)\n"));
+          break;
+        case ETIR__C_STO_HINT_GBL:
+          fprintf (file, _("STO_BR_GBL (store branch global) *todo*\n"));
+          break;
+        case ETIR__C_STO_HINT_PS:
+          fprintf (file, _("STO_BR_PS (store branch psect + offset) *todo*\n"));
+          break;
+
+        case ETIR__C_OPR_NOP:
+          fprintf (file, _("OPR_NOP (no-operation)\n"));
+          break;
+        case ETIR__C_OPR_ADD:
+          fprintf (file, _("OPR_ADD (add)\n"));
+          break;
+        case ETIR__C_OPR_SUB:
+          fprintf (file, _("OPR_SUB (substract)\n"));
+          break;
+        case ETIR__C_OPR_MUL:
+          fprintf (file, _("OPR_MUL (multiply)\n"));
+          break;
+        case ETIR__C_OPR_DIV:
+          fprintf (file, _("OPR_DIV (divide)\n"));
+          break;
+        case ETIR__C_OPR_AND:
+          fprintf (file, _("OPR_AND (logical and)\n"));
+          break;
+        case ETIR__C_OPR_IOR:
+          fprintf (file, _("OPR_IOR (logical inclusive or)\n"));
+          break;
+        case ETIR__C_OPR_EOR:
+          fprintf (file, _("OPR_EOR (logical exclusive or)\n"));
+          break;
+        case ETIR__C_OPR_NEG:
+          fprintf (file, _("OPR_NEG (negate)\n"));
+          break;
+        case ETIR__C_OPR_COM:
+          fprintf (file, _("OPR_COM (complement)\n"));
+          break;
+        case ETIR__C_OPR_INSV:
+          fprintf (file, _("OPR_INSV (insert field)\n"));
+          break;
+        case ETIR__C_OPR_ASH:
+          fprintf (file, _("OPR_ASH (arithmetic shift)\n"));
+          break;
+        case ETIR__C_OPR_USH:
+          fprintf (file, _("OPR_USH (unsigned shift)\n"));
+          break;
+        case ETIR__C_OPR_ROT:
+          fprintf (file, _("OPR_ROT (rotate)\n"));
+          break;
+        case ETIR__C_OPR_SEL:
+          fprintf (file, _("OPR_SEL (select)\n"));
+          break;
+        case ETIR__C_OPR_REDEF:
+          fprintf (file, _("OPR_REDEF (redefine symbol to curr location)\n"));
+          break;
+        case ETIR__C_OPR_DFLIT:
+          fprintf (file, _("OPR_REDEF (define a literal)\n"));
+          break;
+
+        case ETIR__C_STC_LP:
+          fprintf (file, _("STC_LP (store cond linkage pair)\n"));
+          break;
+        case ETIR__C_STC_LP_PSB:
+          fprintf (file,
+                   _("STC_LP_PSB (store cond linkage pair + signature)\n"));
+          fprintf (file, _("   linkage index: %u, procedure: %.*s\n"),
+                   (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+          buf += 4 + 1 + buf[4];
+          fprintf (file, _("   signature: %.*s\n"), buf[0], buf + 1);
+          break;
+        case ETIR__C_STC_GBL:
+          fprintf (file, _("STC_GBL (store cond global)\n"));
+          fprintf (file, _("   linkage index: %u, global: %.*s\n"),
+                   (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+          break;
+        case ETIR__C_STC_GCA:
+          fprintf (file, _("STC_GCA (store cond code address)\n"));
+          fprintf (file, _("   linkage index: %u, procedure name: %.*s\n"),
+                   (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+          break;
+        case ETIR__C_STC_PS:
+          fprintf (file, _("STC_PS (store cond psect + offset)\n"));
+          fprintf (file,
+                   _("   linkage index: %u, psect: %u, offset: 0x%08x %08x\n"),
+                   (unsigned)bfd_getl32 (buf),
+                   (unsigned)bfd_getl32 (buf + 4),
+                   (unsigned)bfd_getl32 (buf + 12),
+                   (unsigned)bfd_getl32 (buf + 8));
+          break;
+        case ETIR__C_STC_NOP_GBL:
+          fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 0);
+          break;
+        case ETIR__C_STC_NOP_PS:
+          fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 1);
+          break;
+        case ETIR__C_STC_BSR_GBL:
+          fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 0);
+          break;
+        case ETIR__C_STC_BSR_PS:
+          fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 1);
+          break;
+        case ETIR__C_STC_LDA_GBL:
+          fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 0);
+          break;
+        case ETIR__C_STC_LDA_PS:
+          fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 1);
+          break;
+        case ETIR__C_STC_BOH_GBL:
+          fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 0);
+          break;
+        case ETIR__C_STC_BOH_PS:
+          fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n"));
+          evax_bfd_print_etir_stc_ir (file, buf, 1);
+          break;
+        case ETIR__C_STC_NBH_GBL:
+          fprintf (file,
+                   _("STC_NBH_GBL (store cond or hint at global addr)\n"));
+          break;
+        case ETIR__C_STC_NBH_PS:
+          fprintf (file,
+                   _("STC_NBH_PS (store cond or hint at psect + offset)\n"));
+          break;
+
+        case ETIR__C_CTL_SETRB:
+          fprintf (file, _("CTL_SETRB (set relocation base)\n"));
+          sec_len += 4;
+          break;
+        case ETIR__C_CTL_AUGRB:
+          {
+            unsigned int val = bfd_getl32 (buf);
+            fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), val);
+          }
+          break;
+        case ETIR__C_CTL_DFLOC:
+          fprintf (file, _("CTL_DFLOC (define location)\n"));
+          break;
+        case ETIR__C_CTL_STLOC:
+          fprintf (file, _("CTL_STLOC (set location)\n"));
+          break;
+        case ETIR__C_CTL_STKDL:
+          fprintf (file, _("CTL_STKDL (stack defined location)\n"));
+          break;
+        default:
+          fprintf (file, _("*unhandled*\n"));
+          break;
+        }
+      off += size;
+    }
+}
+
+static void
+evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
+{
+  bfd_boolean is_first = TRUE;
+  bfd_boolean has_records = FALSE;
+
+  while (1)
+    {
+      unsigned int rec_len;
+      unsigned int pad_len;
+      unsigned char *rec;
+      unsigned int hdr_size;
+      unsigned int type;
+
+      if (is_first)
+        {
+          unsigned char buf[6];
+
+          is_first = FALSE;
+
+          /* Read 6 bytes.  */
+          if (bfd_bread (buf, sizeof (buf), abfd) != sizeof (buf))
+            {
+              fprintf (file, _("cannot read GST record length\n"));
+              return;
+            }
+          rec_len = bfd_getl16 (buf + 0);
+          if (rec_len == bfd_getl16 (buf + 4)
+              && bfd_getl16 (buf + 2) == EOBJ__C_EMH)
+            {
+              /* The format is raw: record-size, type, record-size.  */
+              has_records = TRUE;
+              pad_len = (rec_len + 1) & ~1U;
+              hdr_size = 4;
+            }
+          else if (rec_len == EOBJ__C_EMH)
+            {
+              has_records = FALSE;
+              pad_len = bfd_getl16 (buf + 2);
+              hdr_size = 6;
+            }
+          else
+            {
+              /* Ill-formed.  */
+              fprintf (file, _("cannot find EMH in first GST record\n"));
+              return;
+            }
+          rec = bfd_malloc (pad_len);
+          memcpy (rec, buf + sizeof (buf) - hdr_size, hdr_size);
+        }
+      else
+        {
+          unsigned int rec_len2 = 0;
+          unsigned char hdr[4];
+
+          if (has_records)
+            {
+              unsigned char buf_len[2];
+
+              if (bfd_bread (buf_len, sizeof (buf_len), abfd)
+                  != sizeof (buf_len))
+                {
+                  fprintf (file, _("cannot read GST record length\n"));
+                  return;
+                }
+              rec_len2 = (unsigned)bfd_getl16 (buf_len);
+            }
+
+          if (bfd_bread (hdr, sizeof (hdr), abfd) != sizeof (hdr))
+            {
+              fprintf (file, _("cannot read GST record header\n"));
+              return;
+            }
+          rec_len = (unsigned)bfd_getl16 (hdr + 2);
+          if (has_records)
+            pad_len = (rec_len + 1) & ~1U;
+          else
+            pad_len = rec_len;
+          rec = bfd_malloc (pad_len);
+          memcpy (rec, hdr, sizeof (hdr));
+          hdr_size = sizeof (hdr);
+          if (has_records && rec_len2 != rec_len)
+            {
+              fprintf (file, _(" corrupted GST\n"));
+              break;
+            }
+        }
+
+      if (bfd_bread (rec + hdr_size, pad_len - hdr_size, abfd)
+          != pad_len - hdr_size)
+        {
+          fprintf (file, _("cannot read GST record\n"));
+          return;
+        }
+
+      type = (unsigned)bfd_getl16 (rec);
+
+      switch (type)
+        {
+        case EOBJ__C_EMH:
+          evax_bfd_print_emh (file, rec, rec_len);
+          break;
+        case EOBJ__C_EGSD:
+          evax_bfd_print_egsd (file, rec, rec_len);
+          break;
+        case EOBJ__C_EEOM:
+          evax_bfd_print_eeom (file, rec, rec_len);
+          free (rec);
+          return;
+          break;
+        case EOBJ__C_ETIR:
+          evax_bfd_print_etir (file, "ETIR", rec, rec_len);
+          break;
+        case EOBJ__C_EDBG:
+          evax_bfd_print_etir (file, "EDBG", rec, rec_len);
+          break;
+        case EOBJ__C_ETBT:
+          evax_bfd_print_etir (file, "ETBT", rec, rec_len);
+          break;
+        default:
+          fprintf (file, _(" unhandled EOBJ record type %u\n"), type);
+          break;
+        }
+      free (rec);
+    }
+}
+
+static void
+evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel,
+                                   unsigned int stride)
+{
+  while (1)
+    {
+      unsigned int base;
+      unsigned int count;
+      unsigned int j;
+
+      count = bfd_getl32 (rel + 0);
+
+      if (count == 0)
+        break;
+      base = bfd_getl32 (rel + 4);
+
+      fprintf (file, _("  bitcount: %u, base addr: 0x%08x\n"),
+               count, base);
+
+      rel += 8;
+      for (j = 0; count > 0; j += 4, count -= 32)
+        {
+          unsigned int k;
+          unsigned int n = 0;
+          unsigned int val;
+
+          val = bfd_getl32 (rel);
+          rel += 4;
+
+          fprintf (file, _("   bitmap: 0x%08x (count: %u):\n"), val, count);
+
+          for (k = 0; k < 32; k++)
+            if (val & (1 << k))
+              {
+                if (n == 0)
+                  fputs ("   ", file);
+                fprintf (file, _(" %08x"), base + (j * 8 + k) * stride);
+                n++;
+                if (n == 8)
+                  {
+                    fputs ("\n", file);
+                    n = 0;
+                  }
+              }
+          if (n)
+            fputs ("\n", file);
+        }
+    }
+}
+
+static void
+evax_bfd_print_address_fixups (FILE *file, const unsigned char *rel)
+{
+  while (1)
+    {
+      unsigned int j;
+      unsigned int count;
+
+      count = bfd_getl32 (rel + 0);
+      if (count == 0)
+        return;
+      fprintf (file, _("  image %u (%u entries)\n"),
+               (unsigned)bfd_getl32 (rel + 4), count);
+      rel += 8;
+      for (j = 0; j < count; j++)
+        {
+          fprintf (file, _("   offset: 0x%08x, val: 0x%08x\n"),
+                   (unsigned)bfd_getl32 (rel + 0),
+                   (unsigned)bfd_getl32 (rel + 4));
+          rel += 8;
+        }
+    }
+}
+
+static void
+evax_bfd_print_reference_fixups (FILE *file, const unsigned char *rel)
+{
+  unsigned int count;
+
+  while (1)
+    {
+      unsigned int j;
+      unsigned int n = 0;
+
+      count = bfd_getl32 (rel + 0);
+      if (count == 0)
+        break;
+      fprintf (file, _("  image %u (%u entries), offsets:\n"),
+               (unsigned)bfd_getl32 (rel + 4), count);
+      rel += 8;
+      for (j = 0; j < count; j++)
+        {
+          if (n == 0)
+            fputs ("   ", file);
+          fprintf (file, _(" 0x%08x"), (unsigned)bfd_getl32 (rel));
+          n++;
+          if (n == 7)
+            {
+              fputs ("\n", file);
+              n = 0;
+            }
+          rel += 4;
+        }
+      if (n)
+        fputs ("\n", file);
+    }
+}
+
+static void
+evax_bfd_print_indent (int indent, FILE *file)
+{
+  for (; indent; indent--)
+    fputc (' ', file);
+}
+
+static const char *
+evax_bfd_get_dsc_name (unsigned int v)
+{
+  switch (v)
+    {
+    case DSC__K_DTYPE_Z:
+      return "Z (Unspecified)";
+    case DSC__K_DTYPE_V:
+      return "V (Bit)";
+    case DSC__K_DTYPE_BU:
+      return "BU (Byte logical)";
+    case DSC__K_DTYPE_WU:
+      return "WU (Word logical)";
+    case DSC__K_DTYPE_LU:
+      return "LU (Longword logical)";
+    case DSC__K_DTYPE_QU:
+      return "QU (Quadword logical)";
+    case DSC__K_DTYPE_B:
+      return "B (Byte integer)";
+    case DSC__K_DTYPE_W:
+      return "W (Word integer)";
+    case DSC__K_DTYPE_L:
+      return "L (Longword integer)";
+    case DSC__K_DTYPE_Q:
+      return "Q (Quadword integer)";
+    case DSC__K_DTYPE_F:
+      return "F (Single-precision floating)";
+    case DSC__K_DTYPE_D:
+      return "D (Double-precision floating)";
+    case DSC__K_DTYPE_FC:
+      return "FC (Complex)";
+    case DSC__K_DTYPE_DC:
+      return "DC (Double-precision Complex)";
+    case DSC__K_DTYPE_T:
+      return "T (ASCII text string)";
+    case DSC__K_DTYPE_NU:
+      return "NU (Numeric string, unsigned)";
+    case DSC__K_DTYPE_NL:
+      return "NL (Numeric string, left separate sign)";
+    case DSC__K_DTYPE_NLO:
+      return "NLO (Numeric string, left overpunched sign)";
+    case DSC__K_DTYPE_NR:
+      return "NR (Numeric string, right separate sign)";
+    case DSC__K_DTYPE_NRO:
+      return "NRO (Numeric string, right overpunched sig)";
+    case DSC__K_DTYPE_NZ:
+      return "NZ (Numeric string, zoned sign)";
+    case DSC__K_DTYPE_P:
+      return "P (Packed decimal string)";
+    case DSC__K_DTYPE_ZI:
+      return "ZI (Sequence of instructions)";
+    case DSC__K_DTYPE_ZEM:
+      return "ZEM (Procedure entry mask)";
+    case DSC__K_DTYPE_DSC:
+      return "DSC (Descriptor, used for arrays of dyn strings)";
+    case DSC__K_DTYPE_OU:
+      return "OU (Octaword logical)";
+    case DSC__K_DTYPE_O:
+      return "O (Octaword integer)";
+    case DSC__K_DTYPE_G:
+      return "G (Double precision G floating, 64 bit)";
+    case DSC__K_DTYPE_H:
+      return "H (Quadruple precision floating, 128 bit)";
+    case DSC__K_DTYPE_GC:
+      return "GC (Double precision complex, G floating)";
+    case DSC__K_DTYPE_HC:
+      return "HC (Quadruple precision complex, H floating)";
+    case DSC__K_DTYPE_CIT:
+      return "CIT (COBOL intermediate temporary)";
+    case DSC__K_DTYPE_BPV:
+      return "BPV (Bound Procedure Value)";
+    case DSC__K_DTYPE_BLV:
+      return "BLV (Bound Label Value)";
+    case DSC__K_DTYPE_VU:
+      return "VU (Bit Unaligned)";
+    case DSC__K_DTYPE_ADT:
+      return "ADT (Absolute Date-Time)";
+    case DSC__K_DTYPE_VT:
+      return "VT (Varying Text)";
+    case DSC__K_DTYPE_T2:
+      return "T2 (16-bit char)";
+    case DSC__K_DTYPE_VT2:
+      return "VT2 (16-bit varying char)";
+    default:
+      return "?? (unknown)";
+    }
+}
+
+static void
+evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file)
+{
+  unsigned char bclass = buf[3];
+  unsigned char dtype = buf[2];
+  unsigned int len = (unsigned)bfd_getl16 (buf);
+  unsigned int pointer = (unsigned)bfd_getl32 (buf + 4);
+
+  evax_bfd_print_indent (indent, file);
+
+  if (len == 1 && pointer == 0xffffffffUL)
+    {
+      /* 64 bits.  */
+      fprintf (file, _("64 bits *unhandled*\n"));
+    }
+  else
+    {
+      fprintf (file, _("class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"),
+               bclass, dtype, len, pointer);
+      switch (bclass)
+        {
+        case DSC__K_CLASS_NCA:
+          {
+            const struct vms_dsc_nca *dsc = (const void *)buf;
+            unsigned int i;
+            const unsigned char *b;
+
+            evax_bfd_print_indent (indent, file);
+            fprintf (file, _("non-contiguous array of %s\n"),
+                     evax_bfd_get_dsc_name (dsc->dtype));
+            evax_bfd_print_indent (indent + 1, file);
+            fprintf (file,
+                     _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"),
+                     dsc->dimct, dsc->aflags, dsc->digits, dsc->scale);
+            evax_bfd_print_indent (indent + 1, file);
+            fprintf (file,
+                     _("arsize: %u, a0: 0x%08x\n"),
+                     (unsigned)bfd_getl32 (dsc->arsize),
+                     (unsigned)bfd_getl32 (dsc->a0));
+            evax_bfd_print_indent (indent + 1, file);
+            fprintf (file, _("Strides:\n"));
+            b = buf + sizeof (*dsc);
+            for (i = 0; i < dsc->dimct; i++)
+              {
+                evax_bfd_print_indent (indent + 2, file);
+                fprintf (file, _("[%u]: %u\n"), i + 1,
+                         (unsigned)bfd_getl32 (b));
+                b += 4;
+              }
+            evax_bfd_print_indent (indent + 1, file);
+            fprintf (file, _("Bounds:\n"));
+            b = buf + sizeof (*dsc);
+            for (i = 0; i < dsc->dimct; i++)
+              {
+                evax_bfd_print_indent (indent + 2, file);
+                fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1,
+                         (unsigned)bfd_getl32 (b + 0),
+                         (unsigned)bfd_getl32 (b + 4));
+                b += 8;
+              }
+          }
+          break;
+        case DSC__K_CLASS_UBS:
+          {
+            const struct vms_dsc_ubs *ubs = (const void *)buf;
+
+            evax_bfd_print_indent (indent, file);
+            fprintf (file, _("unaligned bit-string of %s\n"),
+                     evax_bfd_get_dsc_name (ubs->dtype));
+            evax_bfd_print_indent (indent + 1, file);
+            fprintf (file,
+                     _("base: %u, pos: %u\n"),
+                     (unsigned)bfd_getl32 (ubs->base),
+                     (unsigned)bfd_getl32 (ubs->pos));
+          }
+          break;
+        default:
+          fprintf (file, _("*unhandled*\n"));
+          break;
+        }
+    }
+}
+
+static unsigned int
+evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file)
+{
+  unsigned int vflags = buf[0];
+  unsigned int value = (unsigned)bfd_getl32 (buf + 1);
+  unsigned int len = 5;
+
+  evax_bfd_print_indent (indent, file);
+  fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value);
+  buf += 5;
+
+  switch (vflags)
+    {
+    case DST__K_VFLAGS_NOVAL:
+      fprintf (file, _("(no value)\n"));
+      break;
+    case DST__K_VFLAGS_NOTACTIVE:
+      fprintf (file, _("(not active)\n"));
+      break;
+    case DST__K_VFLAGS_UNALLOC:
+      fprintf (file, _("(not allocated)\n"));
+      break;
+    case DST__K_VFLAGS_DSC:
+      fprintf (file, _("(descriptor)\n"));
+      evax_bfd_print_desc (buf + value, indent + 1, file);
+      break;
+    case DST__K_VFLAGS_TVS:
+      fprintf (file, _("(trailing value)\n"));
+      break;
+    case DST__K_VS_FOLLOWS:
+      fprintf (file, _("(value spec follows)\n"));
+      break;
+    case DST__K_VFLAGS_BITOFFS:
+      fprintf (file, _("(at bit offset %u)\n"), value);
+      break;
+    default:
+      fprintf (file, _("(reg: %u, disp: %u, indir: %u, kind: "),
+               (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT,
+               vflags & DST__K_DISP ? 1 : 0,
+               vflags & DST__K_INDIR ? 1 : 0);
+      switch (vflags & DST__K_VALKIND_MASK)
+        {
+        case DST__K_VALKIND_LITERAL:
+          fputs (_("literal"), file);
+          break;
+        case DST__K_VALKIND_ADDR:
+          fputs (_("address"), file);
+          break;
+        case DST__K_VALKIND_DESC:
+          fputs (_("desc"), file);
+          break;
+        case DST__K_VALKIND_REG:
+          fputs (_("reg"), file);
+          break;
+        }
+      fputs (")\n", file);
+      break;
+    }
+  return len;
+}
+
+static void
+evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file)
+{
+  unsigned char kind = buf[2];
+  unsigned int len = (unsigned)bfd_getl16 (buf);
+
+  evax_bfd_print_indent (indent, file);
+  fprintf (file, ("len: %2u, kind: %2u "), len, kind);
+  buf += 3;
+  switch (kind)
+    {
+    case DST__K_TS_ATOM:
+      fprintf (file, ("atomic, type=0x%02x %s\n"),
+               buf[0], evax_bfd_get_dsc_name (buf[0]));
+      break;
+    case DST__K_TS_IND:
+      fprintf (file, ("indirect, defined at 0x%08x\n"),
+               (unsigned)bfd_getl32 (buf));
+      break;
+    case DST__K_TS_TPTR:
+      fprintf (file, ("typed pointer\n"));
+      evax_bfd_print_typspec (buf, indent + 1, file);
+      break;
+    case DST__K_TS_PTR:
+      fprintf (file, ("pointer\n"));
+      break;
+    case DST__K_TS_ARRAY:
+      {
+        const unsigned char *vs;
+        unsigned int vec_len;
+        unsigned int i;
+
+        fprintf (file, ("array, dim: %u, bitmap: "), buf[0]);
+        vec_len = (buf[0] + 1 + 7) / 8;
+        for (i = 0; i < vec_len; i++)
+          fprintf (file, " %02x", buf[i + 1]);
+        fputc ('\n', file);
+        vs = buf + 1 + vec_len;
+        evax_bfd_print_indent (indent, file);
+        fprintf (file, ("array descriptor:\n"));
+        vs += evax_bfd_print_valspec (vs, indent + 1, file);
+        for (i = 0; i < buf[0] + 1U; i++)
+          if (buf[1 + i / 8] & (1 << (i % 8)))
+            {
+              evax_bfd_print_indent (indent, file);
+              if (i == 0)
+                fprintf (file, ("type spec for element:\n"));
+              else
+                fprintf (file, ("type spec for subscript %u:\n"), i);
+              evax_bfd_print_typspec (vs, indent + 1, file);
+              vs += bfd_getl16 (vs);
+            }
+      }
+      break;
+    default:
+      fprintf (file, ("*unhandled*\n"));
+    }
+}
+
+static void
+evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
+{
+  unsigned int off = 0;
+  unsigned int pc = 0;
+  unsigned int line = 0;
+
+  fprintf (file, _("Debug symbol table:\n"));
+
+  while (dst_size > 0)
+    {
+      struct vms_dst_header dsth;
+      unsigned int len;
+      unsigned int type;
+      unsigned char *buf;
+
+      if (bfd_bread (&dsth, sizeof (dsth), abfd) != sizeof (dsth))
+        {
+          fprintf (file, _("cannot read DST header\n"));
+          return;
+        }
+      len = bfd_getl16 (dsth.length);
+      type = bfd_getl16 (dsth.type);
+      fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "),
+               type, len, off);
+      if (len == 0)
+        {
+          fputc ('\n', file);
+          break;
+        }
+      len++;
+      dst_size -= len;
+      off += len;
+      len -= sizeof (dsth);
+      buf = bfd_malloc (len);
+      if (bfd_bread (buf, len, abfd) != len)
+        {
+          fprintf (file, _("cannot read DST symbol\n"));
+          return;
+        }
+      switch (type)
+        {
+        case DSC__K_DTYPE_V:
+        case DSC__K_DTYPE_BU:
+        case DSC__K_DTYPE_WU:
+        case DSC__K_DTYPE_LU:
+        case DSC__K_DTYPE_QU:
+        case DSC__K_DTYPE_B:
+        case DSC__K_DTYPE_W:
+        case DSC__K_DTYPE_L:
+        case DSC__K_DTYPE_Q:
+        case DSC__K_DTYPE_F:
+        case DSC__K_DTYPE_D:
+        case DSC__K_DTYPE_FC:
+        case DSC__K_DTYPE_DC:
+        case DSC__K_DTYPE_T:
+        case DSC__K_DTYPE_NU:
+        case DSC__K_DTYPE_NL:
+        case DSC__K_DTYPE_NLO:
+        case DSC__K_DTYPE_NR:
+        case DSC__K_DTYPE_NRO:
+        case DSC__K_DTYPE_NZ:
+        case DSC__K_DTYPE_P:
+        case DSC__K_DTYPE_ZI:
+        case DSC__K_DTYPE_ZEM:
+        case DSC__K_DTYPE_DSC:
+        case DSC__K_DTYPE_OU:
+        case DSC__K_DTYPE_O:
+        case DSC__K_DTYPE_G:
+        case DSC__K_DTYPE_H:
+        case DSC__K_DTYPE_GC:
+        case DSC__K_DTYPE_HC:
+        case DSC__K_DTYPE_CIT:
+        case DSC__K_DTYPE_BPV:
+        case DSC__K_DTYPE_BLV:
+        case DSC__K_DTYPE_VU:
+        case DSC__K_DTYPE_ADT:
+        case DSC__K_DTYPE_VT:
+        case DSC__K_DTYPE_T2:
+        case DSC__K_DTYPE_VT2:
+          fprintf (file, _("standard data: %s\n"),
+                   evax_bfd_get_dsc_name (type));
+          evax_bfd_print_valspec (buf, 4, file);
+          fprintf (file, _("    name: %.*s\n"), buf[5], buf + 6);
+          break;
+        case DST__K_MODBEG:
+          {
+            struct vms_dst_modbeg *dst = (void *)buf;
+            const char *name = (const char *)buf + sizeof (*dst);
+
+            fprintf (file, _("modbeg\n"));
+            fprintf (file, _("   flags: %d, language: %u, "
+                             "major: %u, minor: %u\n"),
+                     dst->flags,
+                     (unsigned)bfd_getl32 (dst->language),
+                     (unsigned)bfd_getl16 (dst->major),
+                     (unsigned)bfd_getl16 (dst->minor));
+            fprintf (file, _("   module name: %.*s\n"),
+                     name[0], name + 1);
+            name += name[0] + 1;
+            fprintf (file, _("   compiler   : %.*s\n"),
+                     name[0], name + 1);
+          }
+          break;
+        case DST__K_MODEND:
+          fprintf (file, _("modend\n"));
+          break;
+        case DST__K_RTNBEG:
+          {
+            struct vms_dst_rtnbeg *dst = (void *)buf;
+            const char *name = (const char *)buf + sizeof (*dst);
+
+            fputs (_("rtnbeg\n"), file);
+            fprintf (file, _("    flags: %u, address: 0x%08x, "
+                             "pd-address: 0x%08x\n"),
+                     dst->flags,
+                     (unsigned)bfd_getl32 (dst->address),
+                     (unsigned)bfd_getl32 (dst->pd_address));
+            fprintf (file, _("    routine name: %.*s\n"),
+                     name[0], name + 1);
+          }
+          break;
+        case DST__K_RTNEND:
+          {
+            struct vms_dst_rtnend *dst = (void *)buf;
+
+            fprintf (file, _("rtnend: size 0x%08x\n"),
+                     (unsigned)bfd_getl32 (dst->size));
+          }
+          break;
+        case DST__K_PROLOG:
+          {
+            struct vms_dst_prolog *dst = (void *)buf;
+
+            fprintf (file, _("prolog: bkpt address 0x%08x\n"),
+                     (unsigned)bfd_getl32 (dst->bkpt_addr));
+          }
+          break;
+        case DST__K_EPILOG:
+          {
+            struct vms_dst_epilog *dst = (void *)buf;
+
+            fprintf (file, _("epilog: flags: %u, count: %u\n"),
+                     dst->flags, (unsigned)bfd_getl32 (dst->count));
+          }
+          break;
+        case DST__K_BLKBEG:
+          {
+            struct vms_dst_blkbeg *dst = (void *)buf;
+            const char *name = (const char *)buf + sizeof (*dst);
+
+            fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"),
+                     (unsigned)bfd_getl32 (dst->address),
+                     name[0], name + 1);
+          }
+          break;
+        case DST__K_BLKEND:
+          {
+            struct vms_dst_blkend *dst = (void *)buf;
+
+            fprintf (file, _("blkend: size: 0x%08x\n"),
+                     (unsigned)bfd_getl32 (dst->size));
+          }
+          break;
+        case DST__K_TYPSPEC:
+          {
+            fprintf (file, _("typspec (len: %u)\n"), len);
+            fprintf (file, _("    name: %.*s\n"), buf[0], buf + 1);
+            evax_bfd_print_typspec (buf + 1 + buf[0], 5, file);
+          }
+          break;
+        case DST__K_SEPTYP:
+          {
+            fprintf (file, _("septyp, name: %.*s\n"), buf[5], buf + 6);
+            evax_bfd_print_valspec (buf, 4, file);
+          }
+          break;
+        case DST__K_RECBEG:
+          {
+            struct vms_dst_recbeg *recbeg = (void *)buf;
+            const char *name = (const char *)buf + sizeof (*recbeg);
+
+            fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1);
+            evax_bfd_print_valspec (buf, 4, file);
+            fprintf (file, ("    len: %u bits\n"),
+                     (unsigned)bfd_getl32 (name + 1 + name[0]));
+          }
+          break;
+        case DST__K_RECEND:
+          fprintf (file, _("recend\n"));
+          break;
+        case DST__K_ENUMBEG:
+          fprintf (file, _("enumbeg, len: %u, name: %.*s\n"),
+                   buf[0], buf[1], buf + 2);
+          break;
+        case DST__K_ENUMELT:
+          fprintf (file, _("enumelt, name: %.*s\n"), buf[5], buf + 6);
+          evax_bfd_print_valspec (buf, 4, file);
+          break;
+        case DST__K_ENUMEND:
+          fprintf (file, _("enumend\n"));
+          break;
+        case DST__K_LABEL:
+          {
+            struct vms_dst_label *lab = (void *)buf;
+            fprintf (file, ("label, name: %.*s\n"),
+                     lab->name[0], lab->name + 1);
+            fprintf (file, ("    address: 0x%08x\n"),
+                     (unsigned)bfd_getl32 (lab->value));
+          }
+          break;
+        case DST__K_DIS_RANGE:
+          {
+            unsigned int cnt = bfd_getl32 (buf);
+            unsigned char *rng = buf + 4;
+            unsigned int i;
+
+            fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt);
+            for (i = 0; i < cnt; i++, rng += 8)
+              fprintf (file, _("    address: 0x%08x, size: %u\n"),
+                       (unsigned)bfd_getl32 (rng),
+                       (unsigned)bfd_getl32 (rng + 4));
+
+          }
+          break;
+        case DST__K_LINE_NUM:
+          {
+            unsigned char *buf_orig = buf;
+
+            fprintf (file, _("line num  (len: %u)\n"), len);
+
+            while (len > 0)
+              {
+                signed char cmd;
+                unsigned char cmdlen;
+                unsigned int val;
+
+                cmd = buf[0];
+                cmdlen = 0;
+
+                fputs ("    ", file);
+
+                switch (cmd)
+                  {
+                  case DST__K_DELTA_PC_W:
+                    val = bfd_getl16 (buf + 1);
+                    fprintf (file, _("delta_pc_w %u\n"), val);
+                    pc += val;
+                    line++;
+                    cmdlen = 3;
+                    break;
+                  case DST__K_INCR_LINUM:
+                    val = buf[1];
+                    fprintf (file, _("incr_linum: +%u\n"), val);
+                    line += val;
+                    cmdlen = 2;
+                    break;
+                  case DST__K_INCR_LINUM_W:
+                    val = bfd_getl16 (buf + 1);
+                    fprintf (file, _("incr_linum: +%u\n"), val);
+                    line += val;
+                    cmdlen = 3;
+                    break;
+                  case DST__K_SET_LINUM:
+                    line = (unsigned)bfd_getl16 (buf + 1);
+                    fprintf (file, _("set_line_num %u\n"), line);
+                    cmdlen = 3;
+                    break;
+                  case DST__K_SET_LINUM_B:
+                    line = buf[1];
+                    fprintf (file, _("set_line_num_b %u\n"), line);
+                    cmdlen = 2;
+                    break;
+                  case DST__K_SET_LINUM_L:
+                    line = (unsigned)bfd_getl32 (buf + 1);
+                    fprintf (file, _("set_line_num_l %u\n"), line);
+                    cmdlen = 5;
+                    break;
+                  case DST__K_SET_ABS_PC:
+                    pc = (unsigned)bfd_getl32 (buf + 1);
+                    fprintf (file, _("set_abs_pc: 0x%08x\n"), pc);
+                    cmdlen = 5;
+                    break;
+                  case DST__K_DELTA_PC_L:
+                    fprintf (file, _("delta_pc_l: +0x%08x\n"),
+                             (unsigned)bfd_getl32 (buf + 1));
+                    cmdlen = 5;
+                    break;
+                  case DST__K_TERM:
+                    fprintf (file, _("term: 0x%02x"), buf[1]);
+                    pc += buf[1];
+                    fprintf (file, _("        pc: 0x%08x\n"), pc);
+                    cmdlen = 2;
+                    break;
+                  case DST__K_TERM_W:
+                    val = bfd_getl16 (buf + 1);
+                    fprintf (file, _("term_w: 0x%04x"), val);
+                    pc += val;
+                    fprintf (file, _("    pc: 0x%08x\n"), pc);
+                    cmdlen = 3;
+                    break;
+                  default:
+                    if (cmd <= 0)
+                      {
+                        fprintf (file, _("delta pc +%-4d"), -cmd);
+                        line++;  /* FIXME: curr increment.  */
+                        pc += -cmd;
+                        fprintf (file, _("    pc: 0x%08x line: %5u\n"),
+                                 pc, line);
+                        cmdlen = 1;
+                      }
+                    else
+                      fprintf (file, _("    *unhandled* cmd %u\n"), cmd);
+                    break;
+                  }
+                if (cmdlen == 0)
+                  break;
+                len -= cmdlen;
+                buf += cmdlen;
+              }
+            buf = buf_orig;
+          }
+          break;
+        case DST__K_SOURCE:
+          {
+            unsigned char *buf_orig = buf;
+
+            fprintf (file, _("source (len: %u)\n"), len);
+
+            while (len > 0)
+              {
+                signed char cmd = buf[0];
+                unsigned char cmdlen = 0;
+
+                switch (cmd)
+                  {
+                  case DST__K_SRC_DECLFILE:
+                    {
+                      struct vms_dst_src_decl_src *src = (void *)(buf + 1);
+                      const char *name;
+
+                      fprintf (file, _("   declfile: len: %u, flags: %u, "
+                                       "fileid: %u\n"),
+                               src->length, src->flags,
+                               (unsigned)bfd_getl16 (src->fileid));
+                      fprintf (file, _("   rms: cdt: 0x%08x %08x, "
+                                       "ebk: 0x%08x, ffb: 0x%04x, "
+                                       "rfo: %u\n"),
+                               (unsigned)bfd_getl32 (src->rms_cdt + 4),
+                               (unsigned)bfd_getl32 (src->rms_cdt + 0),
+                               (unsigned)bfd_getl32 (src->rms_ebk),
+                               (unsigned)bfd_getl16 (src->rms_ffb),
+                               src->rms_rfo);
+                      name = (const char *)buf + 1 + sizeof (*src);
+                      fprintf (file, _("   filename   : %.*s\n"),
+                               name[0], name + 1);
+                      name += name[0] + 1;
+                      fprintf (file, _("   module name: %.*s\n"),
+                               name[0], name + 1);
+                      cmdlen = 2 + src->length;
+                    }
+                    break;
+                  case DST__K_SRC_SETFILE:
+                    fprintf (file, _("   setfile %u\n"),
+                             (unsigned)bfd_getl16 (buf + 1));
+                    cmdlen = 3;
+                    break;
+                  case DST__K_SRC_SETREC_W:
+                    fprintf (file, _("   setrec %u\n"),
+                             (unsigned)bfd_getl16 (buf + 1));
+                    cmdlen = 3;
+                    break;
+                  case DST__K_SRC_SETREC_L:
+                    fprintf (file, _("   setrec %u\n"),
+                             (unsigned)bfd_getl32 (buf + 1));
+                    cmdlen = 5;
+                    break;
+                  case DST__K_SRC_SETLNUM_W:
+                    fprintf (file, _("   setlnum %u\n"),
+                             (unsigned)bfd_getl16 (buf + 1));
+                    cmdlen = 3;
+                    break;
+                  case DST__K_SRC_SETLNUM_L:
+                    fprintf (file, _("   setlnum %u\n"),
+                             (unsigned)bfd_getl32 (buf + 1));
+                    cmdlen = 5;
+                    break;
+                  case DST__K_SRC_DEFLINES_W:
+                    fprintf (file, _("   deflines %u\n"),
+                             (unsigned)bfd_getl16 (buf + 1));
+                    cmdlen = 3;
+                    break;
+                  case DST__K_SRC_DEFLINES_B:
+                    fprintf (file, _("   deflines %u\n"), buf[1]);
+                    cmdlen = 2;
+                    break;
+                  case DST__K_SRC_FORMFEED:
+                    fprintf (file, _("   formfeed\n"));
+                    cmdlen = 1;
+                    break;
+                  default:
+                    fprintf (file, _("   *unhandled* cmd %u\n"), cmd);
+                    break;
+                  }
+                if (cmdlen == 0)
+                  break;
+                len -= cmdlen;
+                buf += cmdlen;
+              }
+            buf = buf_orig;
+          }
+          break;
+        default:
+          fprintf (file, _("*unhandled* dst type %u\n"), type);
+          break;
+        }
+      free (buf);
+    }
+}
+
+static void
+evax_bfd_print_image (bfd *abfd, FILE *file)
+{
+  struct vms_eihd eihd;
+  const char *name;
+  unsigned int val;
+  unsigned int eiha_off;
+  unsigned int eihi_off;
+  unsigned int eihs_off;
+  unsigned int eisd_off;
+  unsigned int eihef_off = 0;
+  unsigned int eihnp_off = 0;
+  unsigned int dmt_vbn = 0;
+  unsigned int dmt_size = 0;
+  unsigned int dst_vbn = 0;
+  unsigned int dst_size = 0;
+  unsigned int gst_vbn = 0;
+  unsigned int gst_size = 0;
+  unsigned int eiaf_vbn = 0;
+  unsigned int eiaf_size = 0;
+  unsigned int eihvn_off;
+
+  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)
+      || bfd_bread (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
+    {
+      fprintf (file, _("cannot read EIHD\n"));
+      return;
+    }
+  fprintf (file, _("EIHD: (size: %u, nbr blocks: %u)\n"),
+           (unsigned)bfd_getl32 (eihd.size),
+           (unsigned)bfd_getl32 (eihd.hdrblkcnt));
+  fprintf (file, _(" majorid: %u, minorid: %u\n"),
+           (unsigned)bfd_getl32 (eihd.majorid),
+           (unsigned)bfd_getl32 (eihd.minorid));
+
+  val = (unsigned)bfd_getl32 (eihd.imgtype);
+  switch (val)
+    {
+    case EIHD__K_EXE:
+      name = _("executable");
+      break;
+    case EIHD__K_LIM:
+      name = _("linkable image");
+      break;
+    default:
+      name = _("unknown");
+      break;
+    }
+  fprintf (file, _(" image type: %u (%s)"), val, name);
+
+  val = (unsigned)bfd_getl32 (eihd.subtype);
+  switch (val)
+    {
+    case EIHD__C_NATIVE:
+      name = _("native");
+      break;
+    case EIHD__C_CLI:
+      name = _("CLI");
+      break;
+    default:
+      name = _("unknown");
+      break;
+    }
+  fprintf (file, _(", subtype: %u (%s)\n"), val, name);
+
+  eisd_off = bfd_getl32 (eihd.isdoff);
+  eiha_off = bfd_getl32 (eihd.activoff);
+  eihi_off = bfd_getl32 (eihd.imgidoff);
+  eihs_off = bfd_getl32 (eihd.symdbgoff);
+  fprintf (file, _(" offsets: isd: %u, activ: %u, symdbg: %u, "
+                   "imgid: %u, patch: %u\n"),
+           eisd_off, eiha_off, eihs_off, eihi_off,
+           (unsigned)bfd_getl32 (eihd.patchoff));
+  fprintf (file, _(" fixup info rva: "));
+  bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.iafva));
+  fprintf (file, _(", symbol vector rva: "));
+  bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.symvva));
+  eihvn_off = bfd_getl32 (eihd.version_array_off);
+  fprintf (file, _("\n"
+                   " version array off: %u\n"),
+           eihvn_off);
+  fprintf (file,
+           _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"),
+           (unsigned)bfd_getl32 (eihd.imgiocnt),
+           (unsigned)bfd_getl32 (eihd.iochancnt),
+           (unsigned)bfd_getl32 (eihd.privreqs + 4),
+           (unsigned)bfd_getl32 (eihd.privreqs + 0));
+  val = (unsigned)bfd_getl32 (eihd.lnkflags);
+  fprintf (file, _(" linker flags: %08x:"), val);
+  if (val & EIHD__M_LNKDEBUG)
+    fprintf (file, " LNKDEBUG");
+  if (val & EIHD__M_LNKNOTFR)
+    fprintf (file, " LNKNOTFR");
+  if (val & EIHD__M_NOP0BUFS)
+    fprintf (file, " NOP0BUFS");
+  if (val & EIHD__M_PICIMG)
+    fprintf (file, " PICIMG");
+  if (val & EIHD__M_P0IMAGE)
+    fprintf (file, " P0IMAGE");
+  if (val & EIHD__M_DBGDMT)
+    fprintf (file, " DBGDMT");
+  if (val & EIHD__M_INISHR)
+    fprintf (file, " INISHR");
+  if (val & EIHD__M_XLATED)
+    fprintf (file, " XLATED");
+  if (val & EIHD__M_BIND_CODE_SEC)
+    fprintf (file, " BIND_CODE_SEC");
+  if (val & EIHD__M_BIND_DATA_SEC)
+    fprintf (file, " BIND_DATA_SEC");
+  if (val & EIHD__M_MKTHREADS)
+    fprintf (file, " MKTHREADS");
+  if (val & EIHD__M_UPCALLS)
+    fprintf (file, " UPCALLS");
+  if (val & EIHD__M_OMV_READY)
+    fprintf (file, " OMV_READY");
+  if (val & EIHD__M_EXT_BIND_SECT)
+    fprintf (file, " EXT_BIND_SECT");
+  fprintf (file, "\n");
+  fprintf (file, _(" ident: 0x%08x, sysver: 0x%08x, "
+                   "match ctrl: %u, symvect_size: %u\n"),
+           (unsigned)bfd_getl32 (eihd.ident),
+           (unsigned)bfd_getl32 (eihd.sysver),
+           eihd.matchctl,
+           (unsigned)bfd_getl32 (eihd.symvect_size));
+  fprintf (file, _(" BPAGE: %u"),
+           (unsigned)bfd_getl32 (eihd.virt_mem_block_size));
+  if (val & (EIHD__M_OMV_READY | EIHD__M_EXT_BIND_SECT))
+    {
+      eihef_off = bfd_getl32 (eihd.ext_fixup_off);
+      eihnp_off = bfd_getl32 (eihd.noopt_psect_off);
+      fprintf (file, _(", ext fixup offset: %u, no_opt psect off: %u"),
+               eihef_off, eihnp_off);
+    }
+  fprintf (file, _(", alias: %u\n"), (unsigned)bfd_getl16 (eihd.alias));
+
+  if (eihvn_off != 0)
+    {
+      struct vms_eihvn eihvn;
+      unsigned int mask;
+      unsigned int j;
+
+      fprintf (file, _("system version array information:\n"));
+      if (bfd_seek (abfd, (file_ptr) eihvn_off, SEEK_SET)
+          || bfd_bread (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn))
+        {
+          fprintf (file, _("cannot read EIHVN header\n"));
+          return;
+        }
+      mask = bfd_getl32 (eihvn.subsystem_mask);
+      for (j = 0; j < 32; j++)
+        if (mask & (1 << j))
+          {
+            struct vms_eihvn_subversion ver;
+            if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver))
+              {
+                fprintf (file, _("cannot read EIHVN version\n"));
+                return;
+              }
+            fprintf (file, _("   %02u "), j);
+            switch (j)
+              {
+              case EIHVN__BASE_IMAGE_BIT:
+               fputs (_("BASE_IMAGE       "), file);
+                break;
+              case EIHVN__MEMORY_MANAGEMENT_BIT:
+                fputs (_("MEMORY_MANAGEMENT"), file);
+                break;
+              case EIHVN__IO_BIT:
+                fputs (_("IO               "), file);
+                break;
+              case EIHVN__FILES_VOLUMES_BIT:
+                fputs (_("FILES_VOLUMES    "), file);
+                break;
+              case EIHVN__PROCESS_SCHED_BIT:
+                fputs (_("PROCESS_SCHED    "), file);
+                break;
+              case EIHVN__SYSGEN_BIT:
+               fputs (_("SYSGEN           "), file);
+                break;
+              case EIHVN__CLUSTERS_LOCKMGR_BIT:
+                fputs (_("CLUSTERS_LOCKMGR "), file);
+                break;
+              case EIHVN__LOGICAL_NAMES_BIT:
+                fputs (_("LOGICAL_NAMES    "), file);
+                break;
+              case EIHVN__SECURITY_BIT:
+               fputs (_("SECURITY         "), file);
+                break;
+              case EIHVN__IMAGE_ACTIVATOR_BIT:
+                fputs (_("IMAGE_ACTIVATOR  "), file);
+                break;
+              case EIHVN__NETWORKS_BIT:
+               fputs (_("NETWORKS         "), file);
+                break;
+              case EIHVN__COUNTERS_BIT:
+               fputs (_("COUNTERS         "), file);
+                break;
+              case EIHVN__STABLE_BIT:
+               fputs (_("STABLE           "), file);
+                break;
+              case EIHVN__MISC_BIT:
+                fputs (_("MISC             "), file);
+                break;
+              case EIHVN__CPU_BIT:
+                fputs (_("CPU              "), file);
+                break;
+              case EIHVN__VOLATILE_BIT:
+               fputs (_("VOLATILE         "), file);
+                break;
+              case EIHVN__SHELL_BIT:
+               fputs (_("SHELL            "), file);
+                break;
+              case EIHVN__POSIX_BIT:
+               fputs (_("POSIX            "), file);
+                break;
+              case EIHVN__MULTI_PROCESSING_BIT:
+                fputs (_("MULTI_PROCESSING "), file);
+                break;
+              case EIHVN__GALAXY_BIT:
+               fputs (_("GALAXY           "), file);
+                break;
+              default:
+                fputs (_("*unknown*        "), file);
+                break;
+              }
+            fprintf (file, _(": %u.%u\n"),
+                     (unsigned)bfd_getl16 (ver.major),
+                     (unsigned)bfd_getl16 (ver.minor));
+          }
+    }
+
+  if (eiha_off != 0)
+    {
+      struct vms_eiha eiha;
+
+      if (bfd_seek (abfd, (file_ptr) eiha_off, SEEK_SET)
+          || bfd_bread (&eiha, sizeof (eiha), abfd) != sizeof (eiha))
+        {
+          fprintf (file, _("cannot read EIHA\n"));
+          return;
+        }
+      fprintf (file, _("Image activation:  (size=%u)\n"),
+               (unsigned)bfd_getl32 (eiha.size));
+      fprintf (file, _(" First address : 0x%08x 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiha.tfradr1_h),
+               (unsigned)bfd_getl32 (eiha.tfradr1));
+      fprintf (file, _(" Second address: 0x%08x 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiha.tfradr2_h),
+               (unsigned)bfd_getl32 (eiha.tfradr2));
+      fprintf (file, _(" Third address : 0x%08x 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiha.tfradr3_h),
+               (unsigned)bfd_getl32 (eiha.tfradr3));
+      fprintf (file, _(" Fourth address: 0x%08x 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiha.tfradr4_h),
+               (unsigned)bfd_getl32 (eiha.tfradr4));
+      fprintf (file, _(" Shared image  : 0x%08x 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiha.inishr_h),
+               (unsigned)bfd_getl32 (eiha.inishr));
+    }
+  if (eihi_off != 0)
+    {
+      struct vms_eihi eihi;
+
+      if (bfd_seek (abfd, (file_ptr) eihi_off, SEEK_SET)
+          || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
+        {
+          fprintf (file, _("cannot read EIHI\n"));
+          return;
+        }
+      fprintf (file, _("Image identification: (major: %u, minor: %u)\n"),
+               (unsigned)bfd_getl32 (eihi.majorid),
+               (unsigned)bfd_getl32 (eihi.minorid));
+      fprintf (file, _(" image name       : %.*s\n"),
+               eihi.imgnam[0], eihi.imgnam + 1);
+      fprintf (file, _(" link time        : %s\n"),
+               vms_time_to_str (eihi.linktime));
+      fprintf (file, _(" image ident      : %.*s\n"),
+               eihi.imgid[0], eihi.imgid + 1);
+      fprintf (file, _(" linker ident     : %.*s\n"),
+               eihi.linkid[0], eihi.linkid + 1);
+      fprintf (file, _(" image build ident: %.*s\n"),
+               eihi.imgbid[0], eihi.imgbid + 1);
+    }
+  if (eihs_off != 0)
+    {
+      struct vms_eihs eihs;
+
+      if (bfd_seek (abfd, (file_ptr) eihs_off, SEEK_SET)
+          || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
+        {
+          fprintf (file, _("cannot read EIHS\n"));
+          return;
+        }
+      fprintf (file, _("Image symbol & debug table: (major: %u, minor: %u)\n"),
+               (unsigned)bfd_getl32 (eihs.majorid),
+               (unsigned)bfd_getl32 (eihs.minorid));
+      dst_vbn = bfd_getl32 (eihs.dstvbn);
+      dst_size = bfd_getl32 (eihs.dstsize);
+      fprintf (file, _(" debug symbol table : vbn: %u, size: %u\n"),
+               dst_vbn, dst_size);
+      gst_vbn = bfd_getl32 (eihs.gstvbn);
+      gst_size = bfd_getl32 (eihs.gstsize);
+      fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
+               gst_vbn, gst_size);
+      dmt_vbn = bfd_getl32 (eihs.dmtvbn);
+      dmt_size = bfd_getl32 (eihs.dmtsize);
+      fprintf (file, _(" debug module table : vbn: %u, size: %u\n"),
+               dmt_vbn, dmt_size);
+    }
+  while (eisd_off != 0)
+    {
+      struct vms_eisd eisd;
+      unsigned int len;
+
+      while (1)
+        {
+          if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET)
+              || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
+            {
+              fprintf (file, _("cannot read EISD\n"));
+              return;
+            }
+          len = (unsigned)bfd_getl32 (eisd.eisdsize);
+          if (len != (unsigned)-1)
+            break;
+
+          /* Next block.  */
+          eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+        }
+      fprintf (file, _("Image section descriptor: (major: %u, minor: %u, "
+                       "size: %u, offset: %u)\n"),
+               (unsigned)bfd_getl32 (eisd.majorid),
+               (unsigned)bfd_getl32 (eisd.minorid),
+               len, eisd_off);
+      if (len == 0)
+        break;
+      fprintf (file, _(" section: base: 0x%08x%08x size: 0x%08x\n"),
+               (unsigned)bfd_getl32 (eisd.virt_addr + 4),
+               (unsigned)bfd_getl32 (eisd.virt_addr + 0),
+               (unsigned)bfd_getl32 (eisd.secsize));
+      val = (unsigned)bfd_getl32 (eisd.flags);
+      fprintf (file, _(" flags: 0x%04x"), val);
+      if (val & EISD__M_GBL)
+        fprintf (file, " GBL");
+      if (val & EISD__M_CRF)
+        fprintf (file, " CRF");
+      if (val & EISD__M_DZRO)
+        fprintf (file, " DZRO");
+      if (val & EISD__M_WRT)
+        fprintf (file, " WRT");
+      if (val & EISD__M_INITALCODE)
+       fprintf (file, " INITALCODE");
+      if (val & EISD__M_BASED)
+        fprintf (file, " BASED");
+      if (val & EISD__M_FIXUPVEC)
+       fprintf (file, " FIXUPVEC");
+      if (val & EISD__M_RESIDENT)
+       fprintf (file, " RESIDENT");
+      if (val & EISD__M_VECTOR)
+        fprintf (file, " VECTOR");
+      if (val & EISD__M_PROTECT)
+       fprintf (file, " PROTECT");
+      if (val & EISD__M_LASTCLU)
+       fprintf (file, " LASTCLU");
+      if (val & EISD__M_EXE)
+        fprintf (file, " EXE");
+      if (val & EISD__M_NONSHRADR)
+       fprintf (file, " NONSHRADR");
+      if (val & EISD__M_QUAD_LENGTH)
+       fprintf (file, " QUAD_LENGTH");
+      if (val & EISD__M_ALLOC_64BIT)
+       fprintf (file, " ALLOC_64BIT");
+      fprintf (file, "\n");
+      if (val & EISD__M_FIXUPVEC)
+        {
+          eiaf_vbn = bfd_getl32 (eisd.vbn);
+          eiaf_size = bfd_getl32 (eisd.secsize);
+        }
+      fprintf (file, _(" vbn: %u, pfc: %u, matchctl: %u type: %u ("),
+               (unsigned)bfd_getl32 (eisd.vbn),
+               eisd.pfc, eisd.matchctl, eisd.type);
+      switch (eisd.type)
+        {
+        case EISD__K_NORMAL:
+          fputs (_("NORMAL"), file);
+          break;
+        case EISD__K_SHRFXD:
+          fputs (_("SHRFXD"), file);
+          break;
+        case EISD__K_PRVFXD:
+          fputs (_("PRVFXD"), file);
+          break;
+        case EISD__K_SHRPIC:
+          fputs (_("SHRPIC"), file);
+          break;
+        case EISD__K_PRVPIC:
+          fputs (_("PRVPIC"), file);
+          break;
+        case EISD__K_USRSTACK:
+          fputs (_("USRSTACK"), file);
+          break;
+        default:
+          fputs (_("*unknown*"), file);
+          break;
+        }
+      fputs (_(")\n"), file);
+      if (val & EISD__M_GBL)
+        fprintf (file, _(" ident: 0x%08x, name: %.*s\n"),
+                 (unsigned)bfd_getl32 (eisd.ident),
+                 eisd.gblnam[0], eisd.gblnam + 1);
+      eisd_off += len;
+    }
+
+  if (dmt_vbn != 0)
+    {
+      if (bfd_seek (abfd, (file_ptr) (dmt_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
+        {
+          fprintf (file, _("cannot read DMT\n"));
+          return;
+        }
+
+      fprintf (file, _("Debug module table:\n"));
+
+      while (dmt_size > 0)
+        {
+          struct vms_dmt_header dmth;
+          unsigned int count;
+
+          if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
+            {
+              fprintf (file, _("cannot read DMT header\n"));
+              return;
+            }
+          count = bfd_getl16 (dmth.psect_count);
+          fprintf (file,
+                   _(" module address: 0x%08x, size: 0x%08x, (%u psect)\n"),
+                   (unsigned)bfd_getl32 (dmth.modbeg),
+                   (unsigned)bfd_getl32 (dmth.size), count);
+          dmt_size -= sizeof (dmth);
+          while (count > 0)
+            {
+              struct vms_dmt_psect dmtp;
+
+              if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
+                {
+                  fprintf (file, _("cannot read DMT psect\n"));
+                  return;
+                }
+              fprintf (file, _("  psect start: 0x%08x, length: %u\n"),
+                       (unsigned)bfd_getl32 (dmtp.start),
+                       (unsigned)bfd_getl32 (dmtp.length));
+              count--;
+              dmt_size -= sizeof (dmtp);
+            }
+        }
+    }
+
+  if (dst_vbn != 0)
+    {
+      if (bfd_seek (abfd, (file_ptr) (dst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
+        {
+          fprintf (file, _("cannot read DST\n"));
+          return;
+        }
+
+      evax_bfd_print_dst (abfd, dst_size, file);
+    }
+  if (gst_vbn != 0)
+    {
+      if (bfd_seek (abfd, (file_ptr) (gst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
+        {
+          fprintf (file, _("cannot read GST\n"));
+          return;
+        }
+
+      fprintf (file, _("Global symbol table:\n"));
+      evax_bfd_print_eobj (abfd, file);
+    }
+  if (eiaf_vbn != 0)
+    {
+      unsigned char *buf;
+      struct vms_eiaf *eiaf;
+      unsigned int qrelfixoff;
+      unsigned int lrelfixoff;
+      unsigned int qdotadroff;
+      unsigned int ldotadroff;
+      unsigned int shrimgcnt;
+      unsigned int shlstoff;
+      unsigned int codeadroff;
+      unsigned int lpfixoff;
+      unsigned int chgprtoff;
+
+      buf = bfd_malloc (eiaf_size);
+
+      if (bfd_seek (abfd, (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET)
+          || bfd_bread (buf, eiaf_size, abfd) != eiaf_size)
+        {
+          fprintf (file, _("cannot read EIHA\n"));
+          free (buf);
+          return;
+        }
+      eiaf = (struct vms_eiaf *)buf;
+      fprintf (file,
+               _("Image activator fixup: (major: %u, minor: %u)\n"),
+               (unsigned)bfd_getl32 (eiaf->majorid),
+               (unsigned)bfd_getl32 (eiaf->minorid));
+      fprintf (file, _("  iaflink : 0x%08x %08x\n"),
+               (unsigned)bfd_getl32 (eiaf->iaflink + 0),
+               (unsigned)bfd_getl32 (eiaf->iaflink + 4));
+      fprintf (file, _("  fixuplnk: 0x%08x %08x\n"),
+               (unsigned)bfd_getl32 (eiaf->fixuplnk + 0),
+               (unsigned)bfd_getl32 (eiaf->fixuplnk + 4));
+      fprintf (file, _("  size : %u\n"),
+               (unsigned)bfd_getl32 (eiaf->size));
+      fprintf (file, _("  flags: 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiaf->flags));
+      qrelfixoff = bfd_getl32 (eiaf->qrelfixoff);
+      lrelfixoff = bfd_getl32 (eiaf->lrelfixoff);
+      fprintf (file, _("  qrelfixoff: %5u, lrelfixoff: %5u\n"),
+               qrelfixoff, lrelfixoff);
+      qdotadroff = bfd_getl32 (eiaf->qdotadroff);
+      ldotadroff = bfd_getl32 (eiaf->ldotadroff);
+      fprintf (file, _("  qdotadroff: %5u, ldotadroff: %5u\n"),
+               qdotadroff, ldotadroff);
+      codeadroff = bfd_getl32 (eiaf->codeadroff);
+      lpfixoff = bfd_getl32 (eiaf->lpfixoff);
+      fprintf (file, _("  codeadroff: %5u, lpfixoff  : %5u\n"),
+               codeadroff, lpfixoff);
+      chgprtoff = bfd_getl32 (eiaf->chgprtoff);
+      fprintf (file, _("  chgprtoff : %5u\n"), chgprtoff);
+      shrimgcnt = bfd_getl32 (eiaf->shrimgcnt);
+      shlstoff = bfd_getl32 (eiaf->shlstoff);
+      fprintf (file, _("  shlstoff  : %5u, shrimgcnt : %5u\n"),
+               shlstoff, shrimgcnt);
+      fprintf (file, _("  shlextra  : %5u, permctx   : %5u\n"),
+               (unsigned)bfd_getl32 (eiaf->shlextra),
+               (unsigned)bfd_getl32 (eiaf->permctx));
+      fprintf (file, _("  base_va : 0x%08x\n"),
+               (unsigned)bfd_getl32 (eiaf->base_va));
+      fprintf (file, _("  lppsbfixoff: %5u\n"),
+               (unsigned)bfd_getl32 (eiaf->lppsbfixoff));
+
+      if (shlstoff)
+        {
+          struct vms_shl *shl = (struct vms_shl *)(buf + shlstoff);
+          unsigned int j;
+
+          fprintf (file, _(" Shareable images:\n"));
+          for (j = 0; j < shrimgcnt; j++, shl++)
+            {
+              fprintf (file,
+                       _("  %u: size: %u, flags: 0x%02x, name: %.*s\n"),
+                       j, shl->size, shl->flags,
+                       shl->imgnam[0], shl->imgnam + 1);
+            }
+        }
+      if (qrelfixoff != 0)
+        {
+          fprintf (file, _(" quad-word relocation fixups:\n"));
+          evax_bfd_print_relocation_records (file, buf + qrelfixoff, 8);
+        }
+      if (lrelfixoff != 0)
+        {
+          fprintf (file, _(" long-word relocation fixups:\n"));
+          evax_bfd_print_relocation_records (file, buf + lrelfixoff, 4);
+        }
+      if (qdotadroff != 0)
+        {
+          fprintf (file, _(" quad-word .address reference fixups:\n"));
+          evax_bfd_print_address_fixups (file, buf + qdotadroff);
+        }
+      if (ldotadroff != 0)
+        {
+          fprintf (file, _(" long-word .address reference fixups:\n"));
+          evax_bfd_print_address_fixups (file, buf + ldotadroff);
+        }
+      if (codeadroff != 0)
+        {
+          fprintf (file, _(" Code Address Reference Fixups:\n"));
+          evax_bfd_print_reference_fixups (file, buf + codeadroff);
+        }
+      if (lpfixoff != 0)
+        {
+          fprintf (file, _(" Linkage Pairs Referece Fixups:\n"));
+          evax_bfd_print_reference_fixups (file, buf + lpfixoff);
+        }
+      if (chgprtoff)
+        {
+          unsigned int count = (unsigned)bfd_getl32 (buf + chgprtoff);
+          struct vms_eicp *eicp = (struct vms_eicp *)(buf + chgprtoff + 4);
+          unsigned int j;
+
+          fprintf (file, _(" Change Protection (%u entries):\n"), count);
+          for (j = 0; j < count; j++, eicp++)
+            {
+              unsigned int prot = bfd_getl32 (eicp->newprt);
+              fprintf (file,
+                       _("  base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "),
+                       (unsigned)bfd_getl32 (eicp->baseva + 4),
+                       (unsigned)bfd_getl32 (eicp->baseva + 0),
+                       (unsigned)bfd_getl32 (eicp->size),
+                       (unsigned)bfd_getl32 (eicp->newprt));
+              switch (prot)
+                {
+                case PRT__C_NA:
+                  fprintf (file, "NA");
+                  break;
+                case PRT__C_RESERVED:
+                  fprintf (file, "RES");
+                  break;
+                case PRT__C_KW:
+                  fprintf (file, "KW");
+                  break;
+                case PRT__C_KR:
+                  fprintf (file, "KR");
+                  break;
+                case PRT__C_UW:
+                  fprintf (file, "UW");
+                  break;
+                case PRT__C_EW:
+                  fprintf (file, "EW");
+                  break;
+                case PRT__C_ERKW:
+                  fprintf (file, "ERKW");
+                  break;
+                case PRT__C_ER:
+                  fprintf (file, "ER");
+                  break;
+                case PRT__C_SW:
+                  fprintf (file, "SW");
+                  break;
+                case PRT__C_SREW:
+                  fprintf (file, "SREW");
+                  break;
+                case PRT__C_SRKW:
+                  fprintf (file, "SRKW");
+                  break;
+                case PRT__C_SR:
+                  fprintf (file, "SR");
+                  break;
+                case PRT__C_URSW:
+                  fprintf (file, "URSW");
+                  break;
+                case PRT__C_UREW:
+                  fprintf (file, "UREW");
+                  break;
+                case PRT__C_URKW:
+                  fprintf (file, "URKW");
+                  break;
+                case PRT__C_UR:
+                  fprintf (file, "UR");
+                  break;
+                default:
+                  fputs ("??", file);
+                  break;
+                }
+              fputc ('\n', file);
+            }
+        }
+      free (buf);
+    }
+}
+
+static bfd_boolean
+vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+  FILE *file = (FILE *)ptr;
+
+  if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
+    evax_bfd_print_image (abfd, file);
+  else
+    {
+      if (bfd_seek (abfd, 0, SEEK_SET))
+        return FALSE;
+      evax_bfd_print_eobj (abfd, file);
+    }
+  return TRUE;
+}
+\f
+/* Linking.  */
+
+/* Slurp an ordered set of VMS object records.  */
+
+static bfd_boolean
+alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
+{
+  asection *cur_section;
+  file_ptr cur_offset;
+  asection *dst_section;
+  file_ptr dst_offset;
+
+  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+    return FALSE;
+
+  PRIV (image_autoextend) = FALSE;
+
+  cur_section = NULL;
+  cur_offset = 0;
+
+  dst_section = PRIV (dst_section);
+  dst_offset = 0;
+  if (info)
+    {
+      if (info->strip == strip_all || info->strip == strip_debugger)
+        {
+          dst_offset = 0;
+          dst_section = NULL;
+        }
+      else if (dst_section)
+        {
+          dst_offset = dst_section->output_offset;
+          dst_section = dst_section->output_section;
+        }
+    }
+
+  while (1)
+    {
+      int type;
+      bfd_boolean res;
+
+      type = _bfd_vms_get_object_record (abfd);
+      if (type < 0)
+       {
+         vms_debug2 ((2, "next_record failed\n"));
+         return FALSE;
+       }
+      switch (type)
+        {
+        case EOBJ__C_ETIR:
+          PRIV (image_section) = cur_section;
+          PRIV (image_offset) = cur_offset;
+          res = _bfd_vms_slurp_etir (abfd, info);
+          cur_section = PRIV (image_section);
+          cur_offset = PRIV (image_offset);
+          break;
+        case EOBJ__C_EDBG:
+        case EOBJ__C_ETBT:
+          if (dst_section == NULL)
+            continue;
+          PRIV (image_section) = dst_section;
+          PRIV (image_offset) = dst_offset;
+          PRIV (image_autoextend) = TRUE;
+          res = _bfd_vms_slurp_etir (abfd, info);
+          PRIV (image_autoextend) = FALSE;
+          dst_offset = PRIV (image_offset);
+          break;
+        case EOBJ__C_EEOM:
+          return TRUE;
+        default:
+          continue;
+        }
+      if (!res)
+        {
+          vms_debug2 ((2, "slurp eobj type %d failed\n", type));
+          return FALSE;
+        }
+    }
+}
+
+static int
+alpha_vms_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+                          struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* Add a linkage pair fixup at address SECT + OFFSET to SHLIB. */
+
+static void
+alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib)
+{
+  struct alpha_vms_shlib_el *sl;
+  asection *sect = PRIV2 (src, image_section);
+  file_ptr offset = PRIV2 (src, image_offset);
+
+  sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
+                struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+  sl->has_fixups = TRUE;
+  VEC_APPEND_EL (sl->lp, bfd_vma,
+                 sect->output_section->vma + sect->output_offset + offset);
+}
+
+static void
+alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib)
+{
+  struct alpha_vms_shlib_el *sl;
+  asection *sect = PRIV2 (src, image_section);
+  file_ptr offset = PRIV2 (src, image_offset);
+
+  sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
+                struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+  sl->has_fixups = TRUE;
+  VEC_APPEND_EL (sl->ca, bfd_vma,
+                 sect->output_section->vma + sect->output_offset + offset);
+}
+
+static void
+alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
+                        bfd *shlib, bfd_vma vec)
+{
+  struct alpha_vms_shlib_el *sl;
+  struct alpha_vms_vma_ref *r;
+  asection *sect = PRIV2 (src, image_section);
+  file_ptr offset = PRIV2 (src, image_offset);
+
+  sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
+                struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+  sl->has_fixups = TRUE;
+  r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref);
+  r->vma = sect->output_section->vma + sect->output_offset + offset;
+  r->ref = vec;
+}
+
+static void
+alpha_vms_add_lw_fixup (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                        unsigned int shr ATTRIBUTE_UNUSED,
+                        bfd_vma vec ATTRIBUTE_UNUSED)
+{
+  abort ();
+}
+
+#if 0
+static void
+alpha_vms_add_qw_fixup (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                        unsigned int shr ATTRIBUTE_UNUSED,
+                        bfd_vma vec ATTRIBUTE_UNUSED)
+{
+  abort ();
+}
+#endif
+
+static void
+alpha_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+}
+
+static void
+alpha_vms_add_qw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+}
+
+static struct bfd_hash_entry *
+alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry,
+                             struct bfd_hash_table *table,
+                             const char *string)
+{
+  struct alpha_vms_link_hash_entry *ret =
+    (struct alpha_vms_link_hash_entry *) entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == NULL)
+    ret = ((struct alpha_vms_link_hash_entry *)
+          bfd_hash_allocate (table,
+                              sizeof (struct alpha_vms_link_hash_entry)));
+  if (ret == NULL)
+    return NULL;
+
+  /* Call the allocation method of the superclass.  */
+  ret = ((struct alpha_vms_link_hash_entry *)
+        _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+                                table, string));
+
+  ret->sym = NULL;
+
+  return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an Alpha/VMS link hash table.  */
+
+static struct bfd_link_hash_table *
+alpha_vms_bfd_link_hash_table_create (bfd *abfd)
+{
+  struct alpha_vms_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct alpha_vms_link_hash_table);
+
+  ret = (struct alpha_vms_link_hash_table *) bfd_malloc (amt);
+  if (ret == NULL)
+    return NULL;
+  if (!_bfd_link_hash_table_init (&ret->root, abfd,
+                                 alpha_vms_link_hash_newfunc,
+                                 sizeof (struct alpha_vms_link_hash_entry)))
+    {
+      free (ret);
+      return NULL;
+    }
+
+  VEC_INIT (ret->shrlibs);
+  ret->fixup = NULL;
+
+  return &ret->root;
+}
+
+static bfd_boolean
+alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+  unsigned int i;
+
+  for (i = 0; i < PRIV (gsd_sym_count); i++)
+    {
+      struct vms_symbol_entry *e = PRIV (syms)[i];
+      struct alpha_vms_link_hash_entry *h;
+      asymbol sym;
+
+      if (!alpha_vms_convert_symbol (abfd, e, &sym))
+        return FALSE;
+
+      if ((e->flags & EGSY__V_DEF) && abfd->selective_search)
+        {
+          /* In selective_search mode, only add definition that are
+             required.  */
+          h = (struct alpha_vms_link_hash_entry *)bfd_link_hash_lookup
+            (info->hash, sym.name, FALSE, FALSE, FALSE);
+          if (h == NULL || h->root.type != bfd_link_hash_undefined)
+            continue;
+        }
+      else
+        h = NULL;
+
+      if (_bfd_generic_link_add_one_symbol
+          (info, abfd, sym.name, sym.flags, sym.section, sym.value,
+           NULL, FALSE, FALSE, (struct bfd_link_hash_entry **)&h) == FALSE)
+        return FALSE;
+
+      if ((e->flags & EGSY__V_DEF)
+          && h->sym == NULL
+          && abfd->xvec == info->output_bfd->xvec)
+        h->sym = e;
+    }
+
+  if (abfd->flags & DYNAMIC)
+    {
+      struct alpha_vms_shlib_el *shlib;
+
+      /* We do not want to include any of the sections in a dynamic
+         object in the output file.  See comment in elflink.c.  */
+      bfd_section_list_clear (abfd);
+
+      shlib = VEC_APPEND (alpha_vms_link_hash (info)->shrlibs,
+                          struct alpha_vms_shlib_el);
+      shlib->abfd = abfd;
+      VEC_INIT (shlib->ca);
+      VEC_INIT (shlib->lp);
+      VEC_INIT (shlib->qr);
+      PRIV (shr_index) = VEC_COUNT (alpha_vms_link_hash (info)->shrlibs) - 1;
+    }
+
+  return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+  int pass;
+  struct bfd_link_hash_entry **pundef;
+  struct bfd_link_hash_entry **next_pundef;
+
+  /* We only accept VMS libraries.  */
+  if (info->output_bfd->xvec != abfd->xvec)
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
+
+  /* The archive_pass field in the archive itself is used to
+     initialize PASS, since we may search the same archive multiple
+     times.  */
+  pass = ++abfd->archive_pass;
+
+  /* Look through the list of undefined symbols.  */
+  for (pundef = &info->hash->undefs; *pundef != NULL; pundef = next_pundef)
+    {
+      struct bfd_link_hash_entry *h;
+      file_ptr file_offset;
+      bfd *element;
+      bfd *orig_element;
+
+      h = *pundef;
+      next_pundef = &(*pundef)->u.undef.next;
+
+      /* When a symbol is defined, it is not necessarily removed from
+        the list.  */
+      if (h->type != bfd_link_hash_undefined
+         && h->type != bfd_link_hash_common)
+       {
+         /* Remove this entry from the list, for general cleanliness
+            and because we are going to look through the list again
+            if we search any more libraries.  We can't remove the
+            entry if it is the tail, because that would lose any
+            entries we add to the list later on.  */
+         if (*pundef != info->hash->undefs_tail)
+            {
+              *pundef = *next_pundef;
+              next_pundef = pundef;
+            }
+         continue;
+       }
+
+      /* Look for this symbol in the archive hash table.  */
+      file_offset = _bfd_vms_lib_find_symbol (abfd, h->root.string);
+      if (file_offset == 0)
+       {
+         /* Nothing in this slot.  */
+         continue;
+       }
+
+      element = bfd_get_elt_at_index (abfd, file_offset);
+      if (element == NULL)
+       return FALSE;
+
+      if (element->archive_pass == -1 || element->archive_pass == pass)
+        continue;
+
+      if (! bfd_check_format (element, bfd_object))
+        {
+          element->archive_pass = -1;
+          return FALSE;
+        }
+
+      orig_element = element;
+      if (bfd_is_thin_archive (abfd))
+        {
+          element = _bfd_vms_lib_get_imagelib_file (element);
+          if (element == NULL || !bfd_check_format (element, bfd_object))
+            {
+              orig_element->archive_pass = -1;
+              return FALSE;
+            }
+        }
+
+      /* Unlike the generic linker, we know that this element provides
+        a definition for an undefined symbol and we know that we want
+        to include it.  We don't need to check anything.  */
+      if (! (*info->callbacks->add_archive_element) (info, element,
+                                                     h->root.string))
+       return FALSE;
+      if (! alpha_vms_link_add_object_symbols (element, info))
+       return FALSE;
+
+      orig_element->archive_pass = pass;
+    }
+
+  return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+  switch (bfd_get_format (abfd))
+    {
+    case bfd_object:
+      vms_debug2 ((2, "vms_link_add_symbols for object %s\n",
+                   abfd->filename));
+      return alpha_vms_link_add_object_symbols (abfd, info);
+      break;
+    case bfd_archive:
+      vms_debug2 ((2, "vms_link_add_symbols for archive %s\n",
+                   abfd->filename));
+      return alpha_vms_link_add_archive_symbols (abfd, info);
+      break;
+    default:
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
+}
+
+static bfd_boolean
+alpha_vms_build_fixups (struct bfd_link_info *info)
+{
+  struct alpha_vms_link_hash_table *t = alpha_vms_link_hash (info);
+  unsigned char *content;
+  unsigned int i;
+  unsigned int sz = 0;
+  unsigned int lp_sz = 0;
+  unsigned int ca_sz = 0;
+  unsigned int qr_sz = 0;
+  unsigned int shrimg_cnt = 0;
+  struct vms_eiaf *eiaf;
+  unsigned int off;
+  asection *sec;
+
+  /* Shared libraries.  */
+  for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+    {
+      struct alpha_vms_shlib_el *shlib;
+
+      shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+      if (!shlib->has_fixups)
+        continue;
+
+      shrimg_cnt++;
+
+      if (VEC_COUNT (shlib->ca) > 0)
+        {
+          /* Header + entries.  */
+          ca_sz += 8;
+          ca_sz += VEC_COUNT (shlib->ca) * 4;
+        }
+      if (VEC_COUNT (shlib->lp) > 0)
+        {
+          /* Header + entries.  */
+          lp_sz += 8;
+          lp_sz += VEC_COUNT (shlib->lp) * 4;
+        }
+      if (VEC_COUNT (shlib->qr) > 0)
+        {
+          /* Header + entries.  */
+          qr_sz += 8;
+          qr_sz += VEC_COUNT (shlib->qr) * 8;
+        }
+    }
+  /* Add markers.  */
+  if (ca_sz > 0)
+    ca_sz += 8;
+  if (lp_sz > 0)
+    lp_sz += 8;
+  if (qr_sz > 0)
+    qr_sz += 8;
+
+  /* Finish now if there is no content.  */
+  if (ca_sz + lp_sz + qr_sz == 0)
+    return TRUE;
+
+  /* Allocate section content (round-up size)  */
+  sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl)
+    + ca_sz + lp_sz + qr_sz;
+  sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
+  content = bfd_zalloc (info->output_bfd, sz);
+  if (content == NULL)
+    return FALSE;
+
+  sec = alpha_vms_link_hash (info)->fixup;
+  sec->contents = content;
+  sec->size = sz;
+
+  eiaf = (struct vms_eiaf *)content;
+  off = sizeof (struct vms_eiaf);
+  bfd_putl32 (0, eiaf->majorid);
+  bfd_putl32 (0, eiaf->minorid);
+  bfd_putl32 (0, eiaf->iaflink);
+  bfd_putl32 (0, eiaf->fixuplnk);
+  bfd_putl32 (sizeof (struct vms_eiaf), eiaf->size);
+  bfd_putl32 (0, eiaf->flags);
+  bfd_putl32 (0, eiaf->qrelfixoff);
+  bfd_putl32 (0, eiaf->lrelfixoff);
+  bfd_putl32 (0, eiaf->qdotadroff);
+  bfd_putl32 (0, eiaf->ldotadroff);
+  bfd_putl32 (0, eiaf->codeadroff);
+  bfd_putl32 (0, eiaf->lpfixoff);
+  bfd_putl32 (0, eiaf->chgprtoff);
+  bfd_putl32 (shrimg_cnt ? off : 0, eiaf->shlstoff);
+  bfd_putl32 (shrimg_cnt, eiaf->shrimgcnt);
+  bfd_putl32 (0, eiaf->shlextra);
+  bfd_putl32 (0, eiaf->permctx);
+  bfd_putl32 (0, eiaf->base_va);
+  bfd_putl32 (0, eiaf->lppsbfixoff);
+
+  if (shrimg_cnt)
+    {
+      shrimg_cnt = 0;
+
+      /* Write shl.  */
+      for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+        {
+          struct alpha_vms_shlib_el *shlib;
+          struct vms_shl *shl;
+
+          shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+          if (!shlib->has_fixups)
+            continue;
+
+          /* Renumber shared images.  */
+          PRIV2 (shlib->abfd, shr_index) = shrimg_cnt++;
+
+          shl = (struct vms_shl *)(content + off);
+          bfd_putl32 (0, shl->baseva);
+          bfd_putl32 (0, shl->shlptr);
+          bfd_putl32 (0, shl->ident);
+          bfd_putl32 (0, shl->permctx);
+          shl->size = sizeof (struct vms_shl);
+          bfd_putl16 (0, shl->fill_1);
+          shl->flags = 0;
+          bfd_putl32 (0, shl->icb);
+          shl->imgnam[0] = strlen (PRIV2 (shlib->abfd, hdr_data.hdr_t_name));
+          memcpy (shl->imgnam + 1, PRIV2 (shlib->abfd, hdr_data.hdr_t_name),
+                  shl->imgnam[0]);
+
+          off += sizeof (struct vms_shl);
+        }
+
+      /* CA fixups.  */
+      if (ca_sz != 0)
+        {
+          bfd_putl32 (off, eiaf->codeadroff);
+
+          for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+            {
+              struct alpha_vms_shlib_el *shlib;
+              unsigned int j;
+
+              shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+              if (VEC_COUNT (shlib->ca) == 0)
+                continue;
+
+              bfd_putl32 (VEC_COUNT (shlib->ca), content + off);
+              bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+              off += 8;
+
+              for (j = 0; j < VEC_COUNT (shlib->ca); j++)
+                {
+                  bfd_putl32 (VEC_EL (shlib->ca, bfd_vma, j) - t->base_addr,
+                              content + off);
+                  off += 4;
+                }
+            }
+
+          bfd_putl32 (0, content + off);
+          bfd_putl32 (0, content + off + 4);
+          off += 8;
+        }
+
+      /* LP fixups.  */
+      if (lp_sz != 0)
+        {
+          bfd_putl32 (off, eiaf->lpfixoff);
+
+          for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+            {
+              struct alpha_vms_shlib_el *shlib;
+              unsigned int j;
+
+              shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+              if (VEC_COUNT (shlib->lp) == 0)
+                continue;
+
+              bfd_putl32 (VEC_COUNT (shlib->lp), content + off);
+              bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+              off += 8;
+
+              for (j = 0; j < VEC_COUNT (shlib->lp); j++)
+                {
+                  bfd_putl32 (VEC_EL (shlib->lp, bfd_vma, j) - t->base_addr,
+                              content + off);
+                  off += 4;
+                }
+            }
+
+          bfd_putl32 (0, content + off);
+          bfd_putl32 (0, content + off + 4);
+          off += 8;
+        }
+
+      /* QR fixups.  */
+      if (qr_sz != 0)
+        {
+          bfd_putl32 (off, eiaf->qdotadroff);
+
+          for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+            {
+              struct alpha_vms_shlib_el *shlib;
+              unsigned int j;
+
+              shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+              if (VEC_COUNT (shlib->qr) == 0)
+                continue;
+
+              bfd_putl32 (VEC_COUNT (shlib->qr), content + off);
+              bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+              off += 8;
+
+              for (j = 0; j < VEC_COUNT (shlib->qr); j++)
+                {
+                  struct alpha_vms_vma_ref *r;
+                  r = &VEC_EL (shlib->qr, struct alpha_vms_vma_ref, j);
+                  bfd_putl32 (r->vma - t->base_addr, content + off);
+                  bfd_putl32 (r->ref, content + off + 4);
+                  off += 8;
+                }
+            }
+
+          bfd_putl32 (0, content + off);
+          bfd_putl32 (0, content + off + 4);
+          off += 8;
+        }
+
+      /* CA fixups.  */
+    }
+
+  return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+  asection *o;
+  struct bfd_link_order *p;
+  bfd *sub;
+  asection *fixupsec;
+  bfd_vma base_addr;
+  bfd_vma last_addr;
+
+  bfd_get_outsymbols (abfd) = NULL;
+  bfd_get_symcount (abfd) = 0;
+
+  /* Mark all sections which will be included in the output file.  */
+  for (o = abfd->sections; o != NULL; o = o->next)
+    for (p = o->map_head.link_order; p != NULL; p = p->next)
+      if (p->type == bfd_indirect_link_order)
+       p->u.indirect.section->linker_mark = TRUE;
+
+#if 0
+  /* Handle all the link order information for the sections.  */
+  for (o = abfd->sections; o != NULL; o = o->next)
+    {
+      printf ("For section %s (at 0x%08x, flags=0x%08x):\n",
+              o->name, (unsigned)o->vma, (unsigned)o->flags);
+
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
+       {
+          printf (" at 0x%08x - 0x%08x: ",
+                  (unsigned)p->offset, (unsigned)(p->offset + p->size - 1));
+         switch (p->type)
+           {
+           case bfd_section_reloc_link_order:
+           case bfd_symbol_reloc_link_order:
+              printf ("  section/symbol reloc\n");
+             break;
+           case bfd_indirect_link_order:
+              printf ("  section %s of %s\n",
+                      p->u.indirect.section->name,
+                      p->u.indirect.section->owner->filename);
+             break;
+            case bfd_data_link_order:
+              printf ("  explicit data\n");
+              break;
+           default:
+              printf ("  *unknown* type %u\n", p->type);
+             break;
+           }
+       }
+    }
+#endif
+
+  /* Find entry point.  */
+  if (bfd_get_start_address (abfd) == 0)
+    {
+      bfd *startbfd = NULL;
+
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+        {
+          /* Consider only VMS object files.  */
+          if (sub->xvec != abfd->xvec)
+            continue;
+
+          if (!PRIV2 (sub, eom_data).eom_has_transfer)
+            continue;
+          if ((PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR) && startbfd)
+            continue;
+          if (startbfd != NULL
+              && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR))
+            {
+              (*info->callbacks->einfo)
+                (_("%P: multiple entry points: in modules %B and %B\n"),
+                 startbfd, sub);
+              continue;
+            }
+          startbfd = sub;
+        }
+
+      if (startbfd)
+        {
+          unsigned int ps_idx = PRIV2 (startbfd, eom_data).eom_l_psindx;
+          bfd_vma tfradr = PRIV2 (startbfd, eom_data).eom_l_tfradr;
+          asection *sec;
+
+          sec = PRIV2 (startbfd, sections)[ps_idx];
+
+          bfd_set_start_address
+            (abfd, sec->output_section->vma + sec->output_offset + tfradr);
+        }
+    }
+
+  /* Allocate content.  */
+  base_addr = (bfd_vma)-1;
+  last_addr = 0;
+  for (o = abfd->sections; o != NULL; o = o->next)
+    {
+      if (o->flags & SEC_HAS_CONTENTS)
+        {
+          o->contents = bfd_alloc (abfd, o->size);
+          if (o->contents == NULL)
+            return FALSE;
+        }
+      if (o->flags & SEC_LOAD)
+        {
+          if (o->vma < base_addr)
+            base_addr = o->vma;
+          if (o->vma + o->size > last_addr)
+            last_addr = o->vma + o->size;
+        }
+    }
+
+  fixupsec = bfd_make_section_anyway_with_flags
+    (info->output_bfd, "$FIXUP$",
+     SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
+  if (fixupsec == NULL)
+    return FALSE;
+  last_addr = (last_addr + 0xffff) & ~0xffff;
+  fixupsec->vma = last_addr;
+
+  alpha_vms_link_hash (info)->fixup = fixupsec;
+  alpha_vms_link_hash (info)->base_addr = base_addr;
+
+  /* Read all sections from the inputs.  */
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+    {
+      if (sub->flags & DYNAMIC)
+        {
+          alpha_vms_create_eisd_for_shared (abfd, sub);
+          continue;
+        }
+
+      if (!alpha_vms_read_sections_content (sub, info))
+        return FALSE;
+    }
+
+  /* Handle all the link order information for the sections.  */
+  for (o = abfd->sections; o != NULL; o = o->next)
+    {
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
+       {
+         switch (p->type)
+           {
+           case bfd_section_reloc_link_order:
+           case bfd_symbol_reloc_link_order:
+              abort ();
+              return FALSE;
+           case bfd_indirect_link_order:
+              /* Already done.  */
+             break;
+           default:
+             if (! _bfd_default_link_order (abfd, info, o, p))
+               return FALSE;
+             break;
+           }
+       }
+    }
+
+  /* Compute fixups.  */
+  if (!alpha_vms_build_fixups (info))
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Read the contents of a section.
+   buf points to a buffer of buf_size bytes to be filled with
+   section data (starting at offset into section)  */
+
+static bfd_boolean
+alpha_vms_get_section_contents (bfd *abfd, asection *section,
+                                void *buf, file_ptr offset,
+                                bfd_size_type count)
+{
+  asection *sec;
+
+  /* Image are easy.  */
+  if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
+    return _bfd_generic_get_section_contents (abfd, section,
+                                              buf, offset, count);
+
+  /* Safety check.  */
+  if (offset + count < count
+      || offset + count > section->size)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
+
+  /* Alloc in memory and read ETIRs.  */
+  BFD_ASSERT (section->contents == NULL);
+
+  for (sec = abfd->sections; sec; sec = sec->next)
+    {
+      BFD_ASSERT (sec->contents == NULL);
+
+      if (sec->size != 0 && (sec->flags & SEC_HAS_CONTENTS))
+        {
+          sec->contents = bfd_alloc (abfd, sec->size);
+          if (sec->contents == NULL)
+            return FALSE;
+        }
+    }
+  if (!alpha_vms_read_sections_content (abfd, NULL))
+    return FALSE;
+  for (sec = abfd->sections; sec; sec = sec->next)
+    if (section->contents)
+      section->flags |= SEC_IN_MEMORY;
+  memcpy (buf, section->contents + offset, count);
+  return TRUE;
+}
+
+
+/* Set the format of a file being written.  */
+
+static bfd_boolean
+alpha_vms_mkobject (bfd * abfd)
+{
+  const bfd_arch_info_type *arch;
+
+  vms_debug2 ((1, "alpha_vms_mkobject (%p)\n", abfd));
+
+  if (!vms_initialize (abfd))
+    return FALSE;
+
+  PRIV (recwr.buf) = bfd_alloc (abfd, MAX_OUTREC_SIZE);
+  if (PRIV (recwr.buf) == NULL)
+    return FALSE;
+
+  arch = bfd_scan_arch ("alpha");
+
+  if (arch == 0)
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
+
+  abfd->arch_info = arch;
+  return TRUE;
+}
+
+
+/* 4.1, generic.  */
+
+/* Called when the BFD is being closed to do any necessary cleanup.  */
+
+static bfd_boolean
+vms_close_and_cleanup (bfd * abfd)
+{
+  vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd));
+
+  if (abfd == NULL || abfd->tdata.any == NULL)
+    return TRUE;
+
+  if (abfd->format == bfd_archive)
+    {
+      bfd_release (abfd, abfd->tdata.any);
+      abfd->tdata.any = NULL;
+      return TRUE;
+    }
+
+  if (PRIV (recrd.buf) != NULL)
+    free (PRIV (recrd.buf));
+
+  if (PRIV (sections) != NULL)
+    free (PRIV (sections));
+
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+
+#ifdef VMS
+  if (abfd->direction == write_direction)
+    {
+      /* Last step on VMS is to convert the file to variable record length
+        format.  */
+      if (bfd_cache_close (abfd) != TRUE)
+       return FALSE;
+      if (vms_convert_to_var_unix_filename (abfd->filename) != TRUE)
+       return FALSE;
+    }
+#endif
+
+  return TRUE;
+}
+
+/* Called when a new section is created.  */
+
+static bfd_boolean
+vms_new_section_hook (bfd * abfd, asection *section)
+{
+  bfd_size_type amt;
+
+  /* Count hasn't been incremented yet.  */
+  unsigned int section_count = abfd->section_count + 1;
+
+  vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
+               abfd, section->index, section->name, section_count));
+
+  bfd_set_section_alignment (abfd, section, 0);
+
+  if (section_count > PRIV (section_count))
+    {
+      amt = section_count;
+      amt *= sizeof (asection *);
+      PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
+      if (PRIV (sections) == NULL)
+       return FALSE;
+      PRIV (section_count) = section_count;
+    }
+
+  vms_debug2 ((6, "section_count: %d\n", PRIV (section_count)));
+
+  PRIV (sections)[section->index] = section;
+
+  vms_debug2 ((7, "%d: %s\n", section->index, section->name));
+
+  amt = sizeof (struct vms_section_data_struct);
+  section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+  if (section->used_by_bfd == NULL)
+    return FALSE;
+
+  if (strcmp (bfd_get_section_name (abfd, section), "$DST$") == 0)
+    PRIV (dst_section) = section;
+
+  /* Create the section symbol.  */
+  return _bfd_generic_new_section_hook (abfd, section);
+}
+
+/* Part 4.5, symbols.  */
+
+/* Print symbol to file according to how. how is one of
+   bfd_print_symbol_name       just print the name
+   bfd_print_symbol_more       print more (???)
+   bfd_print_symbol_all        print all we know, which is not much right now :-).  */
+
+static void
+vms_print_symbol (bfd * abfd,
+                 void * file,
+                 asymbol *symbol,
+                 bfd_print_symbol_type how)
+{
+  vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n",
+               abfd, file, symbol, how));
+
+  switch (how)
+    {
+      case bfd_print_symbol_name:
+      case bfd_print_symbol_more:
+       fprintf ((FILE *)file," %s", symbol->name);
+      break;
+
+      case bfd_print_symbol_all:
+       {
+         const char *section_name = symbol->section->name;
+
+         bfd_print_symbol_vandf (abfd, file, symbol);
+
+         fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
+        }
+      break;
+    }
+}
+
+/* Return information about symbol in ret.
+
+   fill type, value and name
+   type:
+       A       absolute
+       B       bss segment symbol
+       C       common symbol
+       D       data segment symbol
+       f       filename
+       t       a static function symbol
+       T       text segment symbol
+       U       undefined
+       -       debug.  */
+
+static void
+vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
+                    asymbol *symbol,
+                    symbol_info *ret)
+{
+  asection *sec;
+
+  vms_debug2 ((1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret));
+
+  sec = symbol->section;
+
+  if (ret == NULL)
+    return;
+
+  if (sec == 0)
+    ret->type = 'U';
+  else if (bfd_is_com_section (sec))
+    ret->type = 'C';
+  else if (bfd_is_abs_section (sec))
+    ret->type = 'A';
+  else if (bfd_is_und_section (sec))
+    ret->type = 'U';
+  else if (bfd_is_ind_section (sec))
+    ret->type = 'I';
+  else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
+    ret->type = 'T';
+  else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+    ret->type = 'D';
+  else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+    ret->type = 'B';
+  else
+    ret->type = '-';
+
+  if (ret->type != 'U')
+    ret->value = symbol->value + symbol->section->vma;
+  else
+    ret->value = 0;
+  ret->name = symbol->name;
+}
+
+/* Return TRUE if the given symbol sym in the BFD abfd is
+   a compiler generated local label, else return FALSE.  */
+
+static bfd_boolean
+vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
+                            const char *name)
+{
+  vms_debug2 ((1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name));
+  return name[0] == '$';
+}
+\f
+/* Part 4.7, writing an object file.  */
+
+/* Sets the contents of the section section in BFD abfd to the data starting
+   in memory at LOCATION. The data is written to the output section starting
+   at offset offset for count bytes.
+
+   Normally TRUE is returned, else FALSE. Possible error returns are:
+   o bfd_error_no_contents - The output section does not have the
+       SEC_HAS_CONTENTS attribute, so nothing can be written to it.
+   o and some more too  */
+
+static bfd_boolean
+_bfd_vms_set_section_contents (bfd * abfd,
+                               asection *section,
+                               const void * location,
+                               file_ptr offset,
+                               bfd_size_type count)
+{
+  if (section->contents == NULL)
+    {
+      section->contents = bfd_alloc (abfd, section->size);
+      if (section->contents == NULL)
+        return FALSE;
+
+      memcpy (section->contents + offset, location, (size_t) count);
+    }
+
+  return TRUE;
+}
+
+/* Set the architecture and machine type in BFD abfd to arch and mach.
+   Find the correct pointer to a structure and insert it into the arch_info
+   pointer.  */
+
+static bfd_boolean
+alpha_vms_set_arch_mach (bfd *abfd,
+                         enum bfd_architecture arch, unsigned long mach)
+{
+  if (arch != bfd_arch_alpha
+      && arch != bfd_arch_unknown)
+    return FALSE;
+
+  return bfd_default_set_arch_mach (abfd, arch, mach);
+}
+
+/* Set section VMS flags.  Clear NO_FLAGS and set FLAGS.  */
+
+void
+bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
+                          asection *sec, flagword no_flags, flagword flags)
+{
+  vms_section_data (sec)->no_flags = no_flags;
+  vms_section_data (sec)->flags = flags;
+}
+
+struct vms_private_data_struct *
+bfd_vms_get_data (bfd *abfd)
+{
+  return (struct vms_private_data_struct *)abfd->tdata.any;
+}
+
+#define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define vms_bfd_link_just_syms            _bfd_generic_link_just_syms
+#define vms_bfd_copy_link_hash_symbol_type \
+  _bfd_generic_copy_link_hash_symbol_type
+#define vms_bfd_is_group_section          bfd_generic_is_group_section
+#define vms_bfd_discard_group             bfd_generic_discard_group
+#define vms_section_already_linked        _bfd_generic_section_already_linked
+#define vms_bfd_define_common_symbol      bfd_generic_define_common_symbol
+#define vms_bfd_copy_private_header_data  _bfd_generic_bfd_copy_private_header_data
+
+#define vms_bfd_copy_private_bfd_data    _bfd_generic_bfd_copy_private_bfd_data
+#define vms_bfd_free_cached_info         _bfd_generic_bfd_free_cached_info
+#define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
+#define vms_bfd_copy_private_symbol_data  _bfd_generic_bfd_copy_private_symbol_data
+#define vms_bfd_set_private_flags         _bfd_generic_bfd_set_private_flags
+#define vms_bfd_merge_private_bfd_data    _bfd_generic_bfd_merge_private_bfd_data
+
+/* Symbols table.  */
+#define alpha_vms_make_empty_symbol        _bfd_generic_make_empty_symbol
+#define alpha_vms_bfd_is_target_special_symbol \
+   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define alpha_vms_print_symbol             vms_print_symbol
+#define alpha_vms_get_symbol_info          vms_get_symbol_info
+#define alpha_vms_read_minisymbols         _bfd_generic_read_minisymbols
+#define alpha_vms_minisymbol_to_symbol     _bfd_generic_minisymbol_to_symbol
+#define alpha_vms_get_lineno               _bfd_nosymbols_get_lineno
+#define alpha_vms_find_inliner_info        _bfd_nosymbols_find_inliner_info
+#define alpha_vms_bfd_make_debug_symbol    _bfd_nosymbols_bfd_make_debug_symbol
+#define alpha_vms_find_nearest_line        _bfd_vms_find_nearest_dst_line
+#define alpha_vms_bfd_is_local_label_name  vms_bfd_is_local_label_name
+
+/* Generic table.  */
+#define alpha_vms_close_and_cleanup       vms_close_and_cleanup
+#define alpha_vms_bfd_free_cached_info    vms_bfd_free_cached_info
+#define alpha_vms_new_section_hook        vms_new_section_hook
+#define alpha_vms_set_section_contents    _bfd_vms_set_section_contents
+#define alpha_vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+
+#define alpha_vms_bfd_get_relocated_section_contents \
+  bfd_generic_get_relocated_section_contents
+
+#define alpha_vms_bfd_relax_section bfd_generic_relax_section
+#define alpha_vms_bfd_gc_sections bfd_generic_gc_sections
+#define alpha_vms_bfd_merge_sections bfd_generic_merge_sections
+#define alpha_vms_bfd_is_group_section bfd_generic_is_group_section
+#define alpha_vms_bfd_discard_group bfd_generic_discard_group
+#define alpha_vms_section_already_linked \
+  _bfd_generic_section_already_linked
+
+#define alpha_vms_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define alpha_vms_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
+#define alpha_vms_bfd_link_just_syms _bfd_generic_link_just_syms
+#define alpha_vms_bfd_copy_link_hash_symbol_type \
+  _bfd_generic_copy_link_hash_symbol_type
+
+#define alpha_vms_bfd_link_split_section  _bfd_generic_link_split_section
+
+#define alpha_vms_get_dynamic_symtab_upper_bound \
+  _bfd_nodynamic_get_dynamic_symtab_upper_bound
+#define alpha_vms_canonicalize_dynamic_symtab \
+  _bfd_nodynamic_canonicalize_dynamic_symtab
+#define alpha_vms_get_dynamic_reloc_upper_bound \
+  _bfd_nodynamic_get_dynamic_reloc_upper_bound
+#define alpha_vms_canonicalize_dynamic_reloc \
+  _bfd_nodynamic_canonicalize_dynamic_reloc
+
+const bfd_target vms_alpha_vec =
+{
+  "vms-alpha",                 /* Name.  */
+  bfd_target_evax_flavour,
+  BFD_ENDIAN_LITTLE,           /* Data byte order is little.  */
+  BFD_ENDIAN_LITTLE,           /* Header byte order is little.  */
+
+  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+   | WP_TEXT | D_PAGED),       /* Object flags.  */
+  (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+   | SEC_READONLY | SEC_CODE | SEC_DATA
+   | SEC_HAS_CONTENTS | SEC_IN_MEMORY),                /* Sect flags.  */
+  0,                           /* symbol_leading_char.  */
+  ' ',                         /* ar_pad_char.  */
+  15,                          /* ar_max_namelen.  */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+  bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+  bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+
+  {_bfd_dummy_target, alpha_vms_object_p,      /* bfd_check_format.  */
+   _bfd_vms_lib_alpha_archive_p, _bfd_dummy_target},
+  {bfd_false, alpha_vms_mkobject,              /* bfd_set_format.  */
+   _bfd_vms_lib_mkarchive, bfd_false},
+  {bfd_false, alpha_vms_write_object_contents, /* bfd_write_contents.  */
+   _bfd_vms_lib_write_archive_contents, bfd_false},
+
+  BFD_JUMP_TABLE_GENERIC (alpha_vms),
+  BFD_JUMP_TABLE_COPY (vms),
+  BFD_JUMP_TABLE_CORE (_bfd_nocore),
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib),
+  BFD_JUMP_TABLE_SYMBOLS (alpha_vms),
+  BFD_JUMP_TABLE_RELOCS (alpha_vms),
+  BFD_JUMP_TABLE_WRITE (alpha_vms),
+  BFD_JUMP_TABLE_LINK (alpha_vms),
+  BFD_JUMP_TABLE_DYNAMIC (alpha_vms),
+
+  NULL,
+
+  (PTR) 0
+};
diff --git a/bfd/vms-gsd.c b/bfd/vms-gsd.c
deleted file mode 100644 (file)
index d0ffd78..0000000
+++ /dev/null
@@ -1,1082 +0,0 @@
-/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and
-   EVAX (openVMS/Alpha) files.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2007, 2009 Free Software Foundation, Inc.
-
-   GSD record handling functions
-   EGSD record handling functions
-
-   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
-   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,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   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., 51 Franklin Street - Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
-
-#include "sysdep.h"
-#include "bfd.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "vms.h"
-
-/* Typical sections for vax object files.  */
-
-#define VAX_CODE_NAME          "$CODE"
-#define VAX_DATA_NAME          "$DATA"
-#define VAX_ADDRESS_DATA_NAME  "$ADDRESS_DATA"
-
-/* Typical sections for evax object files.  */
-
-#define EVAX_ABS_NAME          "$ABS$"
-#define EVAX_CODE_NAME         "$CODE$"
-#define EVAX_LINK_NAME         "$LINK$"
-#define EVAX_DATA_NAME         "$DATA$"
-#define EVAX_BSS_NAME          "$BSS$"
-#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
-#define EVAX_READONLY_NAME     "$READONLY$"
-#define EVAX_LITERAL_NAME      "$LITERAL$"
-#define EVAX_LITERALS_NAME     "$LITERALS"
-#define EVAX_COMMON_NAME       "$COMMON$"
-#define EVAX_LOCAL_NAME                "$LOCAL$"
-
-struct sec_flags_struct
-{
-  char *name;                  /* Name of section.  */
-  int vflags_always;
-  flagword flags_always;       /* Flags we set always.  */
-  int vflags_hassize;
-  flagword flags_hassize;      /* Flags we set if the section has a size > 0.  */
-};
-
-/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible.  */
-
-static struct sec_flags_struct vax_section_flags[] =
-  {
-    { VAX_CODE_NAME,
-      (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR | GPS_S_M_EXE | GPS_S_M_RD),
-      (SEC_CODE),
-      (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR | GPS_S_M_EXE | GPS_S_M_RD),
-      (SEC_IN_MEMORY | SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { VAX_DATA_NAME,
-      (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT),
-      (SEC_DATA),
-      (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { VAX_ADDRESS_DATA_NAME,
-      (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD),
-      (SEC_DATA | SEC_READONLY),
-      (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
-    { NULL,
-      (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL | GPS_S_M_RD | GPS_S_M_WRT),
-      (SEC_DATA),
-      (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL | GPS_S_M_RD | GPS_S_M_WRT),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }
-  };
-
-/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible.  */
-
-static struct sec_flags_struct evax_section_flags[] =
-  {
-    { EVAX_ABS_NAME,
-      (EGPS_S_V_SHR),
-      (SEC_DATA),
-      (EGPS_S_V_SHR),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { EVAX_CODE_NAME,
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_EXE),
-      (SEC_CODE),
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_EXE),
-      (SEC_IN_MEMORY | SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { EVAX_LITERAL_NAME,
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD | EGPS_S_V_NOMOD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
-    { EVAX_LINK_NAME,
-      (EGPS_S_V_REL | EGPS_S_V_RD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS_S_V_REL | EGPS_S_V_RD),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
-    { EVAX_DATA_NAME,
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD),
-      (SEC_DATA),
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { EVAX_BSS_NAME,
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD),
-      (SEC_NO_FLAGS),
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD),
-      (SEC_IN_MEMORY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { EVAX_READONLYADDR_NAME,
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_RD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_RD),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
-    { EVAX_READONLY_NAME,
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD | EGPS_S_V_NOMOD),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
-    { EVAX_LOCAL_NAME,
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
-      (SEC_DATA),
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
-    { EVAX_LITERALS_NAME,
-      (EGPS_S_V_PIC | EGPS_S_V_OVR),
-      (SEC_DATA | SEC_READONLY),
-      (EGPS_S_V_PIC | EGPS_S_V_OVR),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
-    { NULL,
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
-      (SEC_DATA),
-      (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
-      (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }
-  };
-
-/* Retrieve bfd section flags by name and size.  */
-
-static flagword
-vms_secflag_by_name (bfd *abfd,
-                    struct sec_flags_struct *section_flags,
-                    char *name,
-                    int hassize)
-{
-  int i = 0;
-
-  while (section_flags[i].name != NULL)
-    {
-      if ((PRIV (is_vax)?
-          strcasecmp (name, section_flags[i].name):
-          strcmp (name, section_flags[i].name)) == 0)
-       {
-         if (hassize)
-           return section_flags[i].flags_hassize;
-         else
-           return section_flags[i].flags_always;
-       }
-      i++;
-    }
-  if (hassize)
-    return section_flags[i].flags_hassize;
-  return section_flags[i].flags_always;
-}
-
-/* Retrieve vms section flags by name and size.  */
-
-static flagword
-vms_esecflag_by_name (struct sec_flags_struct *section_flags,
-                     char *name,
-                     int hassize)
-{
-  int i = 0;
-
-  while (section_flags[i].name != NULL)
-    {
-      if (strcmp (name, section_flags[i].name) == 0)
-       {
-         if (hassize)
-           return section_flags[i].vflags_hassize;
-         else
-           return section_flags[i].vflags_always;
-       }
-      i++;
-    }
-  if (hassize)
-    return section_flags[i].vflags_hassize;
-  return section_flags[i].vflags_always;
-}
-
-#if VMS_DEBUG
-
-struct flagdescstruct { const char *name; flagword value; };
-
-static const struct flagdescstruct gpsflagdesc[] =
-{
-  { "PIC", GPS_S_M_PIC },
-  { "LIB", GPS_S_M_LIB },
-  { "OVR", GPS_S_M_OVR },
-  { "REL", GPS_S_M_REL },
-  { "GBL", GPS_S_M_GBL },
-  { "SHR", GPS_S_M_SHR },
-  { "EXE", GPS_S_M_EXE },
-  { "RD",  GPS_S_M_RD },
-  { "WRT", GPS_S_M_WRT },
-  { "VEC", GPS_S_M_VEC },
-  { "NOMOD", EGPS_S_V_NOMOD },
-  { "COM", EGPS_S_V_COM },
-  { NULL, 0 }
-};
-
-static const struct flagdescstruct gsyflagdesc[] =
-{
-  { "WEAK", GSY_S_M_WEAK },
-  { "DEF",  GSY_S_M_DEF },
-  { "UNI",  GSY_S_M_UNI },
-  { "REL",  GSY_S_M_REL },
-  { "COMM", EGSY_S_V_COMM },
-  { "VECEP", EGSY_S_V_VECEP },
-  { "NORM", EGSY_S_V_NORM },
-  { NULL, 0 }
-};
-
-static char *flag2str (struct flagdescstruct *, flagword);
-
-/* Convert flag to printable string.  */
-
-static char *
-flag2str (struct flagdescstruct * flagdesc, flagword flags)
-{
-  static char res[64];
-  int next = 0;
-
-  res[0] = 0;
-  while (flagdesc->name != NULL)
-    {
-      if ((flags & flagdesc->value) != 0)
-       {
-         if (next)
-           strcat (res, ",");
-         else
-           next = 1;
-         strcat (res, flagdesc->name);
-       }
-      flagdesc++;
-    }
-  return res;
-}
-#endif
-
-/* Input routines.  */
-
-static int register_universal_symbol (bfd *abfd, asymbol *symbol,
-                                     int vms_flags);
-
-/* Process GSD/EGSD record
-   return 0 on success, -1 on error.  */
-
-int
-_bfd_vms_slurp_gsd (bfd * abfd, int objtype)
-{
-  int gsd_type, gsd_size;
-  asection *section;
-  unsigned char *vms_rec;
-  flagword new_flags, old_flags;
-  char *name;
-  asymbol *symbol;
-  vms_symbol_entry *entry;
-  unsigned long base_addr;
-  unsigned long align_addr;
-  static unsigned int psect_idx = 0;
-
-#if VMS_DEBUG
-  vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);
-#endif
-
-  switch (objtype)
-    {
-    case EOBJ_S_C_EGSD:
-      PRIV (vms_rec) += 8;     /* Skip type, size, l_temp.  */
-      PRIV (rec_size) -= 8;
-      break;
-    case OBJ_S_C_GSD:
-      PRIV (vms_rec) += 1;
-      PRIV (rec_size) -= 1;
-      break;
-    default:
-      return -1;
-    }
-
-  /* Calculate base address for each section.  */
-  base_addr = 0L;
-
-  abfd->symcount = 0;
-
-  while (PRIV (rec_size) > 0)
-    {
-      vms_rec = PRIV (vms_rec);
-
-      if (objtype == OBJ_S_C_GSD)
-       gsd_type = vms_rec[0];
-      else
-       {
-         _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
-         gsd_type += EVAX_OFFSET;
-       }
-
-#if VMS_DEBUG
-      vms_debug (3, "gsd_type %d\n", gsd_type);
-#endif
-
-      switch (gsd_type)
-       {
-       case GSD_S_C_PSC:
-         {
-           /* Program section definition.  */
-           asection *old_section = 0;
-
-#if VMS_DEBUG
-           vms_debug (4, "GSD_S_C_PSC\n");
-#endif
-           /* If this section isn't a bfd section.  */
-           if (PRIV (is_vax) && (psect_idx < (abfd->section_count - 1)))
-             {
-               /* Check for temporary section from TIR record.  */
-               if (psect_idx < PRIV (section_count))
-                 old_section = PRIV (sections)[psect_idx];
-               else
-                 old_section = 0;
-             }
-
-           name = _bfd_vms_save_counted_string (vms_rec + 8);
-           section = bfd_make_section (abfd, name);
-           if (!section)
-             {
-               (*_bfd_error_handler) (_("bfd_make_section (%s) failed"),
-                                      name);
-               return -1;
-             }
-           old_flags = bfd_getl16 (vms_rec + 2);
-           section->size = bfd_getl32 (vms_rec + 4);  /* allocation */
-           new_flags = vms_secflag_by_name (abfd, vax_section_flags, name,
-                                            section->size > 0);
-           if (old_flags & EGPS_S_V_REL)
-             new_flags |= SEC_RELOC;
-           if (old_flags & GPS_S_M_OVR)
-             new_flags |= SEC_IS_COMMON;
-           if (!bfd_set_section_flags (abfd, section, new_flags))
-             {
-               (*_bfd_error_handler)
-                 (_("bfd_set_section_flags (%s, %x) failed"),
-                  name, new_flags);
-               return -1;
-             }
-           section->alignment_power = vms_rec[1];
-           align_addr = (1 << section->alignment_power);
-           if ((base_addr % align_addr) != 0)
-             base_addr += (align_addr - (base_addr % align_addr));
-           section->vma = (bfd_vma)base_addr;
-           base_addr += section->size;
-
-           /* Global section is common symbol.  */
-           if (old_flags & GPS_S_M_GBL)
-             {
-               entry = _bfd_vms_enter_symbol (abfd, name);
-               if (entry == NULL)
-                 {
-                   bfd_set_error (bfd_error_no_memory);
-                   return -1;
-                 }
-               symbol = entry->symbol;
-
-               symbol->value = 0;
-               symbol->section = section;
-               symbol->flags = (BSF_GLOBAL | BSF_SECTION_SYM | BSF_OLD_COMMON);
-             }
-
-           /* Copy saved contents if old_section set.  */
-           if (old_section != 0)
-             {
-               section->contents = old_section->contents;
-               if (section->size < old_section->size)
-                 {
-                   (*_bfd_error_handler)
-                     (_("Size mismatch section %s=%lx, %s=%lx"),
-                      old_section->name,
-                      (unsigned long) old_section->size,
-                      section->name,
-                      (unsigned long) section->size);
-                   return -1;
-                 }
-               else if (section->size > old_section->size)
-                 {
-                   section->contents = bfd_realloc (old_section->contents,
-                                                    section->size);
-                   if (section->contents == NULL)
-                     {
-                       bfd_set_error (bfd_error_no_memory);
-                       return -1;
-                     }
-                 }
-             }
-           else
-             {
-               section->contents = bfd_zmalloc (section->size);
-               if (section->contents == NULL)
-                 {
-                   bfd_set_error (bfd_error_no_memory);
-                   return -1;
-                 }
-             }
-#if VMS_DEBUG
-           vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
-                      section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
-           vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
-                      section->size, section->vma, section->contents);
-#endif
-
-           gsd_size = vms_rec[8] + 9;
-
-           psect_idx++;
-         }
-         break;
-
-       case GSD_S_C_EPM:
-       case GSD_S_C_EPMW:
-#if VMS_DEBUG
-         vms_debug (4, "gsd epm\n");
-#endif
-         /* Fall through.  */
-       case GSD_S_C_SYM:
-       case GSD_S_C_SYMW:
-         {
-           int name_offset = 0, value_offset = 0;
-
-           /* Symbol specification (definition or reference).  */
-#if VMS_DEBUG
-           vms_debug (4, "GSD_S_C_SYM(W)\n");
-#endif
-           old_flags = bfd_getl16 (vms_rec + 2);
-           new_flags = BSF_NO_FLAGS;
-
-           if (old_flags & GSY_S_M_WEAK)
-             new_flags |= BSF_WEAK;
-
-           switch (gsd_type)
-             {
-             case GSD_S_C_EPM:
-               name_offset = 11;
-               value_offset = 5;
-               new_flags |= BSF_FUNCTION;
-               break;
-             case GSD_S_C_EPMW:
-               name_offset = 12;
-               value_offset = 6;
-               new_flags |= BSF_FUNCTION;
-               break;
-             case GSD_S_C_SYM:
-               if (old_flags & GSY_S_M_DEF)    /* Symbol definition.  */
-                 name_offset = 9;
-               else
-                 name_offset = 4;
-               value_offset = 5;
-               break;
-             case GSD_S_C_SYMW:
-               if (old_flags & GSY_S_M_DEF)    /* Symbol definition.  */
-                 name_offset = 10;
-               else
-                 name_offset = 5;
-               value_offset = 6;
-               break;
-             }
-
-           /* Save symbol in vms_symbol_table.  */
-           entry = _bfd_vms_enter_symbol
-             (abfd, _bfd_vms_save_counted_string (vms_rec + name_offset));
-           if (entry == NULL)
-             {
-               bfd_set_error (bfd_error_no_memory);
-               return -1;
-             }
-           symbol = entry->symbol;
-
-           if (old_flags & GSY_S_M_DEF)
-             {
-               /* Symbol definition.  */
-               int psect;
-
-               symbol->value = bfd_getl32 (vms_rec + value_offset);
-               if ((gsd_type == GSD_S_C_SYMW)
-                   || (gsd_type == GSD_S_C_EPMW))
-                 psect = bfd_getl16 (vms_rec + value_offset - 2);
-               else
-                 psect = vms_rec[value_offset-1];
-
-               symbol->section = (asection *)(unsigned long)psect;
-#if VMS_DEBUG
-               vms_debug (4, "gsd sym def #%d (%s, %ld, %04x=%s)\n", abfd->symcount,
-                         symbol->name, (long)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
-#endif
-             }
-           else
-             {
-               /* Symbol reference.  */
-#if VMS_DEBUG
-               vms_debug (4, "gsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
-                          symbol->name, old_flags, flag2str (gsyflagdesc, old_flags));
-#endif
-               symbol->section = (asection *)(unsigned long)-1;
-             }
-
-           gsd_size = vms_rec[name_offset] + name_offset + 1;
-           symbol->flags = new_flags;
-         }
-
-         break;
-
-       case GSD_S_C_PRO:
-       case GSD_S_C_PROW:
-#if VMS_DEBUG
-         vms_debug (4, "gsd pro\n");
-#endif
-         break;
-       case GSD_S_C_IDC:
-#if VMS_DEBUG
-         vms_debug (4, "gsd idc\n");
-#endif
-         break;
-       case GSD_S_C_ENV:
-#if VMS_DEBUG
-         vms_debug (4, "gsd env\n");
-#endif
-         break;
-       case GSD_S_C_LSY:
-#if VMS_DEBUG
-         vms_debug (4, "gsd lsy\n");
-#endif
-         break;
-       case GSD_S_C_LEPM:
-#if VMS_DEBUG
-         vms_debug (4, "gsd lepm\n");
-#endif
-         break;
-       case GSD_S_C_LPRO:
-#if VMS_DEBUG
-         vms_debug (4, "gsd lpro\n");
-#endif
-         break;
-       case GSD_S_C_SPSC:
-#if VMS_DEBUG
-         vms_debug (4, "gsd spsc\n");
-#endif
-         break;
-       case GSD_S_C_SYMV:
-#if VMS_DEBUG
-         vms_debug (4, "gsd symv\n");
-#endif
-         break;
-       case GSD_S_C_EPMV:
-#if VMS_DEBUG
-         vms_debug (4, "gsd epmv\n");
-#endif
-         break;
-       case GSD_S_C_PROV:
-#if VMS_DEBUG
-         vms_debug (4, "gsd prov\n");
-#endif
-         break;
-
-       case EGSD_S_C_PSC + EVAX_OFFSET:
-         {
-           /* Program section definition.  */
-           name = _bfd_vms_save_counted_string (vms_rec + EGPS_S_B_NAMLNG);
-           section = bfd_make_section (abfd, name);
-           if (!section)
-             return -1;
-           old_flags = bfd_getl16 (vms_rec + EGPS_S_W_FLAGS);
-           section->size = bfd_getl32 (vms_rec + EGPS_S_L_ALLOC);
-           new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
-                                            section->size > 0);
-           if (old_flags & EGPS_S_V_REL)
-             new_flags |= SEC_RELOC;
-           if (!bfd_set_section_flags (abfd, section, new_flags))
-             return -1;
-           section->alignment_power = vms_rec[EGPS_S_B_ALIGN];
-           align_addr = (1 << section->alignment_power);
-           if ((base_addr % align_addr) != 0)
-             base_addr += (align_addr - (base_addr % align_addr));
-           section->vma = (bfd_vma)base_addr;
-           base_addr += section->size;
-           section->contents = bfd_zmalloc (section->size);
-           if (section->contents == NULL)
-             return -1;
-           section->filepos = (unsigned int)-1;
-#if VMS_DEBUG
-           vms_debug (4, "EGSD P-section %d (%s, flags %04x=%s) ",
-                      section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
-           vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
-                      section->size, section->vma, section->contents);
-#endif
-         }
-         break;
-
-       case EGSD_S_C_SYM + EVAX_OFFSET:
-         {
-           /* Global symbol specification (definition or reference).  */
-           symbol = bfd_make_empty_symbol (abfd);
-           if (symbol == 0)
-             return -1;
-
-           old_flags = bfd_getl16 (vms_rec + EGSY_S_W_FLAGS);
-           new_flags = BSF_NO_FLAGS;
-
-           if (old_flags & EGSY_S_V_WEAK)
-             new_flags |= BSF_WEAK;
-
-           if (old_flags & EGSY_S_V_DEF)
-             {
-               /* Symbol definition.  */
-               if (old_flags & EGSY_S_V_NORM)
-                 new_flags |= BSF_FUNCTION;
-               symbol->name =
-                 _bfd_vms_save_counted_string (vms_rec + ESDF_S_B_NAMLNG);
-               symbol->value = bfd_getl64 (vms_rec + ESDF_S_L_VALUE);
-               symbol->section =
-                 (asection *)(unsigned long) bfd_getl32 (vms_rec + ESDF_S_L_PSINDX);
-#if VMS_DEBUG
-               vms_debug (4, "EGSD sym def #%d (%s, %ld, %04x=%s)\n",
-                          abfd->symcount, symbol->name, (long)symbol->section,
-                          old_flags, flag2str (gsyflagdesc, old_flags));
-#endif
-             }
-           else
-             {
-               /* Symbol reference.  */
-               symbol->name =
-                 _bfd_vms_save_counted_string (vms_rec + ESRF_S_B_NAMLNG);
-#if VMS_DEBUG
-               vms_debug (4, "EGSD sym ref #%d (%s, %04x=%s)\n",
-                          abfd->symcount, symbol->name, old_flags,
-                          flag2str (gsyflagdesc, old_flags));
-#endif
-               symbol->section = (asection *)(unsigned long)-1;
-             }
-
-           symbol->flags = new_flags;
-
-           /* Register symbol in VMS symbol table.  */
-           entry = (vms_symbol_entry *) bfd_hash_lookup
-             (PRIV (vms_symbol_table), symbol->name, TRUE, FALSE);
-
-           if (entry == NULL)
-             {
-               bfd_set_error (bfd_error_no_memory);
-               return -1;
-             }
-
-           if (entry->symbol != NULL)
-             {
-               /* FIXME ?, DEC C generates this.  */
-#if VMS_DEBUG
-               vms_debug (4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
-#endif
-             }
-           else
-             {
-               entry->symbol = symbol;
-               PRIV (gsd_sym_count)++;
-               abfd->symcount++;
-             }
-         }
-         break;
-
-       case EGSD_S_C_SYMG + EVAX_OFFSET:
-         {
-           /* Universal symbol specification (definition).  */
-           symbol = bfd_make_empty_symbol (abfd);
-           if (symbol == 0)
-             return -1;
-
-           old_flags = bfd_getl16 (vms_rec + EGST_S_W_FLAGS);
-           new_flags = BSF_NO_FLAGS;
-
-           if (old_flags & EGSY_S_V_WEAK)
-             new_flags |= BSF_WEAK;
-
-           if (old_flags & EGSY_S_V_DEF) /* symbol definition */
-             {
-               if (old_flags & EGSY_S_V_NORM)
-                 new_flags |= BSF_FUNCTION;
-
-               symbol->name =
-                 _bfd_vms_save_counted_string (vms_rec + EGST_S_B_NAMLNG);
-
-               /* For BSF_FUNCTION symbols, the entry point is in LP_1
-                  and the descriptor in LP_2.  For other symbols, the
-                  unique value is in LP_2.  */
-               symbol->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_2);
-
-               /* Adding this offset is necessary in order for GDB to
-                  read the DWARF-2 debug info from shared libraries.  */
-               if (abfd->flags & DYNAMIC
-                   && strstr (symbol->name, "$DWARF2.DEBUG") != 0)
-                 symbol->value += PRIV (symvva);
-             }
-           else /* symbol reference */
-             (*_bfd_error_handler) ("Invalid EGST reference");
-
-           symbol->flags = new_flags;
-
-           if (register_universal_symbol (abfd, symbol, old_flags) < 0)
-             return -1;
-
-           /* Make a second symbol for the entry point.  */
-           if (symbol->flags & BSF_FUNCTION)
-             {
-               asymbol *en_sym;
-
-               name = bfd_alloc (abfd, strlen (symbol->name) + 5);
-
-               en_sym = bfd_make_empty_symbol (abfd);
-               if (en_sym == 0)
-                 return -1;
-
-               strcpy (name, symbol->name);
-               strcat (name, "..en");
-
-               en_sym->name = name;
-               en_sym->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_1);
-
-               if (register_universal_symbol (abfd, en_sym, old_flags) < 0)
-                 return -1;
-             }
-         }
-         break;
-
-       case EGSD_S_C_IDC + EVAX_OFFSET:
-         break;
-
-       default:
-         (*_bfd_error_handler) (_("Unknown GSD/EGSD subtype %d"), gsd_type);
-         bfd_set_error (bfd_error_bad_value);
-         return -1;
-       }
-
-      PRIV (rec_size) -= gsd_size;
-      PRIV (vms_rec) += gsd_size;
-    }
-
-  if (abfd->symcount > 0)
-    abfd->flags |= HAS_SYMS;
-
-  return 0;
-}
-
-/* Register a universal symbol in the VMS symbol table.  */
-
-static int
-register_universal_symbol (bfd *abfd, asymbol *symbol, int vms_flags)
-{
-  bfd_vma sbase = 0;
-  asection *s, *sec = NULL;
-  vms_symbol_entry *entry;
-
-  /* A universal symbol is by definition global...  */
-  symbol->flags |= BSF_GLOBAL;
-
-  /* ...and dynamic in shared libraries.  */
-  if (abfd->flags & DYNAMIC)
-    symbol->flags |= BSF_DYNAMIC;
-
-  /* Find containing section.  */
-  for (s = abfd->sections; s; s = s->next)
-    {
-      if (symbol->value >= s->vma
-         && s->vma > sbase
-         && !(s->flags & SEC_COFF_SHARED_LIBRARY)
-         && (s->size > 0 || !(vms_flags & EGSY_S_V_REL)))
-       {
-         sbase = s->vma;
-         sec = s;
-       }
-    }
-
-  symbol->value -= sbase;
-  symbol->section = sec;
-
-#if VMS_DEBUG
-  vms_debug (4, "EGST sym def #%d (%s, 0x%llx => 0x%llx, %04x=%s)\n",
-            abfd->symcount, symbol->name, symbol->value + sbase,
-            symbol->value, vms_flags,
-            flag2str(gsyflagdesc, vms_flags));
-#endif
-
-  entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
-                                               symbol->name,
-                                               TRUE, FALSE);
-
-  if (entry == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return -1;
-    }
-
-  if (entry->symbol) /* FIXME: DEC C generates this */
-    {
-#if VMS_DEBUG
-      vms_debug (4, "EGSD_S_C_SYMG: duplicate \"%s\"\n", symbol->name);
-#endif
-    }
-  else
-    {
-      entry->symbol = symbol;
-      PRIV (gsd_sym_count)++;
-      abfd->symcount++;
-    }
-
-  return 0;
-}
-
-/* Set section VMS flags.  */
-
-void
-bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
-                          asection *sec, flagword flags)
-{
-  vms_section_data (sec)->vflags = flags;
-}
-
-/* Write section and symbol directory of bfd abfd.  */
-
-int
-_bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
-{
-  asection *section;
-  asymbol *symbol;
-  unsigned int symnum;
-  int last_index = -1;
-  char dummy_name[10];
-  char *sname;
-  flagword new_flags, old_flags;
-  int abs_section_index = 0;
-
-#if VMS_DEBUG
-  vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
-#endif
-
-  /* Output sections.  */
-  section = abfd->sections;
-#if VMS_DEBUG
-  vms_debug (3, "%d sections found\n", abfd->section_count);
-#endif
-
-  /* Egsd is quadword aligned.  */
-  _bfd_vms_output_alignment (abfd, 8);
-
-  _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
-  _bfd_vms_output_long (abfd, 0);
-  /* Prepare output for subrecords.  */
-  _bfd_vms_output_push (abfd);
-
-  while (section != 0)
-    {
-#if VMS_DEBUG
-      vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size);
-#endif
-
-      /* Don't write out the VMS debug info section since it is in the
-         ETBT and EDBG sections in etir. */
-      if (!strcmp (section->name, ".vmsdebug"))
-        goto done;
-
-      /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
-      if (_bfd_vms_output_check (abfd, 64) < 0)
-       {
-         _bfd_vms_output_pop (abfd);
-         _bfd_vms_output_end (abfd);
-         _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
-         _bfd_vms_output_long (abfd, 0);
-         /* Prepare output for subrecords.  */
-         _bfd_vms_output_push (abfd);
-       }
-
-      /* Create dummy sections to keep consecutive indices.  */
-      while (section->index - last_index > 1)
-       {
-#if VMS_DEBUG
-         vms_debug (3, "index %d, last %d\n", section->index, last_index);
-#endif
-         _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
-         _bfd_vms_output_short (abfd, 0);
-         _bfd_vms_output_short (abfd, 0);
-         _bfd_vms_output_long (abfd, 0);
-         sprintf (dummy_name, ".DUMMY%02d", last_index);
-         _bfd_vms_output_counted (abfd, dummy_name);
-         _bfd_vms_output_flush (abfd);
-         last_index++;
-       }
-
-      /* Don't know if this is necessary for the linker but for now it keeps
-        vms_slurp_gsd happy  */
-      sname = (char *)section->name;
-      if (*sname == '.')
-       {
-         sname++;
-         if ((*sname == 't') && (strcmp (sname, "text") == 0))
-           sname = PRIV (is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
-         else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
-           sname = PRIV (is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
-         else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
-           sname = EVAX_BSS_NAME;
-         else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
-           sname = EVAX_LINK_NAME;
-         else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
-           sname = EVAX_READONLY_NAME;
-         else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
-           sname = EVAX_LITERAL_NAME;
-         else if ((*sname == 'l') && (strcmp (sname, "literals") == 0))
-           {
-             sname = EVAX_LITERALS_NAME;
-             abs_section_index = section->index;
-           }
-         else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
-           sname = EVAX_COMMON_NAME;
-         else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
-           sname = EVAX_LOCAL_NAME;
-       }
-      else
-       sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
-
-      _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
-      _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
-
-      if (bfd_is_com_section (section))
-       new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD
-                    | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM);
-      else
-       new_flags = vms_esecflag_by_name (evax_section_flags, sname,
-                                         section->size > 0);
-
-      /* Modify them as directed.  */
-      if (section->flags & SEC_READONLY)
-       new_flags &= ~EGPS_S_V_WRT;
-
-      new_flags |= vms_section_data (section)->vflags & 0xffff;
-      new_flags &=
-       ~((vms_section_data (section)->vflags >> EGPS_S_V_NO_SHIFT) & 0xffff);
-
-#if VMS_DEBUG
-      vms_debug (3, "sec flags %x\n", section->flags);
-      vms_debug (3, "new_flags %x, _raw_size %d\n", new_flags, section->size);
-#endif
-
-      _bfd_vms_output_short (abfd, new_flags);
-      _bfd_vms_output_long (abfd, (unsigned long) section->size);
-      _bfd_vms_output_counted (abfd, sname);
-      _bfd_vms_output_flush (abfd);
-
-      last_index = section->index;
-done:
-      section = section->next;
-    }
-
-  /* Output symbols.  */
-#if VMS_DEBUG
-  vms_debug (3, "%d symbols found\n", abfd->symcount);
-#endif
-
-  bfd_set_start_address (abfd, (bfd_vma) -1);
-
-  for (symnum = 0; symnum < abfd->symcount; symnum++)
-    {
-      char *hash;
-
-      symbol = abfd->outsymbols[symnum];
-      if (*(symbol->name) == '_')
-       {
-         if (strcmp (symbol->name, "__main") == 0)
-           bfd_set_start_address (abfd, (bfd_vma)symbol->value);
-       }
-      old_flags = symbol->flags;
-
-      if (old_flags & BSF_FILE)
-       continue;
-
-      if ((old_flags & BSF_GLOBAL) == 0                   /* Not xdef...  */
-         && !bfd_is_und_section (symbol->section) /* and not xref... */
-         && !((old_flags & BSF_SECTION_SYM) != 0  /* and not LIB$INITIALIZE.  */
-              && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
-       continue;
-
-      /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  */
-      if (_bfd_vms_output_check (abfd, 80) < 0)
-       {
-         _bfd_vms_output_pop (abfd);
-         _bfd_vms_output_end (abfd);
-         _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
-         _bfd_vms_output_long (abfd, 0);
-         /* Prepare output for subrecords.  */
-         _bfd_vms_output_push (abfd);
-       }
-
-      _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
-
-      /* Data type, alignment.  */
-      _bfd_vms_output_short (abfd, 0);
-
-      new_flags = 0;
-
-      if (old_flags & BSF_WEAK)
-       new_flags |= EGSY_S_V_WEAK;
-      if (bfd_is_com_section (symbol->section))                /* .comm  */
-       new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);
-
-      if (old_flags & BSF_FUNCTION)
-       {
-         new_flags |= EGSY_S_V_NORM;
-         new_flags |= EGSY_S_V_REL;
-       }
-      if (old_flags & BSF_GLOBAL)
-       {
-         new_flags |= EGSY_S_V_DEF;
-         if (!bfd_is_abs_section (symbol->section))
-           new_flags |= EGSY_S_V_REL;
-       }
-      _bfd_vms_output_short (abfd, new_flags);
-
-      if (old_flags & BSF_GLOBAL)
-       {
-         /* Symbol definition.  */
-         uquad code_address = 0;
-         unsigned long ca_psindx = 0;
-         unsigned long psindx;
-
-         if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
-           {
-             asymbol *sym;
-
-             if (bfd_get_flavour (abfd) == bfd_target_evax_flavour)
-               sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
-             else
-               sym = (asymbol *)symbol->udata.p;
-             code_address = sym->value;
-             ca_psindx = sym->section->index;
-           }
-         if (bfd_is_abs_section (symbol->section))
-           psindx = abs_section_index;
-         else
-           psindx = symbol->section->index;
-
-         _bfd_vms_output_quad (abfd, symbol->value);
-         _bfd_vms_output_quad (abfd, code_address);
-         _bfd_vms_output_long (abfd, ca_psindx);
-         _bfd_vms_output_long (abfd, psindx);
-       }
-      hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ);
-      _bfd_vms_output_counted (abfd, hash);
-
-      _bfd_vms_output_flush (abfd);
-
-    }
-
-  _bfd_vms_output_alignment (abfd, 8);
-  _bfd_vms_output_pop (abfd);
-  _bfd_vms_output_end (abfd);
-
-  return 0;
-}
diff --git a/bfd/vms-hdr.c b/bfd/vms-hdr.c
deleted file mode 100644 (file)
index 343f53e..0000000
+++ /dev/null
@@ -1,1382 +0,0 @@
-/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
-   EVAX (openVMS/Alpha) files.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
-   2007, 2008, 2009 Free Software Foundation, Inc.
-
-   HDR record handling functions
-   EMH record handling functions
-
-   EOM record handling functions
-   EEOM record handling functions
-
-   IHD record handling functions
-   EIHD record handling functions
-
-   ISD record handling functions
-   EISD record handling functions
-
-   IHS record handling functions
-   EIHS record handling functions
-
-   DBG record handling functions
-   EDBG record handling functions
-
-   TBT record handling functions
-   ETBT record handling functions
-
-   DST/DMT section handling functions
-
-   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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   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., 51 Franklin Street - Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
-
-#include "sysdep.h"
-#include "bfd.h"
-#include "bfdver.h"
-#include "bfdlink.h"
-#include "safe-ctype.h"
-#include "libbfd.h"
-
-#include "vms.h"
-
-static struct module *new_module (bfd *);
-static void parse_module
-  (bfd *, struct module *, unsigned char *, unsigned int);
-static struct module *build_module_list (bfd *);
-static bfd_boolean module_find_nearest_line
-  (bfd *, struct module *, bfd_vma, const char **, const char **,
-   unsigned int *);
-static int vms_slurp_debug (bfd *);
-
-#define SET_MODULE_PARSED(m) \
-  do { if ((m)->name == NULL) (m)->name = ""; } while (0)
-#define IS_MODULE_PARSED(m) ((m)->name != NULL)
-
-
-/* Read & process emh record
-   return 0 on success, -1 on error.  */
-
-int
-_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
-{
-  unsigned char *ptr;
-  unsigned char *vms_rec;
-  int subtype;
-
-  vms_rec = PRIV(vms_rec);
-
-#if VMS_DEBUG
-  vms_debug(2, "HDR/EMH\n");
-#endif
-
-  switch (objtype)
-    {
-    case OBJ_S_C_HDR:
-      subtype = vms_rec[1];
-      break;
-    case EOBJ_S_C_EMH:
-      subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
-      break;
-    default:
-      subtype = -1;
-    }
-
-#if VMS_DEBUG
-  vms_debug(3, "subtype %d\n", subtype);
-#endif
-
-  switch (subtype)
-    {
-    case MHD_S_C_MHD:
-      /* Module header.  */
-      PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
-      PRIV (hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
-      PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
-      ptr = vms_rec + 5 + vms_rec[5] + 1;
-      PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
-      ptr += *ptr + 1;
-      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
-      break;
-
-    case MHD_S_C_LNM:
-      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
-      break;
-
-    case MHD_S_C_SRC:
-      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
-      break;
-
-    case MHD_S_C_TTL:
-      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
-      break;
-
-    case EMH_S_C_MHD + EVAX_OFFSET:
-      /* Module header.  */
-      PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
-      PRIV (hdr_data).hdr_l_arch1  = bfd_getl32 (vms_rec + 8);
-      PRIV (hdr_data).hdr_l_arch2  = bfd_getl32 (vms_rec + 12);
-      PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
-      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20);
-      ptr = vms_rec + 20 + vms_rec[20] + 1;
-      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
-      ptr += *ptr + 1;
-      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
-      break;
-
-    case EMH_S_C_LNM + EVAX_OFFSET:
-      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
-      break;
-
-    case EMH_S_C_SRC + EVAX_OFFSET:
-      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
-      break;
-
-    case EMH_S_C_TTL + EVAX_OFFSET:
-      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
-      break;
-
-    case MHD_S_C_CPR:
-    case MHD_S_C_MTC:
-    case MHD_S_C_GTX:
-    case EMH_S_C_CPR + EVAX_OFFSET:
-    case EMH_S_C_MTC + EVAX_OFFSET:
-    case EMH_S_C_GTX + EVAX_OFFSET:
-      break;
-
-    default:
-      bfd_set_error (bfd_error_wrong_format);
-      return -1;
-    }
-
-  return 0;
-}
-
-/* Output routines.  */
-
-/* Manufacture a VMS like time on a unix based system.
-   stolen from obj-vms.c.  */
-
-static unsigned char *
-get_vms_time_string (void)
-{
-  static unsigned char tbuf[18];
-#ifndef VMS
-#include <time.h>
-
-  char *pnt;
-  time_t timeb;
-
-  time (& timeb);
-  pnt = ctime (&timeb);
-  pnt[3] = 0;
-  pnt[7] = 0;
-  pnt[10] = 0;
-  pnt[16] = 0;
-  pnt[24] = 0;
-  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
-          pnt + 8, pnt + 4, pnt + 20, pnt + 11);
-#else
-#include <starlet.h>
-  struct
-  {
-    int Size;
-    unsigned char *Ptr;
-  } Descriptor;
-  Descriptor.Size = 17;
-  Descriptor.Ptr = tbuf;
-  SYS$ASCTIM (0, &Descriptor, 0, 0);
-#endif /* not VMS */
-
-#if VMS_DEBUG
-  vms_debug (6, "vmstimestring:'%s'\n", tbuf);
-#endif
-
-  return tbuf;
-}
-
-/* Write object header for bfd abfd.  */
-
-int
-_bfd_vms_write_hdr (bfd *abfd, int objtype)
-{
-  asymbol *symbol;
-  unsigned int symnum;
-  int had_case = 0;
-  int had_file = 0;
-  char version [256];
-
-#if VMS_DEBUG
-  vms_debug (2, "vms_write_hdr (%p)\n", abfd);
-#endif
-
-  _bfd_vms_output_alignment (abfd, 2);
-
-  /* MHD.  */
-  if (objtype != OBJ_S_C_HDR)
-    {
-      _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
-      _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
-      _bfd_vms_output_long (abfd, 0);
-      _bfd_vms_output_long (abfd, 0);
-      _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
-    }
-
-  /* Create module name from filename.  */
-  if (bfd_get_filename (abfd) != 0)
-    {
-      char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
-      _bfd_vms_output_counted (abfd, module);
-      free (module);
-    }
-  else
-    _bfd_vms_output_counted (abfd, "NONAME");
-
-  _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
-  _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
-  _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
-  _bfd_vms_output_flush (abfd);
-
-  /* LMN.  */
-  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
-  snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
-  _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
-  _bfd_vms_output_flush (abfd);
-
-  /* SRC.  */
-  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
-
-  for (symnum = 0; symnum < abfd->symcount; symnum++)
-    {
-      symbol = abfd->outsymbols[symnum];
-
-      if (symbol->flags & BSF_FILE)
-       {
-         if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
-           {
-             PRIV (flag_hash_long_names) = symbol->name[6] - '0';
-             PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
-
-             if (had_file)
-               break;
-             had_case = 1;
-             continue;
-           }
-
-         _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
-                               (int) strlen (symbol->name));
-         if (had_case)
-           break;
-         had_file = 1;
-       }
-    }
-
-  if (symnum == abfd->symcount)
-    _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
-
-  _bfd_vms_output_flush (abfd);
-
-  /* TTL.  */
-  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
-  _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
-  _bfd_vms_output_flush (abfd);
-
-  /* CPR.  */
-  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
-  _bfd_vms_output_dump (abfd,
-                        (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
-                        39);
-  _bfd_vms_output_flush (abfd);
-
-  return 0;
-}
-
-/* Process EOM/EEOM record
-   return 0 on success, -1 on error.  */
-
-int
-_bfd_vms_slurp_eom (bfd *abfd, int objtype)
-{
-  unsigned char *vms_rec;
-
-#if VMS_DEBUG
-  vms_debug(2, "EOM/EEOM\n");
-#endif
-
-  vms_rec = PRIV (vms_rec);
-
-  if ((objtype == OBJ_S_C_EOM)
-     || (objtype == OBJ_S_C_EOMW))
-    {
-    }
-  else
-    {
-      PRIV (eom_data).eom_l_total_lps
-        = bfd_getl32 (vms_rec + EEOM_S_L_TOTAL_LPS);
-      PRIV (eom_data).eom_w_comcod = bfd_getl16 (vms_rec + EEOM_S_W_COMCOD);
-      if (PRIV (eom_data).eom_w_comcod > 1)
-       {
-         (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
-         bfd_set_error (bfd_error_bad_value);
-         return -1;
-       }
-      PRIV (eom_data).eom_has_transfer = FALSE;
-      if (PRIV (rec_size) > 10)
-       {
-          PRIV (eom_data).eom_has_transfer = TRUE;
-          PRIV (eom_data).eom_b_tfrflg = vms_rec[EEOM_S_B_TFRFLG];
-          PRIV (eom_data).eom_l_psindx
-            = bfd_getl32 (vms_rec + EEOM_S_L_PSINDX);
-          PRIV (eom_data).eom_l_tfradr
-            = bfd_getl32 (vms_rec + EEOM_S_L_TFRADR);
-
-          abfd->start_address = PRIV (eom_data).eom_l_tfradr;
-       }
-    }
-  return 0;
-}
-
-/* Write eom record for bfd abfd.  */
-
-int
-_bfd_vms_write_eom (bfd *abfd, int objtype)
-{
-#if VMS_DEBUG
-  vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
-#endif
-
-  _bfd_vms_output_begin (abfd, objtype, -1);
-  _bfd_vms_output_long (abfd, (unsigned long) (PRIV (vms_linkage_index) >> 1));
-  _bfd_vms_output_byte (abfd, 0);      /* Completion code.  */
-  _bfd_vms_output_byte (abfd, 0);      /* Fill byte.  */
-
-  if (bfd_get_start_address (abfd) != (bfd_vma)-1)
-    {
-      asection *section;
-
-      section = bfd_get_section_by_name (abfd, ".link");
-      if (section == 0)
-       {
-         bfd_set_error (bfd_error_nonrepresentable_section);
-         return -1;
-       }
-      _bfd_vms_output_short (abfd, 0);
-      _bfd_vms_output_long (abfd, (unsigned long) (section->index));
-      _bfd_vms_output_long (abfd,
-                            (unsigned long) bfd_get_start_address (abfd));
-      _bfd_vms_output_long (abfd, 0);
-    }
-
-  _bfd_vms_output_end (abfd);
-  return 0;
-}
-
-/* Read & process IHD/EIHD record.
-   Return 0 on success, -1 on error  */
-int
-_bfd_vms_slurp_ihd (bfd *abfd, unsigned int *isd_offset,
-                   unsigned int *ihs_offset)
-{
-  unsigned int imgtype, size;
-  bfd_vma symvva;
-
-#if VMS_DEBUG
-  vms_debug (8, "_bfd_vms_slurp_ihd\n");
-#endif
-
-  size = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
-  imgtype = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_IMGTYPE);
-
-  if (imgtype == EIHD_S_K_EXE)
-    abfd->flags |= EXEC_P;
-
-  symvva = bfd_getl64 (PRIV (vms_rec) + EIHD_S_Q_SYMVVA);
-  if (symvva != 0)
-    {
-      PRIV (symvva) = symvva;
-      abfd->flags |= DYNAMIC;
-    }
-
-  *isd_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_ISDOFF);
-  *ihs_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SYMDBGOFF);
-
-#if VMS_DEBUG
-  vms_debug (4, "EIHD record size %d imgtype %d symvva 0x%llx isd %d ihs %d\n",
-            size, imgtype, symvva, *isd_offset, *ihs_offset);
-#endif
-
-  return 0;
-}
-
-/* Read & process ISD/EISD record
-   return 0 on success, -1 on error  */
-
-int
-_bfd_vms_slurp_isd (bfd *abfd, unsigned int offset)
-{
-  int section_count = 0;
-  unsigned char *p;
-  unsigned int rec_size;
-
-#if VMS_DEBUG
-  vms_debug (8, "_bfd_vms_slurp_isd\n");
-#endif
-
-  for (p = PRIV (vms_rec) + offset;
-       (rec_size = bfd_getl32 (p + EISD_S_L_EISDSIZE)) != 0;
-       p += rec_size)
-    {
-      unsigned long long vaddr = bfd_getl64 (p + EISD_S_Q_VIR_ADDR);
-      unsigned int size = bfd_getl32 (p + EISD_S_L_SECSIZE);
-      unsigned int flags = bfd_getl32 (p + EISD_S_L_FLAGS);
-      unsigned int vbn = bfd_getl32 (p + EISD_S_L_VBN);
-      char *name = NULL;
-      asection *section;
-      flagword bfd_flags;
-
-#if VMS_DEBUG
-      vms_debug (4, "EISD record at 0x%x size 0x%x addr 0x%x bfd_flags 0x%x block %d\n",
-                p - PRIV (vms_rec), size, vaddr, flags, vbn);
-#endif
-
-      /* VMS combines psects from .obj files into isects in the .exe.  This
-        process doesn't preserve enough information to reliably determine
-        what's in each section without examining the data.  This is
-        especially true of DWARF debug sections.  */
-      bfd_flags = SEC_ALLOC;
-
-      if (flags & EISD_S_M_EXE)
-       bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
-
-      if (flags & EISD_S_M_NONSHRADR)
-       bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
-
-      if (!(flags & EISD_S_M_WRT))
-       bfd_flags |= SEC_READONLY;
-
-      if (flags & EISD_S_M_DZRO)
-       bfd_flags |= SEC_DATA;
-
-      if (flags & EISD_S_M_FIXUPVEC)
-       bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
-
-      if (flags & EISD_S_M_CRF)
-       bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
-
-      if (flags & EISD_S_M_GBL)
-       {
-         name = _bfd_vms_save_counted_string (p + EISD_S_T_GBLNAM);
-         bfd_flags |= SEC_COFF_SHARED_LIBRARY;
-         bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
-       }
-      else
-       {
-         name = (char*) bfd_alloc (abfd, 32);
-         sprintf (name, "$LOCAL_%03d$", section_count++);
-       }
-
-      section = bfd_make_section (abfd, name);
-
-      if (!section)
-       return -1;
-
-      section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : (unsigned int)-1;
-      section->size = size;
-      section->vma = vaddr;
-
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
-       return -1;
-    }
-
-  return 0;
-}
-
-/* Read & process IHS/EIHS record
-   return 0 on success, -1 on error  */
-int
-_bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset)
-{
-  unsigned char *p = PRIV (vms_rec) + offset;
-  unsigned int gstvbn = bfd_getl32 (p + EIHS_S_L_GSTVBN);
-  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS_S_L_GSTSIZE);
-  unsigned int dstvbn = bfd_getl32 (p + EIHS_S_L_DSTVBN);
-  unsigned int dstsize = bfd_getl32 (p + EIHS_S_L_DSTSIZE);
-  unsigned int dmtvbn = bfd_getl32 (p + EIHS_S_L_DMTVBN);
-  unsigned int dmtbytes = bfd_getl32 (p + EIHS_S_L_DMTBYTES);
-  asection *section;
-
-#if VMS_DEBUG
-  vms_debug (8, "_bfd_vms_slurp_ihs\n");
-  vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
-            gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
-#endif
-
-  if (dstvbn)
-    {
-      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
-
-      section = bfd_make_section (abfd, "$DST$");
-      if (!section)
-       return -1;
-
-      section->size = dstsize;
-      section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
-
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
-       return -1;
-
-      PRIV (dst_section) = section;
-      abfd->flags |= (HAS_DEBUG | HAS_LINENO);
-    }
-
-  if (dmtvbn)
-    {
-      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
-
-      section = bfd_make_section (abfd, "$DMT$");
-      if (!section)
-       return -1;
-
-      section->size = dmtbytes;
-      section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
-
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
-       return -1;
-    }
-
-  if (gstvbn)
-    {
-      flagword bfd_flags = SEC_HAS_CONTENTS;
-
-      section = bfd_make_section (abfd, "$GST$");
-      if (!section)
-       return -1;
-
-      if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return -1;
-       }
-
-      if (_bfd_vms_slurp_object_records (abfd) != 0)
-       return -1;
-
-      section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
-      section->size = bfd_tell (abfd) - section->filepos;
-
-      if (!bfd_set_section_flags (abfd, section, bfd_flags))
-       return -1;
-
-      abfd->flags |= HAS_SYMS;
-    }
-
-  return 0;
-}
-
-/* Build a new module for the specified BFD.  */
-
-static struct module *
-new_module (bfd *abfd)
-{
-  struct module *module
-    = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
-  module->file_table_count = 16; /* Arbitrary.  */
-  module->file_table
-    = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
-  return module;
-}
-
-/* Parse debug info for a module and internalize it.  */
-
-static void
-parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
-             unsigned int length)
-{
-  unsigned char *maxptr = ptr + length, *src_ptr, *pcl_ptr;
-  unsigned int prev_linum = 0, curr_linenum = 0;
-  bfd_vma prev_pc = 0, curr_pc = 0;
-  struct srecinfo *curr_srec, *srec;
-  struct lineinfo *curr_line, *line;
-  struct funcinfo *funcinfo;
-
-  /* Initialize tables with zero element.  */
-  curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
-  module->srec_table = curr_srec;
-
-  curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
-  module->line_table = curr_line;
-
-  while (ptr < maxptr)
-    {
-      /* The first byte is not counted in the recorded length.  */
-      int rec_length = bfd_getl16 (ptr) + 1;
-      int rec_type = bfd_getl16 (ptr + 2);
-
-#if VMS_DEBUG
-      _bfd_vms_debug (2, "DST record: length %d, type %d\n",
-                     rec_length, rec_type);
-#endif
-
-      switch (rec_type)
-       {
-       case DST_S_C_MODBEG:
-         module->name
-           = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
-
-         curr_pc = 0;
-         prev_pc = 0;
-         curr_linenum = 0;
-         prev_linum = 0;
-
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "module: %s\n", module->name);
-#endif
-         break;
-
-       case DST_S_C_MODEND:
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "end module\n");
-#endif
-         break;
-
-       case DST_S_C_RTNBEG:
-         funcinfo = (struct funcinfo *)
-           bfd_zalloc (abfd, sizeof (struct funcinfo));
-          funcinfo->name
-           = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
-         funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
-         funcinfo->next = module->func_table;
-         module->func_table = funcinfo;
-    
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "routine: %s at 0x%x\n",
-                         funcinfo->name, funcinfo->low);
-#endif
-         break;
-
-       case DST_S_C_RTNEND:
-         module->func_table->high = module->func_table->low
-           + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
-
-         if (module->func_table->high > module->high)
-           module->high = module->func_table->high;
-
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "end routine\n");
-#endif
-         break;
-
-       case DST_S_C_PROLOG:
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "prologue\n");
-#endif
-         break;
-
-       case DST_S_C_EPILOG:
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "epilog\n");
-#endif
-         break;
-
-       case DST_S_C_BLKBEG:
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "block\n");
-#endif
-         break;
-
-       case DST_S_C_BLKEND:
-#if VMS_DEBUG
-          _bfd_vms_debug (3, "end block\n");
-#endif
-         break;
-
-       case DST_S_C_SOURCE:
-         src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
-
-#if VMS_DEBUG
-         _bfd_vms_debug (3, "source info\n");
-#endif
-
-         while (src_ptr < ptr + rec_length)
-           {
-             int cmd = src_ptr[0], cmd_length, data;
-
-             switch (cmd)
-               {
-               case DST_S_C_SRC_DECLFILE:
-                 {
-                   unsigned int fileid
-                     = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
-                   char *filename
-                     = _bfd_vms_save_counted_string (src_ptr
-                         + DST_S_B_SRC_DF_FILENAME);
-
-                   while (fileid >= module->file_table_count)
-                     {
-                       module->file_table_count *= 2;
-                       module->file_table
-                         = bfd_realloc (module->file_table,
-                                        module->file_table_count
-                                          * sizeof (struct fileinfo));
-                     }
-
-                   module->file_table [fileid].name = filename;
-                   module->file_table [fileid].srec = 1;
-                   cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
-#if VMS_DEBUG
-                   _bfd_vms_debug (4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
-                                   fileid,
-                                   module->file_table [fileid].name);
-#endif
-                 }
-                 break;
-
-               case DST_S_C_SRC_DEFLINES_B:
-                 /* Perform the association and set the next higher index
-                    to the limit.  */
-                 data = src_ptr[DST_S_B_SRC_UNSBYTE];
-                 srec = (struct srecinfo *)
-                   bfd_zalloc (abfd, sizeof (struct srecinfo));
-                 srec->line = curr_srec->line + data;
-                 srec->srec = curr_srec->srec + data;
-                 srec->sfile = curr_srec->sfile;
-                 curr_srec->next = srec;
-                 curr_srec = srec;
-                 cmd_length = 2;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_B: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_DEFLINES_W:
-                 /* Perform the association and set the next higher index
-                    to the limit.  */
-                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
-                 srec = (struct srecinfo *)
-                   bfd_zalloc (abfd, sizeof (struct srecinfo));
-                 srec->line = curr_srec->line + data;
-                 srec->srec = curr_srec->srec + data,
-                 srec->sfile = curr_srec->sfile;
-                 curr_srec->next = srec;
-                 curr_srec = srec;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_W: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_INCRLNUM_B:
-                 data = src_ptr[DST_S_B_SRC_UNSBYTE];
-                 curr_srec->line += data;
-                 cmd_length = 2;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_SETFILE:
-                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
-                 curr_srec->sfile = data;
-                 curr_srec->srec = module->file_table[data].srec;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_SETFILE: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_SETLNUM_L:
-                 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
-                 curr_srec->line = data;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_L: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_SETLNUM_W:
-                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
-                 curr_srec->line = data;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_W: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_SETREC_L:
-                 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
-                 curr_srec->srec = data;
-                 module->file_table[curr_srec->sfile].srec = data;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_L: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_SETREC_W:
-                 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
-                 curr_srec->srec = data;
-                 module->file_table[curr_srec->sfile].srec = data;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_W: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SRC_FORMFEED:
-                 cmd_length = 1;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SRC_FORMFEED\n");
-#endif
-                 break;
-
-               default:
-                 (*_bfd_error_handler) (_("unknown source command %d"),
-                                        cmd);
-                 cmd_length = 2;
-                 break;
-               }
-
-             src_ptr += cmd_length;
-           }
-         break;
-
-       case DST_S_C_LINE_NUM:
-         pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
-
-#if VMS_DEBUG
-         _bfd_vms_debug (3, "line info\n");
-#endif
-
-         while (pcl_ptr < ptr + rec_length)
-           {
-             /* The command byte is signed so we must sign-extend it.  */
-             int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
-
-             switch (cmd)
-               {
-               case DST_S_C_DELTA_PC_W:
-                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
-                 curr_pc += data;
-                 curr_linenum += 1;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_DELTA_PC_W: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_DELTA_PC_L:
-                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
-                 curr_pc += data;
-                 curr_linenum += 1;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_DELTA_PC_L: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_INCR_LINUM:
-                 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
-                 curr_linenum += data;
-                 cmd_length = 2;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_INCR_LINUM: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_INCR_LINUM_W:
-                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
-                 curr_linenum += data;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_W: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_INCR_LINUM_L:
-                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
-                 curr_linenum += data;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_L: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SET_LINUM_INCR:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_SET_LINUM_INCR not implemented"));
-                 cmd_length = 2;
-                 break;
-
-               case DST_S_C_SET_LINUM_INCR_W:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_SET_LINUM_INCR_W not implemented"));
-                 cmd_length = 3;
-                 break;
-
-               case DST_S_C_RESET_LINUM_INCR:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_RESET_LINUM_INCR not implemented"));
-                 cmd_length = 1;
-                 break;
-
-               case DST_S_C_BEG_STMT_MODE:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_BEG_STMT_MODE not implemented"));
-                 cmd_length = 1;
-                 break;
-
-               case DST_S_C_END_STMT_MODE:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_END_STMT_MODE not implemented"));
-                 cmd_length = 1;
-                 break;
-
-               case DST_S_C_SET_LINUM_B:
-                 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
-                 curr_linenum = data;
-                 cmd_length = 2;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SET_LINUM_B: %d\n", data);
-#endif
-                 break;
-       
-               case DST_S_C_SET_LINE_NUM:
-                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
-                 curr_linenum = data;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SET_LINE_NUM: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SET_LINUM_L:
-                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
-                 curr_linenum = data;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SET_LINUM_L: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SET_PC:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_SET_PC not implemented"));
-                 cmd_length = 2;
-                 break;
-
-               case DST_S_C_SET_PC_W:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_SET_PC_W not implemented"));
-                 cmd_length = 3;
-                 break;
-
-               case DST_S_C_SET_PC_L:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_SET_PC_L not implemented"));
-                 cmd_length = 5;
-                 break;
-
-               case DST_S_C_SET_STMTNUM:
-                 (*_bfd_error_handler)
-                   (_("DST_S_C_SET_STMTNUM not implemented"));
-                 cmd_length = 2;
-                 break;
-
-               case DST_S_C_TERM:
-                 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
-                 curr_pc += data;
-                 cmd_length = 2;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_TERM: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_TERM_W:
-                 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
-                 curr_pc += data;
-                 cmd_length = 3;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_TERM_W: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_TERM_L:
-                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
-                 curr_pc += data;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_TERM_L: %d\n", data);
-#endif
-                 break;
-
-               case DST_S_C_SET_ABS_PC:
-                 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
-                 curr_pc = data;
-                 cmd_length = 5;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "DST_S_C_SET_ABS_PC: 0x%x\n", data);
-#endif
-                 break;
-
-               default:
-                 if (cmd <= 0)
-                   {
-                     curr_pc -= cmd;
-                     curr_linenum += 1;
-                     cmd_length = 1;
-#if VMS_DEBUG
-                     _bfd_vms_debug (4, "bump pc to 0x%llx and line to %d\n",
-                                     curr_pc, curr_linenum);
-#endif
-                   }
-                 else
-                   {
-                     (*_bfd_error_handler) (_("unknown line command %d"),
-                                            cmd);
-                     cmd_length = 2;
-                   }
-                 break;
-               }
-
-             if ((curr_linenum != prev_linum && curr_pc != prev_pc)
-                 || cmd <= 0
-                 || cmd == DST_S_C_DELTA_PC_L
-                 || cmd == DST_S_C_DELTA_PC_W)
-               {
-                 line = (struct lineinfo *)
-                   bfd_zalloc (abfd, sizeof (struct lineinfo));
-                 line->address = curr_pc;
-                 line->line = curr_linenum;
-
-                 curr_line->next = line;
-                 curr_line = line;
-
-                 prev_linum = curr_linenum;
-                 prev_pc = curr_pc;
-#if VMS_DEBUG
-                 _bfd_vms_debug (4, "-> correlate pc 0x%llx with line %d\n",
-                                 curr_pc, curr_linenum);
-#endif
-               }
-
-             pcl_ptr += cmd_length;
-           }
-         break;
-
-       case 0x17: /* Undocumented type used by DEC C to declare equates.  */
-#if VMS_DEBUG
-         _bfd_vms_debug (3, "undocumented type 0x17\n");
-#endif
-         break;
-
-       default:
-#if VMS_DEBUG
-         _bfd_vms_debug (3, "ignoring record\n");
-#endif
-         break;
-
-       }
-
-      ptr += rec_length;
-    }
-
-  /* Finalize tables with EOL marker.  */
-  srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
-  srec->line = (unsigned int) -1;
-  srec->srec = (unsigned int) -1;
-  curr_srec->next = srec;
-
-  line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
-  line->line = (unsigned int) -1;
-  line->address = (bfd_vma) -1;
-  curr_line->next = line;
-
-  /* Advertise that this module has been parsed.  This is needed
-     because parsing can be either performed at module creation
-     or deferred until debug info is consumed.  */
-  SET_MODULE_PARSED (module);
-}
-
-/* Build the list of modules for the specified BFD.  */
-
-static struct module *
-build_module_list (bfd *abfd)
-{
-  struct module *module, *list = NULL;
-  asection *dmt;
-
-  if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
-    {
-      /* We have a DMT section so this must be an image.  Parse the
-        section and build the list of modules.  This is sufficient
-        since we can compute the start address and the end address
-        of every module from the section contents.  */
-      bfd_size_type size = bfd_get_section_size (dmt);
-      unsigned char *ptr, *end;
-
-      ptr = (unsigned char *) bfd_alloc (abfd, size);
-      if (! ptr)
-       return NULL;
-
-      if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
-       return NULL;
-
-#if VMS_DEBUG
-      _bfd_vms_debug (2, "DMT\n");
-#endif
-
-      end = ptr + size;
-
-      while (ptr < end)
-       {
-         /* Each header declares a module with its start offset and size
-            of debug info in the DST section, as well as the count of
-            program sections (i.e. address spans) it contains.  */
-         int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
-         int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
-         int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
-         ptr += DBG_S_C_DMT_HEADER_SIZE;
-
-#if VMS_DEBUG
-         _bfd_vms_debug (3, "module: modbeg = %d, size = %d, count = %d\n",
-                         modbeg, msize, count);
-#endif
-
-         /* We create a 'module' structure for each program section since
-            we only support contiguous addresses in a 'module' structure.
-            As a consequence, the actual debug info in the DST section is
-            shared and can be parsed multiple times; that doesn't seem to
-            cause problems in practice.  */
-         while (count-- > 0)
-           {
-             int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
-             int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
-             module = new_module (abfd);
-             module->modbeg = modbeg;
-             module->size = msize;
-             module->low = start;
-             module->high = start + length;
-             module->next = list;
-             list = module;
-             ptr += DBG_S_C_DMT_PSECT_SIZE;
-
-#if VMS_DEBUG
-             _bfd_vms_debug (4, "section: start = 0x%x, length = %d\n",
-                             start, length);
-#endif
-           }
-       }
-    }
-  else
-    {
-      /* We don't have a DMT section so this must be an object.  Parse
-        the module right now in order to compute its start address and
-        end address.  */
-      module = new_module (abfd);
-      parse_module (abfd, module, PRIV (dst_section)->contents,
-                   PRIV (dst_ptr_end) - PRIV (dst_section)->contents);
-      list = module;
-    }
-
-  return list;
-}
-
-/* Calculate and return the name of the source file and the line nearest
-   to the wanted location in the specified module.  */
-
-static bfd_boolean
-module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
-                         const char **file, const char **func, 
-                         unsigned int *line)
-{
-  struct funcinfo *funcinfo;
-  struct lineinfo *lineinfo;
-  struct srecinfo *srecinfo;
-  bfd_boolean ret = FALSE;
-
-  /* Parse this module if that was not done at module creation.  */
-  if (! IS_MODULE_PARSED (module))
-    {
-      unsigned int size = module->size;
-      unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
-      unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
-
-      if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
-         || bfd_bread (buffer, size, abfd) != size)
-       {
-         bfd_set_error (bfd_error_no_debug_section);
-         return FALSE;
-       }
-
-      parse_module (abfd, module, buffer, size);
-      free (buffer);
-    }
-
-  /* Find out the function (if any) that contains the address.  */
-  for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
-    if (addr >= funcinfo->low && addr <= funcinfo->high)
-      {
-        *func = funcinfo->name;
-       ret = TRUE;
-       break;
-      }
-
-  /* Find out the source file and the line nearest to the address.  */
-  for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
-    if (lineinfo->next && addr < lineinfo->next->address)
-      {
-       for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
-         if (srecinfo->next && lineinfo->line < srecinfo->next->line)
-           {
-             if (srecinfo->sfile > 0)
-               {
-                 *file = module->file_table[srecinfo->sfile].name;
-                 *line = srecinfo->srec + lineinfo->line - srecinfo->line;
-               }
-             else
-               {
-                 *file = module->name;
-                 *line = lineinfo->line;
-               }
-             return TRUE;
-           }
-
-       break;
-      }
-
-  return ret;
-}
-
-/* Provided a BFD, a section and an offset into the section, calculate and
-   return the name of the source file and the line nearest to the wanted
-   location.  */
-
-bfd_boolean
-_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
-                               asymbol **symbols ATTRIBUTE_UNUSED,
-                               bfd_vma offset, const char **file,
-                               const char **func, unsigned int *line)
-{
-  struct module *module;
-
-  /* What address are we looking for?  */
-  bfd_vma addr = section->vma + offset;
-
-  *file = NULL;
-  *func = NULL;
-  *line = 0;
-
-  if (PRIV (dst_section) == NULL)
-    return FALSE;
-
-  if (PRIV (modules) == NULL)
-    {
-      PRIV (modules) = build_module_list (abfd);
-      if (PRIV (modules) == NULL)
-        return FALSE;
-    }
-
-  for (module = PRIV (modules); module; module = module->next)
-    if (addr >= module->low && addr <= module->high)
-      return module_find_nearest_line (abfd, module, addr, file, func, line);
-
-  return FALSE;
-}
-
-/* Process EDBG/ETBT record.
-   Return 0 on success, -1 on error  */
-
-static int
-vms_slurp_debug (bfd *abfd)
-{
-  if (PRIV (dst_section) == NULL)
-    {
-      /* We have no way to find out beforehand how much debug info there
-        is in an object file, so pick an initial amount and grow it as
-        needed later.  */
-      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC;
-      asection *section = bfd_make_section (abfd, "$DST$");
-      if (!section)
-       return -1;
-      section->size = 1024;
-      if (!bfd_set_section_flags (abfd, section, flags))
-       return -1;
-      section->contents = ((unsigned char *)
-                          bfd_zmalloc (section->size));
-      if (section->contents == NULL)
-       return -1;
-      section->filepos = (unsigned int)-1;
-      PRIV (dst_section) = section;
-    }
-
-  PRIV (image_section) = PRIV (dst_section);
-  PRIV (image_ptr) = PRIV (dst_section)->contents;
-  return _bfd_vms_slurp_tir (abfd, EOBJ_S_C_ETIR);
-}
-
-/* Process DBG/EDBG record.
-   Return 0 on success, -1 on error.  */
-
-int
-_bfd_vms_slurp_dbg (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "DBG/EDBG\n");
-#endif
-
-  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
-
-  return vms_slurp_debug (abfd);
-}
-
-/* Process TBT/ETBT record.
-   Return 0 on success, -1 on error.  */
-
-int
-_bfd_vms_slurp_tbt (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "TBT/ETBT\n");
-#endif
-
-  abfd->flags |= HAS_LINENO;
-
-  return vms_slurp_debug (abfd);
-}
-
-/* Write DBG/EDBG record.  */
-
-int
-_bfd_vms_write_dbg (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "vms_write_dbg (%p, %d)\n", abfd, objtype);
-#endif
-
-  return 0;
-}
-
-/* Write TBT/ETBT record.  */
-
-int
-_bfd_vms_write_tbt (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;
-}
index 96463243b23f8cc037c2f3a5d360d4fc632bc3b7..67cc25adc065efa5d593fcdd67fb6348cd0dccf1 100644 (file)
 #include "libbfd.h"
 #include "safe-ctype.h"
 
-#include "vms.h"
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#ifdef VMS
+#include <rms.h>
+#include <unixlib.h>
+#include <starlet.h>
+#define RME$C_SETRFM 0x00000001
+#include <unistd.h>
+#endif
+#include <time.h>
 
-static int hash_string PARAMS ((const char *));
-static asymbol *new_symbol PARAMS ((bfd *, char *));
-static void maybe_adjust_record_pointer_for_object PARAMS ((bfd *));
-static int vms_get_remaining_object_record PARAMS ((bfd *, int ));
-static int vms_get_remaining_image_record PARAMS ((bfd *, int ));
+#include "vms.h"
+#include "vms/emh.h"
 
 #if VMS_DEBUG
 /* Debug functions.  */
@@ -82,7 +84,7 @@ _bfd_vms_debug (int level, char *format, ...)
   if (abslvl > min_level)
     return;
 
-  while (--level>0)
+  while (--level > 0)
     fprintf (output, " ");
   va_start (args, format);
   vfprintf (output, format, args);
@@ -94,10 +96,7 @@ _bfd_vms_debug (int level, char *format, ...)
    hex dump 'size' bytes starting at 'ptr'.  */
 
 void
-_bfd_hexdump (int level,
-             unsigned char *ptr,
-             int size,
-             int offset)
+_bfd_hexdump (int level, unsigned char *ptr, int size, int offset)
 {
   unsigned char *lptr = ptr;
   int count = 0;
@@ -105,445 +104,35 @@ _bfd_hexdump (int level,
 
   while (size-- > 0)
     {
-      if ((count%16) == 0)
+      if ((count % 16) == 0)
        vms_debug (level, "%08lx:", start);
       vms_debug (-level, " %02x", *ptr++);
       count++;
       start++;
       if (size == 0)
        {
-         while ((count%16) != 0)
+         while ((count % 16) != 0)
            {
              vms_debug (-level, "   ");
              count++;
            }
        }
-      if ((count%16) == 0)
+      if ((count % 16) == 0)
        {
          vms_debug (-level, " ");
          while (lptr < ptr)
            {
-             vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
+             vms_debug (-level, "%c", (*lptr < 32) ? '.' : *lptr);
              lptr++;
            }
          vms_debug (-level, "\n");
        }
     }
-  if ((count%16) != 0)
+  if ((count % 16) != 0)
     vms_debug (-level, "\n");
 }
 #endif
 \f
-/* Hash functions
-
-   These are needed when reading an object file.  */
-
-/* Allocate new vms_hash_entry
-   keep the symbol name and a pointer to the bfd symbol in the table.  */
-
-struct bfd_hash_entry *
-_bfd_vms_hash_newfunc (struct bfd_hash_entry *entry,
-                      struct bfd_hash_table *table,
-                      const char *string)
-{
-  vms_symbol_entry *ret;
-
-#if VMS_DEBUG
-  vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry, table, string);
-#endif
-
-  if (entry == NULL)
-    {
-      ret = (vms_symbol_entry *)
-             bfd_hash_allocate (table, sizeof (vms_symbol_entry));
-      if (ret ==  NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return NULL;
-       }
-      entry = (struct bfd_hash_entry *) ret;
-    }
-
-  /* Call the allocation method of the base class.  */
-  ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string);
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
-#endif
-
-  ret->symbol = NULL;
-
-  return (struct bfd_hash_entry *)ret;
-}
-\f
-/* Object file input functions.  */
-
-/* Return type and size from record header (buf) on Alpha.  */
-
-void
-_bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
-                           unsigned char *buf,
-                           int *type,
-                           int *size)
-{
-  if (type)
-    *type = bfd_getl16 (buf);
-
-  if (size)
-    *size = bfd_getl16 (buf+2);
-
-#if VMS_DEBUG
-  vms_debug (10, "_bfd_vms_get_header_values type %x, size %x\n",
-            type ? *type : 0, size ? *size : 0);
-#endif
-}
-
-/* Get next record from object file to vms_buf.
-   Set PRIV(buf_size) and return it
-
-   This is a little tricky since it should be portable.
-
-   The openVMS object file has 'variable length' which means that
-   read() returns data in chunks of (hopefully) correct and expected
-   size.  The linker (and other tools on VMS) depend on that. Unix
-   doesn't know about 'formatted' files, so reading and writing such
-   an object file in a Unix environment is not trivial.
-
-   With the tool 'file' (available on all VMS FTP sites), one
-   can view and change the attributes of a file.  Changing from
-   'variable length' to 'fixed length, 512 bytes' reveals the
-   record size at the first 2 bytes of every record.  The same
-   may happen during the transfer of object files from VMS to Unix,
-   at least with UCX, the DEC implementation of TCP/IP.
-
-   The VMS format repeats the size at bytes 2 & 3 of every record.
-
-   On the first call (file_format == FF_UNKNOWN) we check if
-   the first and the third byte pair (!) of the record match.
-   If they do it's an object file in an Unix environment or with
-   wrong attributes (FF_FOREIGN), else we should be in a VMS
-   environment where read() returns the record size (FF_NATIVE).
-
-   Reading is always done in 2 steps:
-    1. first just the record header is read and the size extracted,
-    2. then the read buffer is adjusted and the remaining bytes are
-       read in.
-
-   All file I/O is done on even file positions.  */
-
-#define VMS_OBJECT_ADJUSTMENT  2
-
-static void
-maybe_adjust_record_pointer_for_object (bfd *abfd)
-{
-  /* Set the file format once for all on the first invocation.  */
-  if (PRIV (file_format) == FF_UNKNOWN)
-    {
-      if (PRIV (vms_rec)[0] == PRIV (vms_rec)[4]
-         && PRIV (vms_rec)[1] == PRIV (vms_rec)[5])
-       PRIV (file_format) = FF_FOREIGN;
-      else
-       PRIV (file_format) = FF_NATIVE;
-    }
-
-  /* The adjustment is needed only in an Unix environment.  */
-  if (PRIV (file_format) == FF_FOREIGN)
-    PRIV (vms_rec) += VMS_OBJECT_ADJUSTMENT;
-}
-
-/* Get first record from file and return the file type.  */
-
-int
-_bfd_vms_get_first_record (bfd *abfd)
-{
-  unsigned int test_len;
-
-#if VMS_DEBUG
-  vms_debug (8, "_bfd_vms_get_first_record\n");
-#endif
-
-  if (PRIV (is_vax))
-    test_len = 0;
-  else
-    /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
-       2 bytes size repeated) and 12 bytes for images (4 bytes major id,
-       4 bytes minor id, 4 bytes length).  */
-    test_len = 12;
-
-  /* Size the main buffer.  */
-  if (PRIV (buf_size) == 0)
-    {
-      /* On VAX there's no size information in the record, so
-        start with OBJ_S_C_MAXRECSIZ.  */
-      bfd_size_type amt = (test_len ? test_len : OBJ_S_C_MAXRECSIZ);
-      PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt);
-      PRIV (buf_size) = amt;
-    }
-
-  /* Initialize the record pointer.  */
-  PRIV (vms_rec) = PRIV (vms_buf);
-
-  /* We only support modules on VAX.  */
-  if (PRIV (is_vax))
-    {
-      if (vms_get_remaining_object_record (abfd, test_len) <= 0)
-       return FT_UNKNOWN;
-
-#if VMS_DEBUG
-      vms_debug (2, "file type is VAX module\n");
-#endif
-
-      return FT_MODULE;
-    }
-
-  if (bfd_bread (PRIV (vms_buf), test_len, abfd) != test_len)
-    {
-      bfd_set_error (bfd_error_file_truncated);
-      return FT_UNKNOWN;
-    }
-
-  /* Is it an image?  */
-  if ((bfd_getl32 (PRIV (vms_rec)) == EIHD_S_K_MAJORID)
-      && (bfd_getl32 (PRIV (vms_rec) + 4) == EIHD_S_K_MINORID))
-    {
-      if (vms_get_remaining_image_record (abfd, test_len) <= 0)
-       return FT_UNKNOWN;
-
-#if VMS_DEBUG
-      vms_debug (2, "file type is image\n");
-#endif
-
-      return FT_IMAGE;
-    }
-
-  /* Assume it's a module and adjust record pointer if necessary.  */
-  maybe_adjust_record_pointer_for_object (abfd);
-
-  /* But is it really a module?  */
-  if (bfd_getl16 (PRIV (vms_rec)) <= EOBJ_S_C_MAXRECTYP
-      && bfd_getl16 (PRIV (vms_rec) + 2) <= EOBJ_S_C_MAXRECSIZ)
-    {
-      if (vms_get_remaining_object_record (abfd, test_len) <= 0)
-       return FT_UNKNOWN;
-
-#if VMS_DEBUG
-      vms_debug (2, "file type is module\n");
-#endif
-
-      return FT_MODULE;
-    }
-
-#if VMS_DEBUG
-  vms_debug (2, "file type is unknown\n");
-#endif
-
-  return FT_UNKNOWN;
-}
-
-/* Implement step #1 of the object record reading procedure.
-   Return the record type or -1 on failure.  */
-
-int
-_bfd_vms_get_object_record (bfd *abfd)
-{
-  unsigned int test_len;
-  int type;
-
-#if VMS_DEBUG
-  vms_debug (8, "_bfd_vms_get_obj_record\n");
-#endif
-
-  if (PRIV (is_vax))
-    test_len = 0;
-  else
-    {
-      int off = 0;
-
-      /* See _bfd_vms_get_first_record.  */
-      test_len = 6;
-
-      /* Skip odd alignment byte.  */
-      if (bfd_tell (abfd) & 1)
-       {
-         if (bfd_bread (PRIV (vms_buf), 1, abfd) != 1)
-           {
-             bfd_set_error (bfd_error_file_truncated);
-             return -1;
-           }
-          /* Alignment byte may be present or not.  This is not easy to
-             detect but all object record types are not 0 (on Alpha VMS).
-             We also hope that pad byte is 0.  */
-          if (PRIV (vms_buf)[0])
-            off = 1;
-       }
-
-      /* Read the record header  */
-      if (bfd_bread (PRIV (vms_buf) + off, test_len - off, abfd)
-          != test_len - off)
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return -1;
-       }
-
-      /* Reset the record pointer.  */
-      PRIV (vms_rec) = PRIV (vms_buf);
-      maybe_adjust_record_pointer_for_object (abfd);
-    }
-
-  if (vms_get_remaining_object_record (abfd, test_len) <= 0)
-    return -1;
-
-  if (PRIV (is_vax))
-    type = PRIV (vms_rec) [0];
-  else
-    type = bfd_getl16 (PRIV (vms_rec));
-
-#if VMS_DEBUG
-  vms_debug (8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
-             PRIV (vms_rec), PRIV (rec_size), type);
-#endif
-
-  return type;
-}
-
-/* Implement step #2 of the object record reading procedure.
-   Return the size of the record or 0 on failure.  */
-
-static int
-vms_get_remaining_object_record (bfd *abfd, int read_so_far)
-{
-#if VMS_DEBUG
-  vms_debug (8, "vms_get_remaining_obj_record\n");
-#endif
-
-  if (PRIV (is_vax))
-    {
-      if (read_so_far != 0)
-        abort ();
-
-      PRIV (rec_size) = bfd_bread (PRIV (vms_buf), PRIV (buf_size), abfd);
-
-      if (PRIV (rec_size) <= 0)
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return 0;
-       }
-
-      /* Reset the record pointer.  */
-      PRIV (vms_rec) = PRIV (vms_buf);
-    }
-  else
-    {
-      unsigned int to_read;
-
-      /* Extract record size.  */
-      PRIV (rec_size) = bfd_getl16 (PRIV (vms_rec) + 2);
-
-      if (PRIV (rec_size) <= 0)
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return 0;
-       }
-
-      /* That's what the linker manual says.  */
-      if (PRIV (rec_size) > EOBJ_S_C_MAXRECSIZ)
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return 0;
-       }
-
-      /* Take into account object adjustment.  */
-      to_read = PRIV (rec_size);
-      if (PRIV (file_format) == FF_FOREIGN)
-       to_read += VMS_OBJECT_ADJUSTMENT;
-
-      /* Adjust the buffer.  */
-      if (to_read > PRIV (buf_size))
-       {
-         PRIV (vms_buf)
-           = (unsigned char *) bfd_realloc (PRIV (vms_buf), to_read);
-         if (PRIV (vms_buf) == NULL)
-           return 0;
-         PRIV (buf_size) = to_read;
-       }
-
-      /* Read the remaining record.  */
-      to_read -= read_so_far;
-
-#if VMS_DEBUG
-      vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read);
-#endif
-
-      if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return 0;
-       }
-
-      /* Reset the record pointer.  */
-      PRIV (vms_rec) = PRIV (vms_buf);
-      maybe_adjust_record_pointer_for_object (abfd);
-    }
-
-#if VMS_DEBUG
-  vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size));
-#endif
-
-  return PRIV (rec_size);
-}
-
-/* Implement step #2 of the record reading procedure for images.
-   Return the size of the record or 0 on failure.  */
-
-static int
-vms_get_remaining_image_record (bfd *abfd, int read_so_far)
-{
-  unsigned int to_read;
-  int remaining;
-
-  /* Extract record size.  */
-  PRIV (rec_size) = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
-
-  if (PRIV (rec_size) > PRIV (buf_size))
-    {
-      PRIV (vms_buf) = bfd_realloc (PRIV (vms_buf), PRIV (rec_size));
-
-      if (PRIV (vms_buf) == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return 0;
-       }
-
-      PRIV (buf_size) = PRIV (rec_size);
-    }
-
-  /* Read the remaining record.  */
-  remaining = PRIV (rec_size) - read_so_far;
-  to_read = MIN (VMS_BLOCK_SIZE - read_so_far, remaining);
-
-  while (remaining > 0)
-    {
-      if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
-       {
-         bfd_set_error (bfd_error_file_truncated);
-         return 0;
-       }
-
-      read_so_far += to_read;
-      remaining -= to_read;
-
-      /* Eat trailing 0xff's.  */
-      if (remaining > 0)
-       while (PRIV (vms_buf) [read_so_far - 1] == 0xff)
-         read_so_far--;
-
-      to_read = MIN (VMS_BLOCK_SIZE, remaining);
-    }
-
-  /* Reset the record pointer.  */
-  PRIV (vms_rec) = PRIV (vms_buf);
-
-  return PRIV (rec_size);
-}
 
 /* Copy sized string (string with fixed size) to new allocated area
    size is string size (size of record)  */
@@ -555,7 +144,7 @@ _bfd_vms_save_sized_string (unsigned char *str, int size)
 
   if (newstr == NULL)
     return NULL;
-  strncpy (newstr, (char *) str, (size_t) size);
+  memcpy (newstr, (char *) str, (size_t) size);
   newstr[size] = 0;
 
   return newstr;
@@ -572,280 +161,196 @@ _bfd_vms_save_counted_string (unsigned char *ptr)
   return _bfd_vms_save_sized_string (ptr, len);
 }
 \f
-/* Stack routines for vms ETIR commands.  */
+/* Object output routines.   */
 
-/* Push value and section index.  */
+/* Begin new record.
+   Write 2 bytes rectype and 2 bytes record length.  */
 
 void
-_bfd_vms_push (bfd * abfd, uquad val, int psect)
+_bfd_vms_output_begin (struct vms_rec_wr *recwr, int rectype)
 {
-  static int last_psect;
+  vms_debug2 ((6, "_bfd_vms_output_begin (type %d)\n", rectype));
 
-#if VMS_DEBUG
-  vms_debug (4, "<push %016lx (%d) at %d>\n", val, psect, PRIV (stackptr));
-#endif
-
-  if (psect >= 0)
-    last_psect = psect;
+  /* Record must have been closed.  */
+  BFD_ASSERT (recwr->size == 0);
 
-  PRIV (stack[PRIV (stackptr)]).value = val;
-  PRIV (stack[PRIV (stackptr)]).psect = last_psect;
-  PRIV (stackptr)++;
-  if (PRIV (stackptr) >= STACKSIZE)
-    {
-      bfd_set_error (bfd_error_bad_value);
-      (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
-      exit (1);
-    }
-}
+  _bfd_vms_output_short (recwr, (unsigned int) rectype);
 
-/* Pop value and section index.  */
-
-uquad
-_bfd_vms_pop (bfd * abfd, int *psect)
-{
-  uquad value;
-
-  if (PRIV (stackptr) == 0)
-    {
-      bfd_set_error (bfd_error_bad_value);
-      (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
-      exit (1);
-    }
-  PRIV (stackptr)--;
-  value = PRIV (stack[PRIV (stackptr)]).value;
-  if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0))
-    *psect = PRIV (stack[PRIV (stackptr)]).psect;
-
-#if VMS_DEBUG
-  vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
-#endif
-
-  return value;
+  /* Placeholder for length.  */
+  _bfd_vms_output_short (recwr, 0);
 }
-\f
-/* Object output routines.   */
 
-/* Begin new record or record header
-   write 2 bytes rectype
-   write 2 bytes record length (filled in at flush)
-   write 2 bytes header type (ommitted if rechead == -1).  */
+/* Begin new sub-record.
+   Write 2 bytes rectype, and 2 bytes record length.  */
 
 void
-_bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
+_bfd_vms_output_begin_subrec (struct vms_rec_wr *recwr, int rectype)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype,
-             rechead);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_begin_subrec (type %d)\n", rectype));
 
-  _bfd_vms_output_short (abfd, (unsigned int) rectype);
+  /* Subrecord must have been closed.  */
+  BFD_ASSERT (recwr->subrec_offset == 0);
 
-  /* Save current output position to fill in length later.   */
+  /* Save start of subrecord offset.  */
+  recwr->subrec_offset = recwr->size;
 
-  if (PRIV (push_level) > 0)
-    PRIV (length_pos) = PRIV (output_size);
-
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
-             PRIV (length_pos));
-#endif
+  /* Subrecord type.  */
+  _bfd_vms_output_short (recwr, (unsigned int) rectype);
 
   /* Placeholder for length.  */
-  _bfd_vms_output_short (abfd, 0);
-
-  if (rechead != -1)
-    _bfd_vms_output_short (abfd, (unsigned int) rechead);
+  _bfd_vms_output_short (recwr, 0);
 }
 
 /* Set record/subrecord alignment.   */
 
 void
-_bfd_vms_output_alignment (bfd * abfd, int alignto)
+_bfd_vms_output_alignment (struct vms_rec_wr *recwr, int alignto)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto);
-#endif
-
-  PRIV (output_alignment) = alignto;
+  vms_debug2 ((6, "_bfd_vms_output_alignment (%d)\n", alignto));
+  recwr->align = alignto;
 }
 
-/* Prepare for subrecord fields.  */
-
-void
-_bfd_vms_output_push (bfd * abfd)
-{
-#if VMS_DEBUG
-  vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size));
-#endif
+/* Align the size of the current record (whose length is LENGTH).
+   Warning: this obviously changes the record (and the possible subrecord)
+   length.  */
 
-  PRIV (push_level)++;
-  PRIV (pushed_size) = PRIV (output_size);
-}
-
-/* End of subrecord fields.   */
-
-void
-_bfd_vms_output_pop (bfd * abfd)
+static void
+_bfd_vms_output_align (struct vms_rec_wr *recwr, unsigned int length)
 {
-#if VMS_DEBUG
-  vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size));
-#endif
-
-  _bfd_vms_output_flush (abfd);
-  PRIV (length_pos) = 2;
+  unsigned int real_size = recwr->size;
+  unsigned int aligncount;
 
-#if VMS_DEBUG
-  vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
-#endif
+  /* Pad with 0 if alignment is required.  */
+  aligncount = (recwr->align - (length % recwr->align)) % recwr->align;
+  vms_debug2 ((6, "align: adding %d bytes\n", aligncount));
+  while (aligncount-- > 0)
+    recwr->buf[real_size++] = 0;
 
-  PRIV (pushed_size) = 0;
-  PRIV (push_level)--;
+  recwr->size = real_size;
 }
 
-/* Flush unwritten output, ends current record.  */
+/* Ends current sub-record.  Set length field.  */
 
 void
-_bfd_vms_output_flush (bfd * abfd)
+_bfd_vms_output_end_subrec (struct vms_rec_wr *recwr)
 {
-  int real_size = PRIV (output_size);
-  int aligncount;
+  int real_size = recwr->size;
   int length;
 
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n",
-             real_size, PRIV (pushed_size), PRIV (length_pos));
-#endif
+  /* Subrecord must be open.  */
+  BFD_ASSERT (recwr->subrec_offset != 0);
 
-  if (PRIV (push_level) > 0)
-    length = real_size - PRIV (pushed_size);
-  else
-    length = real_size;
+  length = real_size - recwr->subrec_offset;
 
   if (length == 0)
     return;
-  aligncount = (PRIV (output_alignment)
-               - (length % PRIV (output_alignment))) % PRIV (output_alignment);
-
-#if VMS_DEBUG
-  vms_debug (6, "align: adding %d bytes\n", aligncount);
-#endif
 
-  while (aligncount-- > 0)
-    {
-      PRIV (output_buf)[real_size++] = 0;
-      length++;
-    }
+  _bfd_vms_output_align (recwr, length);
 
   /* Put length to buffer.  */
-  PRIV (output_size) = PRIV (length_pos);
-  _bfd_vms_output_short (abfd, (unsigned int) length);
+  bfd_putl16 ((bfd_vma) (recwr->size - recwr->subrec_offset),
+              recwr->buf + recwr->subrec_offset + 2);
 
-  if (PRIV (push_level) == 0)
-    {
-      /* File is open in undefined (UDF) format on VMS, but ultimately will be
-        converted to variable length (VAR) format.  VAR format has a length
-        word first which must be explicitly output in UDF format.  */
-      bfd_bwrite (PRIV (output_buf) + 2, 2, abfd);
-      bfd_bwrite (PRIV (output_buf), (size_t) real_size, abfd);
-      PRIV (output_size) = 0;
-    }
-  else
-    {
-      PRIV (output_size) = real_size;
-      PRIV (pushed_size) = PRIV (output_size);
-    }
+  /* Close the subrecord.  */
+  recwr->subrec_offset = 0;
 }
 
-/* End record output.   */
+/* Ends current record (and write it).  */
 
 void
-_bfd_vms_output_end (bfd * abfd)
+_bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_end\n");
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_end (size %u)\n", recwr->size));
 
-  _bfd_vms_output_flush (abfd);
-}
+  /* Subrecord must have been closed.  */
+  BFD_ASSERT (recwr->subrec_offset == 0);
+
+  if (recwr->size == 0)
+    return;
 
-/* Check remaining buffer size
+  _bfd_vms_output_align (recwr, recwr->size);
 
-   Return what's left.  */
+  /* Write the length word.  */
+  bfd_putl16 ((bfd_vma) recwr->size, recwr->buf + 2);
+
+  /* File is open in undefined (UDF) format on VMS, but ultimately will be
+     converted to variable length (VAR) format.  VAR format has a length
+     word first which must be explicitly output in UDF format.  */
+  /* So, first the length word.  */
+  bfd_bwrite (recwr->buf + 2, 2, abfd);
+
+  /* Align.  */
+  if (recwr->size & 1)
+    recwr->buf[recwr->size++] = 0;
+
+  /* Then the record.  */
+  bfd_bwrite (recwr->buf, (size_t) recwr->size, abfd);
+
+  recwr->size = 0;
+}
+
+/* Check remaining buffer size.  Return what's left.  */
 
 int
-_bfd_vms_output_check (bfd * abfd, int size)
+_bfd_vms_output_check (struct vms_rec_wr *recwr, int size)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_check (%d)\n", size);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_check (%d)\n", size));
 
-  return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
+  return (MAX_OUTREC_SIZE - (recwr->size + size + MIN_OUTREC_LUFT));
 }
 
 /* Output byte (8 bit) value.  */
 
 void
-_bfd_vms_output_byte (bfd * abfd, unsigned int value)
+_bfd_vms_output_byte (struct vms_rec_wr *recwr, unsigned int value)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_byte (%02x)\n", value));
 
-  bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
-  PRIV (output_size) += 1;
+  *(recwr->buf + recwr->size) = value;
+  recwr->size += 1;
 }
 
 /* Output short (16 bit) value.  */
 
 void
-_bfd_vms_output_short (bfd * abfd, unsigned int value)
+_bfd_vms_output_short (struct vms_rec_wr *recwr, unsigned int value)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_short (%04x)\n", value));
 
-  bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
-             PRIV (output_buf) + PRIV (output_size));
-  PRIV (output_size) += 2;
+  bfd_putl16 ((bfd_vma) value & 0xffff, recwr->buf + recwr->size);
+  recwr->size += 2;
 }
 
 /* Output long (32 bit) value.  */
 
 void
-_bfd_vms_output_long (bfd * abfd, unsigned long value)
+_bfd_vms_output_long (struct vms_rec_wr *recwr, unsigned long value)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_long (%08lx)\n", value));
 
-  bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
-  PRIV (output_size) += 4;
+  bfd_putl32 ((bfd_vma) value, recwr->buf + recwr->size);
+  recwr->size += 4;
 }
 
 /* Output quad (64 bit) value.  */
 
 void
-_bfd_vms_output_quad (bfd * abfd, uquad value)
+_bfd_vms_output_quad (struct vms_rec_wr *recwr, bfd_vma value)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_quad (%08lx)\n", (unsigned long)value));
 
-  bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
-  PRIV (output_size) += 8;
+  bfd_putl64 (value, recwr->buf + recwr->size);
+  recwr->size += 8;
 }
 
 /* Output c-string as counted string.  */
 
 void
-_bfd_vms_output_counted (bfd * abfd, char *value)
+_bfd_vms_output_counted (struct vms_rec_wr *recwr, char *value)
 {
   int len;
 
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_counted (%s)\n", value);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_counted (%s)\n", value));
 
   len = strlen (value);
   if (len == 0)
@@ -858,193 +363,117 @@ _bfd_vms_output_counted (bfd * abfd, char *value)
       (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
       return;
     }
-  _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
-  _bfd_vms_output_dump (abfd, (unsigned char *) value, len);
+  _bfd_vms_output_byte (recwr, (unsigned int) len & 0xff);
+  _bfd_vms_output_dump (recwr, (unsigned char *) value, len);
 }
 
 /* Output character area.  */
 
 void
-_bfd_vms_output_dump (bfd * abfd,
-                     unsigned char *data,
-                     int length)
+_bfd_vms_output_dump (struct vms_rec_wr *recwr, unsigned char *data, int len)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_dump (%d)\n", length);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_dump (%d)\n", len));
 
-  if (length == 0)
+  if (len == 0)
     return;
 
-  memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
-  PRIV (output_size) += length;
+  memcpy (recwr->buf + recwr->size, data, (size_t) len);
+  recwr->size += len;
 }
 
 /* Output count bytes of value.  */
 
 void
-_bfd_vms_output_fill (bfd * abfd,
-                     int value,
-                     int count)
+_bfd_vms_output_fill (struct vms_rec_wr *recwr, int value, int count)
 {
-#if VMS_DEBUG
-  vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count);
-#endif
+  vms_debug2 ((6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count));
 
   if (count == 0)
     return;
-  memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
-  PRIV (output_size) += count;
-}
-
-/* This hash routine borrowed from GNU-EMACS, and strengthened slightly.  ERY.  */
-
-static int
-hash_string (const char *ptr)
-{
-  const unsigned char *p = (unsigned char *) ptr;
-  const unsigned char *end = p + strlen (ptr);
-  unsigned char c;
-  int hash = 0;
-
-  while (p != end)
-    {
-      c = *p++;
-      hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
-    }
-  return hash;
+  memset (recwr->buf + recwr->size, value, (size_t) count);
+  recwr->size += count;
 }
 
-/* Generate a length-hashed VMS symbol name (limited to maxlen chars).  */
+#ifdef VMS
+/* Convert the file to variable record length format. This is done
+   using undocumented system call sys$modify().
+   Pure VMS version.  */
 
-char *
-_bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen)
+static void
+vms_convert_to_var (char *vms_filename)
 {
-  unsigned long result;
-  int in_len;
-  char *new_name;
-  const char *old_name;
-  int i;
-  static char outbuf[EOBJ_S_C_SYMSIZ+1];
-  char *out = outbuf;
-
-#if VMS_DEBUG
-  vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
-#endif
-
-  if (maxlen > EOBJ_S_C_SYMSIZ)
-    maxlen = EOBJ_S_C_SYMSIZ;
-
-  /* Save this for later.  */
-  new_name = out;
-
-  /* We may need to truncate the symbol, save the hash for later.  */
-  in_len = strlen (in);
+  struct FAB fab = cc$rms_fab;
 
-  result = (in_len > maxlen) ? hash_string (in) : 0;
+  fab.fab$l_fna = vms_filename;
+  fab.fab$b_fns = strlen (vms_filename);
+  fab.fab$b_fac = FAB$M_PUT;
+  fab.fab$l_fop = FAB$M_ESC;
+  fab.fab$l_ctx = RME$C_SETRFM;
 
-  old_name = in;
+  sys$open (&fab);
 
-  /* Do the length checking.  */
-  if (in_len <= maxlen)
-    i = in_len;
-  else
-    {
-      if (PRIV (flag_hash_long_names))
-       i = maxlen-9;
-      else
-       i = maxlen;
-    }
-
-  strncpy (out, in, (size_t) i);
-  in += i;
-  out += i;
-
-  if ((in_len > maxlen)
-      && PRIV (flag_hash_long_names))
-    sprintf (out, "_%08lx", result);
-  else
-    *out = 0;
-
-#if VMS_DEBUG
-  vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
-#endif
-
-  if (in_len > maxlen
-       && PRIV (flag_hash_long_names)
-       && PRIV (flag_show_after_trunc))
-    printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
+  fab.fab$b_rfm = FAB$C_VAR;
 
-  return outbuf;
+  sys$modify (&fab);
+  sys$close (&fab);
 }
 
-/* Allocate and initialize a new symbol.  */
-
-static asymbol *
-new_symbol (bfd * abfd, char *name)
+static int
+vms_convert_to_var_1 (char *filename, int type)
 {
-  asymbol *symbol;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (7,  "new_symbol %s\n", name);
-#endif
-
-  symbol = bfd_make_empty_symbol (abfd);
-  if (symbol == 0)
-    return symbol;
-  symbol->name = name;
-  symbol->section = (asection *)(unsigned long)-1;
-
-  return symbol;
+  if (type != DECC$K_FILE)
+    return FALSE;
+  vms_convert_to_var (filename);
+  return TRUE;
 }
 
-/* Allocate and enter a new private symbol.  */
+/* Convert the file to variable record length format. This is done
+   using undocumented system call sys$modify().
+   Unix filename version.  */
 
-vms_symbol_entry *
-_bfd_vms_enter_symbol (bfd * abfd, char *name)
-{
-  vms_symbol_entry *entry;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (6,  "_bfd_vms_enter_symbol %s\n", name);
-#endif
-
-  entry = (vms_symbol_entry *)
-         bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
-  if (entry == 0)
-    {
-#if VMS_DEBUG
-      _bfd_vms_debug (8,  "creating hash entry for %s\n", name);
-#endif
-      entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
-                                                   name, TRUE, FALSE);
-      if (entry != 0)
-       {
-         asymbol *symbol;
-         symbol = new_symbol (abfd, name);
-         if (symbol != 0)
-           {
-             entry->symbol = symbol;
-             PRIV (gsd_sym_count)++;
-             abfd->symcount++;
-           }
-         else
-           entry = 0;
-       }
-      else
-       (*_bfd_error_handler) (_("failed to enter %s"), name);
-    }
-  else
-    {
-#if VMS_DEBUG
-      _bfd_vms_debug (8,  "found hash entry for %s\n", name);
-#endif
-    }
-
-#if VMS_DEBUG
-  _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
-#endif
-  return entry;
+static int
+vms_convert_to_var_unix_filename (const char *unix_filename)
+{
+  if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
+    return FALSE;
+  return TRUE;
+}
+#endif /* VMS */
+
+/* Manufacture a VMS like time on a unix based system.
+   stolen from obj-vms.c.  */
+
+unsigned char *
+get_vms_time_string (void)
+{
+  static unsigned char tbuf[18];
+#ifndef VMS
+  char *pnt;
+  time_t timeb;
+
+  time (& timeb);
+  pnt = ctime (&timeb);
+  pnt[3] = 0;
+  pnt[7] = 0;
+  pnt[10] = 0;
+  pnt[16] = 0;
+  pnt[24] = 0;
+  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
+          pnt + 8, pnt + 4, pnt + 20, pnt + 11);
+#else
+  struct
+  {
+    int Size;
+    unsigned char *Ptr;
+  } Descriptor;
+  Descriptor.Size = 17;
+  Descriptor.Ptr = tbuf;
+  SYS$ASCTIM (0, &Descriptor, 0, 0);
+#endif /* not VMS */
+
+  vms_debug2 ((6, "vmstimestring:'%s'\n", tbuf));
+
+  return tbuf;
 }
 
 /* Create module name from filename (ie, extract the basename and convert it
diff --git a/bfd/vms-tir.c b/bfd/vms-tir.c
deleted file mode 100644 (file)
index 1ecb151..0000000
+++ /dev/null
@@ -1,2808 +0,0 @@
-/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
-   EVAX (openVMS/Alpha) files.
-   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
-
-   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
-   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,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   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., 51 Franklin Street - Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
-
-/* The following type abbreviations are used:
-
-       cs      counted string (ascii string with length byte)
-       by      byte (1 byte)
-       sh      short (2 byte, 16 bit)
-       lw      longword (4 byte, 32 bit)
-       qw      quadword (8 byte, 64 bit)
-       da      data stream  */
-
-#include "sysdep.h"
-#include "bfd.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-#include "vms.h"
-
-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
-check_section (bfd * abfd, int size)
-{
-  bfd_size_type offset;
-
-  offset = PRIV (image_ptr) - PRIV (image_section)->contents;
-  if (offset + size > PRIV (image_section)->size)
-    {
-      PRIV (image_section)->contents
-       = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size);
-      if (PRIV (image_section)->contents == NULL)
-       {
-         (*_bfd_error_handler) (_("No Mem !"));
-         return -1;
-       }
-      PRIV (image_section)->size = offset + size;
-      PRIV (image_ptr) = PRIV (image_section)->contents + offset;
-    }
-
-  return 0;
-}
-
-/* Routines to fill sections contents during tir/etir read.  */
-
-/* Initialize image buffer pointer to be filled.  */
-
-static void
-image_set_ptr (bfd * abfd, int psect, uquad offset)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
-                 psect, PRIV (sections)[psect]->name, offset);
-#endif
-
-  PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
-  PRIV (image_section) = PRIV (sections)[psect];
-}
-
-/* Increment image buffer pointer by offset.  */
-
-static void
-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;
-}
-
-/* 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 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
-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,
-                 PRIV (image_ptr));
-  _bfd_hexdump (9, ptr, size, offset);
-#endif
-
-  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++;
-}
-
-/* Write byte to section image.  */
-
-static void
-image_write_b (bfd * abfd, unsigned int value)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
-#endif
-
-  if (PRIV (is_vax) && check_section (abfd, 1))
-    return;
-
-  if (PRIV (dst_section))
-    dst_check_allocation (abfd, 1);
-
-  *PRIV (image_ptr)++ = (value & 0xff);
-}
-
-/* Write 2-byte word to image.  */
-
-static void
-image_write_w (bfd * abfd, unsigned int value)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
-#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;
-}
-
-/* Write 4-byte long to image.  */
-
-static void
-image_write_l (bfd * abfd, unsigned long value)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
-#endif
-
-  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;
-}
-
-/* Write 8-byte quad to image.  */
-
-static void
-image_write_q (bfd * abfd, uquad value)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
-#endif
-
-  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;
-}
-\f
-static const char *
-cmd_name (int cmd)
-{
-  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_CKARG: return "ETIR_S_C_STA_CKARG";
-    case ETIR_S_C_STO_B: return "ETIR_S_C_STO_B";
-    case ETIR_S_C_STO_W: return "ETIR_S_C_STO_W";
-    case ETIR_S_C_STO_GBL: return "ETIR_S_C_STO_GBL";
-    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_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_REDEF: return "ETIR_S_C_OPR_REDEF";
-    case ETIR_S_C_OPR_DFLIT: return "ETIR_S_C_OPR_DFLIT";
-    case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP";
-    case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL";
-    case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA";
-    case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS";
-    case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS";
-    case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL";
-    case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS";
-    case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL";
-    case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS";
-    case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL";
-    case ETIR_S_C_STC_LDA_PS: return "ETIR_S_C_STC_LDA_PS";
-    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.  */
-      (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
-    }
-
-  return NULL;
-}
-#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
-
-/* etir_sta
-
-   Vms stack commands.
-
-   Handle sta_xxx commands in etir section,
-   ptr points to data area in record.
-
-   See table B-8 of the openVMS linker manual.  */
-
-static bfd_boolean
-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);
-  _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
-  switch (cmd)
-    {
-      /* Stack global
-        arg: cs        symbol name
-
-        stack 32 bit value of symbol (high bits set to 0).  */
-    case ETIR_S_C_STA_GBL:
-      {
-       char *name;
-       vms_symbol_entry *entry;
-
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = (vms_symbol_entry *)
-         bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
-       if (entry == NULL)
-         {
-#if VMS_DEBUG
-           _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
-                           cmd_name (cmd), name);
-#endif
-           _bfd_vms_push (abfd, (uquad) 0, -1);
-         }
-       else
-         _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
-      }
-      *quarter_relocs = 1;
-      break;
-
-      /* Stack longword
-        arg: lw        value
-
-        stack 32 bit value, sign extend to 64 bit.  */
-    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;
-
-      /* Stack quadword
-        arg: qw        value
-
-        stack 64 bit value of symbol.  */
-    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;
-
-      /* Stack psect base plus quadword offset
-        arg: lw        section index
-        qw     signed quadword offset (low 32 bits)
-
-        Stack qw argument and section index
-        (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB).  */
-    case ETIR_S_C_STA_PQ:
-      {
-       uquad dummy;
-       int psect;
-
-       psect = bfd_getl32 (ptr);
-       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;
-         }
-       dummy = bfd_getl64 (ptr + 4);
-       _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));
-      *quarter_relocs = 0;
-      return FALSE;
-
-    default:
-      (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
-      *quarter_relocs = 0;
-      return FALSE;
-    }
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "etir_sta true\n");
-#endif
-
-  return TRUE;
-}
-
-/* etir_sto
-
-   vms store commands
-
-   handle sto_xxx commands in etir section
-   ptr points to data area in record
-
-   see table B-9 of the openVMS linker manual.  */
-
-static bfd_boolean
-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);
-  _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
-  switch (cmd)
-    {
-      /* Store byte: pop stack, write byte
-        arg: -.  */
-    case ETIR_S_C_STO_B:
-      dummy = _bfd_vms_pop (abfd, &psect);
-      /* FIXME: check top bits.  */
-      image_write_b (abfd, (unsigned int) dummy & 0xff);
-      *quarter_relocs = 0;
-      break;
-
-      /* Store word: pop stack, write word
-        arg: -.  */
-    case ETIR_S_C_STO_W:
-      dummy = _bfd_vms_pop (abfd, &psect);
-      /* FIXME: check top bits */
-      image_write_w (abfd, (unsigned int) dummy & 0xffff);
-      *quarter_relocs = 0;
-      break;
-
-      /* 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);
-      if (*quarter_relocs == 2)
-       *quarter_relocs = 4;
-      else
-       *quarter_relocs += 1;
-      break;
-
-      /* Store quadword: pop stack, write quadword
-        arg: -.  */
-    case ETIR_S_C_STO_QW:
-      dummy = _bfd_vms_pop (abfd, &psect);
-      dummy += (PRIV (sections)[psect])->vma;
-      /* FIXME: check top bits.  */
-      image_write_q (abfd, dummy);
-      if (*quarter_relocs == 2)
-       *quarter_relocs = 4;
-      else
-       *quarter_relocs += 1;
-      break;
-
-      /* Store immediate repeated: pop stack for repeat count
-        arg: lw        byte count
-        da     data.  */
-    case ETIR_S_C_STO_IMMR:
-      {
-       int size;
-
-       size = bfd_getl32 (ptr);
-       dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
-       while (dummy-- > 0)
-         image_dump (abfd, ptr+4, size, 0);
-      }
-      *quarter_relocs = 0;
-      break;
-
-      /* Store global: write symbol value
-        arg: cs        global symbol name.  */
-    case ETIR_S_C_STO_GBL:
-      {
-       vms_symbol_entry *entry;
-       char *name;
-
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
-                                                     name, FALSE, FALSE);
-       if (entry == NULL)
-         /* FIXME, reloc.  */
-         image_write_q (abfd, (uquad) (0));
-       else
-         /* FIXME, reloc.  */
-         image_write_q (abfd, (uquad) (entry->symbol->value));
-      }
-      *quarter_relocs = 4;
-      break;
-
-      /* Store code address: write address of entry point
-        arg: cs        global symbol name (procedure).  */
-    case ETIR_S_C_STO_CA:
-      {
-       vms_symbol_entry *entry;
-       char *name;
-
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
-                                                     name, FALSE, FALSE);
-       if (entry == NULL)
-         /* FIXME, reloc.  */
-         image_write_q (abfd, (uquad) (0));
-       else
-         /* 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.  */
-    case ETIR_S_C_STO_OFF:
-      {
-       uquad q;
-       int psect1;
-
-       q = _bfd_vms_pop (abfd, & psect1);
-       q += (PRIV (sections)[psect1])->vma;
-       image_write_q (abfd, q);
-      }
-      *quarter_relocs += 2;
-      break;
-
-      /* Store immediate
-        arg: lw        count of bytes
-             da        data.  */
-    case ETIR_S_C_STO_IMM:
-      {
-       int size;
-
-       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
-        linker manual, however it is generated by the DEC C compiler
-        and defined in the include file.
-        FIXME, since the following is just a guess
-        store global longword: store 32bit value of symbol
-        arg: cs        symbol name.  */
-    case ETIR_S_C_STO_GBL_LW:
-      {
-       vms_symbol_entry *entry;
-       char *name;
-
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
-                                                     name, FALSE, FALSE);
-       if (entry == NULL)
-         {
-#if VMS_DEBUG
-           _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
-#endif
-           image_write_l (abfd, (unsigned long) 0);    /* FIXME, reloc */
-         }
-       else
-         /* 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));
-      *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));
-      *quarter_relocs = 0;
-      return FALSE;
-
-    default:
-      (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
-      *quarter_relocs = 0;
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-/* 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 B-10 of the openVMS linker manual.  */
-
-static bfd_boolean
-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);
-  _bfd_hexdump (8, ptr, 16, (long) ptr);
-#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)
-    {
-    case ETIR_S_C_OPR_NOP:      /* No-op.  */
-      break;
-
-    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;
-
-    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;
-
-    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;
-
-    case ETIR_S_C_OPR_DIV:      /* Divide.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (op2 == 0)
-       _bfd_vms_push (abfd, (uquad) 0, -1);
-      else
-       _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
-      break;
-
-    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;
-
-    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;
-
-    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;
-
-    case ETIR_S_C_OPR_NEG:      /* Negate.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      _bfd_vms_push (abfd, (uquad) (-op1), -1);
-      break;
-
-    case ETIR_S_C_OPR_COM:      /* Complement.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
-      break;
-
-    case ETIR_S_C_OPR_ASH:      /* Arithmetic shift.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (op2 < 0)             /* Shift right.  */
-       op1 >>= -op2;
-      else                     /* Shift left.  */
-       op1 <<= op2;
-      _bfd_vms_push (abfd, (uquad) op1, -1);
-      break;
-
-    case ETIR_S_C_OPR_INSV:      /* Insert field.   */
-      (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_REDEF:     /* Redefine symbol to current location.  */
-    case ETIR_S_C_OPR_DFLIT:     /* Define a literal.  */
-      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
-      return FALSE;
-
-    case ETIR_S_C_OPR_SEL:      /* Select.  */
-      if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
-       (void) _bfd_vms_pop (abfd, NULL);
-      else
-       {
-         op1 = (long) _bfd_vms_pop (abfd, NULL);
-         (void) _bfd_vms_pop (abfd, NULL);
-         _bfd_vms_push (abfd, (uquad) op1, -1);
-       }
-      break;
-
-    default:
-      (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-/* Control commands.
-
-   See table B-11 of the openVMS linker manual.  */
-
-static bfd_boolean
-etir_ctl (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
-{
-  uquad dummy;
-  int psect;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
-  _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
-  /* No relocation uses CTL commands.  */
-  *quarter_relocs = 0;
-
-  switch (cmd)
-    {
-      /* Det relocation base: pop stack, set image location counter
-        arg: none.  */
-    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.  */
-    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
-        arg: none.  */
-    case ETIR_S_C_CTL_DFLOC:
-      dummy = _bfd_vms_pop (abfd, NULL);
-      dst_define_location (abfd, dummy);
-      break;
-
-      /* Set location: pop index, restore location counter from index
-        arg: none.  */
-    case ETIR_S_C_CTL_STLOC:
-      dummy = _bfd_vms_pop (abfd, NULL);
-      dst_restore_location (abfd, dummy);
-      break;
-
-      /* Stack defined location: pop index, push location counter from index
-        arg: none.  */
-    case ETIR_S_C_CTL_STKDL:
-      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);
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-/* Store conditional commands
-
-   See table B-12 and B-13 of the openVMS linker manual.  */
-
-static bfd_boolean
-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);
-  _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
-  switch (cmd)
-    {
-      /* 200 Store-conditional Linkage Pair
-        arg: none.  */
-    case ETIR_S_C_STC_LP:
-
-      /* 202 Store-conditional Address at global address
-        arg:   lw      linkage index
-               cs      global name.  */
-
-    case ETIR_S_C_STC_GBL:
-
-      /* 203 Store-conditional Code Address at global address
-        arg:   lw      linkage index
-               cs      procedure name.  */
-    case ETIR_S_C_STC_GCA:
-
-      /* 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));
-      *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.  */
-    case ETIR_S_C_STC_NOP_GBL:
-      /* ALPHA_R_NOP */
-
-      /* 207 Store-conditional BSR at global address
-        arg: none.  */
-
-    case ETIR_S_C_STC_BSR_GBL:
-      /* ALPHA_R_BSR */
-
-      /* 209 Store-conditional LDA at global address
-        arg: none.  */
-
-    case ETIR_S_C_STC_LDA_GBL:
-      /* ALPHA_R_LDA */
-
-      /* 211 Store-conditional BSR or Hint at global address
-        arg: none.  */
-
-    case ETIR_S_C_STC_BOH_GBL:
-      *quarter_relocs = 4;
-      break;
-
-      /* 213 Store-conditional NOP,BSR or HINT at global address
-        arg: none.  */
-
-    case ETIR_S_C_STC_NBH_GBL:
-
-      /* 206 Store-conditional NOP at pect + offset
-        arg: none.  */
-
-    case ETIR_S_C_STC_NOP_PS:
-
-      /* 208 Store-conditional BSR at pect + offset
-        arg: none.  */
-
-    case ETIR_S_C_STC_BSR_PS:
-
-      /* 210 Store-conditional LDA at psect + offset
-        arg: none.  */
-
-    case ETIR_S_C_STC_LDA_PS:
-
-      /* 212 Store-conditional BSR or Hint at pect + offset
-        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:
-      (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd));
-      *quarter_relocs = 0;
-      return FALSE;
-
-    default:
-      (*_bfd_error_handler) (_("reserved STC cmd %d"), cmd);
-      *quarter_relocs = 0;
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-static asection *
-new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
-{
-  asection *section;
-  char sname[16];
-  char *name;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "new_section %d\n", idx);
-#endif
-  sprintf (sname, SECTION_NAME_TEMPLATE, idx);
-
-  name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
-  if (name == 0)
-    return NULL;
-  strcpy (name, sname);
-
-  section = bfd_malloc ((bfd_size_type) sizeof (asection));
-  if (section == 0)
-    {
-#if VMS_DEBUG
-      _bfd_vms_debug (6,  "new_section (%s) failed", name);
-#endif
-      return NULL;
-    }
-
-  section->size = 0;
-  section->vma = 0;
-  section->contents = 0;
-  section->name = name;
-  section->index = idx;
-
-  return section;
-}
-
-static int
-alloc_section (bfd * abfd, unsigned int idx)
-{
-  bfd_size_type amt;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (4, "alloc_section %d\n", idx);
-#endif
-
-  amt = idx + 1;
-  amt *= sizeof (asection *);
-  PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
-  if (PRIV (sections) == NULL)
-    return -1;
-
-  while (PRIV (section_count) <= idx)
-    {
-      PRIV (sections)[PRIV (section_count)]
-       = new_section (abfd, (int) PRIV (section_count));
-      if (PRIV (sections)[PRIV (section_count)] == 0)
-       return -1;
-      PRIV (section_count)++;
-    }
-
-  return 0;
-}
-
-/* tir_sta
-
-   Vax stack commands.
-
-   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 *
-tir_sta (bfd * abfd, unsigned char *ptr)
-{
-  int cmd = *ptr++;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "tir_sta %d\n", cmd);
-#endif
-
-  switch (cmd)
-    {
-      /* stack */
-    case TIR_S_C_STA_GBL:
-      /* stack global
-        arg: cs        symbol name
-
-        stack 32 bit value of symbol (high bits set to 0).  */
-      {
-       char *name;
-       vms_symbol_entry *entry;
-
-       name = _bfd_vms_save_counted_string (ptr);
-
-       entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == NULL)
-         return NULL;
-
-       _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
-       ptr += *ptr + 1;
-      }
-      break;
-
-    case TIR_S_C_STA_SB:
-      /* stack signed byte
-        arg: by        value
-
-        stack byte value, sign extend to 32 bit.  */
-      _bfd_vms_push (abfd, (uquad) *ptr++, -1);
-      break;
-
-    case TIR_S_C_STA_SW:
-      /* stack signed short word
-        arg: sh        value
-
-        stack 16 bit value, sign extend to 32 bit.  */
-      _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
-      ptr += 2;
-      break;
-
-    case TIR_S_C_STA_LW:
-      /* stack signed longword
-        arg: lw        value
-
-        stack 32 bit value.  */
-      _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
-      ptr += 4;
-      break;
-
-    case TIR_S_C_STA_PB:
-    case TIR_S_C_STA_WPB:
-      /* stack psect base plus byte offset (word index)
-        arg: by        section index
-               (sh     section index)
-               by      signed byte offset.  */
-      {
-       unsigned long dummy;
-       int psect;
-
-       if (cmd == TIR_S_C_STA_PB)
-         psect = *ptr++;
-       else
-         {
-           psect = bfd_getl16 (ptr);
-           ptr += 2;
-         }
-
-       if ((unsigned int) psect >= PRIV (section_count))
-         alloc_section (abfd, psect);
-
-       dummy = (long) *ptr++;
-       dummy += (PRIV (sections)[psect])->vma;
-       _bfd_vms_push (abfd, (uquad) dummy, psect);
-      }
-      break;
-
-    case TIR_S_C_STA_PW:
-    case TIR_S_C_STA_WPW:
-      /* stack psect base plus word offset (word index)
-        arg: by        section index
-               (sh     section index)
-               sh      signed short offset.  */
-      {
-       unsigned long dummy;
-       int psect;
-
-       if (cmd == TIR_S_C_STA_PW)
-         psect = *ptr++;
-       else
-         {
-           psect = bfd_getl16 (ptr);
-           ptr += 2;
-         }
-
-       if ((unsigned int) psect >= PRIV (section_count))
-         alloc_section (abfd, psect);
-
-       dummy = bfd_getl16 (ptr); ptr+=2;
-       dummy += (PRIV (sections)[psect])->vma;
-       _bfd_vms_push (abfd, (uquad) dummy, psect);
-      }
-      break;
-
-    case TIR_S_C_STA_PL:
-    case TIR_S_C_STA_WPL:
-      /* stack psect base plus long offset (word index)
-        arg: by        section index
-               (sh     section index)
-               lw      signed longword offset.  */
-      {
-       unsigned long dummy;
-       int psect;
-
-       if (cmd == TIR_S_C_STA_PL)
-         psect = *ptr++;
-       else
-         {
-           psect = bfd_getl16 (ptr);
-           ptr += 2;
-         }
-
-       if ((unsigned int) psect >= PRIV (section_count))
-         alloc_section (abfd, psect);
-
-       dummy = bfd_getl32 (ptr); ptr += 4;
-       dummy += (PRIV (sections)[psect])->vma;
-       _bfd_vms_push (abfd, (uquad) dummy, psect);
-      }
-      break;
-
-    case TIR_S_C_STA_UB:
-      /* stack unsigned byte
-        arg: by        value
-
-        stack byte value.  */
-      _bfd_vms_push (abfd, (uquad) *ptr++, -1);
-      break;
-
-    case TIR_S_C_STA_UW:
-      /* stack unsigned short word
-        arg: sh        value
-
-        stack 16 bit value.  */
-      _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
-      ptr += 2;
-      break;
-
-    case TIR_S_C_STA_BFI:
-      /* stack byte from image
-        arg: none.  */
-      /* FALLTHRU  */
-    case TIR_S_C_STA_WFI:
-      /* stack byte from image
-        arg: none.  */
-      /* FALLTHRU */
-    case TIR_S_C_STA_LFI:
-      /* stack byte from image
-        arg: none.  */
-      (*_bfd_error_handler) (_("stack-from-image not implemented"));
-      return NULL;
-
-    case TIR_S_C_STA_EPM:
-      /* stack entry point mask
-        arg: cs        symbol name
-
-        stack (unsigned) entry point mask of symbol
-        err if symbol is no entry point.  */
-      {
-       char *name;
-       vms_symbol_entry *entry;
-
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == NULL)
-         return NULL;
-
-       (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
-       _bfd_vms_push (abfd, (uquad) 0, -1);
-       ptr += *ptr + 1;
-      }
-      break;
-
-    case TIR_S_C_STA_CKARG:
-      /* compare procedure argument
-        arg: cs        symbol name
-               by      argument index
-               da      argument descriptor
-
-        compare argument descriptor with symbol argument (ARG$V_PASSMECH)
-        and stack TRUE (args match) or FALSE (args dont match) value.  */
-      (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
-      _bfd_vms_push (abfd, (uquad) 1, -1);
-      break;
-
-    case TIR_S_C_STA_LSY:
-      /* stack local symbol value
-        arg:   sh      environment index
-               cs      symbol name.  */
-      {
-       int envidx;
-       char *name;
-       vms_symbol_entry *entry;
-
-       envidx = bfd_getl16 (ptr);
-       ptr += 2;
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = _bfd_vms_enter_symbol (abfd, name);
-       if (entry == NULL)
-         return NULL;
-       (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
-       _bfd_vms_push (abfd, (uquad) 0, -1);
-       ptr += *ptr + 1;
-      }
-      break;
-
-    case TIR_S_C_STA_LIT:
-      /* stack literal
-        arg:   by      literal index
-
-        stack literal.  */
-      ptr++;
-      _bfd_vms_push (abfd, (uquad) 0, -1);
-      (*_bfd_error_handler) (_("stack-literal not fully implemented"));
-      break;
-
-    case TIR_S_C_STA_LEPM:
-      /* stack local symbol entry point mask
-        arg:   sh      environment index
-               cs      symbol name
-
-        stack (unsigned) entry point mask of symbol
-        err if symbol is no entry point.  */
-      {
-       int envidx;
-       char *name;
-       vms_symbol_entry *entry;
-
-       envidx = bfd_getl16 (ptr);
-       ptr += 2;
-       name = _bfd_vms_save_counted_string (ptr);
-       entry = _bfd_vms_enter_symbol (abfd, name);
-       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;
-      }
-      break;
-
-    default:
-      (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]);
-      return NULL;
-      break;
-    }
-
-  return ptr;
-}
-
-static const char *
-tir_cmd_name (int cmd)
-{
-  switch (cmd)
-    {
-    case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB";
-    case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW";
-    case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL";
-    case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS";
-    case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB";
-    case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW";
-    case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB";
-    case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW";
-    case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR";
-    case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV";
-    case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT";
-    case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF";
-    case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT";
-    case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH";
-    case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH";
-    case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC";
-    case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC";
-    case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL";
-
-    default:
-      /* These strings have not been added yet.  */
-      abort ();
-    }
-}
-
-/* tir_sto
-
-   vax store commands
-
-   handle sto_xxx commands in tir section
-   ptr points to data area in record
-
-   See table 7-4 of the VAX/VMS linker manual.  */
-
-static unsigned char *
-tir_sto (bfd * abfd, unsigned char *ptr)
-{
-  unsigned long dummy;
-  int size;
-  int psect;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
-#endif
-
-  switch (*ptr++)
-    {
-    case TIR_S_C_STO_SB:
-      /* 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:
-      /* 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:
-      /* 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:
-      /* Store byte displaced: pop stack, sub lc+1, write byte
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      dummy -= ((PRIV (sections)[psect])->vma + 1);
-      image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
-      break;
-
-    case TIR_S_C_STO_WD:
-      /* Store word displaced: pop stack, sub lc+2, write word
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      dummy -= ((PRIV (sections)[psect])->vma + 2);
-      image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
-      break;
-
-    case TIR_S_C_STO_LD:
-      /* Store long displaced: pop stack, sub lc+4, write long
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      dummy -= ((PRIV (sections)[psect])->vma + 4);
-      image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
-      break;
-
-    case TIR_S_C_STO_LI:
-      /* 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:
-      /* Store position independent data reference: pop stack, write longword
-        arg: none.
-        FIXME: incomplete !  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      image_write_l (abfd, dummy & 0xffffffff);
-      break;
-
-    case TIR_S_C_STO_PICR:
-      /* Store position independent code reference: pop stack, write longword
-        arg: none.
-        FIXME: incomplete !  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      image_write_b (abfd, 0x9f);
-      image_write_l (abfd, dummy & 0xffffffff);
-      break;
-
-    case TIR_S_C_STO_RIVB:
-      /* 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++;
-      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
-      while (dummy-- > 0L)
-       image_dump (abfd, ptr, size, 0);
-      ptr += size;
-      break;
-
-    case TIR_S_C_STO_B:
-      /* 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:
-      /* 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:
-      /* 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)
-       image_write_b (abfd, dummy & 0xff);
-      break;
-
-    case TIR_S_C_STO_RW:
-      /* 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)
-       image_write_w (abfd, dummy & 0xffff);
-      break;
-
-    case TIR_S_C_STO_RSB:
-    case TIR_S_C_STO_RSW:
-    case TIR_S_C_STO_RL:
-    case TIR_S_C_STO_VPS:
-    case TIR_S_C_STO_USB:
-    case TIR_S_C_STO_USW:
-    case TIR_S_C_STO_RUB:
-    case TIR_S_C_STO_RUW:
-    case TIR_S_C_STO_PIRR:
-      (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1]));
-      break;
-
-    default:
-      (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]);
-      break;
-    }
-
-  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
-
-   See table 7-5 of the VAX/VMS linker manual.  */
-
-static unsigned char *
-tir_opr (bfd * abfd, unsigned char *ptr)
-{
-  long op1, op2;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
-#endif
-
-  /* Operation.  */
-  switch (*ptr++)
-    {
-    case TIR_S_C_OPR_NOP: /* No-op.  */
-      break;
-
-    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;
-
-    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;
-
-    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;
-
-    case TIR_S_C_OPR_DIV: /* Divide.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (op2 == 0)
-       _bfd_vms_push (abfd, (uquad) 0, -1);
-      else
-       _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
-      break;
-
-    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;
-
-    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;
-
-    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;
-
-    case TIR_S_C_OPR_NEG: /* Negate.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      _bfd_vms_push (abfd, (uquad) (-op1), -1);
-      break;
-
-    case TIR_S_C_OPR_COM: /* Complement.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
-      break;
-
-    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;
-
-    case TIR_S_C_OPR_ASH: /* Arithmetic shift.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (HIGHBIT (op1))       /* Shift right.  */
-       op2 >>= op1;
-      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;
-
-    case TIR_S_C_OPR_USH: /* Unsigned shift.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (HIGHBIT (op1))       /* Shift right.  */
-       op2 >>= op1;
-      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;
-
-    case TIR_S_C_OPR_ROT: /* Rotate.  */
-      op1 = (long) _bfd_vms_pop (abfd, NULL);
-      op2 = (long) _bfd_vms_pop (abfd, NULL);
-      if (HIGHBIT (0)) /* Shift right.  */
-       op2 >>= op1;
-      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;
-
-    case TIR_S_C_OPR_SEL: /* Select.  */
-      if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
-       (void) _bfd_vms_pop (abfd, NULL);
-      else
-       {
-         op1 = (long) _bfd_vms_pop (abfd, NULL);
-         (void) _bfd_vms_pop (abfd, NULL);
-         _bfd_vms_push (abfd, (uquad) op1, -1);
-       }
-      break;
-
-    case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location.  */
-    case TIR_S_C_OPR_DFLIT: /* Define a literal.  */
-      (*_bfd_error_handler) (_("%s: not supported"),
-                            tir_cmd_name (ptr[-1]));
-      break;
-
-    default:
-      (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]);
-      break;
-    }
-
-  return ptr;
-}
-
-/* Control commands
-
-   See table 7-6 of the VAX/VMS linker manual.  */
-
-static unsigned char *
-tir_ctl (bfd * abfd, unsigned char *ptr)
-{
-  unsigned long dummy;
-  int psect;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
-#endif
-
-  switch (*ptr++)
-    {
-    case TIR_S_C_CTL_SETRB:
-      /* Set relocation base: pop stack, set image location counter
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      if ((unsigned int) psect >= PRIV (section_count))
-       alloc_section (abfd, psect);
-      image_set_ptr (abfd, psect, (uquad) dummy);
-      break;
-
-    case TIR_S_C_CTL_AUGRB:
-      /* Augment relocation base: increment image location counter by offset
-        arg: lw        offset value.  */
-      dummy = bfd_getl32 (ptr);
-      image_inc_ptr (abfd, (uquad) dummy);
-      break;
-
-    case TIR_S_C_CTL_DFLOC:
-      /* Define location: pop index, save location counter under index
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, NULL);
-      (*_bfd_error_handler) (_("%s: not fully implemented"),
-                            tir_cmd_name (ptr[-1]));
-      break;
-
-    case TIR_S_C_CTL_STLOC:
-      /* Set location: pop index, restore location counter from index
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      (*_bfd_error_handler) (_("%s: not fully implemented"),
-                            tir_cmd_name (ptr[-1]));
-      break;
-
-    case TIR_S_C_CTL_STKDL:
-      /* Stack defined location: pop index, push location counter from index
-        arg: none.  */
-      dummy = _bfd_vms_pop (abfd, &psect);
-      (*_bfd_error_handler) (_("%s: not fully implemented"),
-                            tir_cmd_name (ptr[-1]));
-      break;
-
-    default:
-      (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]);
-      break;
-    }
-  return ptr;
-}
-
-/* Handle command from TIR section.  */
-
-static unsigned char *
-tir_cmd (bfd * abfd, unsigned char *ptr)
-{
-  static const struct
-  {
-    int mincod;
-    int maxcod;
-    unsigned char * (*explain) (bfd *, unsigned char *);
-  }
-  tir_table[] =
-  {
-    { 0,                TIR_S_C_MAXSTACOD, tir_sta },
-    { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto },
-    { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr },
-    { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl },
-    { -1, -1, NULL }
-  };
-  int i = 0;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
-  _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
-  if (*ptr & 0x80)
-    {
-      /* Store immediate.  */
-      i = 128 - (*ptr++ & 0x7f);
-      image_dump (abfd, ptr, i, 0);
-      ptr += i;
-    }
-  else
-    {
-      while (tir_table[i].mincod >= 0)
-       {
-         if ( (tir_table[i].mincod <= *ptr)
-              && (*ptr <= tir_table[i].maxcod))
-           {
-             ptr = tir_table[i].explain (abfd, ptr);
-             break;
-           }
-         i++;
-       }
-      if (tir_table[i].mincod < 0)
-       {
-         (*_bfd_error_handler) (_("obj code %d not found"), *ptr);
-         ptr = 0;
-       }
-    }
-
-  return ptr;
-}
-
-/* Handle command from ETIR section.  */
-
-static int
-etir_cmd (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
-{
-  static const struct
-  {
-    int mincod;
-    int maxcod;
-    bfd_boolean (*explain) (bfd *, int, unsigned char *, int *);
-  }
-  etir_table[] =
-  {
-    { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
-    { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
-    { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
-    { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
-    { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
-    { -1, -1, NULL }
-  };
-
-  int i = 0;
-
-#if VMS_DEBUG
-  _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)
-    {
-      if ( (etir_table[i].mincod <= cmd)
-          && (cmd <= etir_table[i].maxcod))
-       {
-         if (!etir_table[i].explain (abfd, cmd, ptr, quarter_relocs))
-           return -1;
-         break;
-       }
-      i++;
-    }
-
-#if VMS_DEBUG
-  _bfd_vms_debug (4, "etir_cmd: result = 0\n");
-#endif
-  return 0;
-}
-
-/* Text Information and Relocation Records (OBJ$C_TIR)
-   handle tir record.  */
-
-static int
-analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
-{
-  unsigned char *maxptr;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
-#endif
-
-  maxptr = ptr + length;
-
-  while (ptr < maxptr)
-    {
-      ptr = tir_cmd (abfd, ptr);
-      if (ptr == 0)
-       return -1;
-    }
-
-  return 0;
-}
-
-/* Text Information and Relocation Records (EOBJ$C_ETIR)
-   handle etir record.  */
-
-static int
-analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
-{
-  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
-
-  while (ptr < maxptr)
-    {
-      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 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
-  _bfd_vms_debug (3, "analyze_etir: result = %d\n", result);
-#endif
-
-  return result;
-}
-
-/* Process ETIR record
-   Return 0 on success, -1 on error.  */
-
-int
-_bfd_vms_slurp_tir (bfd * abfd, int objtype)
-{
-  int result;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "TIR/ETIR\n");
-#endif
-
-  switch (objtype)
-    {
-    case EOBJ_S_C_ETIR:
-      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:
-      PRIV (vms_rec) += 1;     /* Skip type.  */
-      PRIV (rec_size) -= 1;
-      result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
-      break;
-    default:
-      result = -1;
-      break;
-    }
-
-  return result;
-}
-
- /* Slurp relocs from ETIR sections and (temporarily) save them
-    in the per-section reloc buffer.  */
-
-int
-_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
-  _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: result = 0\n");
-#endif
-
-  return 0;
-}
-
-/* Decode relocs from the reloc buffer of the specified section
-   and internalize them in the specified buffer.  */
-
-int
-_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
-  _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;
-}
-
-/* Process LNK record
-   Return 0 on success, -1 on error
-
-   Not implemented yet.  */
-
-int
-_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
-                   int objtype ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "LNK\n");
-#endif
-
-  return 0;
-}
-\f
-/* WRITE ETIR SECTION
-
-   This is still under construction and therefore not documented.  */
-
-static void start_etir_record (bfd *abfd, int sec_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 sec_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
-start_etir_record (bfd * abfd, int sec_index, uquad offset, bfd_boolean justoffset)
-{
-  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) sec_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 SEC_INDEX and NAME.  */
-
-static void
-sto_imm (bfd *abfd, bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr,
-        int sec_index, const char *name)
-{
-  bfd_size_type size;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (8, "sto_imm %d bytes\n", ssize);
-  _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
-#endif
-
-  while (ssize > 0)
-    {
-      /* Try all the rest.  */
-      size = ssize;
-
-      if (_bfd_vms_output_check (abfd, size) < 0)
-       {
-         /* Doesn't fit, split !  */
-         end_etir_record (abfd);
-
-         if (name [0] && name[1] == 'v' && !strcmp (name, ".vmsdebug"))
-           start_another_etbt_record (abfd);
-         else
-           start_etir_record (abfd, sec_index, vaddr, FALSE);
-
-         size = _bfd_vms_output_check (abfd, 0);       /* get max size */
-         if (size > ssize)                     /* more than what's left ? */
-           size = ssize;
-       }
-
-      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
-      _bfd_vms_output_long (abfd, (unsigned long) (size));
-      _bfd_vms_output_dump (abfd, cptr, size);
-      _bfd_vms_output_flush (abfd);
-
-#if VMS_DEBUG
-      _bfd_vms_debug (10, "dumped %d bytes\n", size);
-      _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
-#endif
-
-      vaddr += size;
-      cptr += size;
-      ssize -= size;
-    }
-}
-
-/* Start ETBT record for section #index at virtual addr offset.  */
-
-static void
-start_first_etbt_record (bfd *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_LW, -1);   /* push start offset */
-  _bfd_vms_output_long (abfd, (unsigned long) 0);
-  _bfd_vms_output_flush (abfd);
-
-  _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_DFLOC, -1);        /* start = pop() */
-  _bfd_vms_output_flush (abfd);
-}
-
-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
-etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
-{
-  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
-_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
-{
-  asection *section;
-
-#if VMS_DEBUG
-  _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
-#endif
-
-  _bfd_vms_output_alignment (abfd, 4);
-
-  PRIV (vms_linkage_index) = 1;
-
-  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 (!(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)
-       {
-         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 VMS_DEBUG
-         else
-           {
-             int i = section->reloc_count;
-             arelent **rptr = section->orelocation;
-             _bfd_vms_debug (4, "%d relocations:\n", i);
-             while (i-- > 0)
-               {
-                 _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)->howto->name);
-                 rptr++;
-               }
-           }
-#endif
-
-       new_pass:
-         for (irel = 0; irel < section->reloc_count; irel++)
-           {
-             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;
-               }
-
-             size = bfd_get_reloc_size (rptr->howto);
-
-             switch (rptr->howto->type)
-               {
-               case ALPHA_R_IGNORE:
-                 break;
-
-               case ALPHA_R_REFLONG:
-                 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)
-                       {
-                         _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
-                       {
-                         _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL_LW, -1);
-                         _bfd_vms_output_counted (abfd, hash);
-                         _bfd_vms_output_flush (abfd);
-                       }
-                   }
-                 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)
-                       {
-                         _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);
-                       }
-                     else
-                       {
-                         _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL, -1);
-                         _bfd_vms_output_counted (abfd, hash);
-                         _bfd_vms_output_flush (abfd);
-                       }
-                   }
-                 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;
-               }
-
-             curr_data += size;
-             curr_addr += size;
-           } /* End of relocs loop.  */
-
-         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);
-
-      end_etir_record (abfd);
-    }
-
-  _bfd_vms_output_alignment (abfd, 2);
-  return 0;
-}
diff --git a/bfd/vms.c b/bfd/vms.c
deleted file mode 100644 (file)
index c63e175..0000000
--- a/bfd/vms.c
+++ /dev/null
@@ -1,1518 +0,0 @@
-/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
-   EVAX (openVMS/Alpha) files.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-
-   Main file.
-
-   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 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   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., 51 Franklin Street - Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
-
-#ifdef VMS
-#include <rms.h>
-#include <unixlib.h>
-#include <starlet.h>
-#define RME$C_SETRFM 0x00000001
-#include <unistd.h>
-#endif
-
-#include "sysdep.h"
-#include "bfd.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "vms.h"
-
-static bfd_boolean vms_initialize (bfd *);
-static bfd_boolean fill_section_ptr (struct bfd_hash_entry *, PTR);
-static bfd_boolean vms_fixup_sections (bfd *);
-static bfd_boolean copy_symbols (struct bfd_hash_entry *, PTR);
-static bfd_reloc_status_type reloc_nil (bfd *, arelent *, asymbol *, PTR,
-                                       asection *, bfd *, char **);
-static int vms_slurp_module (bfd *abfd);
-static int vms_slurp_image (bfd *abfd);
-static const struct bfd_target *vms_object_p (bfd *abfd);
-static bfd_boolean vms_mkobject (bfd *abfd);
-static bfd_boolean vms_write_object_contents (bfd *abfd);
-static void free_reloc_stream (bfd *abfd, asection *section, void *data);
-static bfd_boolean vms_close_and_cleanup (bfd *abfd);
-static bfd_boolean vms_new_section_hook (bfd *abfd, asection *section);
-static bfd_boolean vms_get_section_contents
-  (bfd *abfd, asection *section, PTR x1, file_ptr x2, bfd_size_type x3);
-static long vms_get_symtab_upper_bound (bfd *abfd);
-static long vms_canonicalize_symtab (bfd *abfd, asymbol **symbols);
-static void vms_print_symbol (bfd *abfd, PTR file, asymbol *symbol,
-                             bfd_print_symbol_type how);
-static void vms_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret);
-static bfd_boolean vms_bfd_is_local_label_name (bfd *abfd, const char *);
-static bfd_boolean vms_find_nearest_line
-  (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
-   const char **file, const char **func, unsigned int *line);
-static void alloc_reloc_stream (bfd *abfd, asection *section,
-                               void *alloc_error);
-static bfd_boolean vms_slurp_reloc_table (bfd *abfd, asection *section,
-                                         asymbol **symbols);
-static long vms_get_reloc_upper_bound (bfd *abfd, asection *sect);
-static long vms_canonicalize_reloc (bfd *abfd, asection *srcsec,
-                                   arelent **location, asymbol **symbols);
-static const struct reloc_howto_struct *vms_bfd_reloc_type_lookup
-  (bfd *abfd, bfd_reloc_code_real_type code);
-static bfd_boolean vms_set_arch_mach
-  (bfd *abfd, enum bfd_architecture arch, unsigned long mach);
-static bfd_boolean vms_set_section_contents
-  (bfd *abfd, asection *section, const PTR location, file_ptr offset,
-   bfd_size_type count);
-
-#define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
-#define vms_make_empty_symbol             _bfd_generic_make_empty_symbol
-#define vms_bfd_link_just_syms            _bfd_generic_link_just_syms
-#define vms_bfd_copy_link_hash_symbol_type \
-  _bfd_generic_copy_link_hash_symbol_type
-#define vms_bfd_is_group_section          bfd_generic_is_group_section
-#define vms_bfd_discard_group             bfd_generic_discard_group
-#define vms_section_already_linked        _bfd_generic_section_already_linked
-#define vms_bfd_define_common_symbol      bfd_generic_define_common_symbol
-#define vms_bfd_copy_private_header_data  _bfd_generic_bfd_copy_private_header_data
-#define vms_get_synthetic_symtab          _bfd_nodynamic_get_synthetic_symtab
-
-#define vms_bfd_copy_private_bfd_data    _bfd_generic_bfd_copy_private_bfd_data
-#define vms_bfd_free_cached_info         _bfd_generic_bfd_free_cached_info
-#define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
-#define vms_bfd_copy_private_symbol_data  _bfd_generic_bfd_copy_private_symbol_data
-#define vms_bfd_set_private_flags         _bfd_generic_bfd_set_private_flags
-#define vms_bfd_merge_private_bfd_data    _bfd_generic_bfd_merge_private_bfd_data
-#define vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
-#define vms_read_minisymbols               _bfd_generic_read_minisymbols
-#define vms_minisymbol_to_symbol           _bfd_generic_minisymbol_to_symbol
-#define vms_get_lineno                     _bfd_nosymbols_get_lineno
-#define vms_find_inliner_info              _bfd_nosymbols_find_inliner_info
-#define vms_bfd_make_debug_symbol          _bfd_nosymbols_bfd_make_debug_symbol
-\f
-#ifdef VMS_DEBUG
-/* Cause debug info to be emitted for the structure.  */
-struct vms_private_data_struct _vms_private_data_struct_dummy;
-struct vms_section_data_struct _vms_section_data_struct_dummy;
-#endif
-
-extern const bfd_target vms_vax_vec;
-extern const bfd_target vms_alpha_vec;
-
-/* Initialize private data  */
-static bfd_boolean
-vms_initialize (bfd * abfd)
-{
-  bfd_size_type amt;
-
-  bfd_set_start_address (abfd, (bfd_vma) -1);
-
-  amt = sizeof (struct vms_private_data_struct);
-  abfd->tdata.any = bfd_zalloc (abfd, amt);
-  if (abfd->tdata.any == NULL)
-    return FALSE;
-
-  if (bfd_get_flavour (abfd) == bfd_target_ovax_flavour)
-    PRIV (is_vax) = TRUE;
-
-  PRIV (file_format) = FF_UNKNOWN;
-
-  amt = sizeof (struct stack_struct) * STACKSIZE;
-  PRIV (stack) = bfd_alloc (abfd, amt);
-  if (PRIV (stack) == NULL)
-    goto error_ret1;
-
-  amt = sizeof (struct bfd_hash_table);
-  PRIV (vms_symbol_table) = bfd_alloc (abfd, amt);
-  if (PRIV (vms_symbol_table) == NULL)
-    goto error_ret1;
-
-  if (!bfd_hash_table_init (PRIV (vms_symbol_table), _bfd_vms_hash_newfunc,
-                           sizeof (vms_symbol_entry)))
-    goto error_ret1;
-
-  amt = MAX_OUTREC_SIZE;
-  PRIV (output_buf) = bfd_alloc (abfd, amt);
-  if (PRIV (output_buf) == NULL)
-    goto error_ret2;
-
-  PRIV (length_pos) = 2;
-
-  return TRUE;
-
- error_ret2:
-  bfd_hash_table_free (PRIV (vms_symbol_table));
- error_ret1:
-  bfd_release (abfd, abfd->tdata.any);
-  abfd->tdata.any = NULL;
-  return FALSE;
-}
-
-struct pair
-{
-  unsigned int section_count;
-  asection **sections;
-};
-
-/* Fill symbol->section with section pointer.
-
-   symbol->section is filled with the section index for defined symbols
-   during reading the GSD/EGSD section.  But we need the pointer to the
-   bfd section later.
-
-   It has the correct value for referenced (undefined section) symbols.
-
-   Called from bfd_hash_traverse in vms_fixup_sections.  */
-
-static bfd_boolean
-fill_section_ptr (struct bfd_hash_entry *entry, void *sections)
-{
-  asymbol *sym = ((vms_symbol_entry *)entry)->symbol;
-  struct pair *data = (struct pair *)sections;
-  unsigned long sec = (unsigned long)sym->section;
-
-  vms_debug2 ((6, "fill_section_ptr: sym %p, sec %lu\n", sym, sec));
-
-  if (sec < data->section_count)
-    {
-      sym->section = data->sections[sec];
-
-      if (strcmp (sym->name, sym->section->name) == 0)
-       sym->flags |= BSF_SECTION_SYM;
-    }
-  else if (sec == (unsigned long)-1)
-    sym->section = &bfd_und_section;
-
-  return TRUE;
-}
-
-/* Fixup section pointers in symbols.  */
-static bfd_boolean
-vms_fixup_sections (bfd * abfd)
-{
-  struct pair data;
-
-  if (PRIV (fixup_done))
-    return TRUE;
-
-  data.section_count = PRIV (section_count);
-  data.sections = PRIV (sections);
-  bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr, &data);
-
-  PRIV (fixup_done) = TRUE;
-  return TRUE;
-}
-
-/* Slurp an ordered set of VMS object records.  */
-int
-_bfd_vms_slurp_object_records (bfd * abfd)
-{
-  int err, new_type, type = -1;
-
-  do
-    {
-      vms_debug2 ((7, "reading at %08lx\n", bfd_tell (abfd)));
-
-      new_type = _bfd_vms_get_object_record (abfd);
-      if (new_type < 0)
-       {
-         vms_debug2 ((2, "next_record failed\n"));
-         return -1;
-       }
-
-      if (type == EOBJ_S_C_EGSD && new_type != EOBJ_S_C_EGSD)
-       {
-         if (! vms_fixup_sections (abfd))
-           {
-             vms_debug2 ((2, "vms_fixup_sections failed\n"));
-             return -1;
-           }
-       }
-
-      type = new_type;
-
-      switch (type)
-       {
-         case OBJ_S_C_HDR:
-         case EOBJ_S_C_EMH:
-           err = _bfd_vms_slurp_hdr (abfd, type);
-           break;
-         case OBJ_S_C_EOM:
-         case OBJ_S_C_EOMW:
-         case EOBJ_S_C_EEOM:
-           err = _bfd_vms_slurp_eom (abfd, type);
-           break;
-         case OBJ_S_C_GSD:
-         case EOBJ_S_C_EGSD:
-           err = _bfd_vms_slurp_gsd (abfd, type);
-           break;
-         case OBJ_S_C_TIR:
-         case EOBJ_S_C_ETIR:
-           err = _bfd_vms_slurp_tir (abfd, type);
-           break;
-         case OBJ_S_C_DBG:
-         case EOBJ_S_C_EDBG:
-           err = _bfd_vms_slurp_dbg (abfd, type);
-           PRIV (dst_ptr_end) = PRIV (image_ptr);
-           break;
-         case OBJ_S_C_TBT:
-         case EOBJ_S_C_ETBT:
-           err = _bfd_vms_slurp_tbt (abfd, type);
-           PRIV (dst_ptr_end) = PRIV (image_ptr);
-           break;
-         case OBJ_S_C_LNK:
-           err = _bfd_vms_slurp_lnk (abfd, type);
-           break;
-         default:
-           err = -1;
-       }
-      if (err != 0)
-       {
-         vms_debug2 ((2, "slurp type %d failed with %d\n", type, err));
-         return err;
-       }
-    }
-  while (type != EOBJ_S_C_EEOM && type != OBJ_S_C_EOM && type != OBJ_S_C_EOMW);
-
-  return 0;
-}
-
-/* Slurp a VMS module and return an error status.  */
-
-static int
-vms_slurp_module (bfd *abfd)
-{
-  int type, err;
-
-  if (PRIV (is_vax))
-    type = PRIV (vms_rec)[0];
-  else
-    type = bfd_getl16 (PRIV (vms_rec));
-
-  err = _bfd_vms_slurp_hdr (abfd, type);
-  if (err != 0)
-    {
-      bfd_set_error (bfd_error_wrong_format);
-      return err;
-    }
-
-  return _bfd_vms_slurp_object_records (abfd);
-}
-
-/* Slurp a VMS image and return an error status.  */
-
-static int
-vms_slurp_image (bfd *abfd)
-{
-  unsigned int isd_offset, ihs_offset;
-  int err;
-
-  err = _bfd_vms_slurp_ihd (abfd, &isd_offset, &ihs_offset);
-  if (err != 0)
-    {
-      bfd_set_error (bfd_error_wrong_format);
-      return err;
-    }
-
-  err = _bfd_vms_slurp_isd (abfd, isd_offset);
-  if (err != 0)
-    {
-      bfd_set_error (bfd_error_wrong_format);
-      return err;
-    }
-
-  return _bfd_vms_slurp_ihs (abfd, ihs_offset);
-}
-
-/* Check the format for a file being read.
-   Return a (bfd_target *) if it's an object file or zero if not.  */
-
-static const struct bfd_target *
-vms_object_p (bfd *abfd)
-{
-  const struct bfd_target *target_vector;
-  const bfd_arch_info_type *arch;
-  PTR tdata_save = abfd->tdata.any;
-  bfd_vma saddr_save = bfd_get_start_address (abfd);
-  int err = 0;
-
-  vms_debug2 ((1, "vms_object_p(%p)\n", abfd));
-
-  if (!vms_initialize (abfd))
-    goto error_ret;
-
-  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
-    goto err_wrong_format;
-
-  switch (_bfd_vms_get_first_record (abfd))
-    {
-    case FT_UNKNOWN:
-    default:
-      err = -1;
-      break;
-
-    case FT_MODULE:
-      err = vms_slurp_module (abfd);
-      break;
-
-    case FT_IMAGE:
-      err = vms_slurp_image (abfd);
-      break;
-    }
-
-  if (err != 0)
-    goto err_wrong_format;
-
-  if (PRIV (is_vax))
-    {
-      if (! vms_fixup_sections (abfd))
-       {
-         vms_debug2 ((2, "vms_fixup_sections failed\n"));
-         goto err_wrong_format;
-       }
-
-      target_vector = &vms_vax_vec;
-      arch = bfd_scan_arch ("vax");
-
-      vms_debug2 ((2, "arch is vax\n"));
-    }
-  else
-    {
-      /* Set arch_info to alpha.   */
-      target_vector = &vms_alpha_vec;
-      arch = bfd_scan_arch ("alpha");
-      vms_debug2 ((2, "arch is alpha\n"));
-    }
-
-  abfd->arch_info = arch;
-  return target_vector;
-
- err_wrong_format:
-  bfd_set_error (bfd_error_wrong_format);
-
- error_ret:
-  if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
-    bfd_release (abfd, abfd->tdata.any);
-  abfd->tdata.any = tdata_save;
-  bfd_set_start_address (abfd, saddr_save);
-  return NULL;
-}
-
-/* Set the format of a file being written.  */
-
-static bfd_boolean
-vms_mkobject (bfd * abfd)
-{
-  const bfd_arch_info_type *arch;
-
-  vms_debug2 ((1, "vms_mkobject (%p)\n", abfd));
-
-  if (!vms_initialize (abfd))
-    return FALSE;
-
-  if (PRIV (is_vax))
-    arch = bfd_scan_arch ("vax");
-  else
-    arch = bfd_scan_arch ("alpha");
-
-  if (arch == 0)
-    {
-      bfd_set_error(bfd_error_wrong_format);
-      return FALSE;
-    }
-
-  abfd->arch_info = arch;
-  return TRUE;
-}
-
-/* Write cached information into a file being written, at bfd_close.  */
-
-static bfd_boolean
-vms_write_object_contents (bfd * abfd)
-{
-  vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd));
-
-  if (abfd->section_count > 0)                 /* we have sections */
-    {
-      if (PRIV (is_vax))
-       {
-         if (_bfd_vms_write_hdr (abfd, OBJ_S_C_HDR) != 0)
-           return FALSE;
-         if (_bfd_vms_write_gsd (abfd, OBJ_S_C_GSD) != 0)
-           return FALSE;
-         if (_bfd_vms_write_tir (abfd, OBJ_S_C_TIR) != 0)
-           return FALSE;
-         if (_bfd_vms_write_tbt (abfd, OBJ_S_C_TBT) != 0)
-           return FALSE;
-         if (_bfd_vms_write_dbg (abfd, OBJ_S_C_DBG) != 0)
-           return FALSE;
-         if (abfd->section_count > 255)
-           {
-             if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOMW) != 0)
-               return FALSE;
-           }
-         else
-           {
-             if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOM) != 0)
-               return FALSE;
-           }
-       }
-      else
-       {
-         if (_bfd_vms_write_hdr (abfd, EOBJ_S_C_EMH) != 0)
-           return FALSE;
-         if (_bfd_vms_write_gsd (abfd, EOBJ_S_C_EGSD) != 0)
-           return FALSE;
-         if (_bfd_vms_write_tir (abfd, EOBJ_S_C_ETIR) != 0)
-           return FALSE;
-         if (_bfd_vms_write_tbt (abfd, EOBJ_S_C_ETBT) != 0)
-           return FALSE;
-         if (_bfd_vms_write_dbg (abfd, EOBJ_S_C_EDBG) != 0)
-           return FALSE;
-         if (_bfd_vms_write_eom (abfd, EOBJ_S_C_EEOM) != 0)
-           return FALSE;
-       }
-    }
-  return TRUE;
-}
-
-/* 4.1, generic.  */
-
-/* Free the reloc buffer for the specified section.  */
-
-static void
-free_reloc_stream (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
-                  void *data ATTRIBUTE_UNUSED)
-{
-  if (vms_section_data (section)->reloc_stream)
-    free (vms_section_data (section)->reloc_stream);
-}
-
-#ifdef VMS
-/* Convert the file to variable record length format. This is done
-   using undocumented system call sys$modify().
-   Pure VMS version.  */
-
-static void
-vms_convert_to_var (char *vms_filename)
-{
-  struct FAB fab = cc$rms_fab;
-
-  fab.fab$l_fna = vms_filename;
-  fab.fab$b_fns = strlen (vms_filename);
-  fab.fab$b_fac = FAB$M_PUT;
-  fab.fab$l_fop = FAB$M_ESC;
-  fab.fab$l_ctx = RME$C_SETRFM;
-
-  sys$open (&fab);
-
-  fab.fab$b_rfm = FAB$C_VAR;
-
-  sys$modify (&fab);
-  sys$close (&fab);
-}
-
-static int
-vms_convert_to_var_1 (char *filename, int type)
-{
-  if (type != DECC$K_FILE)
-    return FALSE;
-  vms_convert_to_var (filename);
-  return TRUE;
-}
-
-/* Convert the file to variable record length format. This is done
-   using undocumented system call sys$modify().
-   Unix filename version.  */
-
-static int
-vms_convert_to_var_unix_filename (const char *unix_filename)
-{
-  if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
-    return FALSE;
-  return TRUE;
-}
-#endif /* VMS */
-
-/* Called when the BFD is being closed to do any necessary cleanup.  */
-
-static bfd_boolean
-vms_close_and_cleanup (bfd * abfd)
-{
-  vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd));
-
-  if (abfd == NULL || abfd->tdata.any == NULL)
-    return TRUE;
-
-  if (PRIV (vms_buf) != NULL)
-    free (PRIV (vms_buf));
-
-  if (PRIV (sections) != NULL)
-    free (PRIV (sections));
-
-  if (PRIV (vms_symbol_table))
-    bfd_hash_table_free (PRIV (vms_symbol_table));
-
-  bfd_map_over_sections (abfd, free_reloc_stream, NULL);
-
-  bfd_release (abfd, abfd->tdata.any);
-  abfd->tdata.any = NULL;
-
-#ifdef VMS
-  if (abfd->direction == write_direction)
-    {
-      /* Last step on VMS is to convert the file to variable record length
-        format.  */
-      if (bfd_cache_close (abfd) != TRUE)
-       return FALSE;
-      if (vms_convert_to_var_unix_filename (abfd->filename) != TRUE)
-       return FALSE;
-    }
-#endif
-
-  return TRUE;
-}
-
-/* Called when a new section is created.  */
-
-static bfd_boolean
-vms_new_section_hook (bfd * abfd, asection *section)
-{
-  bfd_size_type amt;
-
-  /* Count hasn't been incremented yet.  */
-  unsigned int section_count = abfd->section_count + 1;
-
-  vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
-               abfd, section->index, section->name, section_count));
-
-  bfd_set_section_alignment (abfd, section, 0);
-
-  if (section_count > PRIV (section_count))
-    {
-      amt = section_count;
-      amt *= sizeof (asection *);
-      PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
-      if (PRIV (sections) == NULL)
-       return FALSE;
-      PRIV (section_count) = section_count;
-    }
-
-  vms_debug2 ((6, "section_count: %d\n", PRIV (section_count)));
-
-  PRIV (sections)[section->index] = section;
-
-  vms_debug2 ((7, "%d: %s\n", section->index, section->name));
-
-  amt = sizeof (struct vms_section_data_struct);
-  section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
-  if (section->used_by_bfd == NULL)
-    return FALSE;
-
-  return _bfd_generic_new_section_hook (abfd, section);
-}
-
-/* Read the contents of a section.
-   buf points to a buffer of buf_size bytes to be filled with
-   section data (starting at offset into section)  */
-
-static bfd_boolean
-vms_get_section_contents (bfd * abfd ATTRIBUTE_UNUSED,
-                         asection *section ATTRIBUTE_UNUSED,
-                         void * buf ATTRIBUTE_UNUSED,
-                         file_ptr offset ATTRIBUTE_UNUSED,
-                         bfd_size_type buf_size ATTRIBUTE_UNUSED)
-{
-  bfd_size_type size = section->size;
-
-  vms_debug2 ((1, "vms_get_section_contents (%p, %s, %p, off %ld, size %d)\n",
-               abfd, section->name, buf, offset, (int)buf_size));
-
-  if (section->contents)
-    abort ();
-
-  section->contents = (unsigned char *) bfd_malloc (size);
-
-  if (section->contents == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return FALSE;
-    }
-
-  if (bfd_seek (abfd, section->filepos, SEEK_SET))
-    {
-      bfd_set_error (bfd_error_file_truncated);
-      return FALSE;
-    }
-
-  if (bfd_bread (section->contents, size, abfd) != size)
-    {
-      bfd_set_error (bfd_error_file_truncated);
-      return FALSE;
-    }
-
-  section->flags |= SEC_IN_MEMORY;
-
-  if (buf)
-    memcpy (buf, section->contents + offset, (size_t) buf_size);
-
-  return TRUE;
-}
-
-/* Part 4.5, symbols.  */
-
-/* Return the number of bytes required to store a vector of pointers
-   to asymbols for all the symbols in the BFD abfd, including a
-   terminal NULL pointer. If there are no symbols in the BFD,
-   then return 0.  If an error occurs, return -1.  */
-
-static long
-vms_get_symtab_upper_bound (bfd * abfd)
-{
-  vms_debug2 ((1, "vms_get_symtab_upper_bound (%p), %d symbols\n",
-               abfd, PRIV (gsd_sym_count)));
-
-  return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
-}
-
-/* Copy symbols from hash table to symbol vector
-
-   called from bfd_hash_traverse in vms_canonicalize_symtab
-   init counter to 0 if entry == 0.  */
-
-static bfd_boolean
-copy_symbols (struct bfd_hash_entry *entry, void * arg)
-{
-  bfd * abfd = (bfd *) arg;
-
-  if (entry == NULL)   /* Init counter.  */
-    PRIV (symnum) = 0;
-  else                 /* Fill vector, inc counter.  */
-    PRIV (symcache)[PRIV (symnum)++] = ((vms_symbol_entry *)entry)->symbol;
-
-  return TRUE;
-}
-
-/* Read the symbols from the BFD abfd, and fills in the vector
-   location with pointers to the symbols and a trailing NULL.
-
-   Return number of symbols read.   */
-
-static long
-vms_canonicalize_symtab (bfd * abfd, asymbol **symbols)
-{
-  vms_debug2 ((1, "vms_canonicalize_symtab (%p, <ret>)\n", abfd));
-
-  /* Init counter.  */
-  copy_symbols (NULL, abfd);
-
-  /* Traverse table and fill symbols vector.  */
-  PRIV (symcache) = symbols;
-  bfd_hash_traverse (PRIV (vms_symbol_table), copy_symbols, abfd);
-
-  symbols[PRIV (gsd_sym_count)] = NULL;
-
-  return PRIV (gsd_sym_count);
-}
-
-/* Print symbol to file according to how. how is one of
-   bfd_print_symbol_name       just print the name
-   bfd_print_symbol_more       print more (???)
-   bfd_print_symbol_all        print all we know, which is not much right now :-).  */
-
-static void
-vms_print_symbol (bfd * abfd,
-                 void * file,
-                 asymbol *symbol,
-                 bfd_print_symbol_type how)
-{
-  vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n",
-               abfd, file, symbol, how));
-
-  switch (how)
-    {
-      case bfd_print_symbol_name:
-      case bfd_print_symbol_more:
-       fprintf ((FILE *)file," %s", symbol->name);
-      break;
-
-      case bfd_print_symbol_all:
-       {
-         const char *section_name = symbol->section->name;
-
-         bfd_print_symbol_vandf (abfd, file, symbol);
-
-         fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
-        }
-      break;
-    }
-}
-
-/* Return information about symbol in ret.
-
-   fill type, value and name
-   type:
-       A       absolute
-       B       bss segment symbol
-       C       common symbol
-       D       data segment symbol
-       f       filename
-       t       a static function symbol
-       T       text segment symbol
-       U       undefined
-       -       debug.  */
-
-static void
-vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
-                    asymbol *symbol,
-                    symbol_info *ret)
-{
-  asection *sec;
-
-  vms_debug2 ((1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret));
-
-  sec = symbol->section;
-
-  if (ret == NULL)
-    return;
-
-  if (sec == 0)
-    ret->type = 'U';
-  else if (bfd_is_com_section (sec))
-    ret->type = 'C';
-  else if (bfd_is_abs_section (sec))
-    ret->type = 'A';
-  else if (bfd_is_und_section (sec))
-    ret->type = 'U';
-  else if (bfd_is_ind_section (sec))
-    ret->type = 'I';
-  else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
-    ret->type = 'T';
-  else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
-    ret->type = 'D';
-  else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
-    ret->type = 'B';
-  else
-    ret->type = '-';
-
-  if (ret->type != 'U')
-    ret->value = symbol->value + symbol->section->vma;
-  else
-    ret->value = 0;
-  ret->name = symbol->name;
-}
-
-/* Return TRUE if the given symbol sym in the BFD abfd is
-   a compiler generated local label, else return FALSE.  */
-
-static bfd_boolean
-vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
-                            const char *name)
-{
-  vms_debug2 ((1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name));
-  return name[0] == '$';
-}
-
-/* Provided a BFD, a section and an offset into the section, calculate and
-   return the name of the source file and the line nearest to the wanted
-   location.  */
-
-static bfd_boolean
-vms_find_nearest_line (bfd * abfd ATTRIBUTE_UNUSED,
-                      asection *section ATTRIBUTE_UNUSED,
-                      asymbol **symbols ATTRIBUTE_UNUSED,
-                      bfd_vma offset ATTRIBUTE_UNUSED,
-                      const char **file ATTRIBUTE_UNUSED,
-                      const char **func ATTRIBUTE_UNUSED,
-                      unsigned int *line ATTRIBUTE_UNUSED)
-{
-  vms_debug2 ((1, "vms_find_nearest_line (%p, %s, %p, %ld, ...)\n",
-               abfd, section->name, symbols, (long int)offset));
-  return _bfd_vms_find_nearest_dst_line (abfd, section, symbols, offset, file, func, line);
-}
-
-/* Part 4.6, relocations.  */
-
-/* Allocate the reloc buffer for the specified section.  */
-
-static void
-alloc_reloc_stream (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
-                   void *alloc_error)
-{
-  unsigned char *ptr;
-
-  /* If there were no relocations, there is nothing to do.  */
-  if (section->reloc_count == 0)
-    return;
-
-  ptr = bfd_malloc (vms_section_data (section)->reloc_size);
-  if (ptr == NULL)
-    {
-      *(bfd_boolean *)alloc_error = TRUE;
-      return;
-    }
-
-  vms_section_data (section)->reloc_stream = ptr;
-}
-
-/* Read in the relocs for the specified section and internalize them.
-
-   The implementation is loosely based on the SOM code and made up
-   of 3 distinct phases:
-
-   1. When the VMS object is opened and parsed, the number and the size
-      of the relocations are computed for all sections.  This makes it
-      possible to know upfront both which sections have no relocs and
-      the size of the reloc buffers for the other sections, at virtually
-      no cost for consumers that don't care about relocs at all.
-
-   2. When vms_slurp_reloc_table is invoked for the first time on a section
-      with relocs, the object is traversed and all the reloc information
-      is saved in per-section reloc buffers.  It would be very inefficient
-      to scan the whole file on each invocation, so we slurp for all the
-      sections at once.
-
-   3. On subsequent invocations of vms_slurp_reloc_table, the relocs for the
-      specified section are fetched from the buffer, decoded and internalized.
-      The buffer is then freed since the internalized relocs are attached to
-      the section, turning additional invocations of vms_slurp_reloc_table
-      on the same section into no-ops.
-
-   Since VMS objects have very few sections, it could be profitable to merge
-   phase #2 and phase #3, i.e. to decode and internalize the relocs for all
-   the sections at once.  The current implementation is more elegant.  */
-
-static bfd_boolean
-vms_slurp_reloc_table (bfd *abfd, asection *section, asymbol **symbols)
-{
-  arelent *internal_relocs;
-  bfd_size_type amt;
-  int err;
-
-  /* If there were no relocations, there is nothing to do.  */
-  if (section->reloc_count == 0)
-    return TRUE;
-
-  /* Return saved information about the relocations if it is available.  */
-  if (section->relocation != NULL)
-    return TRUE;
-
-  /* If the relocation stream has not been slurped, do it now.  */
-  if (vms_section_data (section)->reloc_stream == NULL)
-    {
-      bfd_boolean alloc_error = FALSE;
-      int type;
-
-      /* Size the reloc buffer for each section.  */
-      bfd_map_over_sections (abfd, alloc_reloc_stream, &alloc_error);
-      if (alloc_error)
-       return FALSE;
-
-      if (bfd_seek (abfd, 0, SEEK_SET) != 0)
-       return FALSE;
-
-      /* Reset section pointer.  */
-      PRIV (image_section) = NULL;
-
-      do
-       {
-         type = _bfd_vms_get_object_record (abfd);
-         if (type != EOBJ_S_C_ETIR
-             && type != EOBJ_S_C_EDBG
-             && type != EOBJ_S_C_ETBT)
-           continue;
-         err = _bfd_vms_slurp_relocs (abfd);
-         if (err != 0)
-           {
-             vms_debug2 ((2, "slurp relocs failed with %d\n", err));
-             return FALSE;
-           }
-       }
-      while (type != EOBJ_S_C_EEOM);
-    }
-
-  amt = section->reloc_count * sizeof (arelent);
-  internal_relocs = (arelent *) bfd_zalloc (abfd, amt);
-  if (internal_relocs == NULL)
-    return FALSE;
-
-  /* Decode and internalize the relocations.  */
-  err = _bfd_vms_decode_relocs (abfd, internal_relocs, section, symbols);
-  if (err != 0)
-    {
-      vms_debug2 ((2, "decode relocs failed with %d\n", err));
-      return FALSE;
-    }
-
-  /* We're done with the external relocations.  Free them.  */
-  free (vms_section_data (section)->reloc_stream);
-  vms_section_data (section)->reloc_stream = NULL;
-
-  /* Save our results and return success.  */
-  section->relocation = internal_relocs;
-  return TRUE;
-}
-
-/* Return the number of bytes required to store the relocation
-   information associated with the given section.  */
-
-static long
-vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
-{
-  return (section->reloc_count + 1) * sizeof (arelent *);
-}
-
-/* Convert relocations from VMS (external) form into BFD internal
-   form.  Return the number of relocations.  */
-
-static long
-vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
-                       asymbol **symbols)
-{
-  arelent *tblptr;
-  int count;
-
-  if (! vms_slurp_reloc_table (abfd, section, symbols))
-    return -1;
-
-  count = section->reloc_count;
-  tblptr = section->relocation;
-
-  while (count--)
-    *relptr++ = tblptr++;
-
-  *relptr = (arelent *) NULL;
-  return section->reloc_count;
-}
-\f
-/* This is just copied from ecoff-alpha, needs to be fixed probably.  */
-
-/* How to process the various reloc types.  */
-
-static bfd_reloc_status_type
-reloc_nil (bfd * abfd ATTRIBUTE_UNUSED,
-          arelent *reloc ATTRIBUTE_UNUSED,
-          asymbol *sym ATTRIBUTE_UNUSED,
-          void * data ATTRIBUTE_UNUSED,
-          asection *sec ATTRIBUTE_UNUSED,
-          bfd *output_bfd ATTRIBUTE_UNUSED,
-          char **error_message ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
-  vms_debug (1, "reloc_nil (abfd %p, output_bfd %p)\n", abfd, output_bfd);
-  vms_debug (2, "In section %s, symbol %s\n",
-       sec->name, sym->name);
-  vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
-               reloc->sym_ptr_ptr[0]->name,
-               (unsigned long)reloc->address,
-               (unsigned long)reloc->addend, reloc->howto->name);
-  vms_debug (2, "data at %p\n", data);
-  /*  _bfd_hexdump (2, data, bfd_get_reloc_size (reloc->howto), 0); */
-#endif
-
-  return bfd_reloc_ok;
-}
-
-/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
-   from smaller values.  Start with zero, widen, *then* decrement.  */
-#define MINUS_ONE      (((bfd_vma)0) - 1)
-
-static reloc_howto_type alpha_howto_table[] =
-{
-  HOWTO (ALPHA_R_IGNORE,       /* Type.  */
-        0,                     /* Rightshift.  */
-        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        8,                     /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "IGNORE",              /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        0,                     /* Source mask */
-        0,                     /* Dest mask.  */
-        TRUE),                 /* PC rel offset.  */
-
-  /* A 64 bit reference to a symbol.  */
-  HOWTO (ALPHA_R_REFQUAD,      /* Type.  */
-        0,                     /* Rightshift.  */
-        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        64,                    /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_bitfield, /* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "REFQUAD",             /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        MINUS_ONE,             /* Source mask.  */
-        MINUS_ONE,             /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* A 21 bit branch.  The native assembler generates these for
-     branches within the text segment, and also fills in the PC
-     relative offset in the instruction.  */
-  HOWTO (ALPHA_R_BRADDR,       /* Type.  */
-        2,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        21,                    /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_signed, /* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "BRADDR",              /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        0x1fffff,              /* Source mask.  */
-        0x1fffff,              /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* A hint for a jump to a register.  */
-  HOWTO (ALPHA_R_HINT,         /* Type.  */
-        2,                     /* Rightshift.  */
-        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        14,                    /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "HINT",                /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        0x3fff,                /* Source mask.  */
-        0x3fff,                /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* 16 bit PC relative offset.  */
-  HOWTO (ALPHA_R_SREL16,       /* Type.  */
-        0,                     /* Rightshift.  */
-        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        16,                    /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_signed, /* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "SREL16",              /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        0xffff,                /* Source mask.  */
-        0xffff,                /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* 32 bit PC relative offset.  */
-  HOWTO (ALPHA_R_SREL32,       /* Type.  */
-        0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        32,                    /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_signed, /* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "SREL32",              /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* A 64 bit PC relative offset.  */
-  HOWTO (ALPHA_R_SREL64,       /* Type.  */
-        0,                     /* Rightshift.  */
-        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        64,                    /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_signed, /* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "SREL64",              /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        MINUS_ONE,             /* Source mask.  */
-        MINUS_ONE,             /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* Push a value on the reloc evaluation stack.  */
-  HOWTO (ALPHA_R_OP_PUSH,      /* Type.  */
-        0,                     /* Rightshift.  */
-        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "OP_PUSH",             /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Source mask.  */
-        0,                     /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* Store the value from the stack at the given address.  Store it in
-     a bitfield of size r_size starting at bit position r_offset.  */
-  HOWTO (ALPHA_R_OP_STORE,     /* Type.  */
-        0,                     /* Rightshift.  */
-        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        64,                    /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "OP_STORE",            /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Source mask.  */
-        MINUS_ONE,             /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* Subtract the reloc address from the value on the top of the
-     relocation stack.  */
-  HOWTO (ALPHA_R_OP_PSUB,      /* Type.  */
-        0,                     /* Rightshift.  */
-        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "OP_PSUB",             /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Source mask.  */
-        0,                     /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* Shift the value on the top of the relocation stack right by the
-     given value.  */
-  HOWTO (ALPHA_R_OP_PRSHIFT,   /* Type.  */
-        0,                     /* Rightshift.  */
-        0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "OP_PRSHIFT",          /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Source mask.  */
-        0,                     /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* Hack. Linkage is done by linker.  */
-  HOWTO (ALPHA_R_LINKAGE,      /* Type.  */
-        0,                     /* Rightshift.  */
-        8,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        256,                   /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "LINKAGE",             /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Source mask.  */
-        0,                     /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* A 32 bit reference to a symbol.  */
-  HOWTO (ALPHA_R_REFLONG,      /* Type.  */
-        0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        32,                    /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_bitfield, /* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "REFLONG",             /* Name.  */
-        TRUE,                  /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  /* A 64 bit reference to a procedure, written as 32 bit value.  */
-  HOWTO (ALPHA_R_CODEADDR,     /* Type.  */
-        0,                     /* Rightshift.  */
-        4,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        64,                    /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_signed,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "CODEADDR",            /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  HOWTO (ALPHA_R_NOP,          /* Type.  */
-        0,                     /* Rightshift.  */
-        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH
-           because the calculations for the 3 relocations are the same.
-           See B.4.5.2 of the OpenVMS Linker Utility Manual.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.   */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "NOP",                 /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  HOWTO (ALPHA_R_BSR,          /* Type.  */
-        0,                     /* Rightshift.  */
-        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "BSR",                 /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  HOWTO (ALPHA_R_LDA,          /* Type.  */
-        0,                     /* Rightshift.  */
-        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        FALSE,                 /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "LDA",                 /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-
-  HOWTO (ALPHA_R_BOH,          /* Type.  */
-        0,                     /* Rightshift.  */
-        3,                     /* Size (0 = byte, 1 = short, 2 = long, 3 = nil).  */
-        0,                     /* Bitsize.  */
-        TRUE,                  /* PC relative.  */
-        0,                     /* Bitpos.  */
-        complain_overflow_dont,/* Complain_on_overflow.  */
-        reloc_nil,             /* Special_function.  */
-        "BOH",                 /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0xffffffff,            /* Source mask.  */
-        0xffffffff,            /* Dest mask.  */
-        FALSE),                /* PC rel offset.  */
-};
-
-/* Return a pointer to a howto structure which, when invoked, will perform
-   the relocation code on data from the architecture noted.  */
-
-static const struct reloc_howto_struct *
-vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
-                          bfd_reloc_code_real_type code)
-{
-  int alpha_type;
-
-  vms_debug2 ((1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code));
-
-  switch (code)
-    {
-      case BFD_RELOC_16:               alpha_type = ALPHA_R_SREL16;    break;
-      case BFD_RELOC_32:               alpha_type = ALPHA_R_REFLONG;   break;
-      case BFD_RELOC_64:               alpha_type = ALPHA_R_REFQUAD;   break;
-      case BFD_RELOC_CTOR:             alpha_type = ALPHA_R_REFQUAD;   break;
-      case BFD_RELOC_23_PCREL_S2:      alpha_type = ALPHA_R_BRADDR;    break;
-      case BFD_RELOC_ALPHA_HINT:       alpha_type = ALPHA_R_HINT;      break;
-      case BFD_RELOC_16_PCREL:         alpha_type = ALPHA_R_SREL16;    break;
-      case BFD_RELOC_32_PCREL:         alpha_type = ALPHA_R_SREL32;    break;
-      case BFD_RELOC_64_PCREL:         alpha_type = ALPHA_R_SREL64;    break;
-      case BFD_RELOC_ALPHA_LINKAGE:    alpha_type = ALPHA_R_LINKAGE;   break;
-      case BFD_RELOC_ALPHA_CODEADDR:   alpha_type = ALPHA_R_CODEADDR;  break;
-      case BFD_RELOC_ALPHA_NOP:                alpha_type = ALPHA_R_NOP;       break;
-      case BFD_RELOC_ALPHA_BSR:                alpha_type = ALPHA_R_BSR;       break;
-      case BFD_RELOC_ALPHA_LDA:                alpha_type = ALPHA_R_LDA;       break;
-      case BFD_RELOC_ALPHA_BOH:                alpha_type = ALPHA_R_BOH;       break;
-      default:
-       (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
-       return NULL;
-    }
-  vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name));
-  return & alpha_howto_table[alpha_type];
-}
-
-static reloc_howto_type *
-vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-                          const char *r_name)
-{
-  unsigned int i;
-
-  for (i = 0;
-       i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
-       i++)
-    if (alpha_howto_table[i].name != NULL
-       && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
-      return &alpha_howto_table[i];
-
-  return NULL;
-}
-
-/* Part 4.7, writing an object file.  */
-
-/* Set the architecture and machine type in BFD abfd to arch and mach.
-   Find the correct pointer to a structure and insert it into the arch_info
-   pointer.  */
-
-static bfd_boolean
-vms_set_arch_mach (bfd * abfd,
-                  enum bfd_architecture arch ATTRIBUTE_UNUSED,
-                  unsigned long mach ATTRIBUTE_UNUSED)
-{
-  vms_debug2 ((1, "vms_set_arch_mach (%p, %d, %ld)\n", abfd, arch, mach));
-
-  if (arch != bfd_arch_alpha
-      && arch != bfd_arch_vax
-      && arch != bfd_arch_unknown)
-    return FALSE;
-
-  return bfd_default_set_arch_mach (abfd, arch, mach);
-}
-
-/* Sets the contents of the section section in BFD abfd to the data starting
-   in memory at LOCATION. The data is written to the output section starting
-   at offset offset for count bytes.
-
-   Normally TRUE is returned, else FALSE. Possible error returns are:
-   o bfd_error_no_contents - The output section does not have the
-       SEC_HAS_CONTENTS attribute, so nothing can be written to it.
-   o and some more too  */
-
-static bfd_boolean
-vms_set_section_contents (bfd * abfd,
-                         asection *section,
-                         const void * location,
-                         file_ptr offset,
-                         bfd_size_type count)
-{
-#if VMS_DEBUG
-  vms_debug (1, "vms_set_section_contents (%p, sec %s, loc %p, off %ld, count %d)\n",
-            abfd, section->name, location, (long int)offset, (int)count);
-  vms_debug (2, "size %d\n", (int) section->size);
-#endif
-  if (count == (bfd_size_type)0)
-    return TRUE;
-
-  if (section->contents == NULL)
-    section->contents = bfd_alloc (abfd, section->size);
-  if (section->contents == NULL)
-    return FALSE;
-
-  memcpy (section->contents + offset, location, (size_t) count);
-  return TRUE;
-}
-
-static bfd_boolean
-vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr)
-{
-  FILE *file = (FILE *)ptr;
-
-  fprintf (file, _("structure level: %d\n"), PRIV(hdr_data.hdr_b_strlvl));
-  fprintf (file, _("module name    : %s\n"), PRIV(hdr_data.hdr_t_name));
-  fprintf (file, _("module version : %s\n"), PRIV(hdr_data.hdr_t_version));
-  fprintf (file, _("module date    : %s\n"), PRIV(hdr_data.hdr_t_date));
-  fprintf (file, _("language name  : %s\n"), PRIV(hdr_data.hdr_c_lnm));
-  fprintf (file, _("source files   : %s\n"), PRIV(hdr_data.hdr_c_src));
-  fprintf (file, _("title          : %s\n"), PRIV(hdr_data.hdr_c_ttl));
-
-  return TRUE;
-}
-\f
-const bfd_target vms_alpha_vec =
-{
-  "vms-alpha",                 /* Name.  */
-  bfd_target_evax_flavour,
-  BFD_ENDIAN_LITTLE,           /* Data byte order is little.  */
-  BFD_ENDIAN_LITTLE,           /* Header byte order is little.  */
-
-  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
-   | WP_TEXT | D_PAGED),       /* Object flags.  */
-  (SEC_ALLOC | SEC_LOAD | SEC_RELOC
-   | SEC_READONLY | SEC_CODE | SEC_DATA
-   | SEC_HAS_CONTENTS | SEC_IN_MEMORY),                /* Sect flags.  */
-  0,                           /* symbol_leading_char.  */
-  ' ',                         /* ar_pad_char.  */
-  15,                          /* ar_max_namelen.  */
-  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
-  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
-  bfd_getl16, bfd_getl_signed_16, bfd_putl16,
-  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
-  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
-  bfd_getl16, bfd_getl_signed_16, bfd_putl16,
-
-  {_bfd_dummy_target, vms_object_p,            /* bfd_check_format.  */
-   _bfd_vms_lib_alpha_archive_p, _bfd_dummy_target},
-  {bfd_false, vms_mkobject,                    /* bfd_set_format.  */
-   _bfd_vms_lib_mkarchive, bfd_false},
-  {bfd_false, vms_write_object_contents,       /* bfd_write_contents.  */
-   _bfd_vms_lib_write_archive_contents, bfd_false},
-
-  BFD_JUMP_TABLE_GENERIC (vms),
-  BFD_JUMP_TABLE_COPY (vms),
-  BFD_JUMP_TABLE_CORE (_bfd_nocore),
-  BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib),
-  BFD_JUMP_TABLE_SYMBOLS (vms),
-  BFD_JUMP_TABLE_RELOCS (vms),
-  BFD_JUMP_TABLE_WRITE (vms),
-  BFD_JUMP_TABLE_LINK (_bfd_nolink),
-  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
-
-  NULL,
-
-  (PTR) 0
-};
-
-const bfd_target vms_vax_vec =
-{
-  "vms-vax",                   /* Name.  */
-  bfd_target_ovax_flavour,
-  BFD_ENDIAN_LITTLE,           /* Data byte order is little.  */
-  BFD_ENDIAN_LITTLE,           /* Header byte order is little.  */
-
-  (HAS_RELOC | HAS_SYMS        /* Object flags.  */
-   | WP_TEXT | D_PAGED
-   | HAS_LINENO | HAS_DEBUG | HAS_LOCALS),
-
-  (SEC_ALLOC | SEC_LOAD | SEC_RELOC
-   | SEC_READONLY | SEC_CODE | SEC_DATA
-   | SEC_HAS_CONTENTS | SEC_IN_MEMORY),                /* Sect flags.  */
-  0,                           /* symbol_leading_char */
-  ' ',                         /* ar_pad_char */
-  15,                          /* ar_max_namelen */
-  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
-  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
-  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
-  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
-  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
-  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
-
-  {_bfd_dummy_target, vms_object_p,            /* bfd_check_format.  */
-   _bfd_dummy_target, _bfd_dummy_target},
-  {bfd_false, vms_mkobject,                    /* bfd_set_format.  */
-   bfd_false, bfd_false},
-  {bfd_false, vms_write_object_contents,       /* bfd_write_contents.  */
-   bfd_false, bfd_false},
-
-  BFD_JUMP_TABLE_GENERIC (vms),
-  BFD_JUMP_TABLE_COPY (vms),
-  BFD_JUMP_TABLE_CORE (_bfd_nocore),
-  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
-  BFD_JUMP_TABLE_SYMBOLS (vms),
-  BFD_JUMP_TABLE_RELOCS (vms),
-  BFD_JUMP_TABLE_WRITE (vms),
-  BFD_JUMP_TABLE_LINK (_bfd_nolink),
-  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
-
-  NULL,
-
-  (PTR) 0
-};
index a40e85ebbcf5f020c20fb36e319856cd46242c13..4a3e1d0a6fc00c3c44682ca1a362d0ab38bbd78b 100644 (file)
--- a/bfd/vms.h
+++ b/bfd/vms.h
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#include <time.h>
-
 #undef vms
 #ifndef VMS_H
 #define VMS_H
 
-/* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object
-   language).  */
-
-#define VMS_BLOCK_SIZE  512
-
-/* VMS Text Information and Relocation Records (TIR/ETIR).  */
-
-#define TIR_S_C_STA_GBL                0
-#define TIR_S_C_STA_SB         1
-#define TIR_S_C_STA_SW         2
-#define TIR_S_C_STA_LW         3
-#define TIR_S_C_STA_PB         4
-#define TIR_S_C_STA_PW         5
-#define TIR_S_C_STA_PL         6
-#define TIR_S_C_STA_UB         7
-#define TIR_S_C_STA_UW         8
-#define TIR_S_C_STA_BFI        9
-#define TIR_S_C_STA_WFI        10
-#define TIR_S_C_STA_LFI        11
-#define TIR_S_C_STA_EPM        12
-#define TIR_S_C_STA_CKARG       13
-#define TIR_S_C_STA_WPB        14
-#define TIR_S_C_STA_WPW        15
-#define TIR_S_C_STA_WPL        16
-#define TIR_S_C_STA_LSY        17
-#define TIR_S_C_STA_LIT        18
-#define TIR_S_C_STA_LEPM        19
-#define TIR_S_C_MAXSTACOD       19
-#define TIR_S_C_MINSTOCOD       20
-#define TIR_S_C_STO_SB         20
-#define TIR_S_C_STO_SW         21
-#define TIR_S_C_STO_L          22
-#define TIR_S_C_STO_LW         22
-#define TIR_S_C_STO_BD         23
-#define TIR_S_C_STO_WD         24
-#define TIR_S_C_STO_LD         25
-#define TIR_S_C_STO_LI         26
-#define TIR_S_C_STO_PIDR        27
-#define TIR_S_C_STO_PICR        28
-#define TIR_S_C_STO_RSB        29
-#define TIR_S_C_STO_RSW        30
-#define TIR_S_C_STO_RL         31
-#define TIR_S_C_STO_VPS        32
-#define TIR_S_C_STO_USB        33
-#define TIR_S_C_STO_USW        34
-#define TIR_S_C_STO_RUB        35
-#define TIR_S_C_STO_RUW        36
-#define TIR_S_C_STO_B          37
-#define TIR_S_C_STO_W          38
-#define TIR_S_C_STO_RB         39
-#define TIR_S_C_STO_RW         40
-#define TIR_S_C_STO_RIVB        41
-#define TIR_S_C_STO_PIRR        42
-#define TIR_S_C_MAXSTOCOD       42
-#define TIR_S_C_MINOPRCOD       50
-#define TIR_S_C_OPR_NOP        50
-#define TIR_S_C_OPR_ADD        51
-#define TIR_S_C_OPR_SUB        52
-#define TIR_S_C_OPR_MUL        53
-#define TIR_S_C_OPR_DIV        54
-#define TIR_S_C_OPR_AND        55
-#define TIR_S_C_OPR_IOR        56
-#define TIR_S_C_OPR_EOR        57
-#define TIR_S_C_OPR_NEG        58
-#define TIR_S_C_OPR_COM        59
-#define TIR_S_C_OPR_INSV        60
-#define TIR_S_C_OPR_ASH        61
-#define TIR_S_C_OPR_USH        62
-#define TIR_S_C_OPR_ROT        63
-#define TIR_S_C_OPR_SEL        64
-#define TIR_S_C_OPR_REDEF       65
-#define TIR_S_C_OPR_DFLIT       66
-#define TIR_S_C_MAXOPRCOD       66
-#define TIR_S_C_MINCTLCOD       80
-#define TIR_S_C_CTL_SETRB       80
-#define TIR_S_C_CTL_AUGRB       81
-#define TIR_S_C_CTL_DFLOC       82
-#define TIR_S_C_CTL_STLOC       83
-#define TIR_S_C_CTL_STKDL       84
-#define TIR_S_C_MAXCTLCOD       84
-
-#define ETIR_S_C_MINSTACOD 0           /* Minimum store code.          */
-#define ETIR_S_C_STA_GBL 0             /* Stack global symbol value.   */
-#define ETIR_S_C_STA_LW 1              /* Stack longword.              */
-#define ETIR_S_C_STA_QW 2              /* Stack quadword.              */
-#define ETIR_S_C_STA_PQ 3              /* Stack psect base + quadword off.  */
-#define ETIR_S_C_STA_LI 4              /* Stack literal.               */
-#define ETIR_S_C_STA_MOD 5             /* Stack module.                */
-#define ETIR_S_C_STA_CKARG 6           /* Check Arguments.             */
-#define ETIR_S_C_MAXSTACOD 6           /* Maximum stack code.          */
-#define ETIR_S_C_MINSTOCOD 50          /* Minimum store code.          */
-#define ETIR_S_C_STO_B 50              /* Store byte.                  */
-#define ETIR_S_C_STO_W 51              /* Store word.                  */
-#define ETIR_S_C_STO_LW 52             /* Store longword.              */
-#define ETIR_S_C_STO_QW 53             /* Store quadword.              */
-#define ETIR_S_C_STO_IMMR 54           /* Store immediate Repeated.    */
-#define ETIR_S_C_STO_GBL 55            /* Store global.                */
-#define ETIR_S_C_STO_CA 56             /* Store code address.          */
-#define ETIR_S_C_STO_RB 57             /* Store relative branch.       */
-#define ETIR_S_C_STO_AB 58             /* Store absolute branch.       */
-#define ETIR_S_C_STO_OFF 59            /* Store offset within psect.   */
-#define ETIR_S_C_STO_IMM 61            /* Store immediate.             */
-#define ETIR_S_C_STO_GBL_LW 62         /* Store global Longword.       */
-#define ETIR_S_C_STO_LP_PSB 63         /* STO_LP_PSB not valid in level 2 use STC_LP_PSB.  */
-#define ETIR_S_C_STO_HINT_GBL 64       /* Store 14 bit HINT at global address.  */
-#define ETIR_S_C_STO_HINT_PS 65                /* Store 14 bit HINT at psect + offset */
-#define ETIR_S_C_MAXSTOCOD 65          /* Maximum store code.          */
-#define ETIR_S_C_MINOPRCOD 100         /* Minimum operate code.        */
-#define ETIR_S_C_OPR_NOP 100           /* No-op.                       */
-#define ETIR_S_C_OPR_ADD 101           /* Add.                         */
-#define ETIR_S_C_OPR_SUB 102           /* Subtract.                    */
-#define ETIR_S_C_OPR_MUL 103           /* Multiply.                    */
-#define ETIR_S_C_OPR_DIV 104           /* Divide.                      */
-#define ETIR_S_C_OPR_AND 105           /* Logical AND.                 */
-#define ETIR_S_C_OPR_IOR 106           /* Logical inclusive OR.        */
-#define ETIR_S_C_OPR_EOR 107           /* Logical exclusive OR.        */
-#define ETIR_S_C_OPR_NEG 108           /* Negate.                      */
-#define ETIR_S_C_OPR_COM 109           /* Complement.                  */
-#define ETIR_S_C_OPR_INSV 110          /* Insert bit field.            */
-#define ETIR_S_C_OPR_ASH 111           /* Arithmetic shift.            */
-#define ETIR_S_C_OPR_USH 112           /* Unsigned shift.              */
-#define ETIR_S_C_OPR_ROT 113           /* Rotate.                      */
-#define ETIR_S_C_OPR_SEL 114           /* Select one of three longwords on top of stack.   */
-#define ETIR_S_C_OPR_REDEF 115         /* Redefine this symbol after pass 2.  */
-#define ETIR_S_C_OPR_DFLIT 116         /* Define a literal.            */
-#define ETIR_S_C_MAXOPRCOD 116         /* Maximum operate code.        */
-#define ETIR_S_C_MINCTLCOD 150         /* Minimum control code.        */
-#define ETIR_S_C_CTL_SETRB 150         /* Set relocation base.         */
-#define ETIR_S_C_CTL_AUGRB 151         /* Augment relocation base.     */
-#define ETIR_S_C_CTL_DFLOC 152         /* Define debug location.       */
-#define ETIR_S_C_CTL_STLOC 153         /* Set debug location.          */
-#define ETIR_S_C_CTL_STKDL 154         /* Stack debug location.        */
-#define ETIR_S_C_MAXCTLCOD 154         /* Maximum control code.        */
-#define ETIR_S_C_MINSTCCOD 200         /* Minimum store-conditional code.   */
-#define ETIR_S_C_STC_LP 200            /* Store-conditional Linkage Pair.   */
-#define ETIR_S_C_STC_LP_PSB 201                /* Store-conditional Linkage Pair with Procedure Signature.  */
-#define ETIR_S_C_STC_GBL 202           /* Store-conditional Address at global address.  */
-#define ETIR_S_C_STC_GCA 203           /* Store-conditional Code Address at global address.  */
-#define ETIR_S_C_STC_PS 204            /* Store-conditional Address at psect + offset.  */
-#define ETIR_S_C_STC_NOP_GBL 205       /* Store-conditional NOP at address of global.  */
-#define ETIR_S_C_STC_NOP_PS 206                /* Store-conditional NOP at pect + offset.  */
-#define ETIR_S_C_STC_BSR_GBL 207       /* Store-conditional BSR at global address.  */
-#define ETIR_S_C_STC_BSR_PS 208                /* Store-conditional BSR at pect + offset.  */
-#define ETIR_S_C_STC_LDA_GBL 209       /* Store-conditional LDA at global address.  */
-#define ETIR_S_C_STC_LDA_PS 210                /* Store-conditional LDA at psect + offset.  */
-#define ETIR_S_C_STC_BOH_GBL 211       /* Store-conditional BSR or Hint at global address.  */
-#define ETIR_S_C_STC_BOH_PS 212                /* Store-conditional BSR or Hint at pect + offset.  */
-#define ETIR_S_C_STC_NBH_GBL 213       /* Store-conditional NOP,BSR or HINT at global address.  */
-#define ETIR_S_C_STC_NBH_PS 214                /* Store-conditional NOP,BSR or HINT at psect + offset.  */
-#define ETIR_S_C_MAXSTCCOD 214         /* Maximum store-conditional code.   */
-
-#define ETIR_S_C_HEADER_SIZE 4         /* Size of the header of a command */
-
-/* VMS Global Symbol Directory Records (GSD/EGSD).  */
-
-#define GSD_S_K_ENTRIES 1
-#define GSD_S_C_ENTRIES 1
-#define GSD_S_C_PSC     0
-#define GSD_S_C_SYM     1
-#define GSD_S_C_EPM     2
-#define GSD_S_C_PRO     3
-#define GSD_S_C_SYMW    4
-#define GSD_S_C_EPMW    5
-#define GSD_S_C_PROW    6
-#define GSD_S_C_IDC     7
-#define GSD_S_C_ENV     8
-#define GSD_S_C_LSY     9
-#define GSD_S_C_LEPM    10
-#define GSD_S_C_LPRO    11
-#define GSD_S_C_SPSC    12
-#define GSD_S_C_SYMV    13
-#define GSD_S_C_EPMV    14
-#define GSD_S_C_PROV    15
-#define GSD_S_C_MAXRECTYP       15
-
-#define EGSD_S_K_ENTRIES 2     /* Offset to first entry in record.     */
-#define EGSD_S_C_ENTRIES 2     /* Offset to first entry in record.     */
-#define EGSD_S_C_PSC 0         /* Psect definition.                    */
-#define EGSD_S_C_SYM 1         /* Symbol specification.                */
-#define EGSD_S_C_IDC 2         /* Random entity check.                 */
-#define EGSD_S_C_SPSC 5                /* Shareable image psect definition.    */
-#define EGSD_S_C_SYMV 6                /* Vectored (dual-valued) versions of SYM.  */
-#define EGSD_S_C_SYMM 7                /* Masked versions of SYM.              */
-#define EGSD_S_C_SYMG 8                /* EGST - gst version of SYM.           */
-#define EGSD_S_C_MAXRECTYP 8   /* Maximum entry type defined.          */
-
-/* Program Section Definition.  */
-#define GPS_S_M_PIC     1
-#define GPS_S_M_LIB     2
-#define GPS_S_M_OVR     4
-#define GPS_S_M_REL     8
-#define GPS_S_M_GBL     16
-#define GPS_S_M_SHR     32
-#define GPS_S_M_EXE     64
-#define GPS_S_M_RD      128
-#define GPS_S_M_WRT     256
-#define GPS_S_M_VEC     512
-#define GPS_S_K_NAME    9
-#define GPS_S_C_NAME    9
-
-#define EGPS_S_B_ALIGN    4
-#define EGPS_S_W_FLAGS    6
-#define EGPS_S_L_ALLOC    8
-#define EGPS_S_B_NAMLNG  12
-
-#define EGPS_S_V_PIC           0x0001
-#define EGPS_S_V_LIB           0x0002
-#define EGPS_S_V_OVR           0x0004
-#define EGPS_S_V_REL           0x0008
-#define EGPS_S_V_GBL           0x0010
-#define EGPS_S_V_SHR           0x0020
-#define EGPS_S_V_EXE           0x0040
-#define EGPS_S_V_RD            0x0080
-#define EGPS_S_V_WRT           0x0100
-#define EGPS_S_V_VEC           0x0200
-#define EGPS_S_V_NOMOD         0x0400
-#define EGPS_S_V_COM           0x0800
-#define EGPS_S_V_ALLOC_64BIT   0x1000
-
-/* Symbol Defintion or Reference.  */
-#define GSY_S_M_WEAK    1
-#define GSY_S_M_DEF     2
-#define GSY_S_M_UNI     4
-#define GSY_S_M_REL     8
-
-#define EGSY_S_W_FLAGS  6
-
-#define EGSY_S_V_WEAK          0x0001
-#define EGSY_S_V_DEF           0x0002
-#define EGSY_S_V_UNI           0x0004
-#define EGSY_S_V_REL           0x0008
-#define EGSY_S_V_COMM          0x0010
-#define EGSY_S_V_VECEP         0x0020
-#define EGSY_S_V_NORM          0x0040
-#define EGSY_S_V_QUAD_VAL      0x0080
-
-#define LSY_S_M_DEF     2
-#define LSY_S_M_REL     8
-
-#define ENV_S_M_DEF     1
-#define ENV_S_M_NESTED  2
-
-/* Symbol Definition.  */
-#define ESDF_S_L_VALUE     8
-#define ESDF_S_L_PSINDX   28
-#define ESDF_S_B_NAMLNG   32
-
-/* Universal Symbol Definition.  */
-#define EGST_S_W_FLAGS    6
-#define EGST_S_Q_LP_1    16
-#define EGST_S_Q_LP_2    24
-#define EGST_S_L_PSINDX  32
-#define EGST_S_B_NAMLNG  36
-
-/* Symbol Reference.  */
-#define ESRF_S_B_NAMLNG   8
-
-/* Debugger symbol definitions:  These are done by hand,
-   as no machine-readable version seems to be available.  */
-#define DST_S_C_C                7     /* Language == "C".     */
-#define DST_S_C_CXX             15     /* Language == "C++".   */
-#define DST_S_C_EPILOG         127
-#define DST_S_C_VERSION                153
-#define        DST_S_C_SOURCE          155     /* Source file.         */
-#define DST_S_C_PROLOG         162
-#define        DST_S_C_BLKBEG          176     /* Beginning of block.  */
-#define        DST_S_C_BLKEND          177     /* End of block.        */
-#define DST_S_C_ENTRY          181
-#define DST_S_C_PSECT          184
-#define        DST_S_C_LINE_NUM        185     /* Line Number.         */
-#define DST_S_C_LBLORLIT       186
-#define DST_S_C_LABEL          187
-#define        DST_S_C_MODBEG          188     /* Beginning of module. */
-#define        DST_S_C_MODEND          189     /* End of module.       */
-#define        DST_S_C_RTNBEG          190     /* Beginning of routine.*/
-#define        DST_S_C_RTNEND          191     /* End of routine.      */
-
-/* These are used with DST_S_C_LINE_NUM.  */
-#define DST_S_C_LINE_NUM_HEADER_SIZE 4
-
-#define DST_S_C_DELTA_PC_W      1      /* Incr PC.             */
-#define DST_S_C_INCR_LINUM      2      /* Incr Line #.         */
-#define DST_S_C_INCR_LINUM_W    3      /* Incr Line #.         */
-#define DST_S_C_SET_LINUM_INCR  4
-#define DST_S_C_SET_LINUM_INCR_W 5
-#define DST_S_C_RESET_LINUM_INCR 6
-#define DST_S_C_BEG_STMT_MODE   7
-#define DST_S_C_END_STMT_MODE   8
-#define DST_S_C_SET_LINE_NUM    9      /* Set Line #.          */
-#define DST_S_C_SET_PC         10
-#define DST_S_C_SET_PC_W       11
-#define DST_S_C_SET_PC_L       12
-#define DST_S_C_SET_STMTNUM    13
-#define DST_S_C_TERM           14      /* End of lines.        */
-#define DST_S_C_TERM_W         15      /* End of lines.        */
-#define        DST_S_C_SET_ABS_PC      16      /* Set PC.              */
-#define        DST_S_C_DELTA_PC_L      17      /* Incr PC.             */
-#define DST_S_C_INCR_LINUM_L   18      /* Incr Line #.         */
-#define DST_S_C_SET_LINUM_B    19      /* Set Line #.          */
-#define DST_S_C_SET_LINUM_L    20      /* Set Line #.          */
-#define        DST_S_C_TERM_L          21      /* End of lines.        */
-/* These are used with DST_S_C_SOURCE */
-#define DST_S_C_SRC_DECLFILE    1      /* Declare source file.  */
-#define DST_S_C_SRC_SETFILE     2      /* Set source file.      */
-#define DST_S_C_SRC_SETREC_L    3      /* Set record, longword value.  */
-#define DST_S_C_SRC_SETREC_W    4      /* Set record, word value.  */
-#define DST_S_C_SRC_SETLNUM_L   5      /* Set line, longword value.  */
-#define DST_S_C_SRC_SETLNUM_W   6      /* Set line, word value.  */
-#define DST_S_C_SRC_INCRLNUM_B  7      /* Increment line.  */
-#define DST_S_C_SRC_DEFLINES_W 10      /* # of line, word counter.  */
-#define DST_S_C_SRC_DEFLINES_B 11      /* # of line, byte counter.  */
-#define DST_S_C_SRC_FORMFEED   16      /* ^L counts as a record.  */
-
-#define DST_S_B_PCLINE_UNSBYTE  1
-#define DST_S_W_PCLINE_UNSWORD  1
-#define DST_S_L_PCLINE_UNSLONG  1
-
-#define DST_S_B_MODBEG_NAME    14
-#define DST_S_L_RTNBEG_ADDRESS  5
-#define DST_S_B_RTNBEG_NAME    13
-#define DST_S_L_RTNEND_SIZE     5
-
-/* These are used with DST_S_C_SOURCE.  */
-#define DST_S_C_SOURCE_HEADER_SIZE 4
-
-#define DST_S_B_SRC_DF_LENGTH    1
-#define DST_S_W_SRC_DF_FILEID    3
-#define DST_S_B_SRC_DF_FILENAME         20
-#define DST_S_B_SRC_UNSBYTE      1
-#define DST_S_W_SRC_UNSWORD      1
-#define DST_S_L_SRC_UNSLONG      1
-
-/* The following are the codes for the various data types.  Anything not on
-   the list is included under 'advanced_type'.  */
-#define DBG_S_C_UCHAR          0x02
-#define DBG_S_C_USINT          0x03
-#define DBG_S_C_ULINT          0x04
-#define DBG_S_C_UQUAD          0x05
-#define DBG_S_C_SCHAR          0x06
-#define DBG_S_C_SSINT          0x07
-#define DBG_S_C_SLINT          0x08
-#define DBG_S_C_SQUAD          0x09
-#define DBG_S_C_REAL4          0x0a
-#define DBG_S_C_REAL8          0x0b    /* D_float double.  */
-#define DBG_S_C_COMPLX4                0x0c    /* 2xF_float complex float.  */
-#define DBG_S_C_COMPLX8                0x0d    /* 2xD_float complex double.  */
-#define DBG_S_C_REAL8_G                0x1b    /* G_float double.  */
-#define DBG_S_C_COMPLX8_G      0x1d    /* 2xG_float complex double.  */
-#define DBG_S_C_FUNCTION_ADDR  0x17
-#define DBG_S_C_ADVANCED_TYPE  0xa3
-/*  Some of these are just for future reference.  [pr].  */
-#define DBG_S_C_UBITA          0x01    /* Unsigned, aligned bit field.  */
-#define DBG_S_C_UBITU          0x22    /* Unsigned, unaligned bit field.  */
-#define DBG_S_C_SBITA          0x29    /* Signed, aligned bit field.  */
-#define DBG_S_C_SBITU          0x2a    /* Signed, unaligned bit field.  */
-#define DBG_S_C_CSTRING                0x2e    /* Asciz ('\0' terminated) string.  */
-#define DBG_S_C_WCHAR          0x38    /* Wchar_t.  */
-/*  These are descriptor class codes.  */
-#define DSC_K_CLASS_S          0x01    /* Static (fixed length).  */
-#define DSC_K_CLASS_D          0x02    /* Dynamic string (not via malloc!).  */
-#define DSC_K_CLASS_A          0x04    /* Array.  */
-#define DSC_K_CLASS_UBS                0x0d    /* Unaligned bit string.  */
-
-/*  These are the codes that are used to generate the definitions of struct
-    union and enum records.  */
-#define DBG_S_C_ENUM_ITEM              0xa4
-#define DBG_S_C_ENUM_START             0xa5
-#define DBG_S_C_ENUM_END               0xa6
-#define DBG_S_C_STRUCT_ITEM            DST_K_VFLAGS_BITOFFS    /* 0xff */
-#define DBG_S_C_STRUCT_START           0xab
-#define DBG_S_C_STRUCT_END             0xac
-#define DST_K_TYPSPEC                  0xaf    /* Type specification.  */
-/* These codes are used in the generation of the symbol definition records.  */
-#define DST_K_VFLAGS_NOVAL             0x80    /* Struct definition only.  */
-#define DST_K_VFLAGS_DSC               0xfa    /* Descriptor used.  */
-#define DST_K_VFLAGS_TVS               0xfb    /* Trailing value specified.  */
-#define DST_K_VS_FOLLOWS               0xfd    /* Value spec follows.  */
-#define DST_K_VFLAGS_BITOFFS           0xff    /* Value contains bit offset.  */
-#define DST_K_VALKIND_LITERAL  0
-#define DST_K_VALKIND_ADDR     1
-#define DST_K_VALKIND_DESC     2
-#define DST_K_VALKIND_REG      3
-#define DST_K_REG_VAX_AP       0x0c    /* R12.  */
-#define DST_K_REG_VAX_FP       0x0d    /* R13.  */
-#define DST_K_REG_VAX_SP       0x0e    /* R14.  */
-#define DST_V_VALKIND          0       /* Offset of valkind field.  */
-#define DST_V_INDIRECT         2       /* Offset to indirect bit.  */
-#define DST_V_DISP             3       /* Offset to displacement bit.  */
-#define DST_V_REGNUM           4       /* Offset to register number.  */
-#define DST_M_INDIRECT         (1<<DST_V_INDIRECT)
-#define DST_M_DISP             (1<<DST_V_DISP)
-#define DBG_C_FUNCTION_PARAM   /* 0xc9 */      \
-       (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_AP<<DST_V_REGNUM))
-#define DBG_C_LOCAL_SYM                /* 0xd9 */      \
-       (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_FP<<DST_V_REGNUM))
-/* Kinds of value specifications.   */
-#define DST_K_VS_ALLOC_SPLIT   3       /* Split lifetime.  */
-/* Kinds of type specifications.  */
-#define DST_K_TS_ATOM          0x01    /* Atomic type specification.  */
-#define DST_K_TS_DSC           0x02    /* Descriptor type spec.  */
-#define DST_K_TS_IND           0x03    /* Indirect type specification.  */
-#define DST_K_TS_TPTR          0x04    /* Typed pointer type spec.  */
-#define DST_K_TS_PTR           0x05    /* Pointer type spec.  */
-#define DST_K_TS_ARRAY         0x07    /* Array type spec.  */
-#define DST_K_TS_NOV_LENG      0x0e    /* Novel length type spec.  */
-/* These are the codes that are used in the suffix records to determine the
-   actual data type.  */
-#define DBG_S_C_BASIC                  DST_K_TS_ATOM
-#define DBG_S_C_BASIC_ARRAY            DST_K_TS_DSC
-#define DBG_S_C_STRUCT                 DST_K_TS_IND
-#define DBG_S_C_POINTER                        DST_K_TS_TPTR
-#define DBG_S_C_VOID                   DST_K_TS_PTR
-#define DBG_S_C_COMPLEX_ARRAY          DST_K_TS_ARRAY
-
-/* VMS Module Header Records (MHD/EMH).  */
-
-#define MHD_S_C_MHD 0
-#define MHD_S_C_LNM 1
-#define MHD_S_C_SRC 2
-#define MHD_S_C_TTL 3
-#define MHD_S_C_CPR 4
-#define MHD_S_C_MTC 5
-#define MHD_S_C_GTX 6
-#define MHD_S_C_MAXHDRTYP 6
-
-#define EMH_S_C_MHD 0          /* Main header record.          */
-#define EMH_S_C_LNM 1          /* Language name and version.   */
-#define EMH_S_C_SRC 2          /* Source file specification.   */
-#define EMH_S_C_TTL 3          /* Title text of module.        */
-#define EMH_S_C_CPR 4          /* Copyright notice.            */
-#define EMH_S_C_MTC 5          /* Maintenance status.          */
-#define EMH_S_C_GTX 6          /* General text.                */
-#define EMH_S_C_MAXHDRTYP 6    /* Maximum allowable type.      */
-
-/* vms.c.  */
-
-extern asymbol *_bfd_vms_make_empty_symbol (bfd *);
-extern int _bfd_vms_slurp_object_records (bfd *abfd);
-
-/* vms-gsd.c.  */
-
-extern int _bfd_vms_slurp_gsd (bfd *abfd, int objtype);
-extern int _bfd_vms_write_gsd (bfd *abfd, int objtype);
-extern int _bfd_vms_slurp_dbg (bfd *abfd, int objtype);
-extern int _bfd_vms_write_dbg (bfd *abfd, int objtype);
-extern int _bfd_vms_slurp_tbt (bfd *abfd, int objtype);
-extern int _bfd_vms_write_tbt (bfd *abfd, int objtype);
-
-/* vms-misc.c.  */
-
-extern int _bfd_vms_get_object_record (bfd *abfd);
-extern int _bfd_vms_get_first_record (bfd *abfd);
+#include <time.h>
 
-extern char *vms_get_module_name (const char *filename, bfd_boolean);
-extern time_t vms_time_to_time_t (unsigned int hi, unsigned int lo);
-extern time_t vms_rawtime_to_time_t (unsigned char *buf);
+/* Size of a VMS block on disk.  */
 
-/* vms-hdr.c.  */
-
-extern int _bfd_vms_slurp_hdr (bfd *abfd, int objtype);
-extern int _bfd_vms_write_hdr (bfd *abfd, int objtype);
-extern int _bfd_vms_slurp_eom (bfd *abfd, int objtype);
-extern int _bfd_vms_write_eom (bfd *abfd, int objtype);
-extern bfd_boolean _bfd_vms_find_nearest_dst_line
-  (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
-          const char **file, const char **func, unsigned int *line);
-extern int _bfd_vms_slurp_ihd
-  (bfd *abfd, unsigned int *isd_offset, unsigned int *ihs_offset);
-extern int _bfd_vms_slurp_isd (bfd *abfd, unsigned int offset);
-extern int _bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset);
-
-/* vms-tir.c.  */
-
-extern int _bfd_vms_slurp_tir (bfd *abfd, int objtype);
-extern int _bfd_vms_write_tir (bfd *abfd, int objtype);
-extern int _bfd_vms_slurp_lnk (bfd *abfd, int objtype);
-
-extern int _bfd_vms_slurp_relocs (bfd *abfd);
-extern int _bfd_vms_decode_relocs
-  (bfd *abfd, arelent *relocs, asection *section, asymbol **symbols);
-
-/* The r_type field in a reloc is one of the following values.  */
-#define ALPHA_R_IGNORE         0
-#define ALPHA_R_REFQUAD                1
-#define ALPHA_R_BRADDR         2
-#define ALPHA_R_HINT           3
-#define ALPHA_R_SREL16         4
-#define ALPHA_R_SREL32         5
-#define ALPHA_R_SREL64         6
-#define ALPHA_R_OP_PUSH                7
-#define ALPHA_R_OP_STORE       8
-#define ALPHA_R_OP_PSUB                9
-#define ALPHA_R_OP_PRSHIFT     10
-#define ALPHA_R_LINKAGE                11
-#define ALPHA_R_REFLONG                12
-#define ALPHA_R_CODEADDR       13
-#define ALPHA_R_NOP            14
-#define ALPHA_R_BSR            15
-#define ALPHA_R_LDA            16
-#define ALPHA_R_BOH            17
-
-/* VMS Object Language (OBJ/EOBJ).  */
-
-#define OBJ_S_C_HDR 0          /* VAX moule header record.             */
-#define OBJ_S_C_GSD 1          /* VAX glbal symbol definition record.  */
-#define OBJ_S_C_TIR 2          /* VAX tet information record.          */
-#define OBJ_S_C_EOM 3          /* VAX en of module record.             */
-#define OBJ_S_C_DBG 4          /* VAX Deugger information record.      */
-#define OBJ_S_C_TBT 5          /* VAX Trceback information record.     */
-#define OBJ_S_C_LNK 6          /* VAX liker options record.            */
-#define OBJ_S_C_EOMW 7         /* VAX en of module word-psect record.  */
-#define OBJ_S_C_MAXRECTYP 7    /* VAX Lat assigned record type.        */
-
-#define EOBJ_S_C_EMH 8         /* EVAX mdule header record.            */
-#define EOBJ_S_C_EEOM 9                /* EVAX ed of module record.            */
-#define EOBJ_S_C_EGSD 10       /* EVAX gobal symbol definition record. */
-#define EOBJ_S_C_ETIR 11       /* EVAX txt information record.         */
-#define EOBJ_S_C_EDBG 12       /* EVAX Dbugger information record.     */
-#define EOBJ_S_C_ETBT 13       /* EVAX Taceback information record.    */
-#define EOBJ_S_C_MAXRECTYP 13  /* EVAX Lst assigned record type.       */
-
-#define OBJ_S_K_SUBTYP 1
-#define OBJ_S_C_SUBTYP 1
-#define EOBJ_S_K_SUBTYP 4
-#define EOBJ_S_C_SUBTYP 4
-#define OBJ_S_C_MAXRECSIZ 2048 /* Maximu legal record size.           */
-#define EOBJ_S_C_MAXRECSIZ 8192 /* Maximu legal record size.           */
-#define OBJ_S_C_STRLVL 0       /* Structre level.                     */
-#define EOBJ_S_C_STRLVL 2      /* Structre level.                     */
-#define OBJ_S_C_SYMSIZ 31      /* Maximu symbol length.                */
-#define EOBJ_S_C_SYMSIZ 64     /* Maximu symbol length.                */
-#define EOBJ_S_C_SECSIZ 31     /* Maximu section name length.          */
-#define OBJ_S_C_STOREPLIM -1   /* Maximu repeat count on store commands.  */
-#define EOBJ_S_C_STOREPLIM -1  /* Maximu repeat count on store commands.  */
-#define OBJ_S_C_PSCALILIM 9    /* Maximu p-sect alignment.            */
-#define EOBJ_S_C_PSCALILIM 16  /* Maximu p-sect alignment.            */
-
-#define EVAX_OFFSET    256     /* Type ofset for EVAX codes in switch.  */
+#define VMS_BLOCK_SIZE  512
 
 /* Miscellaneous definitions.  */
 
-#if __GNUC__
-typedef unsigned long long uquad;
-#else
-typedef unsigned long uquad;
-#endif
-
 #define MAX_OUTREC_SIZE 4096
 #define MIN_OUTREC_LUFT 64
 
-/* VMS module header.  */
-
-struct hdr_struct
-{
-  char hdr_b_strlvl;
-  int hdr_l_arch1;
-  int hdr_l_arch2;
-  int hdr_l_recsiz;
-  char *hdr_t_name;
-  char *hdr_t_version;
-  char *hdr_t_date;
-  char *hdr_c_lnm;
-  char *hdr_c_src;
-  char *hdr_c_ttl;
-};
-
-#define EMH_S_W_HDRTYP   4
-#define EMH_S_B_STRLVL   6
-#define EMH_S_L_ARCH1    8
-#define EMH_S_L_ARCH2   12
-#define EH_S_L_RECSIZ  16
-#define EMH_S_B_NAMLNG  20
-
-#define EMH_DATE_LENGTH  17
-
-/* VMS End-Of-Module records (EOM/EEOM).  */
-
-struct eom_struct
-{
-  int eom_l_total_lps;
-  short eom_w_comcod;
-  bfd_boolean eom_has_transfer;
-  char eom_b_tfrflg;
-  int eom_l_psindx;
-  int eom_l_tfradr;
-};
-
-#define EEOM_S_L_TOTAL_LPS   4
-#define EEOM_S_W_COMCOD      8
-#define EEOM_S_B_TFRFLG     10
-#define EEOM_S_L_PSINDX     12
-#define EEOM_S_L_TFRADR     16
-
-/* VMS Image Header Records (IHD/EIHD).  */
-
-#define EIHD_S_K_MAJORID       3       /* Major id constant    */
-#define EIHD_S_K_MINORID       0       /* Minor id constant    */
-#define EIHD_S_K_EXE           1       /* Executable image     */
-
-#define EIHD_S_L_SIZE          8
-#define EIHD_S_L_ISDOFF                12
-#define EIHD_S_L_SYMDBGOFF     20
-#define EIHD_S_Q_SYMVVA                40
-#define EIHD_S_L_IMGTYPE       52
-
-/* VMS Image Section Description Records (ISD/EISD).  */
-
-#define EISD_S_L_EISDSIZE       8
-#define EISD_S_L_SECSIZE       12
-#define EISD_S_Q_VIR_ADDR      16
-#define EISD_S_L_FLAGS         24
-#define EISD_S_L_VBN           28
-#define EISD_S_R_CONTROL       32
-#define EISD_S_L_IDENT         36
-#define EISD_S_T_GBLNAM                40
-
-#define EISD_S_M_GBL           0x0001
-#define EISD_S_M_CRF           0x0002
-#define EISD_S_M_DZRO          0x0004
-#define EISD_S_M_WRT           0x0008
-#define EISD_S_M_INITALCODE    0x0010
-#define EISD_S_M_BASED         0x0020
-#define EISD_S_M_FIXUPVEC      0x0040
-#define EISD_S_M_RESIDENT      0x0080
-#define EISD_S_M_VECTOR                0x0100
-#define EISD_S_M_PROTECT       0x0200
-#define EISD_S_M_LASTCLU       0x0400
-#define EISD_S_M_EXE           0x0800
-#define EISD_S_M_NONSHRADR     0x1000
-#define EISD_S_M_QUAD_LENGTH   0x2000
-#define EISD_S_M_ALLOC_64BIT   0x4000
-
-/* VMS Image Header Symbol Records (IHS/EIHS).  */
-
-#define EIHS_S_L_DSTVBN                 8
-#define EIHS_S_L_DSTSIZE       12
-#define EIHS_S_L_GSTVBN                16
-#define EIHS_S_L_GSTSIZE       20
-#define EIHS_S_L_DMTVBN                24
-#define EIHS_S_L_DMTBYTES      28
-
-/* Debugger symbol definitions.  */
-
-#define DBG_S_L_DMT_MODBEG       0
-#define DBG_S_L_DST_SIZE         4
-#define DBG_S_W_DMT_PSECT_COUNT  8
-#define DBG_S_C_DMT_HEADER_SIZE 12
-
-#define DBG_S_L_DMT_PSECT_START  0
-#define DBG_S_L_DMT_PSECT_LENGTH 4
-#define DBG_S_C_DMT_PSECT_SIZE   8
-
 /* File format.  */
+
 enum file_format_enum
   {
     /* Not yet known.  */
@@ -697,169 +55,40 @@ enum file_format_enum
     FF_NATIVE
   };
 
-enum file_type_enum { FT_UNKNOWN, FT_MODULE, FT_IMAGE };
-
-typedef struct vms_symbol_struct
-{
-  struct bfd_hash_entry bfd_hash;
-  asymbol *symbol;
-} vms_symbol_entry;
-
-/* Stack value for push/pop commands.  */
-
-struct stack_struct
-{
-  uquad value;
-  int psect;
-};
-
-#define STACKSIZE 8192
-
-/* A minimal decoding of DST compilation units.  We only decode
-   what's needed to get to the line number information.  */
-
-struct fileinfo
-{
-  char *name;
-  unsigned int srec;
-};
-
-struct srecinfo
-{
-  struct srecinfo *next;
-  unsigned int line;
-  unsigned int sfile;
-  unsigned int srec;
-};
-
-struct lineinfo
-{
-  struct lineinfo *next;
-  bfd_vma address;
-  unsigned int line;
-};
-
-struct funcinfo
-{
-  struct funcinfo *next;
-  char *name;
-  bfd_vma low;
-  bfd_vma high;
-};
+/* VMS records input buffer.  */
 
-struct module
+struct vms_rec_rd
 {
-  /* Chain the previously read compilation unit.  */
-  struct module *next;
-
-  /* The module name.  */
-  char *name;
+  /* Buffer and its size.  */
+  unsigned char *buf;
+  unsigned int buf_size;
 
-  /* The start offset and size of debug info in the DST section.  */
-  unsigned int modbeg;
-  unsigned int size;
+  /* Current record and its size.  */
+  unsigned char *rec;
+  unsigned int rec_size;
 
-  /* The lowest and highest addresses contained in this compilation
-     unit as specified in the compilation unit header.  */
-  bfd_vma low;
-  bfd_vma high;
-
-  /* The listing line table.  */
-  struct lineinfo *line_table;
-
-  /* The source record table.  */
-  struct srecinfo *srec_table;
-
-  /* A list of the functions found in this module.  */
-  struct funcinfo *func_table;
-
-  /* Current allocation of file_table.  */
-  unsigned int file_table_count;
-
-  /* An array of the files making up this module.  */
-  struct fileinfo *file_table;
-};
-
-struct vms_private_data_struct
-{
-  bfd_boolean is_vax;
-  bfd_boolean fixup_done;              /* Flag to indicate if all
-                                          section pointers and PRIV(sections)
-                                          are set up correctly.  */
-  unsigned char *vms_buf;              /* record buffer */
-  unsigned int buf_size;               /* size of record buffer  */
-  unsigned char *vms_rec;              /* record pointer in record buffer */
-  unsigned int rec_size;               /* record size  */
+  /* Input file format.  */
   enum file_format_enum file_format;
-
-  struct hdr_struct hdr_data;          /* data from HDR/EMH record  */
-  struct eom_struct eom_data;          /* data from EOM/EEOM record  */
-  unsigned int section_count;          /* # of sections in following array  */
-  asection **sections;                 /* array of GSD/EGSD sections  */
-  unsigned int gsd_sym_count;          /* # of GSD/EGSD symbols  */
-  asymbol **symbols;                   /* vector of GSD/EGSD symbols  */
-  struct proc_value *procedure;
-
-  struct stack_struct *stack;
-  int stackptr;
-
-  struct bfd_hash_table *vms_symbol_table;
-  struct bfd_symbol **symcache;
-  int symnum;
-
-  asection *image_section;             /* section for image_ptr  */
-  unsigned char *image_ptr;            /* a pointer to section->contents */
-
-  unsigned char pdsc[8];               /* procedure descriptor */
-
-  struct module *modules;              /* list of all compilation units */
-
-  struct dst_info *dst_info;
-  asection *dst_section;
-  unsigned char *dst_ptr_end;
-  unsigned int dst_ptr_offsets_count;  /* # of offsets in following array  */
-  unsigned int *dst_ptr_offsets;       /* array of saved image_ptr offsets */
-
-  /* Shared library support */
-  bfd_vma symvva; /* relative virtual address of symbol vector */
-
-  /* Output routine storage  */
-  unsigned char *output_buf;           /* output data  */
-  int push_level;
-  int pushed_size;
-  int length_pos;
-  int output_size;
-  int output_alignment;
-
-  /* linkage index counter used by conditional store commands */
-  int vms_linkage_index;
-
-  /* see tc-alpha.c of gas for a description.  */
-  int flag_hash_long_names;    /* -+, hash instead of truncate */
-  int flag_show_after_trunc;   /* -H, show hashing/truncation */
 };
 
-#define PRIV(name) ((struct vms_private_data_struct *)abfd->tdata.any)->name
+/* VMS records output buffer.  */
 
-/* Used to keep extra VMS specific information for a given section.
+struct vms_rec_wr
+{
+  /* Output buffer.  */
+  unsigned char *buf;
 
-   reloc_size holds the size of the relocation stream, note this
-   is very different from the number of relocations as VMS relocations
-   are variable length.
+  /* Current length of the record.  */
+  unsigned short int size;
 
-   reloc_stream is the actual stream of relocation entries.  */
+  /* Sub-record start offset.  */
+  unsigned short int subrec_offset;
 
-struct vms_section_data_struct
-{
-  bfd_size_type reloc_size;
-  unsigned char *reloc_stream;
-  bfd_size_type reloc_offset;
-  flagword vflags;
+  /* Some records must have a size that is a multiple of the alignment.
+     Mustn't be 0.  */
+  unsigned short int align;
 };
 
-#define vms_section_data(sec) \
-  ((struct vms_section_data_struct *)sec->used_by_bfd)
-
 struct evax_private_udata_struct
 {
   asymbol *bsym;
@@ -868,7 +97,9 @@ struct evax_private_udata_struct
   int lkindex;
 };
 
-#define SECTION_NAME_TEMPLATE "__SEC__%d"
+/* vms-misc.c.  */
+
+#define VMS_DEBUG 1
 
 #if VMS_DEBUG
 extern void _bfd_vms_debug (int, char *, ...) ATTRIBUTE_PRINTF_2;
@@ -880,32 +111,29 @@ extern void _bfd_hexdump   (int, unsigned char *, int, int);
 #define vms_debug2(X)
 #endif
 
-extern struct bfd_hash_entry * _bfd_vms_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
-extern void        _bfd_vms_get_header_values (bfd *, unsigned char *, int *, int *);
-extern int         _bfd_vms_get_record  (bfd *abf);
-extern int         _bfd_vms_next_record (bfd *abf);
-extern char *      _bfd_vms_save_sized_string (unsigned char *, int);
-extern char *      _bfd_vms_save_counted_string (unsigned char *);
-extern void        _bfd_vms_push (bfd *, uquad, int);
-extern uquad       _bfd_vms_pop (bfd *, int *);
-extern void        _bfd_vms_output_begin (bfd *, int, int);
-extern void        _bfd_vms_output_alignment (bfd *, int);
-extern void        _bfd_vms_output_push (bfd *);
-extern void        _bfd_vms_output_pop (bfd *);
-extern void        _bfd_vms_output_flush (bfd *);
-extern void        _bfd_vms_output_end (bfd *);
-extern int         _bfd_vms_output_check (bfd *, int);
-extern void        _bfd_vms_output_byte (bfd *, unsigned);
-extern void        _bfd_vms_output_short (bfd *, unsigned);
-extern void        _bfd_vms_output_long (bfd *, unsigned long);
-extern void        _bfd_vms_output_quad (bfd *, uquad);
-extern void        _bfd_vms_output_counted (bfd *, char *);
-extern void        _bfd_vms_output_dump (bfd *, unsigned char *, int);
-extern void        _bfd_vms_output_fill (bfd *, int, int);
-extern char *      _bfd_vms_length_hash_symbol (bfd *, const char *, int);
-extern vms_symbol_entry * _bfd_vms_enter_symbol (bfd *, char *);
-
-#define EGPS_S_V_NO_SHIFT 16
-
-extern void        bfd_vms_set_section_flags (bfd *, asection *, flagword);
+extern char *vms_get_module_name (const char *filename, bfd_boolean);
+extern unsigned char *get_vms_time_string (void);
+extern time_t vms_time_to_time_t (unsigned int hi, unsigned int lo);
+extern time_t vms_rawtime_to_time_t (unsigned char *buf);
+
+extern char *_bfd_vms_save_sized_string (unsigned char *, int);
+extern char *_bfd_vms_save_counted_string (unsigned char *);
+extern void _bfd_vms_output_begin (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_alignment (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_begin_subrec (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_end_subrec (struct vms_rec_wr *);
+extern void _bfd_vms_output_end (bfd *, struct vms_rec_wr *);
+extern int _bfd_vms_output_check (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_byte (struct vms_rec_wr *, unsigned);
+extern void _bfd_vms_output_short (struct vms_rec_wr *, unsigned);
+extern void _bfd_vms_output_long (struct vms_rec_wr *, unsigned long);
+extern void _bfd_vms_output_quad (struct vms_rec_wr *, bfd_vma);
+extern void _bfd_vms_output_counted (struct vms_rec_wr *, char *);
+extern void _bfd_vms_output_dump (struct vms_rec_wr *, unsigned char *, int);
+extern void _bfd_vms_output_fill (struct vms_rec_wr *, int, int);
+
+/* vms-alpha.c  */
+
+extern void bfd_vms_set_section_flags (bfd *, asection *, flagword, flagword);
+
 #endif /* VMS_H */