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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [vms-tir.c] - Diff between revs 157 and 225

Show entire file | Details | Blame | View Log

Rev 157 Rev 225
Line 1... Line 1...
/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
   EVAX (openVMS/Alpha) files.
   EVAX (openVMS/Alpha) files.
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007,
   Free Software Foundation, Inc.
   2008, 2009 Free Software Foundation, Inc.
 
 
   TIR record handling functions
   TIR record handling functions
   ETIR record handling functions
   ETIR record handling functions
 
 
   go and read the openVMS linker manual (esp. appendix B)
   Go and read the openVMS linker manual (esp. appendix B)
   if you don't know what's going on here :-)
   if you don't know what's going on here :-)
 
 
   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
Line 24... Line 24...
   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.  */
 
 
 
 
/* The following type abbreviations are used:
/* The following type abbreviations are used:
 
 
        cs      counted string (ascii string with length byte)
        cs      counted string (ascii string with length byte)
        by      byte (1 byte)
        by      byte (1 byte)
        sh      short (2 byte, 16 bit)
        sh      short (2 byte, 16 bit)
Line 39... Line 38...
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "bfdlink.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "libbfd.h"
#include "vms.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);
 
 


static int
static int
check_section (bfd * abfd, int size)
check_section (bfd * abfd, int size)
{
{
  bfd_size_type offset;
  bfd_size_type offset;
Line 90... Line 116...
#endif
#endif
 
 
  PRIV (image_ptr) += offset;
  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.  */
/* Dump multiple bytes to section image.  */
 
 
static void
static void
image_dump (bfd * abfd,
image_dump (bfd * abfd,
            unsigned char *ptr,
            unsigned char *ptr,
Line 107... Line 204...
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, size))
  if (PRIV (is_vax) && check_section (abfd, size))
    return;
    return;
 
 
 
  if (PRIV (dst_section))
 
    dst_check_allocation (abfd, size);
 
 
  while (size-- > 0)
  while (size-- > 0)
    *PRIV (image_ptr)++ = *ptr++;
    *PRIV (image_ptr)++ = *ptr++;
}
}
 
 
/* Write byte to section image.  */
/* Write byte to section image.  */
Line 123... Line 223...
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 1))
  if (PRIV (is_vax) && check_section (abfd, 1))
    return;
    return;
 
 
 
  if (PRIV (dst_section))
 
    dst_check_allocation (abfd, 1);
 
 
  *PRIV (image_ptr)++ = (value & 0xff);
  *PRIV (image_ptr)++ = (value & 0xff);
}
}
 
 
/* Write 2-byte word to image.  */
/* Write 2-byte word to image.  */
 
 
Line 138... Line 241...
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 2))
  if (PRIV (is_vax) && check_section (abfd, 2))
    return;
    return;
 
 
 
  if (PRIV (dst_section))
 
    dst_check_allocation (abfd, 2);
 
 
  bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
  bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
  PRIV (image_ptr) += 2;
  PRIV (image_ptr) += 2;
}
}
 
 
/* Write 4-byte long to image.  */
/* Write 4-byte long to image.  */
Line 154... Line 260...
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 4))
  if (PRIV (is_vax) && check_section (abfd, 4))
    return;
    return;
 
 
 
  if (PRIV (dst_section))
 
    dst_check_allocation (abfd, 4);
 
 
  bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
  bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
  PRIV (image_ptr) += 4;
  PRIV (image_ptr) += 4;
}
}
 
 
/* Write 8-byte quad to image.  */
/* Write 8-byte quad to image.  */
Line 170... Line 279...
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 8))
  if (PRIV (is_vax) && check_section (abfd, 8))
    return;
    return;
 
 
 
  if (PRIV (dst_section))
 
    dst_check_allocation (abfd, 8);
 
 
  bfd_putl64 (value, PRIV (image_ptr));
  bfd_putl64 (value, PRIV (image_ptr));
  PRIV (image_ptr) += 8;
  PRIV (image_ptr) += 8;
}
}


static const char *
static const char *
cmd_name (int cmd)
cmd_name (int cmd)
{
{
  switch (cmd)
  switch (cmd)
    {
    {
    case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
    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_PQ: return "ETIR_S_C_STA_PQ";
    case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
    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_MOD: return "ETIR_S_C_STA_MOD";
    case ETIR_S_C_STA_CKARG: return "ETIR_S_C_STA_CKARG";
    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_B: return "ETIR_S_C_STO_B";
    case ETIR_S_C_STO_W: return "ETIR_S_C_STO_W";
    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_GBL: return "ETIR_S_C_STO_GBL";
    case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
    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_RB: return "ETIR_S_C_STO_RB";
    case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
    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_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_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_GBL: return "ETIR_S_C_STO_HINT_GBL";
    case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
    case ETIR_S_C_STO_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_INSV: return "ETIR_S_C_OPR_INSV";
    case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
    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_ROT: return "ETIR_S_C_OPR_ROT";
    case ETIR_S_C_OPR_REDEF: return "ETIR_S_C_OPR_REDEF";
    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_OPR_DFLIT: return "ETIR_S_C_OPR_DFLIT";
Line 213... Line 333...
    case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL";
    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_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_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_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
    case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
    case ETIR_S_C_STC_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:
    default:
      /* These names have not yet been added to this switch statement.  */
      /* These names have not yet been added to this switch statement.  */
      abort ();
      (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
    }
    }
 
 
 
  return NULL;
}
}
#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
 
 
/* etir_sta
/* etir_sta
 
 
   vms stack commands
   Vms stack commands.
 
 
   handle sta_xxx commands in etir section
   Handle sta_xxx commands in etir section,
   ptr points to data area in record
   ptr points to data area in record.
 
 
   see table B-8 of the openVMS linker manual.  */
   See table B-8 of the openVMS linker manual.  */
 
 
static bfd_boolean
static bfd_boolean
etir_sta (bfd * abfd, int cmd, unsigned char *ptr)
etir_sta (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
  _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
  switch (cmd)
  switch (cmd)
    {
    {
      /* stack global
      /* Stack global
         arg: cs        symbol name
         arg: cs        symbol name
 
 
         stack 32 bit value of symbol (high bits set to 0).  */
         stack 32 bit value of symbol (high bits set to 0).  */
    case ETIR_S_C_STA_GBL:
    case ETIR_S_C_STA_GBL:
      {
      {
Line 263... Line 390...
            _bfd_vms_push (abfd, (uquad) 0, -1);
            _bfd_vms_push (abfd, (uquad) 0, -1);
          }
          }
        else
        else
          _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
          _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
      }
      }
 
      *quarter_relocs = 1;
      break;
      break;
 
 
      /* stack longword
      /* Stack longword
         arg: lw        value
         arg: lw        value
 
 
         stack 32 bit value, sign extend to 64 bit.  */
         stack 32 bit value, sign extend to 64 bit.  */
    case ETIR_S_C_STA_LW:
    case ETIR_S_C_STA_LW:
      _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
      _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
 
      /* This one is special as it is both part of the section header
 
         and of the ALPHA_R_REFLONG relocation.  */
 
      if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_DFLOC)
 
        *quarter_relocs = 0;
 
      else if (*quarter_relocs)
 
        *quarter_relocs += 1;
 
      else
 
        *quarter_relocs = 2;
      break;
      break;
 
 
      /* stack global
      /* Stack quadword
         arg: qw        value
         arg: qw        value
 
 
         stack 64 bit value of symbol.  */
         stack 64 bit value of symbol.  */
    case ETIR_S_C_STA_QW:
    case ETIR_S_C_STA_QW:
      _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
      _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
 
      if (*quarter_relocs)
 
        *quarter_relocs += 1;
 
      else
 
        *quarter_relocs = 2;
      break;
      break;
 
 
      /* stack psect base plus quadword offset
      /* Stack psect base plus quadword offset
         arg: lw        section index
         arg: lw        section index
         qw     signed quadword offset (low 32 bits)
         qw     signed quadword offset (low 32 bits)
 
 
         stack qw argument and section index
         Stack qw argument and section index
         (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB).  */
         (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB).  */
    case ETIR_S_C_STA_PQ:
    case ETIR_S_C_STA_PQ:
      {
      {
        uquad dummy;
        uquad dummy;
        unsigned int psect;
        int psect;
 
 
        psect = bfd_getl32 (ptr);
        psect = bfd_getl32 (ptr);
        if (psect >= PRIV (section_count))
        if ((unsigned int) psect >= PRIV (section_count))
          {
          {
            (*_bfd_error_handler) (_("bad section index in %s"),
            (*_bfd_error_handler) (_("bad section index in %s"),
                                   cmd_name (cmd));
                                   cmd_name (cmd));
            bfd_set_error (bfd_error_bad_value);
            bfd_set_error (bfd_error_bad_value);
            return FALSE;
            return FALSE;
          }
          }
        dummy = bfd_getl64 (ptr + 4);
        dummy = bfd_getl64 (ptr + 4);
        _bfd_vms_push (abfd, dummy, (int) psect);
        _bfd_vms_push (abfd, dummy, (int) psect);
      }
      }
 
      /* This one is special as it is both part of the section header
 
         and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations.  */
 
      if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_SETRB)
 
        *quarter_relocs = 0;
 
      else
 
        *quarter_relocs = 2;
      break;
      break;
 
 
    case ETIR_S_C_STA_LI:
    case ETIR_S_C_STA_LI:
    case ETIR_S_C_STA_MOD:
    case ETIR_S_C_STA_MOD:
    case ETIR_S_C_STA_CKARG:
    case ETIR_S_C_STA_CKARG:
      (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
      (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
 
      *quarter_relocs = 0;
      return FALSE;
      return FALSE;
      break;
 
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
 
      *quarter_relocs = 0;
      return FALSE;
      return FALSE;
      break;
 
    }
    }
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "etir_sta true\n");
  _bfd_vms_debug (5, "etir_sta true\n");
#endif
#endif
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* etir_sto
/* etir_sto
 
 
Line 333... Line 481...
   ptr points to data area in record
   ptr points to data area in record
 
 
   see table B-9 of the openVMS linker manual.  */
   see table B-9 of the openVMS linker manual.  */
 
 
static bfd_boolean
static bfd_boolean
etir_sto (bfd * abfd, int cmd, unsigned char *ptr)
etir_sto (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
{
  uquad dummy;
  uquad dummy;
  int psect;
  int psect;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
  _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
  switch (cmd)
  switch (cmd)
    {
    {
      /* Store byte: pop stack, write byte
      /* Store byte: pop stack, write byte
         arg: -.  */
         arg: -.  */
    case ETIR_S_C_STO_B:
    case ETIR_S_C_STO_B:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      /* FIXME: check top bits.  */
      /* FIXME: check top bits.  */
      image_write_b (abfd, (unsigned int) dummy & 0xff);
      image_write_b (abfd, (unsigned int) dummy & 0xff);
 
      *quarter_relocs = 0;
      break;
      break;
 
 
      /* Store word: pop stack, write word
      /* Store word: pop stack, write word
         arg: -.  */
         arg: -.  */
    case ETIR_S_C_STO_W:
    case ETIR_S_C_STO_W:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      /* FIXME: check top bits */
      /* FIXME: check top bits */
      image_write_w (abfd, (unsigned int) dummy & 0xffff);
      image_write_w (abfd, (unsigned int) dummy & 0xffff);
 
      *quarter_relocs = 0;
      break;
      break;
 
 
      /* Store longword: pop stack, write longword
      /* Store longword: pop stack, write longword
         arg: -.  */
         arg: -.  */
    case ETIR_S_C_STO_LW:
    case ETIR_S_C_STO_LW:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy += (PRIV (sections)[psect])->vma;
      dummy += (PRIV (sections)[psect])->vma;
      /* FIXME: check top bits.  */
      /* FIXME: check top bits.  */
      image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
      image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
 
      if (*quarter_relocs == 2)
 
        *quarter_relocs = 4;
 
      else
 
        *quarter_relocs += 1;
      break;
      break;
 
 
      /* Store quadword: pop stack, write quadword
      /* Store quadword: pop stack, write quadword
         arg: -.  */
         arg: -.  */
    case ETIR_S_C_STO_QW:
    case ETIR_S_C_STO_QW:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy += (PRIV (sections)[psect])->vma;
      dummy += (PRIV (sections)[psect])->vma;
      /* FIXME: check top bits.  */
      /* FIXME: check top bits.  */
      image_write_q (abfd, dummy);
      image_write_q (abfd, dummy);
 
      if (*quarter_relocs == 2)
 
        *quarter_relocs = 4;
 
      else
 
        *quarter_relocs += 1;
      break;
      break;
 
 
      /* Store immediate repeated: pop stack for repeat count
      /* Store immediate repeated: pop stack for repeat count
         arg: lw        byte count
         arg: lw        byte count
         da     data.  */
         da     data.  */
Line 391... Line 549...
        size = bfd_getl32 (ptr);
        size = bfd_getl32 (ptr);
        dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
        dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
        while (dummy-- > 0)
        while (dummy-- > 0)
          image_dump (abfd, ptr+4, size, 0);
          image_dump (abfd, ptr+4, size, 0);
      }
      }
 
      *quarter_relocs = 0;
      break;
      break;
 
 
      /* Store global: write symbol value
      /* Store global: write symbol value
         arg: cs        global symbol name.  */
         arg: cs        global symbol name.  */
    case ETIR_S_C_STO_GBL:
    case ETIR_S_C_STO_GBL:
Line 404... Line 563...
 
 
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
                                                      name, FALSE, FALSE);
        if (entry == NULL)
        if (entry == NULL)
          {
          /* FIXME, reloc.  */
            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
          image_write_q (abfd, (uquad) (0));
                                   cmd_name (cmd), name);
 
            return FALSE;
 
          }
 
        else
        else
          /* FIXME, reloc.  */
          /* FIXME, reloc.  */
          image_write_q (abfd, (uquad) (entry->symbol->value));
          image_write_q (abfd, (uquad) (entry->symbol->value));
      }
      }
 
      *quarter_relocs = 4;
      break;
      break;
 
 
      /* Store code address: write address of entry point
      /* Store code address: write address of entry point
         arg: cs        global symbol name (procedure).  */
         arg: cs        global symbol name (procedure).  */
    case ETIR_S_C_STO_CA:
    case ETIR_S_C_STO_CA:
Line 426... Line 583...
 
 
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
        entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
                                                      name, FALSE, FALSE);
                                                      name, FALSE, FALSE);
        if (entry == NULL)
        if (entry == NULL)
          {
          /* FIXME, reloc.  */
            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
          image_write_q (abfd, (uquad) (0));
                                   cmd_name (cmd), name);
 
            return FALSE;
 
          }
 
        else
        else
          /* FIXME, reloc.  */
          /* FIXME, reloc.  */
          image_write_q (abfd, (uquad) (entry->symbol->value));
          image_write_q (abfd, (uquad) (entry->symbol->value));
      }
      }
 
      *quarter_relocs = 4;
      break;
      break;
 
 
      /* Store offset to psect: pop stack, add low 32 bits to base of psect
      /* Store offset to psect: pop stack, add low 32 bits to base of psect
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STO_OFF:
    case ETIR_S_C_STO_OFF:
Line 448... Line 603...
 
 
        q = _bfd_vms_pop (abfd, & psect1);
        q = _bfd_vms_pop (abfd, & psect1);
        q += (PRIV (sections)[psect1])->vma;
        q += (PRIV (sections)[psect1])->vma;
        image_write_q (abfd, q);
        image_write_q (abfd, q);
      }
      }
 
      *quarter_relocs += 2;
      break;
      break;
 
 
      /* Store immediate
      /* Store immediate
         arg: lw        count of bytes
         arg: lw        count of bytes
              da        data.  */
              da        data.  */
Line 460... Line 616...
        int size;
        int size;
 
 
        size = bfd_getl32 (ptr);
        size = bfd_getl32 (ptr);
        image_dump (abfd, ptr+4, size, 0);
        image_dump (abfd, ptr+4, size, 0);
      }
      }
 
      *quarter_relocs = 0;
      break;
      break;
 
 
      /* This code is 'reserved to digital' according to the openVMS
      /* This code is 'reserved to digital' according to the openVMS
         linker manual, however it is generated by the DEC C compiler
         linker manual, however it is generated by the DEC C compiler
         and defined in the include file.
         and defined in the include file.
Line 487... Line 644...
          }
          }
        else
        else
          /* FIXME, reloc.  */
          /* FIXME, reloc.  */
          image_write_l (abfd, (unsigned long) (entry->symbol->value));
          image_write_l (abfd, (unsigned long) (entry->symbol->value));
      }
      }
 
      *quarter_relocs = 4;
      break;
      break;
 
 
    case ETIR_S_C_STO_RB:
    case ETIR_S_C_STO_RB:
    case ETIR_S_C_STO_AB:
    case ETIR_S_C_STO_AB:
    case ETIR_S_C_STO_LP_PSB:
    case ETIR_S_C_STO_LP_PSB:
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      break;
      *quarter_relocs = 0;
 
      return FALSE;
 
 
    case ETIR_S_C_STO_HINT_GBL:
    case ETIR_S_C_STO_HINT_GBL:
    case ETIR_S_C_STO_HINT_PS:
    case ETIR_S_C_STO_HINT_PS:
      (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
      (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
      break;
      *quarter_relocs = 0;
 
      return FALSE;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
      break;
      *quarter_relocs = 0;
 
      return FALSE;
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
Line 516... Line 677...
   arguments are popped from stack, results are pushed on stack
   arguments are popped from stack, results are pushed on stack
 
 
   see table B-10 of the openVMS linker manual.  */
   see table B-10 of the openVMS linker manual.  */
 
 
static bfd_boolean
static bfd_boolean
etir_opr (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
etir_opr (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
 
          int *quarter_relocs)
{
{
  long op1, op2;
  long op1, op2;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
  _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
 
  /* No relocation uses OPR commands except ETIR_S_C_OPR_ADD.  */
 
  if (cmd == ETIR_S_C_OPR_ADD)
 
    *quarter_relocs += 1;
 
  else
 
    *quarter_relocs = 0;
 
 
  switch (cmd)
  switch (cmd)
    {
    {
    case ETIR_S_C_OPR_NOP:      /* No-op.  */
    case ETIR_S_C_OPR_NOP:      /* No-op.  */
      break;
      break;
 
 
Line 602... Line 770...
    case ETIR_S_C_OPR_USH:       /* Unsigned shift.   */
    case ETIR_S_C_OPR_USH:       /* Unsigned shift.   */
    case ETIR_S_C_OPR_ROT:       /* Rotate.  */
    case ETIR_S_C_OPR_ROT:       /* Rotate.  */
    case ETIR_S_C_OPR_REDEF:     /* Redefine symbol to current location.  */
    case ETIR_S_C_OPR_REDEF:     /* Redefine symbol to current location.  */
    case ETIR_S_C_OPR_DFLIT:     /* Define a literal.  */
    case ETIR_S_C_OPR_DFLIT:     /* Define a literal.  */
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      break;
      return FALSE;
 
 
    case ETIR_S_C_OPR_SEL:      /* Select.  */
    case ETIR_S_C_OPR_SEL:      /* Select.  */
      if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
      if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
        (void) _bfd_vms_pop (abfd, NULL);
        (void) _bfd_vms_pop (abfd, NULL);
      else
      else
Line 617... Line 785...
        }
        }
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
      break;
      return FALSE;
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Control commands.
/* Control commands.
 
 
   See table B-11 of the openVMS linker manual.  */
   See table B-11 of the openVMS linker manual.  */
 
 
static bfd_boolean
static bfd_boolean
etir_ctl (bfd * abfd, int cmd, unsigned char *ptr)
etir_ctl (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
{
  uquad  dummy;
  uquad  dummy;
  int psect;
  int psect;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
  _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
 
  /* No relocation uses CTL commands.  */
 
  *quarter_relocs = 0;
 
 
  switch (cmd)
  switch (cmd)
    {
    {
      /* Det relocation base: pop stack, set image location counter
      /* Det relocation base: pop stack, set image location counter
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_CTL_SETRB:
    case ETIR_S_C_CTL_SETRB:
Line 658... Line 829...
 
 
      /* Define location: pop index, save location counter under index
      /* Define location: pop index, save location counter under index
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_CTL_DFLOC:
    case ETIR_S_C_CTL_DFLOC:
      dummy = _bfd_vms_pop (abfd, NULL);
      dummy = _bfd_vms_pop (abfd, NULL);
      /* FIXME */
      dst_define_location (abfd, dummy);
      break;
      break;
 
 
      /* Set location: pop index, restore location counter from index
      /* Set location: pop index, restore location counter from index
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_CTL_STLOC:
    case ETIR_S_C_CTL_STLOC:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, NULL);
      /* FIXME */
      dst_restore_location (abfd, dummy);
      break;
      break;
 
 
      /* Stack defined location: pop index, push location counter from index
      /* Stack defined location: pop index, push location counter from index
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_CTL_STKDL:
    case ETIR_S_C_CTL_STKDL:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, NULL);
      /* FIXME.  */
      _bfd_vms_push (abfd, dst_retrieve_location (abfd, dummy), -1);
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
      break;
      return FALSE;
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Store conditional commands
/* Store conditional commands
 
 
   See table B-12 and B-13 of the openVMS linker manual.  */
   See table B-12 and B-13 of the openVMS linker manual.  */
 
 
static bfd_boolean
static bfd_boolean
etir_stc (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
etir_stc (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
 
          int *quarter_relocs)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
  _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
  switch (cmd)
  switch (cmd)
    {
    {
      /* 200 Store-conditional Linkage Pair
      /* 200 Store-conditional Linkage Pair
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_LP:
    case ETIR_S_C_STC_LP:
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
 
      break;
 
 
 
      /* 201 Store-conditional Linkage Pair with Procedure Signature
 
         arg:   lw      linkage index
 
                cs      procedure name
 
                by      signature length
 
                da      signature.  */
 
    case ETIR_S_C_STC_LP_PSB:
 
      image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
 
      break;
 
 
 
      /* 202 Store-conditional Address at global address
      /* 202 Store-conditional Address at global address
         arg:   lw      linkage index
         arg:   lw      linkage index
                cs      global name.  */
                cs      global name.  */
 
 
    case ETIR_S_C_STC_GBL:
    case ETIR_S_C_STC_GBL:
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
 
      break;
 
 
 
      /* 203 Store-conditional Code Address at global address
      /* 203 Store-conditional Code Address at global address
         arg:   lw      linkage index
         arg:   lw      linkage index
                cs      procedure name.  */
                cs      procedure name.  */
    case ETIR_S_C_STC_GCA:
    case ETIR_S_C_STC_GCA:
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
 
      break;
 
 
 
      /* 204 Store-conditional Address at psect + offset
      /* 204 Store-conditional Address at psect + offset
         arg:   lw      linkage index
         arg:   lw      linkage index
                lw      psect index
                lw      psect index
                qw      offset.  */
                qw      offset.  */
    case ETIR_S_C_STC_PS:
    case ETIR_S_C_STC_PS:
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      (*_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;
      break;
 
 
      /* 205 Store-conditional NOP at address of global
      /* 205 Store-conditional NOP at address of global
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_NOP_GBL:
    case ETIR_S_C_STC_NOP_GBL:
 
      /* ALPHA_R_NOP */
      /* 206 Store-conditional NOP at pect + offset
 
         arg: none.  */
 
    case ETIR_S_C_STC_NOP_PS:
 
 
 
      /* 207 Store-conditional BSR at global address
      /* 207 Store-conditional BSR at global address
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_BSR_GBL:
 
 
 
      /* 208 Store-conditional BSR at pect + offset
    case ETIR_S_C_STC_BSR_GBL:
         arg: none.  */
      /* ALPHA_R_BSR */
    case ETIR_S_C_STC_BSR_PS:
 
 
 
      /* 209 Store-conditional LDA at global address
      /* 209 Store-conditional LDA at global address
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_LDA_GBL:
 
 
 
      /* 210 Store-conditional LDA at psect + offset
    case ETIR_S_C_STC_LDA_GBL:
         arg: none.  */
      /* ALPHA_R_LDA */
    case ETIR_S_C_STC_LDA_PS:
 
 
 
      /* 211 Store-conditional BSR or Hint at global address
      /* 211 Store-conditional BSR or Hint at global address
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_BOH_GBL:
 
 
 
      /* 212 Store-conditional BSR or Hint at pect + offset
    case ETIR_S_C_STC_BOH_GBL:
         arg: none.  */
      *quarter_relocs = 4;
    case ETIR_S_C_STC_BOH_PS:
      break;
 
 
      /* 213 Store-conditional NOP,BSR or HINT at global address
      /* 213 Store-conditional NOP,BSR or HINT at global address
         arg: none.  */
         arg: none.  */
 
 
    case ETIR_S_C_STC_NBH_GBL:
    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
      /* 214 Store-conditional NOP,BSR or HINT at psect + offset
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_NBH_PS:
    case ETIR_S_C_STC_NBH_PS:
      /* FIXME */
      (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd));
      break;
      *quarter_relocs = 0;
 
      return FALSE;
 
 
    default:
    default:
#if VMS_DEBUG
      (*_bfd_error_handler) (_("reserved STC cmd %d"), cmd);
      _bfd_vms_debug (3,  "reserved STC cmd %d", cmd);
      *quarter_relocs = 0;
#endif
      return FALSE;
      break;
 
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
static asection *
static asection *
new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
Line 849... Line 1033...
  return 0;
  return 0;
}
}
 
 
/* tir_sta
/* tir_sta
 
 
   vax stack commands
   Vax stack commands.
 
 
   Handle sta_xxx commands in tir section
   Handle sta_xxx commands in tir section,
   ptr points to data area in record
   ptr points to data area in record.
 
 
   See table 7-3 of the VAX/VMS linker manual.  */
   See table 7-3 of the VAX/VMS linker manual.  */
 
 
static unsigned char *
static unsigned char *
tir_sta (bfd * abfd, unsigned char *ptr)
tir_sta (bfd * abfd, unsigned char *ptr)
Line 922... Line 1106...
         arg: by        section index
         arg: by        section index
                (sh     section index)
                (sh     section index)
                by      signed byte offset.  */
                by      signed byte offset.  */
      {
      {
        unsigned long dummy;
        unsigned long dummy;
        unsigned int psect;
        int psect;
 
 
        if (cmd == TIR_S_C_STA_PB)
        if (cmd == TIR_S_C_STA_PB)
          psect = *ptr++;
          psect = *ptr++;
        else
        else
          {
          {
            psect = bfd_getl16 (ptr);
            psect = bfd_getl16 (ptr);
            ptr += 2;
            ptr += 2;
          }
          }
 
 
        if (psect >= PRIV (section_count))
        if ((unsigned int) psect >= PRIV (section_count))
          alloc_section (abfd, psect);
          alloc_section (abfd, psect);
 
 
        dummy = (long) *ptr++;
        dummy = (long) *ptr++;
        dummy += (PRIV (sections)[psect])->vma;
        dummy += (PRIV (sections)[psect])->vma;
        _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
        _bfd_vms_push (abfd, (uquad) dummy, psect);
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_PW:
    case TIR_S_C_STA_PW:
    case TIR_S_C_STA_WPW:
    case TIR_S_C_STA_WPW:
Line 949... Line 1133...
         arg: by        section index
         arg: by        section index
                (sh     section index)
                (sh     section index)
                sh      signed short offset.  */
                sh      signed short offset.  */
      {
      {
        unsigned long dummy;
        unsigned long dummy;
        unsigned int psect;
        int psect;
 
 
        if (cmd == TIR_S_C_STA_PW)
        if (cmd == TIR_S_C_STA_PW)
          psect = *ptr++;
          psect = *ptr++;
        else
        else
          {
          {
            psect = bfd_getl16 (ptr);
            psect = bfd_getl16 (ptr);
            ptr += 2;
            ptr += 2;
          }
          }
 
 
        if (psect >= PRIV (section_count))
        if ((unsigned int) psect >= PRIV (section_count))
          alloc_section (abfd, psect);
          alloc_section (abfd, psect);
 
 
        dummy = bfd_getl16 (ptr); ptr+=2;
        dummy = bfd_getl16 (ptr); ptr+=2;
        dummy += (PRIV (sections)[psect])->vma;
        dummy += (PRIV (sections)[psect])->vma;
        _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
        _bfd_vms_push (abfd, (uquad) dummy, psect);
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_PL:
    case TIR_S_C_STA_PL:
    case TIR_S_C_STA_WPL:
    case TIR_S_C_STA_WPL:
Line 976... Line 1160...
         arg: by        section index
         arg: by        section index
                (sh     section index)
                (sh     section index)
                lw      signed longword offset.  */
                lw      signed longword offset.  */
      {
      {
        unsigned long dummy;
        unsigned long dummy;
        unsigned int psect;
        int psect;
 
 
        if (cmd == TIR_S_C_STA_PL)
        if (cmd == TIR_S_C_STA_PL)
          psect = *ptr++;
          psect = *ptr++;
        else
        else
          {
          {
            psect = bfd_getl16 (ptr);
            psect = bfd_getl16 (ptr);
            ptr += 2;
            ptr += 2;
          }
          }
 
 
        if (psect >= PRIV (section_count))
        if ((unsigned int) psect >= PRIV (section_count))
          alloc_section (abfd, psect);
          alloc_section (abfd, psect);
 
 
        dummy = bfd_getl32 (ptr); ptr += 4;
        dummy = bfd_getl32 (ptr); ptr += 4;
        dummy += (PRIV (sections)[psect])->vma;
        dummy += (PRIV (sections)[psect])->vma;
        _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
        _bfd_vms_push (abfd, (uquad) dummy, psect);
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_UB:
    case TIR_S_C_STA_UB:
      /* stack unsigned byte
      /* stack unsigned byte
Line 1455... Line 1639...
 
 
static unsigned char *
static unsigned char *
tir_ctl (bfd * abfd, unsigned char *ptr)
tir_ctl (bfd * abfd, unsigned char *ptr)
{
{
  unsigned long dummy;
  unsigned long dummy;
  unsigned int psect;
  int psect;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
  _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
#endif
#endif
 
 
  switch (*ptr++)
  switch (*ptr++)
    {
    {
    case TIR_S_C_CTL_SETRB:
    case TIR_S_C_CTL_SETRB:
      /* Set relocation base: pop stack, set image location counter
      /* Set relocation base: pop stack, set image location counter
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, (int *) &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      if (psect >= PRIV (section_count))
      if ((unsigned int) psect >= PRIV (section_count))
        alloc_section (abfd, psect);
        alloc_section (abfd, psect);
      image_set_ptr (abfd, (int) psect, (uquad) dummy);
      image_set_ptr (abfd, psect, (uquad) dummy);
      break;
      break;
 
 
    case TIR_S_C_CTL_AUGRB:
    case TIR_S_C_CTL_AUGRB:
      /* Augment relocation base: increment image location counter by offset
      /* Augment relocation base: increment image location counter by offset
         arg: lw        offset value.  */
         arg: lw        offset value.  */
Line 1490... Line 1674...
      break;
      break;
 
 
    case TIR_S_C_CTL_STLOC:
    case TIR_S_C_CTL_STLOC:
      /* Set location: pop index, restore location counter from index
      /* Set location: pop index, restore location counter from index
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, (int *) &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      (*_bfd_error_handler) (_("%s: not fully implemented"),
      (*_bfd_error_handler) (_("%s: not fully implemented"),
                             tir_cmd_name (ptr[-1]));
                             tir_cmd_name (ptr[-1]));
      break;
      break;
 
 
    case TIR_S_C_CTL_STKDL:
    case TIR_S_C_CTL_STKDL:
      /* Stack defined location: pop index, push location counter from index
      /* Stack defined location: pop index, push location counter from index
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, (int *) &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      (*_bfd_error_handler) (_("%s: not fully implemented"),
      (*_bfd_error_handler) (_("%s: not fully implemented"),
                             tir_cmd_name (ptr[-1]));
                             tir_cmd_name (ptr[-1]));
      break;
      break;
 
 
    default:
    default:
Line 1515... Line 1699...
/* Handle command from TIR section.  */
/* Handle command from TIR section.  */
 
 
static unsigned char *
static unsigned char *
tir_cmd (bfd * abfd, unsigned char *ptr)
tir_cmd (bfd * abfd, unsigned char *ptr)
{
{
  struct
  static const struct
  {
  {
    int mincod;
    int mincod;
    int maxcod;
    int maxcod;
    unsigned char * (*explain) (bfd *, unsigned char *);
    unsigned char * (*explain) (bfd *, unsigned char *);
  }
  }
Line 1533... Line 1717...
  };
  };
  int i = 0;
  int i = 0;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
  _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
  if (*ptr & 0x80)
  if (*ptr & 0x80)
    {
    {
      /* Store immediate.  */
      /* Store immediate.  */
Line 1568... Line 1752...
}
}
 
 
/* Handle command from ETIR section.  */
/* Handle command from ETIR section.  */
 
 
static int
static int
etir_cmd (bfd * abfd, int cmd, unsigned char *ptr)
etir_cmd (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
{
{
  static struct
  static const struct
  {
  {
    int mincod;
    int mincod;
    int maxcod;
    int maxcod;
    bfd_boolean (*explain) (bfd *, int, unsigned char *);
    bfd_boolean (*explain) (bfd *, int, unsigned char *, int *);
  }
  }
  etir_table[] =
  etir_table[] =
  {
  {
    { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
    { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
    { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
    { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
Line 1589... Line 1773...
  };
  };
 
 
  int i = 0;
  int i = 0;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (4, "etir_cmd %d/%x\n", cmd, cmd);
  _bfd_vms_debug (4, "etir_cmd: %s(%d)\n", cmd_name (cmd), cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (long) ptr);
#endif
#endif
 
 
  while (etir_table[i].mincod >= 0)
  while (etir_table[i].mincod >= 0)
    {
    {
      if ( (etir_table[i].mincod <= cmd)
      if ( (etir_table[i].mincod <= cmd)
           && (cmd <= etir_table[i].maxcod))
           && (cmd <= etir_table[i].maxcod))
        {
        {
          if (!etir_table[i].explain (abfd, cmd, ptr))
          if (!etir_table[i].explain (abfd, cmd, ptr, quarter_relocs))
            return -1;
            return -1;
          break;
          break;
        }
        }
      i++;
      i++;
    }
    }
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (4, "etir_cmd: = 0\n");
  _bfd_vms_debug (4, "etir_cmd: result = 0\n");
#endif
#endif
  return 0;
  return 0;
}
}
 
 
/* Text Information and Relocation Records (OBJ$C_TIR)
/* Text Information and Relocation Records (OBJ$C_TIR)
Line 1641... Line 1825...
   handle etir record.  */
   handle etir record.  */
 
 
static int
static int
analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
{
{
  int cmd;
  unsigned char *maxptr = ptr + length;
  unsigned char *maxptr;
  /* Relocations are made of 1, 2 or 4 ETIR commands.
 
     We therefore count them using quarters.  */
 
  int quarter_relocs = 0;
  int result = 0;
  int result = 0;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
  _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
#endif
#endif
 
 
  maxptr = ptr + length;
 
 
 
  while (ptr < maxptr)
  while (ptr < maxptr)
    {
    {
      cmd = bfd_getl16 (ptr);
      int cmd = bfd_getl16 (ptr);
      length = bfd_getl16 (ptr + 2);
      int cmd_length = bfd_getl16 (ptr + 2);
      result = etir_cmd (abfd, cmd, ptr+4);
      result = etir_cmd (abfd, cmd, ptr + 4, &quarter_relocs);
      if (result != 0)
      if (result != 0)
        break;
        break;
      ptr += length;
 
 
      /* If we have a relocation, we record its length to size
 
         future buffers and bump the reloc count of the section.  */
 
      if (quarter_relocs)
 
        {
 
          vms_section_data (PRIV (image_section))->reloc_size += cmd_length;
 
          abfd->flags |= HAS_RELOC;
 
 
 
          if (quarter_relocs == 4)
 
            {
 
              PRIV (image_section)->reloc_count++;
 
 
 
#if VMS_DEBUG
 
              _bfd_vms_debug (4, "-> reloc %d at 0x%x\n",
 
                              PRIV (image_section)->reloc_count-1,
 
                              ptr - (maxptr - length));
 
#endif
 
 
 
              quarter_relocs = 0;
 
            }
 
          else if (quarter_relocs > 4)
 
            {
 
 
 
#if VMS_DEBUG
 
              _bfd_vms_debug (4, "Reloc count error (%d) in section %s\n",
 
                              PRIV (image_section)->reloc_count,
 
                              PRIV (image_section)->name);
 
#endif
 
 
 
              quarter_relocs = 0;
 
            }
 
        }
 
 
 
      /* If we have a Store Immediate, we reserve space for the
 
         count argument.  */
 
      else if (cmd == ETIR_S_C_STO_IMM)
 
        vms_section_data (PRIV (image_section))->reloc_size
 
          += ETIR_S_C_HEADER_SIZE + 4;
 
 
 
      ptr += cmd_length;
    }
    }
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
  _bfd_vms_debug (3, "analyze_etir: result = %d\n", result);
#endif
#endif
 
 
  return result;
  return result;
}
}
 
 
Line 1683... Line 1906...
#endif
#endif
 
 
  switch (objtype)
  switch (objtype)
    {
    {
    case EOBJ_S_C_ETIR:
    case EOBJ_S_C_ETIR:
      PRIV (vms_rec) += 4;      /* Skip type, size.  */
      PRIV (vms_rec) += ETIR_S_C_HEADER_SIZE;
      PRIV (rec_size) -= 4;
      PRIV (rec_size) -= ETIR_S_C_HEADER_SIZE;
      result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
      result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
      break;
      break;
    case OBJ_S_C_TIR:
    case OBJ_S_C_TIR:
      PRIV (vms_rec) += 1;      /* Skip type.  */
      PRIV (vms_rec) += 1;      /* Skip type.  */
      PRIV (rec_size) -= 1;
      PRIV (rec_size) -= 1;
Line 1700... Line 1923...
    }
    }
 
 
  return result;
  return result;
}
}
 
 
/* Process EDBG record
 /* Slurp relocs from ETIR sections and (temporarily) save them
   Return 0 on success, -1 on error
    in the per-section reloc buffer.  */
 
 
   Not implemented yet.  */
 
 
 
int
int
_bfd_vms_slurp_dbg (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_slurp_relocs (bfd *abfd)
{
{
 
  struct vms_section_data_struct *vsd;
 
  unsigned char *begin = PRIV (vms_rec) + 4;
 
  unsigned char *end = PRIV (vms_rec) + PRIV (rec_size);
 
  unsigned char *ptr;
 
  int cmd, length, slurped_length;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "DBG/EDBG\n");
  _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: %d bytes\n", PRIV (rec_size));
#endif
#endif
 
 
  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
  for (ptr = begin; ptr < end; ptr += length)
  return 0;
    {
 
      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;
}
}
 
 
/* Process ETBT record
        case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
   Return 0 on success, -1 on error
                               /* ALPHA_R_REFQUAD und_section, step 1 */
 
          break;
 
 
   Not implemented yet.  */
        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;
 
            }
 
 
int
        case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD und_section, step 2 */
_bfd_vms_slurp_tbt (bfd * abfd ATTRIBUTE_UNUSED,
                              /* ALPHA_R_REFQUAD abs_section, step 1 */
                    int objtype ATTRIBUTE_UNUSED)
 
 
        case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
 
                              /* ALPHA_R_REFLONG abs_section, step 2 */
 
                              /* ALPHA_R_REFLONG others, step 2 */
 
 
 
        case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
 
                              /* ALPHA_R_REFQUAD abs_section, step 2 */
 
 
 
        case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
 
 
 
        case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
 
                               /* ALPHA_R_REFQUAD und_section, step 3 */
 
 
 
        case ETIR_S_C_STO_CA:      /* ALPHA_R_CODEADDR */
 
        case ETIR_S_C_STO_GBL:     /* ALPHA_R_REFQUAD und_section */
 
        case ETIR_S_C_STO_GBL_LW:  /* ALPHA_R_REFLONG und_section */
 
        case ETIR_S_C_STC_LP_PSB:  /* ALPHA_R_LINKAGE */
 
        case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
 
        case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
 
        case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
 
        case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
 
          break;
 
 
 
        case ETIR_S_C_STO_IMM:
 
          if (PRIV (image_section)->reloc_count == 0)
 
            continue;
 
          /* This is not a relocation, but we nevertheless slurp the
 
             count argument.  We'll use it to compute the addresses
 
             of the relocations.  */
 
          slurped_length = ETIR_S_C_HEADER_SIZE + 4;
 
          break;
 
 
 
        default:
 
          continue;
 
        }
 
 
 
      vsd = vms_section_data (PRIV (image_section));
 
      memcpy (vsd->reloc_stream + vsd->reloc_offset, ptr, slurped_length);
 
      vsd->reloc_offset += slurped_length;
 
      if (vsd->reloc_offset > vsd->reloc_size)
{
{
 
          (*_bfd_error_handler) (_("Reloc size error in section %s"),
 
                                 PRIV (image_section)->name);
 
          return -1;
 
        }
 
    }
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "TBT/ETBT\n");
  _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: result = 0\n");
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* Process LNK record
/* Decode relocs from the reloc buffer of the specified section
   Return 0 on success, -1 on error
   and internalize them in the specified buffer.  */
 
 
   Not implemented yet.  */
 
 
 
int
int
_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
_bfd_vms_decode_relocs (bfd *abfd, arelent *relocs, asection *section,
                    int objtype ATTRIBUTE_UNUSED)
                        asymbol **symbols ATTRIBUTE_UNUSED)
{
{
 
  int saved_cmd, saved_sym_offset, saved_sec_offset, saved_addend_offset;
 
  int cmd, sym_offset, sec_offset, address_offset, addend_offset;
 
  struct vms_section_data_struct *vsd = vms_section_data (section);
 
  bfd_reloc_code_real_type reloc_code;
 
  vms_symbol_entry *entry;
 
  bfd_vma vaddr = 0;
 
  unsigned char *begin = vsd->reloc_stream;
 
  unsigned char *end = vsd->reloc_stream + vsd->reloc_size;
 
  unsigned char *ptr, *arg_ptr;
 
  const char *name;
 
  int length;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "LNK\n");
  _bfd_vms_debug (3, "_bfd_vms_decode_relocs: %d bytes\n", vsd->reloc_size);
#endif
#endif
 
 
  return 0;
  #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;                                         \
}
}

 
/* Start ETIR record for section #index at virtual addr offset.  */
 
 
 
static void
  #define POP_CMD()                                     \
start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset)
    {                                                   \
{
      cmd = saved_cmd;                                  \
  if (!justoffset)
      saved_cmd = ETIR_S_C_MAXSTCCOD + 1;               \
    {
      sym_offset = saved_sym_offset;                    \
      /* One ETIR per section.  */
      sec_offset = saved_sec_offset;                    \
      _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
      addend_offset= saved_addend_offset;               \
      _bfd_vms_output_push (abfd);
 
    }
    }
 
 
  /* Push start offset.  */
  #define CMD_PUSHED (saved_cmd != ETIR_S_C_MAXSTCCOD + 1)
  _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
 
  _bfd_vms_output_long (abfd, (unsigned long) index);
  #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;
 
}
 

 
/* WRITE ETIR SECTION
 
 
 
   This is still under construction and therefore not documented.  */
 
 
 
static void start_etir_record (bfd *abfd, int index, uquad offset,
 
                               bfd_boolean justoffset);
 
static void start_first_etbt_record (bfd *abfd);
 
static void start_another_etbt_record (bfd *abfd);
 
static void sto_imm (bfd *abfd, bfd_size_type, unsigned char *, bfd_vma vaddr,
 
                     int index, const char *name);
 
static void end_etir_record (bfd *abfd);
 
static void etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr,
 
                               int checklen);
 
 
 
/* Start ETIR record for section #index at virtual addr offset.  */
 
 
 
static void
 
start_etir_record (bfd * abfd, int 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) index);
  _bfd_vms_output_quad (abfd, (uquad) offset);
  _bfd_vms_output_quad (abfd, (uquad) offset);
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
 
 
  /* Start = pop ().  */
  /* Start = pop ().  */
  _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);
  _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);
Line 1778... Line 2343...
{
{
  _bfd_vms_output_pop (abfd);
  _bfd_vms_output_pop (abfd);
  _bfd_vms_output_end (abfd);
  _bfd_vms_output_end (abfd);
}
}
 
 
/* WRITE ETIR SECTION
/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
 
   address VADDR in section specified by INDEX and NAME.  */
   This is still under construction and therefore not documented.  */
 
 
 
static void
static void
sto_imm (bfd * abfd, vms_section *sptr, bfd_vma vaddr, int index)
sto_imm (bfd *abfd, bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr,
 
         int index, const char *name)
{
{
  int size;
  bfd_size_type size;
  int ssize;
 
  unsigned char *cptr;
 
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
  _bfd_vms_debug (8, "sto_imm %d bytes\n", ssize);
  _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
  _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
#endif
#endif
 
 
  ssize = sptr->size;
 
  cptr = sptr->contents;
 
 
 
  while (ssize > 0)
  while (ssize > 0)
    {
    {
      /* Try all the rest.  */
      /* Try all the rest.  */
      size = ssize;
      size = ssize;
 
 
      if (_bfd_vms_output_check (abfd, size) < 0)
      if (_bfd_vms_output_check (abfd, size) < 0)
        {
        {
          /* Doesn't fit, split !  */
          /* Doesn't fit, split !  */
          end_etir_record (abfd);
          end_etir_record (abfd);
 
 
 
          if (name [0] && name[1] == 'v' && !strcmp (name, ".vmsdebug"))
 
            start_another_etbt_record (abfd);
 
          else
          start_etir_record (abfd, index, vaddr, FALSE);
          start_etir_record (abfd, index, vaddr, FALSE);
          /* Get max size.  */
 
          size = _bfd_vms_output_check (abfd, 0);
          size = _bfd_vms_output_check (abfd, 0);        /* get max size */
          /* More than what's left ?  */
          if (size > ssize)                     /* more than what's left ? */
          if (size > ssize)
 
            size = ssize;
            size = ssize;
        }
        }
 
 
      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
      _bfd_vms_output_long (abfd, (unsigned long) (size));
      _bfd_vms_output_long (abfd, (unsigned long) (size));
Line 1825... Line 2388...
      _bfd_vms_debug (10, "dumped %d bytes\n", size);
      _bfd_vms_debug (10, "dumped %d bytes\n", size);
      _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
      _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
#endif
#endif
 
 
      vaddr += size;
      vaddr += size;
      ssize -= size;
 
      cptr += 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.  */
/* Write section contents for bfd abfd.  */
 
 
int
int
_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
{
{
  asection *section;
  asection *section;
  vms_section *sptr;
 
  int nextoffset;
 
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
  _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
#endif
#endif
 
 
  _bfd_vms_output_alignment (abfd, 4);
  _bfd_vms_output_alignment (abfd, 4);
 
 
  nextoffset = 0;
 
  PRIV (vms_linkage_index) = 1;
  PRIV (vms_linkage_index) = 1;
 
 
  /* Dump all other sections.  */
  for (section = abfd->sections; section; section = section->next)
  section = abfd->sections;
 
 
 
  while (section != NULL)
 
    {
    {
 
 
#if VMS_DEBUG
#if VMS_DEBUG
      _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
      _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
                      section->index, section->name,
                      section->index, section->name,
                      (int) (section->size));
                      (int) (section->size));
#endif
#endif
 
 
 
      if (!(section->flags & SEC_HAS_CONTENTS)
 
          || bfd_is_com_section (section))
 
        continue;
 
 
 
      if (!section->contents)
 
        {
 
          bfd_set_error (bfd_error_no_contents);
 
          return -1;
 
        }
 
 
 
      if (section->name[0]
 
          && section->name[1] == 'v'
 
          && !strcmp (section->name, ".vmsdebug"))
 
        start_first_etbt_record (abfd);
 
      else
 
        start_etir_record (abfd, section->index, 0, FALSE);
 
 
      if (section->flags & SEC_RELOC)
      if (section->flags & SEC_RELOC)
        {
        {
          int i;
          bfd_vma curr_addr = 0;
 
          unsigned char *curr_data = section->contents;
 
          bfd_size_type size;
 
          int pass2_needed = 0;
 
          int pass2_in_progress = 0;
 
          unsigned int irel;
 
 
 
          if (section->reloc_count <= 0)
 
            (*_bfd_error_handler)
 
              (_("SEC_RELOC with no relocs in section %s"), section->name);
 
 
          if ((i = section->reloc_count) <= 0)
 
            (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
 
                                   section->name);
 
#if VMS_DEBUG
#if VMS_DEBUG
          else
          else
            {
            {
              arelent **rptr;
              int i = section->reloc_count;
 
              arelent **rptr = section->orelocation;
              _bfd_vms_debug (4, "%d relocations:\n", i);
              _bfd_vms_debug (4, "%d relocations:\n", i);
              rptr = section->orelocation;
 
              while (i-- > 0)
              while (i-- > 0)
                {
                {
                  _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
                  _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, "
 
                                     "addr %08lx, off %08lx, len %d: %s\n",
                                  (*(*rptr)->sym_ptr_ptr)->name,
                                  (*(*rptr)->sym_ptr_ptr)->name,
                                  (*(*rptr)->sym_ptr_ptr)->section->name,
                                  (*(*rptr)->sym_ptr_ptr)->section->name,
                                  (long) (*(*rptr)->sym_ptr_ptr)->value,
                                  (long) (*(*rptr)->sym_ptr_ptr)->value,
                                  (*rptr)->address, (*rptr)->addend,
                                  (*rptr)->address, (*rptr)->addend,
                                  bfd_get_reloc_size ((*rptr)->howto),
                                  bfd_get_reloc_size ((*rptr)->howto),
                                  (*rptr)->howto->name);
                                  (*rptr)->howto->name);
                  rptr++;
                  rptr++;
                }
                }
            }
            }
#endif
#endif
        }
 
 
 
      if ((section->flags & SEC_HAS_CONTENTS)
        new_pass:
          && (! bfd_is_com_section (section)))
          for (irel = 0; irel < section->reloc_count; irel++)
        {
        {
          /* Virtual addr in section.  */
              struct evax_private_udata_struct *udata;
          bfd_vma vaddr;
              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;
 
 
          sptr = _bfd_get_vms_section (abfd, section->index);
              if (pass2_in_progress)
          if (sptr == NULL)
 
            {
            {
              bfd_set_error (bfd_error_no_contents);
                  /* Non-deferred relocs have already been output.  */
              return -1;
                  if (!defer)
 
                    continue;
            }
            }
 
              else
          vaddr = (bfd_vma) (sptr->offset);
 
 
 
          start_etir_record (abfd, section->index, (uquad) sptr->offset,
 
                             FALSE);
 
 
 
          while (sptr != NULL)
 
            {
 
              /* One STA_PQ, CTL_SETRB per vms_section.  */
 
              if (section->flags & SEC_RELOC)
 
                {
 
                  /* Check for relocs.  */
 
                  arelent **rptr = section->orelocation;
 
                  int i = section->reloc_count;
 
 
 
                  for (;;)
 
                    {
 
                      bfd_size_type addr = (*rptr)->address;
 
                      bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
 
                      if (sptr->offset < addr)
 
                        {
                        {
                          /* Sptr starts before reloc.  */
                  /* Deferred relocs must be output at the very end.  */
                          bfd_size_type before = addr - sptr->offset;
                  if (defer)
                          if (sptr->size <= before)
 
                            {
                            {
                              /* Complete before.  */
                      pass2_needed = 1;
                              sto_imm (abfd, sptr, vaddr, section->index);
                      continue;
                              vaddr += sptr->size;
 
                              break;
 
                            }
                            }
                          else
 
                            {
 
                              /* Partly before.  */
 
                              int after = sptr->size - before;
 
 
 
                              sptr->size = before;
                  /* Regular relocs are intertwined with binary data.  */
                              sto_imm (abfd, sptr, vaddr, section->index);
                  if (curr_addr > addr)
                              vaddr += sptr->size;
                    (*_bfd_error_handler) (_("Size error in section %s"),
                              sptr->contents += before;
                                           section->name);
                              sptr->offset += before;
                  size = addr - curr_addr;
                              sptr->size = after;
                  sto_imm (abfd, size, curr_data, curr_addr,
                            }
                          section->index, section->name);
 
                  curr_data += size;
 
                  curr_addr += size;
                        }
                        }
                      else if (sptr->offset == addr)
 
                        {
 
                          /* Sptr starts at reloc.  */
 
                          asymbol *sym = *(*rptr)->sym_ptr_ptr;
 
                          asection *sec = sym->section;
 
 
 
                          switch ((*rptr)->howto->type)
              size = bfd_get_reloc_size (rptr->howto);
 
 
 
              switch (rptr->howto->type)
                            {
                            {
                            case ALPHA_R_IGNORE:
                            case ALPHA_R_IGNORE:
                              break;
                              break;
 
 
                            case ALPHA_R_REFLONG:
                            case ALPHA_R_REFLONG:
                              {
 
                                if (bfd_is_und_section (sym->section))
                                if (bfd_is_und_section (sym->section))
                                  {
                                  {
                                    int slen = strlen ((char *) sym->name);
                      bfd_vma addend = rptr->addend;
                                    char *hash;
                      slen = strlen ((char *) sym->name);
 
                      hash = _bfd_vms_length_hash_symbol
                                    if (_bfd_vms_output_check (abfd, slen) < 0)
                               (abfd, sym->name, EOBJ_S_C_SYMSIZ);
 
                      etir_output_check (abfd, section, curr_addr, slen);
 
                      if (addend)
                                      {
                                      {
                                        end_etir_record (abfd);
                          _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
                                        start_etir_record (abfd,
 
                                                           section->index,
 
                                                           vaddr, FALSE);
 
                                      }
 
                                    _bfd_vms_output_begin (abfd,
 
                                                           ETIR_S_C_STO_GBL_LW,
 
                                                           -1);
 
                                    hash = (_bfd_vms_length_hash_symbol
 
                                            (abfd, sym->name, EOBJ_S_C_SYMSIZ));
 
                                    _bfd_vms_output_counted (abfd, hash);
                                    _bfd_vms_output_counted (abfd, hash);
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
 
                          _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
 
                          _bfd_vms_output_long (abfd, (unsigned long) addend);
 
                          _bfd_vms_output_flush (abfd);
 
                          _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
 
                          _bfd_vms_output_flush (abfd);
 
                          _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
 
                          _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else if (bfd_is_abs_section (sym->section))
                      else
                                  {
 
                                    if (_bfd_vms_output_check (abfd, 16) < 0)
 
                                      {
                                      {
                                        end_etir_record (abfd);
                          _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL_LW, -1);
                                        start_etir_record (abfd,
                          _bfd_vms_output_counted (abfd, hash);
                                                           section->index,
                          _bfd_vms_output_flush (abfd);
                                                           vaddr, FALSE);
 
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                    }
                                                           ETIR_S_C_STA_LW,
                  else if (bfd_is_abs_section (sym->section))
                                                           -1);
                    {
                                    _bfd_vms_output_quad (abfd,
                      etir_output_check (abfd, section, curr_addr, 16);
                                                          (uquad) sym->value);
                      _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_flush (abfd);
                                    _bfd_vms_output_begin (abfd,
                      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
                                                           ETIR_S_C_STO_LW,
 
                                                           -1);
 
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else
                                else
                                  {
                                  {
                                    if (_bfd_vms_output_check (abfd, 32) < 0)
                      etir_output_check (abfd, section, curr_addr, 32);
                                      {
                      _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
                                        end_etir_record (abfd);
                      _bfd_vms_output_long (abfd, (unsigned long) sec->index);
                                        start_etir_record (abfd,
                      _bfd_vms_output_quad (abfd, (uquad) rptr->addend
                                                           section->index,
                                                    + (uquad) sym->value);
                                                           vaddr, FALSE);
                      _bfd_vms_output_flush (abfd);
                                      }
                      /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
                                    _bfd_vms_output_begin (abfd,
                         says that we should have a ETIR_S_C_STO_OFF here.
                                                           ETIR_S_C_STA_PQ,
                         But the relocation would not be BFD_RELOC_32 then.
                                                           -1);
                         This case is very likely unreachable.  */
                                    _bfd_vms_output_long (abfd,
                      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
                                                          (unsigned long) (sec->index));
 
                                    _bfd_vms_output_quad (abfd,
 
                                                          ((uquad) (*rptr)->addend
 
                                                           + (uquad) sym->value));
 
                                    _bfd_vms_output_flush (abfd);
 
                                    _bfd_vms_output_begin (abfd,
 
                                                           ETIR_S_C_STO_LW,
 
                                                           -1);
 
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
 
                              }
                              }
                              break;
                              break;
 
 
                            case ALPHA_R_REFQUAD:
                            case ALPHA_R_REFQUAD:
                              {
 
                                if (bfd_is_und_section (sym->section))
                                if (bfd_is_und_section (sym->section))
                                  {
                                  {
                                    int slen = strlen ((char *) sym->name);
                      bfd_vma addend = rptr->addend;
                                    char *hash;
                      slen = strlen ((char *) sym->name);
 
                      hash = _bfd_vms_length_hash_symbol
                                    if (_bfd_vms_output_check (abfd, slen) < 0)
                               (abfd, sym->name, EOBJ_S_C_SYMSIZ);
 
                      etir_output_check (abfd, section, curr_addr, slen);
 
                      if (addend)
                                      {
                                      {
                                        end_etir_record (abfd);
                          _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
                                        start_etir_record (abfd,
 
                                                           section->index,
 
                                                           vaddr, FALSE);
 
                                      }
 
                                    _bfd_vms_output_begin (abfd,
 
                                                           ETIR_S_C_STO_GBL,
 
                                                           -1);
 
                                    hash = (_bfd_vms_length_hash_symbol
 
                                            (abfd, sym->name, EOBJ_S_C_SYMSIZ));
 
                                    _bfd_vms_output_counted (abfd, hash);
                                    _bfd_vms_output_counted (abfd, hash);
                                    _bfd_vms_output_flush (abfd);
                                    _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 if (bfd_is_abs_section (sym->section))
                      else
                                  {
 
                                    if (_bfd_vms_output_check (abfd, 16) < 0)
 
                                      {
                                      {
                                        end_etir_record (abfd);
                          _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL, -1);
                                        start_etir_record (abfd,
                          _bfd_vms_output_counted (abfd, hash);
                                                           section->index,
                          _bfd_vms_output_flush (abfd);
                                                           vaddr, FALSE);
 
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                    }
                                                           ETIR_S_C_STA_QW,
                  else if (bfd_is_abs_section (sym->section))
                                                           -1);
                    {
                                    _bfd_vms_output_quad (abfd,
                      etir_output_check (abfd, section, curr_addr, 16);
                                                          (uquad) sym->value);
                      _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_flush (abfd);
                                    _bfd_vms_output_begin (abfd,
                      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
                                                           ETIR_S_C_STO_QW,
 
                                                           -1);
 
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else
                                else
                                  {
                                  {
                                    if (_bfd_vms_output_check (abfd, 32) < 0)
                      etir_output_check (abfd, section, curr_addr, 32);
                                      {
                      _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
                                        end_etir_record (abfd);
                      _bfd_vms_output_long (abfd, (unsigned long) sec->index);
                                        start_etir_record (abfd,
                      _bfd_vms_output_quad (abfd, (uquad) rptr->addend
                                                           section->index,
                                                    + (uquad) sym->value);
                                                           vaddr, FALSE);
                      _bfd_vms_output_flush (abfd);
                                      }
                      _bfd_vms_output_begin (abfd, ETIR_S_C_STO_OFF, -1);
                                    _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);
                                    _bfd_vms_output_flush (abfd);
                                  }
 
                              }
                              }
                              break;
                              break;
 
 
                            case ALPHA_R_HINT:
                            case ALPHA_R_HINT:
                              {
                  sto_imm (abfd, size, curr_data, curr_addr,
                                int hint_size;
                           section->index, section->name);
                                char *hash ATTRIBUTE_UNUSED;
 
 
 
                                hint_size = sptr->size;
 
                                sptr->size = len;
 
                                sto_imm (abfd, sptr, vaddr, section->index);
 
                                sptr->size = hint_size;
 
                              }
 
                              break;
                              break;
                            case ALPHA_R_LINKAGE:
 
                              {
 
                                char *hash;
 
 
 
                                if (_bfd_vms_output_check (abfd, 64) < 0)
                case ALPHA_R_LINKAGE:
                                  {
                  etir_output_check (abfd, section, curr_addr, 64);
                                    end_etir_record (abfd);
                  _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LP_PSB, -1);
                                    start_etir_record (abfd, section->index,
                  _bfd_vms_output_long
                                                       vaddr, FALSE);
                    (abfd, (unsigned long) PRIV (vms_linkage_index));
                                  }
 
                                _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;
                                PRIV (vms_linkage_index) += 2;
                                hash = (_bfd_vms_length_hash_symbol
                  hash = _bfd_vms_length_hash_symbol
                                        (abfd, sym->name, EOBJ_S_C_SYMSIZ));
                           (abfd, sym->name, EOBJ_S_C_SYMSIZ);
                                _bfd_vms_output_counted (abfd, hash);
                                _bfd_vms_output_counted (abfd, hash);
                                _bfd_vms_output_byte (abfd, 0);
                                _bfd_vms_output_byte (abfd, 0);
                                _bfd_vms_output_flush (abfd);
                                _bfd_vms_output_flush (abfd);
                              }
 
                              break;
                              break;
 
 
                            case ALPHA_R_CODEADDR:
                            case ALPHA_R_CODEADDR:
                              {
                  slen = strlen ((char *) sym->name);
                                int slen = strlen ((char *) sym->name);
                  hash = _bfd_vms_length_hash_symbol
                                char *hash;
                           (abfd, sym->name, EOBJ_S_C_SYMSIZ);
                                if (_bfd_vms_output_check (abfd, slen) < 0)
                  etir_output_check (abfd, section, curr_addr, slen);
                                  {
                  _bfd_vms_output_begin (abfd, ETIR_S_C_STO_CA, -1);
                                    end_etir_record (abfd);
 
                                    start_etir_record (abfd,
 
                                                       section->index,
 
                                                       vaddr, FALSE);
 
                                  }
 
                                _bfd_vms_output_begin (abfd,
 
                                                       ETIR_S_C_STO_CA,
 
                                                       -1);
 
                                hash = (_bfd_vms_length_hash_symbol
 
                                        (abfd, sym->name, EOBJ_S_C_SYMSIZ));
 
                                _bfd_vms_output_counted (abfd, hash);
                                _bfd_vms_output_counted (abfd, hash);
                                _bfd_vms_output_flush (abfd);
                                _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;
                              break;
 
 
                            default:
                            default:
                              (*_bfd_error_handler) (_("Unhandled relocation %s"),
                              (*_bfd_error_handler) (_("Unhandled relocation %s"),
                                                     (*rptr)->howto->name);
                                         rptr->howto->name);
                              break;
                              break;
                            }
                            }
 
 
                          vaddr += len;
              curr_data += size;
 
              curr_addr += size;
 
            } /* End of relocs loop.  */
 
 
                          if (len == sptr->size)
          if (!pass2_in_progress)
                            {
                            {
                              break;
              /* Output rest of section.  */
                            }
              if (curr_addr > section->size)
                          else
                (*_bfd_error_handler) (_("Size error in section %s"),
                            {
                                       section->name);
                              sptr->contents += len;
              size = section->size - curr_addr;
                              sptr->offset += len;
              sto_imm (abfd, size, curr_data, curr_addr,
                              sptr->size -= len;
                       section->index, section->name);
                              i--;
              curr_data += size;
                              rptr++;
              curr_addr += size;
                            }
 
                        }
 
                      else
 
                        {
 
                          /* Sptr starts after reloc.  */
 
                          i--;
 
                          /* Check next reloc.  */
 
                          rptr++;
 
                        }
 
 
 
                      if (i == 0)
              if (pass2_needed)
                        {
 
                          /* All reloc checked.  */
 
                          if (sptr->size > 0)
 
                            {
                            {
                              /* Dump rest.  */
                  pass2_in_progress = 1;
                              sto_imm (abfd, sptr, vaddr, section->index);
                  goto new_pass;
                              vaddr += sptr->size;
 
                            }
 
                          break;
 
                        }
 
                    }
                    }
                }
                }
              else
 
                {
 
                  /* No relocs, just dump.  */
 
                  sto_imm (abfd, sptr, vaddr, section->index);
 
                  vaddr += sptr->size;
 
                }
                }
 
 
              sptr = sptr->next;
      else /* (section->flags & SEC_RELOC) */
            }
        sto_imm (abfd, section->size, section->contents, 0,
 
                 section->index, section->name);
 
 
          end_etir_record (abfd);
          end_etir_record (abfd);
        }
        }
 
 
      section = section->next;
 
    }
 
 
 
  _bfd_vms_output_alignment (abfd, 2);
  _bfd_vms_output_alignment (abfd, 2);
  return 0;
  return 0;
}
}
 
 
/* Write traceback data for bfd abfd.  */
 
 
 
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;
 
}
 
 
 
/* Write debug info for bfd abfd.  */
 
 
 
int
 
_bfd_vms_write_dbg (bfd * abfd ATTRIBUTE_UNUSED,
 
                    int objtype ATTRIBUTE_UNUSED)
 
{
 
#if VMS_DEBUG
 
  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
 
#endif
 
 
 
  return 0;
 
}
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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