OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [vms-hdr.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
   EVAX (openVMS/Alpha) files.
   EVAX (openVMS/Alpha) files.
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
   2007, 2008, 2009 Free Software Foundation, Inc.
   2007, 2008, 2009 Free Software Foundation, Inc.
 
 
   HDR record handling functions
   HDR record handling functions
   EMH record handling functions
   EMH record handling functions
 
 
   EOM record handling functions
   EOM record handling functions
   EEOM record handling functions
   EEOM record handling functions
 
 
   IHD record handling functions
   IHD record handling functions
   EIHD record handling functions
   EIHD record handling functions
 
 
   ISD record handling functions
   ISD record handling functions
   EISD record handling functions
   EISD record handling functions
 
 
   IHS record handling functions
   IHS record handling functions
   EIHS record handling functions
   EIHS record handling functions
 
 
   DBG record handling functions
   DBG record handling functions
   EDBG record handling functions
   EDBG record handling functions
 
 
   TBT record handling functions
   TBT record handling functions
   ETBT record handling functions
   ETBT record handling functions
 
 
   DST/DMT section handling functions
   DST/DMT section handling functions
 
 
   Written by Klaus K"ampf (kkaempf@rmi.de)
   Written by Klaus K"ampf (kkaempf@rmi.de)
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "bfdver.h"
#include "bfdver.h"
#include "bfdlink.h"
#include "bfdlink.h"
#include "safe-ctype.h"
#include "safe-ctype.h"
#include "libbfd.h"
#include "libbfd.h"
 
 
#include "vms.h"
#include "vms.h"
 
 
static struct module *new_module (bfd *);
static struct module *new_module (bfd *);
static void parse_module
static void parse_module
  (bfd *, struct module *, unsigned char *, unsigned int);
  (bfd *, struct module *, unsigned char *, unsigned int);
static struct module *build_module_list (bfd *);
static struct module *build_module_list (bfd *);
static bfd_boolean module_find_nearest_line
static bfd_boolean module_find_nearest_line
  (bfd *, struct module *, bfd_vma, const char **, const char **,
  (bfd *, struct module *, bfd_vma, const char **, const char **,
   unsigned int *);
   unsigned int *);
static int vms_slurp_debug (bfd *);
static int vms_slurp_debug (bfd *);
 
 
#define SET_MODULE_PARSED(m) \
#define SET_MODULE_PARSED(m) \
  do { if ((m)->name == NULL) (m)->name = ""; } while (0)
  do { if ((m)->name == NULL) (m)->name = ""; } while (0)
#define IS_MODULE_PARSED(m) ((m)->name != NULL)
#define IS_MODULE_PARSED(m) ((m)->name != NULL)
 
 
 
 
/* Read & process emh record
/* Read & process emh record
   return 0 on success, -1 on error.  */
   return 0 on success, -1 on error.  */
 
 
int
int
_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
{
{
  unsigned char *ptr;
  unsigned char *ptr;
  unsigned char *vms_rec;
  unsigned char *vms_rec;
  int subtype;
  int subtype;
 
 
  vms_rec = PRIV(vms_rec);
  vms_rec = PRIV(vms_rec);
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug(2, "HDR/EMH\n");
  vms_debug(2, "HDR/EMH\n");
#endif
#endif
 
 
  switch (objtype)
  switch (objtype)
    {
    {
    case OBJ_S_C_HDR:
    case OBJ_S_C_HDR:
      subtype = vms_rec[1];
      subtype = vms_rec[1];
      break;
      break;
    case EOBJ_S_C_EMH:
    case EOBJ_S_C_EMH:
      subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
      subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
      break;
      break;
    default:
    default:
      subtype = -1;
      subtype = -1;
    }
    }
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug(3, "subtype %d\n", subtype);
  vms_debug(3, "subtype %d\n", subtype);
#endif
#endif
 
 
  switch (subtype)
  switch (subtype)
    {
    {
    case MHD_S_C_MHD:
    case MHD_S_C_MHD:
      /* Module header.  */
      /* Module header.  */
      PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
      PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
      PRIV (hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
      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);
      PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
      ptr = vms_rec + 5 + vms_rec[5] + 1;
      ptr = vms_rec + 5 + vms_rec[5] + 1;
      PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
      PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
      ptr += *ptr + 1;
      ptr += *ptr + 1;
      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
      break;
      break;
 
 
    case MHD_S_C_LNM:
    case MHD_S_C_LNM:
      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
      break;
      break;
 
 
    case MHD_S_C_SRC:
    case MHD_S_C_SRC:
      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
      break;
      break;
 
 
    case MHD_S_C_TTL:
    case MHD_S_C_TTL:
      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
      break;
      break;
 
 
    case EMH_S_C_MHD + EVAX_OFFSET:
    case EMH_S_C_MHD + EVAX_OFFSET:
      /* Module header.  */
      /* Module header.  */
      PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
      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_arch1  = bfd_getl32 (vms_rec + 8);
      PRIV (hdr_data).hdr_l_arch2  = bfd_getl32 (vms_rec + 12);
      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_l_recsiz = bfd_getl32 (vms_rec + 16);
      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20);
      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20);
      ptr = vms_rec + 20 + vms_rec[20] + 1;
      ptr = vms_rec + 20 + vms_rec[20] + 1;
      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
      ptr += *ptr + 1;
      ptr += *ptr + 1;
      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
      break;
      break;
 
 
    case EMH_S_C_LNM + EVAX_OFFSET:
    case EMH_S_C_LNM + EVAX_OFFSET:
      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
      break;
      break;
 
 
    case EMH_S_C_SRC + EVAX_OFFSET:
    case EMH_S_C_SRC + EVAX_OFFSET:
      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
      break;
      break;
 
 
    case EMH_S_C_TTL + EVAX_OFFSET:
    case EMH_S_C_TTL + EVAX_OFFSET:
      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
      break;
      break;
 
 
    case MHD_S_C_CPR:
    case MHD_S_C_CPR:
    case MHD_S_C_MTC:
    case MHD_S_C_MTC:
    case MHD_S_C_GTX:
    case MHD_S_C_GTX:
    case EMH_S_C_CPR + EVAX_OFFSET:
    case EMH_S_C_CPR + EVAX_OFFSET:
    case EMH_S_C_MTC + EVAX_OFFSET:
    case EMH_S_C_MTC + EVAX_OFFSET:
    case EMH_S_C_GTX + EVAX_OFFSET:
    case EMH_S_C_GTX + EVAX_OFFSET:
      break;
      break;
 
 
    default:
    default:
      bfd_set_error (bfd_error_wrong_format);
      bfd_set_error (bfd_error_wrong_format);
      return -1;
      return -1;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Output routines.  */
/* Output routines.  */
 
 
/* Manufacture a VMS like time on a unix based system.
/* Manufacture a VMS like time on a unix based system.
   stolen from obj-vms.c.  */
   stolen from obj-vms.c.  */
 
 
static unsigned char *
static unsigned char *
get_vms_time_string (void)
get_vms_time_string (void)
{
{
  static unsigned char tbuf[18];
  static unsigned char tbuf[18];
#ifndef VMS
#ifndef VMS
#include <time.h>
#include <time.h>
 
 
  char *pnt;
  char *pnt;
  time_t timeb;
  time_t timeb;
 
 
  time (& timeb);
  time (& timeb);
  pnt = ctime (&timeb);
  pnt = ctime (&timeb);
  pnt[3] = 0;
  pnt[3] = 0;
  pnt[7] = 0;
  pnt[7] = 0;
  pnt[10] = 0;
  pnt[10] = 0;
  pnt[16] = 0;
  pnt[16] = 0;
  pnt[24] = 0;
  pnt[24] = 0;
  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
           pnt + 8, pnt + 4, pnt + 20, pnt + 11);
           pnt + 8, pnt + 4, pnt + 20, pnt + 11);
#else
#else
#include <starlet.h>
#include <starlet.h>
  struct
  struct
  {
  {
    int Size;
    int Size;
    unsigned char *Ptr;
    unsigned char *Ptr;
  } Descriptor;
  } Descriptor;
  Descriptor.Size = 17;
  Descriptor.Size = 17;
  Descriptor.Ptr = tbuf;
  Descriptor.Ptr = tbuf;
  SYS$ASCTIM (0, &Descriptor, 0, 0);
  SYS$ASCTIM (0, &Descriptor, 0, 0);
#endif /* not VMS */
#endif /* not VMS */
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (6, "vmstimestring:'%s'\n", tbuf);
  vms_debug (6, "vmstimestring:'%s'\n", tbuf);
#endif
#endif
 
 
  return tbuf;
  return tbuf;
}
}
 
 
/* Write object header for bfd abfd.  */
/* Write object header for bfd abfd.  */
 
 
int
int
_bfd_vms_write_hdr (bfd *abfd, int objtype)
_bfd_vms_write_hdr (bfd *abfd, int objtype)
{
{
  asymbol *symbol;
  asymbol *symbol;
  unsigned int symnum;
  unsigned int symnum;
  int had_case = 0;
  int had_case = 0;
  int had_file = 0;
  int had_file = 0;
  char version [256];
  char version [256];
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (2, "vms_write_hdr (%p)\n", abfd);
  vms_debug (2, "vms_write_hdr (%p)\n", abfd);
#endif
#endif
 
 
  _bfd_vms_output_alignment (abfd, 2);
  _bfd_vms_output_alignment (abfd, 2);
 
 
  /* MHD.  */
  /* MHD.  */
  if (objtype != OBJ_S_C_HDR)
  if (objtype != OBJ_S_C_HDR)
    {
    {
      _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
      _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_short (abfd, EOBJ_S_C_STRLVL);
      _bfd_vms_output_long (abfd, 0);
      _bfd_vms_output_long (abfd, 0);
      _bfd_vms_output_long (abfd, 0);
      _bfd_vms_output_long (abfd, 0);
      _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
      _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
    }
    }
 
 
  if (bfd_get_filename (abfd) != 0)
  if (bfd_get_filename (abfd) != 0)
    {
    {
      /* Strip path and suffix information.  */
      /* Strip path and suffix information.  */
      char *fname, *fout, *fptr;
      char *fname, *fout, *fptr;
 
 
      fptr = bfd_get_filename (abfd);
      fptr = bfd_get_filename (abfd);
      fname = strdup (fptr);
      fname = strdup (fptr);
 
 
      /* Strip VMS path.  */
      /* Strip VMS path.  */
      fout = strrchr (fname, ']');
      fout = strrchr (fname, ']');
      if (fout == NULL)
      if (fout == NULL)
        fout = strchr (fname, ':');
        fout = strchr (fname, ':');
      if (fout != NULL)
      if (fout != NULL)
        fout++;
        fout++;
      else
      else
        fout = fname;
        fout = fname;
 
 
      /* Strip UNIX path.  */
      /* Strip UNIX path.  */
      fptr = strrchr (fout, '/');
      fptr = strrchr (fout, '/');
      if (fptr != NULL)
      if (fptr != NULL)
        fout = fptr + 1;
        fout = fptr + 1;
 
 
      /* Strip .obj suffix.  */
      /* Strip .obj suffix.  */
      fptr = strrchr (fout, '.');
      fptr = strrchr (fout, '.');
      if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
      if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
        *fptr = 0;
        *fptr = 0;
 
 
      /* Convert to upper case and truncate at 31 characters.
      /* Convert to upper case and truncate at 31 characters.
         (VMS object file format restricts module name length to 31).  */
         (VMS object file format restricts module name length to 31).  */
      fptr = fout;
      fptr = fout;
      while (*fptr != 0)
      while (*fptr != 0)
        {
        {
          *fptr = TOUPPER (*fptr);
          *fptr = TOUPPER (*fptr);
          fptr++;
          fptr++;
          if (*fptr == ';' || (fptr - fout) >= 31)
          if (*fptr == ';' || (fptr - fout) >= 31)
            *fptr = 0;
            *fptr = 0;
        }
        }
      _bfd_vms_output_counted (abfd, fout);
      _bfd_vms_output_counted (abfd, fout);
      free (fname);
      free (fname);
    }
    }
  else
  else
    _bfd_vms_output_counted (abfd, "NONAME");
    _bfd_vms_output_counted (abfd, "NONAME");
 
 
  _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
  _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
  _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
  _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
  _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
  _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
 
 
  /* LMN.  */
  /* LMN.  */
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
  snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
  snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
  _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
  _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
 
 
  /* SRC.  */
  /* SRC.  */
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
 
 
  for (symnum = 0; symnum < abfd->symcount; symnum++)
  for (symnum = 0; symnum < abfd->symcount; symnum++)
    {
    {
      symbol = abfd->outsymbols[symnum];
      symbol = abfd->outsymbols[symnum];
 
 
      if (symbol->flags & BSF_FILE)
      if (symbol->flags & BSF_FILE)
        {
        {
          if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
          if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
            {
            {
              PRIV (flag_hash_long_names) = symbol->name[6] - '0';
              PRIV (flag_hash_long_names) = symbol->name[6] - '0';
              PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
              PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
 
 
              if (had_file)
              if (had_file)
                break;
                break;
              had_case = 1;
              had_case = 1;
              continue;
              continue;
            }
            }
 
 
          _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
          _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
                                (int) strlen (symbol->name));
                                (int) strlen (symbol->name));
          if (had_case)
          if (had_case)
            break;
            break;
          had_file = 1;
          had_file = 1;
        }
        }
    }
    }
 
 
  if (symnum == abfd->symcount)
  if (symnum == abfd->symcount)
    _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
    _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
 
 
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
 
 
  /* TTL.  */
  /* TTL.  */
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_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_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
 
 
  /* CPR.  */
  /* CPR.  */
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
  _bfd_vms_output_dump (abfd,
  _bfd_vms_output_dump (abfd,
                         (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
                         (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
                         39);
                         39);
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
 
 
  return 0;
  return 0;
}
}
 
 
/* Process EOM/EEOM record
/* Process EOM/EEOM record
   return 0 on success, -1 on error.  */
   return 0 on success, -1 on error.  */
 
 
int
int
_bfd_vms_slurp_eom (bfd *abfd, int objtype)
_bfd_vms_slurp_eom (bfd *abfd, int objtype)
{
{
  unsigned char *vms_rec;
  unsigned char *vms_rec;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug(2, "EOM/EEOM\n");
  vms_debug(2, "EOM/EEOM\n");
#endif
#endif
 
 
  vms_rec = PRIV (vms_rec);
  vms_rec = PRIV (vms_rec);
 
 
  if ((objtype == OBJ_S_C_EOM)
  if ((objtype == OBJ_S_C_EOM)
     || (objtype == OBJ_S_C_EOMW))
     || (objtype == OBJ_S_C_EOMW))
    {
    {
    }
    }
  else
  else
    {
    {
      PRIV (eom_data).eom_l_total_lps
      PRIV (eom_data).eom_l_total_lps
        = bfd_getl32 (vms_rec + EEOM_S_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);
      PRIV (eom_data).eom_w_comcod = bfd_getl16 (vms_rec + EEOM_S_W_COMCOD);
      if (PRIV (eom_data).eom_w_comcod > 1)
      if (PRIV (eom_data).eom_w_comcod > 1)
        {
        {
          (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
          (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          return -1;
          return -1;
        }
        }
      PRIV (eom_data).eom_has_transfer = FALSE;
      PRIV (eom_data).eom_has_transfer = FALSE;
      if (PRIV (rec_size) > 10)
      if (PRIV (rec_size) > 10)
        {
        {
           PRIV (eom_data).eom_has_transfer = TRUE;
           PRIV (eom_data).eom_has_transfer = TRUE;
           PRIV (eom_data).eom_b_tfrflg = vms_rec[EEOM_S_B_TFRFLG];
           PRIV (eom_data).eom_b_tfrflg = vms_rec[EEOM_S_B_TFRFLG];
           PRIV (eom_data).eom_l_psindx
           PRIV (eom_data).eom_l_psindx
             = bfd_getl32 (vms_rec + EEOM_S_L_PSINDX);
             = bfd_getl32 (vms_rec + EEOM_S_L_PSINDX);
           PRIV (eom_data).eom_l_tfradr
           PRIV (eom_data).eom_l_tfradr
             = bfd_getl32 (vms_rec + EEOM_S_L_TFRADR);
             = bfd_getl32 (vms_rec + EEOM_S_L_TFRADR);
 
 
           abfd->start_address = PRIV (eom_data).eom_l_tfradr;
           abfd->start_address = PRIV (eom_data).eom_l_tfradr;
        }
        }
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Write eom record for bfd abfd.  */
/* Write eom record for bfd abfd.  */
 
 
int
int
_bfd_vms_write_eom (bfd *abfd, int objtype)
_bfd_vms_write_eom (bfd *abfd, int objtype)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
  vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
#endif
#endif
 
 
  _bfd_vms_output_begin (abfd, objtype, -1);
  _bfd_vms_output_begin (abfd, objtype, -1);
  _bfd_vms_output_long (abfd, (unsigned long) (PRIV (vms_linkage_index) >> 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);        /* Completion code.  */
  _bfd_vms_output_byte (abfd, 0);        /* Fill byte.  */
  _bfd_vms_output_byte (abfd, 0);        /* Fill byte.  */
 
 
  if (bfd_get_start_address (abfd) != (bfd_vma)-1)
  if (bfd_get_start_address (abfd) != (bfd_vma)-1)
    {
    {
      asection *section;
      asection *section;
 
 
      section = bfd_get_section_by_name (abfd, ".link");
      section = bfd_get_section_by_name (abfd, ".link");
      if (section == 0)
      if (section == 0)
        {
        {
          bfd_set_error (bfd_error_nonrepresentable_section);
          bfd_set_error (bfd_error_nonrepresentable_section);
          return -1;
          return -1;
        }
        }
      _bfd_vms_output_short (abfd, 0);
      _bfd_vms_output_short (abfd, 0);
      _bfd_vms_output_long (abfd, (unsigned long) (section->index));
      _bfd_vms_output_long (abfd, (unsigned long) (section->index));
      _bfd_vms_output_long (abfd,
      _bfd_vms_output_long (abfd,
                             (unsigned long) bfd_get_start_address (abfd));
                             (unsigned long) bfd_get_start_address (abfd));
      _bfd_vms_output_long (abfd, 0);
      _bfd_vms_output_long (abfd, 0);
    }
    }
 
 
  _bfd_vms_output_end (abfd);
  _bfd_vms_output_end (abfd);
  return 0;
  return 0;
}
}
 
 
/* Read & process IHD/EIHD record.
/* Read & process IHD/EIHD record.
   Return 0 on success, -1 on error  */
   Return 0 on success, -1 on error  */
int
int
_bfd_vms_slurp_ihd (bfd *abfd, unsigned int *isd_offset,
_bfd_vms_slurp_ihd (bfd *abfd, unsigned int *isd_offset,
                    unsigned int *ihs_offset)
                    unsigned int *ihs_offset)
{
{
  unsigned int imgtype, size;
  unsigned int imgtype, size;
  bfd_vma symvva;
  bfd_vma symvva;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (8, "_bfd_vms_slurp_ihd\n");
  vms_debug (8, "_bfd_vms_slurp_ihd\n");
#endif
#endif
 
 
  size = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
  size = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
  imgtype = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_IMGTYPE);
  imgtype = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_IMGTYPE);
 
 
  if (imgtype == EIHD_S_K_EXE)
  if (imgtype == EIHD_S_K_EXE)
    abfd->flags |= EXEC_P;
    abfd->flags |= EXEC_P;
 
 
  symvva = bfd_getl64 (PRIV (vms_rec) + EIHD_S_Q_SYMVVA);
  symvva = bfd_getl64 (PRIV (vms_rec) + EIHD_S_Q_SYMVVA);
  if (symvva != 0)
  if (symvva != 0)
    {
    {
      PRIV (symvva) = symvva;
      PRIV (symvva) = symvva;
      abfd->flags |= DYNAMIC;
      abfd->flags |= DYNAMIC;
    }
    }
 
 
  *isd_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_ISDOFF);
  *isd_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_ISDOFF);
  *ihs_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SYMDBGOFF);
  *ihs_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SYMDBGOFF);
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (4, "EIHD record size %d imgtype %d symvva 0x%llx isd %d ihs %d\n",
  vms_debug (4, "EIHD record size %d imgtype %d symvva 0x%llx isd %d ihs %d\n",
             size, imgtype, symvva, *isd_offset, *ihs_offset);
             size, imgtype, symvva, *isd_offset, *ihs_offset);
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* Read & process ISD/EISD record
/* Read & process ISD/EISD record
   return 0 on success, -1 on error  */
   return 0 on success, -1 on error  */
 
 
int
int
_bfd_vms_slurp_isd (bfd *abfd, unsigned int offset)
_bfd_vms_slurp_isd (bfd *abfd, unsigned int offset)
{
{
  int section_count = 0;
  int section_count = 0;
  unsigned char *p;
  unsigned char *p;
  unsigned int rec_size;
  unsigned int rec_size;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (8, "_bfd_vms_slurp_isd\n");
  vms_debug (8, "_bfd_vms_slurp_isd\n");
#endif
#endif
 
 
  for (p = PRIV (vms_rec) + offset;
  for (p = PRIV (vms_rec) + offset;
       (rec_size = bfd_getl32 (p + EISD_S_L_EISDSIZE)) != 0;
       (rec_size = bfd_getl32 (p + EISD_S_L_EISDSIZE)) != 0;
       p += rec_size)
       p += rec_size)
    {
    {
      unsigned long long vaddr = bfd_getl64 (p + EISD_S_Q_VIR_ADDR);
      unsigned long long vaddr = bfd_getl64 (p + EISD_S_Q_VIR_ADDR);
      unsigned int size = bfd_getl32 (p + EISD_S_L_SECSIZE);
      unsigned int size = bfd_getl32 (p + EISD_S_L_SECSIZE);
      unsigned int flags = bfd_getl32 (p + EISD_S_L_FLAGS);
      unsigned int flags = bfd_getl32 (p + EISD_S_L_FLAGS);
      unsigned int vbn = bfd_getl32 (p + EISD_S_L_VBN);
      unsigned int vbn = bfd_getl32 (p + EISD_S_L_VBN);
      char *name = NULL;
      char *name = NULL;
      asection *section;
      asection *section;
      flagword bfd_flags;
      flagword bfd_flags;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
      vms_debug (4, "EISD record at 0x%x size 0x%x addr 0x%x bfd_flags 0x%x block %d\n",
      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);
                 p - PRIV (vms_rec), size, vaddr, flags, vbn);
#endif
#endif
 
 
      /* VMS combines psects from .obj files into isects in the .exe.  This
      /* VMS combines psects from .obj files into isects in the .exe.  This
         process doesn't preserve enough information to reliably determine
         process doesn't preserve enough information to reliably determine
         what's in each section without examining the data.  This is
         what's in each section without examining the data.  This is
         especially true of DWARF debug sections.  */
         especially true of DWARF debug sections.  */
      bfd_flags = SEC_ALLOC;
      bfd_flags = SEC_ALLOC;
 
 
      if (flags & EISD_S_M_EXE)
      if (flags & EISD_S_M_EXE)
        bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
        bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
 
 
      if (flags & EISD_S_M_NONSHRADR)
      if (flags & EISD_S_M_NONSHRADR)
        bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
        bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
 
 
      if (!(flags & EISD_S_M_WRT))
      if (!(flags & EISD_S_M_WRT))
        bfd_flags |= SEC_READONLY;
        bfd_flags |= SEC_READONLY;
 
 
      if (flags & EISD_S_M_DZRO)
      if (flags & EISD_S_M_DZRO)
        bfd_flags |= SEC_DATA;
        bfd_flags |= SEC_DATA;
 
 
      if (flags & EISD_S_M_FIXUPVEC)
      if (flags & EISD_S_M_FIXUPVEC)
        bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
        bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
 
 
      if (flags & EISD_S_M_CRF)
      if (flags & EISD_S_M_CRF)
        bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
        bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
 
 
      if (flags & EISD_S_M_GBL)
      if (flags & EISD_S_M_GBL)
        {
        {
          name = _bfd_vms_save_counted_string (p + EISD_S_T_GBLNAM);
          name = _bfd_vms_save_counted_string (p + EISD_S_T_GBLNAM);
          bfd_flags |= SEC_COFF_SHARED_LIBRARY;
          bfd_flags |= SEC_COFF_SHARED_LIBRARY;
          bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
          bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
        }
        }
      else
      else
        {
        {
          name = (char*) bfd_alloc (abfd, 32);
          name = (char*) bfd_alloc (abfd, 32);
          sprintf (name, "$LOCAL_%03d$", section_count++);
          sprintf (name, "$LOCAL_%03d$", section_count++);
        }
        }
 
 
      section = bfd_make_section (abfd, name);
      section = bfd_make_section (abfd, name);
 
 
      if (!section)
      if (!section)
        return -1;
        return -1;
 
 
      section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : (unsigned int)-1;
      section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : (unsigned int)-1;
      section->size = size;
      section->size = size;
      section->vma = vaddr;
      section->vma = vaddr;
 
 
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
        return -1;
        return -1;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Read & process IHS/EIHS record
/* Read & process IHS/EIHS record
   return 0 on success, -1 on error  */
   return 0 on success, -1 on error  */
int
int
_bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset)
_bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset)
{
{
  unsigned char *p = PRIV (vms_rec) + offset;
  unsigned char *p = PRIV (vms_rec) + offset;
  unsigned int gstvbn = bfd_getl32 (p + EIHS_S_L_GSTVBN);
  unsigned int gstvbn = bfd_getl32 (p + EIHS_S_L_GSTVBN);
  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS_S_L_GSTSIZE);
  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS_S_L_GSTSIZE);
  unsigned int dstvbn = bfd_getl32 (p + EIHS_S_L_DSTVBN);
  unsigned int dstvbn = bfd_getl32 (p + EIHS_S_L_DSTVBN);
  unsigned int dstsize = bfd_getl32 (p + EIHS_S_L_DSTSIZE);
  unsigned int dstsize = bfd_getl32 (p + EIHS_S_L_DSTSIZE);
  unsigned int dmtvbn = bfd_getl32 (p + EIHS_S_L_DMTVBN);
  unsigned int dmtvbn = bfd_getl32 (p + EIHS_S_L_DMTVBN);
  unsigned int dmtbytes = bfd_getl32 (p + EIHS_S_L_DMTBYTES);
  unsigned int dmtbytes = bfd_getl32 (p + EIHS_S_L_DMTBYTES);
  asection *section;
  asection *section;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  vms_debug (8, "_bfd_vms_slurp_ihs\n");
  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",
  vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
             gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
             gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
#endif
#endif
 
 
  if (dstvbn)
  if (dstvbn)
    {
    {
      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
 
 
      section = bfd_make_section (abfd, "$DST$");
      section = bfd_make_section (abfd, "$DST$");
      if (!section)
      if (!section)
        return -1;
        return -1;
 
 
      section->size = dstsize;
      section->size = dstsize;
      section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
      section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
 
 
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
        return -1;
        return -1;
 
 
      PRIV (dst_section) = section;
      PRIV (dst_section) = section;
      abfd->flags |= (HAS_DEBUG | HAS_LINENO);
      abfd->flags |= (HAS_DEBUG | HAS_LINENO);
    }
    }
 
 
  if (dmtvbn)
  if (dmtvbn)
    {
    {
      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
 
 
      section = bfd_make_section (abfd, "$DMT$");
      section = bfd_make_section (abfd, "$DMT$");
      if (!section)
      if (!section)
        return -1;
        return -1;
 
 
      section->size = dmtbytes;
      section->size = dmtbytes;
      section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
      section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
 
 
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
        return -1;
        return -1;
    }
    }
 
 
  if (gstvbn)
  if (gstvbn)
    {
    {
      flagword bfd_flags = SEC_HAS_CONTENTS;
      flagword bfd_flags = SEC_HAS_CONTENTS;
 
 
      section = bfd_make_section (abfd, "$GST$");
      section = bfd_make_section (abfd, "$GST$");
      if (!section)
      if (!section)
        return -1;
        return -1;
 
 
      if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
      if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
        {
        {
          bfd_set_error (bfd_error_file_truncated);
          bfd_set_error (bfd_error_file_truncated);
          return -1;
          return -1;
        }
        }
 
 
      if (_bfd_vms_slurp_object_records (abfd) != 0)
      if (_bfd_vms_slurp_object_records (abfd) != 0)
        return -1;
        return -1;
 
 
      section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
      section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
      section->size = bfd_tell (abfd) - section->filepos;
      section->size = bfd_tell (abfd) - section->filepos;
 
 
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
        return -1;
        return -1;
 
 
      abfd->flags |= HAS_SYMS;
      abfd->flags |= HAS_SYMS;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Build a new module for the specified BFD.  */
/* Build a new module for the specified BFD.  */
 
 
static struct module *
static struct module *
new_module (bfd *abfd)
new_module (bfd *abfd)
{
{
  struct module *module
  struct module *module
    = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
    = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
  module->file_table_count = 16; /* Arbitrary.  */
  module->file_table_count = 16; /* Arbitrary.  */
  module->file_table
  module->file_table
    = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
    = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
  return module;
  return module;
}
}
 
 
/* Parse debug info for a module and internalize it.  */
/* Parse debug info for a module and internalize it.  */
 
 
static void
static void
parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
              unsigned int length)
              unsigned int length)
{
{
  unsigned char *maxptr = ptr + length, *src_ptr, *pcl_ptr;
  unsigned char *maxptr = ptr + length, *src_ptr, *pcl_ptr;
  unsigned int prev_linum = 0, curr_linenum = 0;
  unsigned int prev_linum = 0, curr_linenum = 0;
  bfd_vma prev_pc = 0, curr_pc = 0;
  bfd_vma prev_pc = 0, curr_pc = 0;
  struct srecinfo *curr_srec, *srec;
  struct srecinfo *curr_srec, *srec;
  struct lineinfo *curr_line, *line;
  struct lineinfo *curr_line, *line;
  struct funcinfo *funcinfo;
  struct funcinfo *funcinfo;
 
 
  /* Initialize tables with zero element.  */
  /* Initialize tables with zero element.  */
  curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
  curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
  module->srec_table = curr_srec;
  module->srec_table = curr_srec;
 
 
  curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
  curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
  module->line_table = curr_line;
  module->line_table = curr_line;
 
 
  while (ptr < maxptr)
  while (ptr < maxptr)
    {
    {
      /* The first byte is not counted in the recorded length.  */
      /* The first byte is not counted in the recorded length.  */
      int rec_length = bfd_getl16 (ptr) + 1;
      int rec_length = bfd_getl16 (ptr) + 1;
      int rec_type = bfd_getl16 (ptr + 2);
      int rec_type = bfd_getl16 (ptr + 2);
 
 
#if VMS_DEBUG
#if VMS_DEBUG
      _bfd_vms_debug (2, "DST record: length %d, type %d\n",
      _bfd_vms_debug (2, "DST record: length %d, type %d\n",
                      rec_length, rec_type);
                      rec_length, rec_type);
#endif
#endif
 
 
      switch (rec_type)
      switch (rec_type)
        {
        {
        case DST_S_C_MODBEG:
        case DST_S_C_MODBEG:
          module->name
          module->name
            = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
            = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
 
 
          curr_pc = 0;
          curr_pc = 0;
          prev_pc = 0;
          prev_pc = 0;
          curr_linenum = 0;
          curr_linenum = 0;
          prev_linum = 0;
          prev_linum = 0;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "module: %s\n", module->name);
          _bfd_vms_debug (3, "module: %s\n", module->name);
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_MODEND:
        case DST_S_C_MODEND:
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "end module\n");
          _bfd_vms_debug (3, "end module\n");
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_RTNBEG:
        case DST_S_C_RTNBEG:
          funcinfo = (struct funcinfo *)
          funcinfo = (struct funcinfo *)
            bfd_zalloc (abfd, sizeof (struct funcinfo));
            bfd_zalloc (abfd, sizeof (struct funcinfo));
          funcinfo->name
          funcinfo->name
            = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
            = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
          funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
          funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
          funcinfo->next = module->func_table;
          funcinfo->next = module->func_table;
          module->func_table = funcinfo;
          module->func_table = funcinfo;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "routine: %s at 0x%x\n",
          _bfd_vms_debug (3, "routine: %s at 0x%x\n",
                          funcinfo->name, funcinfo->low);
                          funcinfo->name, funcinfo->low);
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_RTNEND:
        case DST_S_C_RTNEND:
          module->func_table->high = module->func_table->low
          module->func_table->high = module->func_table->low
            + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
            + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
 
 
          if (module->func_table->high > module->high)
          if (module->func_table->high > module->high)
            module->high = module->func_table->high;
            module->high = module->func_table->high;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "end routine\n");
          _bfd_vms_debug (3, "end routine\n");
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_PROLOG:
        case DST_S_C_PROLOG:
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "prologue\n");
          _bfd_vms_debug (3, "prologue\n");
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_EPILOG:
        case DST_S_C_EPILOG:
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "epilog\n");
          _bfd_vms_debug (3, "epilog\n");
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_BLKBEG:
        case DST_S_C_BLKBEG:
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "block\n");
          _bfd_vms_debug (3, "block\n");
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_BLKEND:
        case DST_S_C_BLKEND:
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "end block\n");
          _bfd_vms_debug (3, "end block\n");
#endif
#endif
          break;
          break;
 
 
        case DST_S_C_SOURCE:
        case DST_S_C_SOURCE:
          src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
          src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "source info\n");
          _bfd_vms_debug (3, "source info\n");
#endif
#endif
 
 
          while (src_ptr < ptr + rec_length)
          while (src_ptr < ptr + rec_length)
            {
            {
              int cmd = src_ptr[0], cmd_length, data;
              int cmd = src_ptr[0], cmd_length, data;
 
 
              switch (cmd)
              switch (cmd)
                {
                {
                case DST_S_C_SRC_DECLFILE:
                case DST_S_C_SRC_DECLFILE:
                  {
                  {
                    unsigned int fileid
                    unsigned int fileid
                      = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
                      = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
                    char *filename
                    char *filename
                      = _bfd_vms_save_counted_string (src_ptr
                      = _bfd_vms_save_counted_string (src_ptr
                          + DST_S_B_SRC_DF_FILENAME);
                          + DST_S_B_SRC_DF_FILENAME);
 
 
                    while (fileid >= module->file_table_count)
                    while (fileid >= module->file_table_count)
                      {
                      {
                        module->file_table_count *= 2;
                        module->file_table_count *= 2;
                        module->file_table
                        module->file_table
                          = bfd_realloc (module->file_table,
                          = bfd_realloc (module->file_table,
                                         module->file_table_count
                                         module->file_table_count
                                           * sizeof (struct fileinfo));
                                           * sizeof (struct fileinfo));
                      }
                      }
 
 
                    module->file_table [fileid].name = filename;
                    module->file_table [fileid].name = filename;
                    module->file_table [fileid].srec = 1;
                    module->file_table [fileid].srec = 1;
                    cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
                    cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
#if VMS_DEBUG
#if VMS_DEBUG
                    _bfd_vms_debug (4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
                    _bfd_vms_debug (4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
                                    fileid,
                                    fileid,
                                    module->file_table [fileid].name);
                                    module->file_table [fileid].name);
#endif
#endif
                  }
                  }
                  break;
                  break;
 
 
                case DST_S_C_SRC_DEFLINES_B:
                case DST_S_C_SRC_DEFLINES_B:
                  /* Perform the association and set the next higher index
                  /* Perform the association and set the next higher index
                     to the limit.  */
                     to the limit.  */
                  data = src_ptr[DST_S_B_SRC_UNSBYTE];
                  data = src_ptr[DST_S_B_SRC_UNSBYTE];
                  srec = (struct srecinfo *)
                  srec = (struct srecinfo *)
                    bfd_zalloc (abfd, sizeof (struct srecinfo));
                    bfd_zalloc (abfd, sizeof (struct srecinfo));
                  srec->line = curr_srec->line + data;
                  srec->line = curr_srec->line + data;
                  srec->srec = curr_srec->srec + data;
                  srec->srec = curr_srec->srec + data;
                  srec->sfile = curr_srec->sfile;
                  srec->sfile = curr_srec->sfile;
                  curr_srec->next = srec;
                  curr_srec->next = srec;
                  curr_srec = srec;
                  curr_srec = srec;
                  cmd_length = 2;
                  cmd_length = 2;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_B: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_B: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_DEFLINES_W:
                case DST_S_C_SRC_DEFLINES_W:
                  /* Perform the association and set the next higher index
                  /* Perform the association and set the next higher index
                     to the limit.  */
                     to the limit.  */
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  srec = (struct srecinfo *)
                  srec = (struct srecinfo *)
                    bfd_zalloc (abfd, sizeof (struct srecinfo));
                    bfd_zalloc (abfd, sizeof (struct srecinfo));
                  srec->line = curr_srec->line + data;
                  srec->line = curr_srec->line + data;
                  srec->srec = curr_srec->srec + data,
                  srec->srec = curr_srec->srec + data,
                  srec->sfile = curr_srec->sfile;
                  srec->sfile = curr_srec->sfile;
                  curr_srec->next = srec;
                  curr_srec->next = srec;
                  curr_srec = srec;
                  curr_srec = srec;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_W: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_W: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_INCRLNUM_B:
                case DST_S_C_SRC_INCRLNUM_B:
                  data = src_ptr[DST_S_B_SRC_UNSBYTE];
                  data = src_ptr[DST_S_B_SRC_UNSBYTE];
                  curr_srec->line += data;
                  curr_srec->line += data;
                  cmd_length = 2;
                  cmd_length = 2;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_SETFILE:
                case DST_S_C_SRC_SETFILE:
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  curr_srec->sfile = data;
                  curr_srec->sfile = data;
                  curr_srec->srec = module->file_table[data].srec;
                  curr_srec->srec = module->file_table[data].srec;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETFILE: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETFILE: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_SETLNUM_L:
                case DST_S_C_SRC_SETLNUM_L:
                  data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
                  data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
                  curr_srec->line = data;
                  curr_srec->line = data;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_L: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_L: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_SETLNUM_W:
                case DST_S_C_SRC_SETLNUM_W:
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  curr_srec->line = data;
                  curr_srec->line = data;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_W: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_W: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_SETREC_L:
                case DST_S_C_SRC_SETREC_L:
                  data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
                  data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
                  curr_srec->srec = data;
                  curr_srec->srec = data;
                  module->file_table[curr_srec->sfile].srec = data;
                  module->file_table[curr_srec->sfile].srec = data;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_L: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_L: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_SETREC_W:
                case DST_S_C_SRC_SETREC_W:
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
                  curr_srec->srec = data;
                  curr_srec->srec = data;
                  module->file_table[curr_srec->sfile].srec = data;
                  module->file_table[curr_srec->sfile].srec = data;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_W: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_W: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SRC_FORMFEED:
                case DST_S_C_SRC_FORMFEED:
                  cmd_length = 1;
                  cmd_length = 1;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SRC_FORMFEED\n");
                  _bfd_vms_debug (4, "DST_S_C_SRC_FORMFEED\n");
#endif
#endif
                  break;
                  break;
 
 
                default:
                default:
                  (*_bfd_error_handler) (_("unknown source command %d"),
                  (*_bfd_error_handler) (_("unknown source command %d"),
                                         cmd);
                                         cmd);
                  cmd_length = 2;
                  cmd_length = 2;
                  break;
                  break;
                }
                }
 
 
              src_ptr += cmd_length;
              src_ptr += cmd_length;
            }
            }
          break;
          break;
 
 
        case DST_S_C_LINE_NUM:
        case DST_S_C_LINE_NUM:
          pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
          pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "line info\n");
          _bfd_vms_debug (3, "line info\n");
#endif
#endif
 
 
          while (pcl_ptr < ptr + rec_length)
          while (pcl_ptr < ptr + rec_length)
            {
            {
              /* The command byte is signed so we must sign-extend it.  */
              /* The command byte is signed so we must sign-extend it.  */
              int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
              int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
 
 
              switch (cmd)
              switch (cmd)
                {
                {
                case DST_S_C_DELTA_PC_W:
                case DST_S_C_DELTA_PC_W:
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  curr_pc += data;
                  curr_pc += data;
                  curr_linenum += 1;
                  curr_linenum += 1;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_DELTA_PC_W: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_DELTA_PC_W: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_DELTA_PC_L:
                case DST_S_C_DELTA_PC_L:
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  curr_pc += data;
                  curr_pc += data;
                  curr_linenum += 1;
                  curr_linenum += 1;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_DELTA_PC_L: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_DELTA_PC_L: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_INCR_LINUM:
                case DST_S_C_INCR_LINUM:
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
                  curr_linenum += data;
                  curr_linenum += data;
                  cmd_length = 2;
                  cmd_length = 2;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_INCR_LINUM_W:
                case DST_S_C_INCR_LINUM_W:
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  curr_linenum += data;
                  curr_linenum += data;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_W: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_W: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_INCR_LINUM_L:
                case DST_S_C_INCR_LINUM_L:
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  curr_linenum += data;
                  curr_linenum += data;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_L: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_L: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SET_LINUM_INCR:
                case DST_S_C_SET_LINUM_INCR:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_SET_LINUM_INCR not implemented"));
                    (_("DST_S_C_SET_LINUM_INCR not implemented"));
                  cmd_length = 2;
                  cmd_length = 2;
                  break;
                  break;
 
 
                case DST_S_C_SET_LINUM_INCR_W:
                case DST_S_C_SET_LINUM_INCR_W:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_SET_LINUM_INCR_W not implemented"));
                    (_("DST_S_C_SET_LINUM_INCR_W not implemented"));
                  cmd_length = 3;
                  cmd_length = 3;
                  break;
                  break;
 
 
                case DST_S_C_RESET_LINUM_INCR:
                case DST_S_C_RESET_LINUM_INCR:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_RESET_LINUM_INCR not implemented"));
                    (_("DST_S_C_RESET_LINUM_INCR not implemented"));
                  cmd_length = 1;
                  cmd_length = 1;
                  break;
                  break;
 
 
                case DST_S_C_BEG_STMT_MODE:
                case DST_S_C_BEG_STMT_MODE:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_BEG_STMT_MODE not implemented"));
                    (_("DST_S_C_BEG_STMT_MODE not implemented"));
                  cmd_length = 1;
                  cmd_length = 1;
                  break;
                  break;
 
 
                case DST_S_C_END_STMT_MODE:
                case DST_S_C_END_STMT_MODE:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_END_STMT_MODE not implemented"));
                    (_("DST_S_C_END_STMT_MODE not implemented"));
                  cmd_length = 1;
                  cmd_length = 1;
                  break;
                  break;
 
 
                case DST_S_C_SET_LINUM_B:
                case DST_S_C_SET_LINUM_B:
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
                  curr_linenum = data;
                  curr_linenum = data;
                  cmd_length = 2;
                  cmd_length = 2;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SET_LINUM_B: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SET_LINUM_B: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SET_LINE_NUM:
                case DST_S_C_SET_LINE_NUM:
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  curr_linenum = data;
                  curr_linenum = data;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SET_LINE_NUM: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SET_LINE_NUM: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SET_LINUM_L:
                case DST_S_C_SET_LINUM_L:
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  curr_linenum = data;
                  curr_linenum = data;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SET_LINUM_L: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SET_LINUM_L: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SET_PC:
                case DST_S_C_SET_PC:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_SET_PC not implemented"));
                    (_("DST_S_C_SET_PC not implemented"));
                  cmd_length = 2;
                  cmd_length = 2;
                  break;
                  break;
 
 
                case DST_S_C_SET_PC_W:
                case DST_S_C_SET_PC_W:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_SET_PC_W not implemented"));
                    (_("DST_S_C_SET_PC_W not implemented"));
                  cmd_length = 3;
                  cmd_length = 3;
                  break;
                  break;
 
 
                case DST_S_C_SET_PC_L:
                case DST_S_C_SET_PC_L:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_SET_PC_L not implemented"));
                    (_("DST_S_C_SET_PC_L not implemented"));
                  cmd_length = 5;
                  cmd_length = 5;
                  break;
                  break;
 
 
                case DST_S_C_SET_STMTNUM:
                case DST_S_C_SET_STMTNUM:
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("DST_S_C_SET_STMTNUM not implemented"));
                    (_("DST_S_C_SET_STMTNUM not implemented"));
                  cmd_length = 2;
                  cmd_length = 2;
                  break;
                  break;
 
 
                case DST_S_C_TERM:
                case DST_S_C_TERM:
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
                  curr_pc += data;
                  curr_pc += data;
                  cmd_length = 2;
                  cmd_length = 2;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_TERM: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_TERM: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_TERM_W:
                case DST_S_C_TERM_W:
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
                  curr_pc += data;
                  curr_pc += data;
                  cmd_length = 3;
                  cmd_length = 3;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_TERM_W: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_TERM_W: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_TERM_L:
                case DST_S_C_TERM_L:
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  curr_pc += data;
                  curr_pc += data;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_TERM_L: %d\n", data);
                  _bfd_vms_debug (4, "DST_S_C_TERM_L: %d\n", data);
#endif
#endif
                  break;
                  break;
 
 
                case DST_S_C_SET_ABS_PC:
                case DST_S_C_SET_ABS_PC:
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
                  curr_pc = data;
                  curr_pc = data;
                  cmd_length = 5;
                  cmd_length = 5;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "DST_S_C_SET_ABS_PC: 0x%x\n", data);
                  _bfd_vms_debug (4, "DST_S_C_SET_ABS_PC: 0x%x\n", data);
#endif
#endif
                  break;
                  break;
 
 
                default:
                default:
                  if (cmd <= 0)
                  if (cmd <= 0)
                    {
                    {
                      curr_pc -= cmd;
                      curr_pc -= cmd;
                      curr_linenum += 1;
                      curr_linenum += 1;
                      cmd_length = 1;
                      cmd_length = 1;
#if VMS_DEBUG
#if VMS_DEBUG
                      _bfd_vms_debug (4, "bump pc to 0x%llx and line to %d\n",
                      _bfd_vms_debug (4, "bump pc to 0x%llx and line to %d\n",
                                      curr_pc, curr_linenum);
                                      curr_pc, curr_linenum);
#endif
#endif
                    }
                    }
                  else
                  else
                    {
                    {
                      (*_bfd_error_handler) (_("unknown line command %d"),
                      (*_bfd_error_handler) (_("unknown line command %d"),
                                             cmd);
                                             cmd);
                      cmd_length = 2;
                      cmd_length = 2;
                    }
                    }
                  break;
                  break;
                }
                }
 
 
              if ((curr_linenum != prev_linum && curr_pc != prev_pc)
              if ((curr_linenum != prev_linum && curr_pc != prev_pc)
                  || cmd <= 0
                  || cmd <= 0
                  || cmd == DST_S_C_DELTA_PC_L
                  || cmd == DST_S_C_DELTA_PC_L
                  || cmd == DST_S_C_DELTA_PC_W)
                  || cmd == DST_S_C_DELTA_PC_W)
                {
                {
                  line = (struct lineinfo *)
                  line = (struct lineinfo *)
                    bfd_zalloc (abfd, sizeof (struct lineinfo));
                    bfd_zalloc (abfd, sizeof (struct lineinfo));
                  line->address = curr_pc;
                  line->address = curr_pc;
                  line->line = curr_linenum;
                  line->line = curr_linenum;
 
 
                  curr_line->next = line;
                  curr_line->next = line;
                  curr_line = line;
                  curr_line = line;
 
 
                  prev_linum = curr_linenum;
                  prev_linum = curr_linenum;
                  prev_pc = curr_pc;
                  prev_pc = curr_pc;
#if VMS_DEBUG
#if VMS_DEBUG
                  _bfd_vms_debug (4, "-> correlate pc 0x%llx with line %d\n",
                  _bfd_vms_debug (4, "-> correlate pc 0x%llx with line %d\n",
                                  curr_pc, curr_linenum);
                                  curr_pc, curr_linenum);
#endif
#endif
                }
                }
 
 
              pcl_ptr += cmd_length;
              pcl_ptr += cmd_length;
            }
            }
          break;
          break;
 
 
        case 0x17: /* Undocumented type used by DEC C to declare equates.  */
        case 0x17: /* Undocumented type used by DEC C to declare equates.  */
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "undocumented type 0x17\n");
          _bfd_vms_debug (3, "undocumented type 0x17\n");
#endif
#endif
          break;
          break;
 
 
        default:
        default:
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "ignoring record\n");
          _bfd_vms_debug (3, "ignoring record\n");
#endif
#endif
          break;
          break;
 
 
        }
        }
 
 
      ptr += rec_length;
      ptr += rec_length;
    }
    }
 
 
  /* Finalize tables with EOL marker.  */
  /* Finalize tables with EOL marker.  */
  srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
  srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
  srec->line = (unsigned int) -1;
  srec->line = (unsigned int) -1;
  srec->srec = (unsigned int) -1;
  srec->srec = (unsigned int) -1;
  curr_srec->next = srec;
  curr_srec->next = srec;
 
 
  line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
  line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
  line->line = (unsigned int) -1;
  line->line = (unsigned int) -1;
  line->address = (bfd_vma) -1;
  line->address = (bfd_vma) -1;
  curr_line->next = line;
  curr_line->next = line;
 
 
  /* Advertise that this module has been parsed.  This is needed
  /* Advertise that this module has been parsed.  This is needed
     because parsing can be either performed at module creation
     because parsing can be either performed at module creation
     or deferred until debug info is consumed.  */
     or deferred until debug info is consumed.  */
  SET_MODULE_PARSED (module);
  SET_MODULE_PARSED (module);
}
}
 
 
/* Build the list of modules for the specified BFD.  */
/* Build the list of modules for the specified BFD.  */
 
 
static struct module *
static struct module *
build_module_list (bfd *abfd)
build_module_list (bfd *abfd)
{
{
  struct module *module, *list = NULL;
  struct module *module, *list = NULL;
  asection *dmt;
  asection *dmt;
 
 
  if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
  if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
    {
    {
      /* We have a DMT section so this must be an image.  Parse the
      /* We have a DMT section so this must be an image.  Parse the
         section and build the list of modules.  This is sufficient
         section and build the list of modules.  This is sufficient
         since we can compute the start address and the end address
         since we can compute the start address and the end address
         of every module from the section contents.  */
         of every module from the section contents.  */
      bfd_size_type size = bfd_get_section_size (dmt);
      bfd_size_type size = bfd_get_section_size (dmt);
      unsigned char *ptr, *end;
      unsigned char *ptr, *end;
 
 
      ptr = (unsigned char *) bfd_alloc (abfd, size);
      ptr = (unsigned char *) bfd_alloc (abfd, size);
      if (! ptr)
      if (! ptr)
        return NULL;
        return NULL;
 
 
      if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
      if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
        return NULL;
        return NULL;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
      _bfd_vms_debug (2, "DMT\n");
      _bfd_vms_debug (2, "DMT\n");
#endif
#endif
 
 
      end = ptr + size;
      end = ptr + size;
 
 
      while (ptr < end)
      while (ptr < end)
        {
        {
          /* Each header declares a module with its start offset and size
          /* Each header declares a module with its start offset and size
             of debug info in the DST section, as well as the count of
             of debug info in the DST section, as well as the count of
             program sections (i.e. address spans) it contains.  */
             program sections (i.e. address spans) it contains.  */
          int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
          int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
          int size = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
          int size = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
          int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
          int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
          ptr += DBG_S_C_DMT_HEADER_SIZE;
          ptr += DBG_S_C_DMT_HEADER_SIZE;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
          _bfd_vms_debug (3, "module: modbeg = %d, size = %d, count = %d\n",
          _bfd_vms_debug (3, "module: modbeg = %d, size = %d, count = %d\n",
                          modbeg, size, count);
                          modbeg, size, count);
#endif
#endif
 
 
          /* We create a 'module' structure for each program section since
          /* We create a 'module' structure for each program section since
             we only support contiguous addresses in a 'module' structure.
             we only support contiguous addresses in a 'module' structure.
             As a consequence, the actual debug info in the DST section is
             As a consequence, the actual debug info in the DST section is
             shared and can be parsed multiple times; that doesn't seem to
             shared and can be parsed multiple times; that doesn't seem to
             cause problems in practice.  */
             cause problems in practice.  */
          while (count-- > 0)
          while (count-- > 0)
            {
            {
              int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
              int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
              int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
              int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
              module = new_module (abfd);
              module = new_module (abfd);
              module->modbeg = modbeg;
              module->modbeg = modbeg;
              module->size = size;
              module->size = size;
              module->low = start;
              module->low = start;
              module->high = start + length;
              module->high = start + length;
              module->next = list;
              module->next = list;
              list = module;
              list = module;
              ptr += DBG_S_C_DMT_PSECT_SIZE;
              ptr += DBG_S_C_DMT_PSECT_SIZE;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
              _bfd_vms_debug (4, "section: start = 0x%x, length = %d\n",
              _bfd_vms_debug (4, "section: start = 0x%x, length = %d\n",
                              start, length);
                              start, length);
#endif
#endif
            }
            }
        }
        }
    }
    }
  else
  else
    {
    {
      /* We don't have a DMT section so this must be an object.  Parse
      /* 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
         the module right now in order to compute its start address and
         end address.  */
         end address.  */
      module = new_module (abfd);
      module = new_module (abfd);
      parse_module (abfd, module, PRIV (dst_section)->contents,
      parse_module (abfd, module, PRIV (dst_section)->contents,
                    PRIV (dst_ptr_end) - PRIV (dst_section)->contents);
                    PRIV (dst_ptr_end) - PRIV (dst_section)->contents);
      list = module;
      list = module;
    }
    }
 
 
  return list;
  return list;
}
}
 
 
/* Calculate and return the name of the source file and the line nearest
/* Calculate and return the name of the source file and the line nearest
   to the wanted location in the specified module.  */
   to the wanted location in the specified module.  */
 
 
static bfd_boolean
static bfd_boolean
module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
                          const char **file, const char **func,
                          const char **file, const char **func,
                          unsigned int *line)
                          unsigned int *line)
{
{
  struct funcinfo *funcinfo;
  struct funcinfo *funcinfo;
  struct lineinfo *lineinfo;
  struct lineinfo *lineinfo;
  struct srecinfo *srecinfo;
  struct srecinfo *srecinfo;
  bfd_boolean ret = FALSE;
  bfd_boolean ret = FALSE;
 
 
  /* Parse this module if that was not done at module creation.  */
  /* Parse this module if that was not done at module creation.  */
  if (! IS_MODULE_PARSED (module))
  if (! IS_MODULE_PARSED (module))
    {
    {
      unsigned int size = module->size;
      unsigned int size = module->size;
      unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
      unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
      unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
      unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
 
 
      if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
      if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
          || bfd_bread (buffer, size, abfd) != size)
          || bfd_bread (buffer, size, abfd) != size)
        {
        {
          bfd_set_error (bfd_error_no_debug_section);
          bfd_set_error (bfd_error_no_debug_section);
          return FALSE;
          return FALSE;
        }
        }
 
 
      parse_module (abfd, module, buffer, size);
      parse_module (abfd, module, buffer, size);
      free (buffer);
      free (buffer);
    }
    }
 
 
  /* Find out the function (if any) that contains the address.  */
  /* Find out the function (if any) that contains the address.  */
  for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
  for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
    if (addr >= funcinfo->low && addr <= funcinfo->high)
    if (addr >= funcinfo->low && addr <= funcinfo->high)
      {
      {
        *func = funcinfo->name;
        *func = funcinfo->name;
        ret = TRUE;
        ret = TRUE;
        break;
        break;
      }
      }
 
 
  /* Find out the source file and the line nearest to the address.  */
  /* Find out the source file and the line nearest to the address.  */
  for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
  for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
    if (lineinfo->next && addr < lineinfo->next->address)
    if (lineinfo->next && addr < lineinfo->next->address)
      {
      {
        for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
        for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
          if (srecinfo->next && lineinfo->line < srecinfo->next->line)
          if (srecinfo->next && lineinfo->line < srecinfo->next->line)
            {
            {
              if (srecinfo->sfile > 0)
              if (srecinfo->sfile > 0)
                {
                {
                  *file = module->file_table[srecinfo->sfile].name;
                  *file = module->file_table[srecinfo->sfile].name;
                  *line = srecinfo->srec + lineinfo->line - srecinfo->line;
                  *line = srecinfo->srec + lineinfo->line - srecinfo->line;
                }
                }
              else
              else
                {
                {
                  *file = module->name;
                  *file = module->name;
                  *line = lineinfo->line;
                  *line = lineinfo->line;
                }
                }
              return TRUE;
              return TRUE;
            }
            }
 
 
        break;
        break;
      }
      }
 
 
  return ret;
  return ret;
}
}
 
 
/* Provided a BFD, a section and an offset into the section, calculate and
/* 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
   return the name of the source file and the line nearest to the wanted
   location.  */
   location.  */
 
 
bfd_boolean
bfd_boolean
_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
                                asymbol **symbols ATTRIBUTE_UNUSED,
                                asymbol **symbols ATTRIBUTE_UNUSED,
                                bfd_vma offset, const char **file,
                                bfd_vma offset, const char **file,
                                const char **func, unsigned int *line)
                                const char **func, unsigned int *line)
{
{
  struct module *module;
  struct module *module;
 
 
  /* What address are we looking for?  */
  /* What address are we looking for?  */
  bfd_vma addr = section->vma + offset;
  bfd_vma addr = section->vma + offset;
 
 
  *file = NULL;
  *file = NULL;
  *func = NULL;
  *func = NULL;
  *line = 0;
  *line = 0;
 
 
  if (PRIV (dst_section) == NULL)
  if (PRIV (dst_section) == NULL)
    return FALSE;
    return FALSE;
 
 
  if (PRIV (modules) == NULL)
  if (PRIV (modules) == NULL)
    {
    {
      PRIV (modules) = build_module_list (abfd);
      PRIV (modules) = build_module_list (abfd);
      if (PRIV (modules) == NULL)
      if (PRIV (modules) == NULL)
        return FALSE;
        return FALSE;
    }
    }
 
 
  for (module = PRIV (modules); module; module = module->next)
  for (module = PRIV (modules); module; module = module->next)
    if (addr >= module->low && addr <= module->high)
    if (addr >= module->low && addr <= module->high)
      return module_find_nearest_line (abfd, module, addr, file, func, line);
      return module_find_nearest_line (abfd, module, addr, file, func, line);
 
 
  return FALSE;
  return FALSE;
}
}
 
 
/* Process EDBG/ETBT record.
/* Process EDBG/ETBT record.
   Return 0 on success, -1 on error  */
   Return 0 on success, -1 on error  */
 
 
static int
static int
vms_slurp_debug (bfd *abfd)
vms_slurp_debug (bfd *abfd)
{
{
  if (PRIV (dst_section) == NULL)
  if (PRIV (dst_section) == NULL)
    {
    {
      /* We have no way to find out beforehand how much debug info there
      /* 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
         is in an object file, so pick an initial amount and grow it as
         needed later.  */
         needed later.  */
      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC;
      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC;
      asection *section = bfd_make_section (abfd, "$DST$");
      asection *section = bfd_make_section (abfd, "$DST$");
      if (!section)
      if (!section)
        return -1;
        return -1;
      section->size = 1024;
      section->size = 1024;
      if (!bfd_set_section_flags (abfd, section, flags))
      if (!bfd_set_section_flags (abfd, section, flags))
        return -1;
        return -1;
      section->contents = ((unsigned char *)
      section->contents = ((unsigned char *)
                           bfd_zmalloc (section->size));
                           bfd_zmalloc (section->size));
      if (section->contents == NULL)
      if (section->contents == NULL)
        return -1;
        return -1;
      section->filepos = (unsigned int)-1;
      section->filepos = (unsigned int)-1;
      PRIV (dst_section) = section;
      PRIV (dst_section) = section;
    }
    }
 
 
  PRIV (image_section) = PRIV (dst_section);
  PRIV (image_section) = PRIV (dst_section);
  PRIV (image_ptr) = PRIV (dst_section)->contents;
  PRIV (image_ptr) = PRIV (dst_section)->contents;
 
 
  return _bfd_vms_slurp_tir (abfd, EOBJ_S_C_ETIR);
  return _bfd_vms_slurp_tir (abfd, EOBJ_S_C_ETIR);
}
}
 
 
/* Process DBG/EDBG record.
/* Process DBG/EDBG record.
   Return 0 on success, -1 on error.  */
   Return 0 on success, -1 on error.  */
 
 
int
int
_bfd_vms_slurp_dbg (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_slurp_dbg (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "DBG/EDBG\n");
  _bfd_vms_debug (2, "DBG/EDBG\n");
#endif
#endif
 
 
  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
 
 
  return vms_slurp_debug (abfd);
  return vms_slurp_debug (abfd);
}
}
 
 
/* Process TBT/ETBT record.
/* Process TBT/ETBT record.
   Return 0 on success, -1 on error.  */
   Return 0 on success, -1 on error.  */
 
 
int
int
_bfd_vms_slurp_tbt (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_slurp_tbt (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "TBT/ETBT\n");
  _bfd_vms_debug (2, "TBT/ETBT\n");
#endif
#endif
 
 
  abfd->flags |= HAS_LINENO;
  abfd->flags |= HAS_LINENO;
 
 
  return vms_slurp_debug (abfd);
  return vms_slurp_debug (abfd);
}
}
 
 
/* Write DBG/EDBG record.  */
/* Write DBG/EDBG record.  */
 
 
int
int
_bfd_vms_write_dbg (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_write_dbg (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* Write TBT/ETBT record.  */
/* Write TBT/ETBT record.  */
 
 
int
int
_bfd_vms_write_tbt (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_write_tbt (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
  _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.