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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [vms-tir.c] - Diff between revs 156 and 816

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

Rev 156 Rev 816
/* 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, 2008
   Free Software Foundation, Inc.
   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
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
 
 
/* 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)
        lw      longword (4 byte, 32 bit)
        lw      longword (4 byte, 32 bit)
        qw      quadword (8 byte, 64 bit)
        qw      quadword (8 byte, 64 bit)
        da      data stream  */
        da      data stream  */
 
 
#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
static int
check_section (bfd * abfd, int size)
check_section (bfd * abfd, int size)
{
{
  bfd_size_type offset;
  bfd_size_type offset;
 
 
  offset = PRIV (image_ptr) - PRIV (image_section)->contents;
  offset = PRIV (image_ptr) - PRIV (image_section)->contents;
  if (offset + size > PRIV (image_section)->size)
  if (offset + size > PRIV (image_section)->size)
    {
    {
      PRIV (image_section)->contents
      PRIV (image_section)->contents
        = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size);
        = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size);
      if (PRIV (image_section)->contents == NULL)
      if (PRIV (image_section)->contents == NULL)
        {
        {
          (*_bfd_error_handler) (_("No Mem !"));
          (*_bfd_error_handler) (_("No Mem !"));
          return -1;
          return -1;
        }
        }
      PRIV (image_section)->size = offset + size;
      PRIV (image_section)->size = offset + size;
      PRIV (image_ptr) = PRIV (image_section)->contents + offset;
      PRIV (image_ptr) = PRIV (image_section)->contents + offset;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Routines to fill sections contents during tir/etir read.  */
/* Routines to fill sections contents during tir/etir read.  */
 
 
/* Initialize image buffer pointer to be filled.  */
/* Initialize image buffer pointer to be filled.  */
 
 
static void
static void
image_set_ptr (bfd * abfd, int psect, uquad offset)
image_set_ptr (bfd * abfd, int psect, uquad offset)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
  _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
                  psect, PRIV (sections)[psect]->name, offset);
                  psect, PRIV (sections)[psect]->name, offset);
#endif
#endif
 
 
  PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
  PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
  PRIV (image_section) = PRIV (sections)[psect];
  PRIV (image_section) = PRIV (sections)[psect];
}
}
 
 
/* Increment image buffer pointer by offset.  */
/* Increment image buffer pointer by offset.  */
 
 
static void
static void
image_inc_ptr (bfd * abfd, uquad offset)
image_inc_ptr (bfd * abfd, uquad offset)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
  _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
#endif
#endif
 
 
  PRIV (image_ptr) += offset;
  PRIV (image_ptr) += offset;
}
}
 
 
/* 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,
            int size,
            int size,
            int offset ATTRIBUTE_UNUSED)
            int offset ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
  _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
                  PRIV (image_ptr));
                  PRIV (image_ptr));
  _bfd_hexdump (9, ptr, size, offset);
  _bfd_hexdump (9, ptr, size, offset);
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, size))
  if (PRIV (is_vax) && check_section (abfd, size))
    return;
    return;
 
 
  while (size-- > 0)
  while (size-- > 0)
    *PRIV (image_ptr)++ = *ptr++;
    *PRIV (image_ptr)++ = *ptr++;
}
}
 
 
/* Write byte to section image.  */
/* Write byte to section image.  */
 
 
static void
static void
image_write_b (bfd * abfd, unsigned int value)
image_write_b (bfd * abfd, unsigned int value)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
  _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 1))
  if (PRIV (is_vax) && check_section (abfd, 1))
    return;
    return;
 
 
  *PRIV (image_ptr)++ = (value & 0xff);
  *PRIV (image_ptr)++ = (value & 0xff);
}
}
 
 
/* Write 2-byte word to image.  */
/* Write 2-byte word to image.  */
 
 
static void
static void
image_write_w (bfd * abfd, unsigned int value)
image_write_w (bfd * abfd, unsigned int value)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
  _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 2))
  if (PRIV (is_vax) && check_section (abfd, 2))
    return;
    return;
 
 
  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.  */
 
 
static void
static void
image_write_l (bfd * abfd, unsigned long value)
image_write_l (bfd * abfd, unsigned long value)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
  _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 4))
  if (PRIV (is_vax) && check_section (abfd, 4))
    return;
    return;
 
 
  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.  */
 
 
static void
static void
image_write_q (bfd * abfd, uquad value)
image_write_q (bfd * abfd, uquad value)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
  _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
#endif
#endif
 
 
  if (PRIV (is_vax) && check_section (abfd, 8))
  if (PRIV (is_vax) && check_section (abfd, 8))
    return;
    return;
 
 
  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_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_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_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";
    case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP";
    case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP";
    case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL";
    case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL";
    case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA";
    case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA";
    case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS";
    case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS";
    case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS";
    case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS";
    case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL";
    case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL";
    case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS";
    case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS";
    case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL";
    case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL";
    case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS";
    case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS";
    case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL";
    case ETIR_S_C_STC_LDA_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";
 
 
    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 ();
      abort ();
    }
    }
}
}
#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)
{
{
#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, (int) 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:
      {
      {
        char *name;
        char *name;
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
 
 
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
        entry = (vms_symbol_entry *)
        entry = (vms_symbol_entry *)
          bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
          bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
        if (entry == NULL)
        if (entry == NULL)
          {
          {
#if VMS_DEBUG
#if VMS_DEBUG
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
                            cmd_name (cmd), name);
                            cmd_name (cmd), name);
#endif
#endif
            _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);
      }
      }
      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);
      break;
      break;
 
 
      /* stack global
      /* stack global
         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);
      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;
        unsigned int psect;
 
 
        psect = bfd_getl32 (ptr);
        psect = bfd_getl32 (ptr);
        if (psect >= PRIV (section_count))
        if (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);
      }
      }
      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));
      return FALSE;
      return FALSE;
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
      return FALSE;
      return FALSE;
      break;
      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
 
 
   vms store commands
   vms store commands
 
 
   handle sto_xxx commands in etir section
   handle sto_xxx commands in etir section
   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)
{
{
  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, (int) 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);
      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);
      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);
      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);
      break;
      break;
 
 
      /* Store immediate repeated: pop stack for repeat count
      /* Store immediate repeated: pop stack for repeat count
         arg: lw        byte count
         arg: lw        byte count
         da     data.  */
         da     data.  */
    case ETIR_S_C_STO_IMMR:
    case ETIR_S_C_STO_IMMR:
      {
      {
        int size;
        int size;
 
 
        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);
      }
      }
      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:
      {
      {
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
        char *name;
        char *name;
 
 
        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)
          {
          {
            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
                                   cmd_name (cmd), name);
                                   cmd_name (cmd), name);
            return FALSE;
            return FALSE;
          }
          }
        else
        else
          /* FIXME, reloc.  */
          /* FIXME, reloc.  */
          image_write_q (abfd, (uquad) (entry->symbol->value));
          image_write_q (abfd, (uquad) (entry->symbol->value));
      }
      }
      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:
      {
      {
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
        char *name;
        char *name;
 
 
        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)
          {
          {
            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
            (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
                                   cmd_name (cmd), name);
                                   cmd_name (cmd), name);
            return FALSE;
            return FALSE;
          }
          }
        else
        else
          /* FIXME, reloc.  */
          /* FIXME, reloc.  */
          image_write_q (abfd, (uquad) (entry->symbol->value));
          image_write_q (abfd, (uquad) (entry->symbol->value));
      }
      }
      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:
      {
      {
        uquad q;
        uquad q;
        int psect1;
        int psect1;
 
 
        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);
      }
      }
      break;
      break;
 
 
      /* Store immediate
      /* Store immediate
         arg: lw        count of bytes
         arg: lw        count of bytes
              da        data.  */
              da        data.  */
    case ETIR_S_C_STO_IMM:
    case ETIR_S_C_STO_IMM:
      {
      {
        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);
      }
      }
      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.
         FIXME, since the following is just a guess
         FIXME, since the following is just a guess
         store global longword: store 32bit value of symbol
         store global longword: store 32bit value of symbol
         arg: cs        symbol name.  */
         arg: cs        symbol name.  */
    case ETIR_S_C_STO_GBL_LW:
    case ETIR_S_C_STO_GBL_LW:
      {
      {
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
        char *name;
        char *name;
 
 
        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)
          {
          {
#if VMS_DEBUG
#if VMS_DEBUG
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
            _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
#endif
#endif
            image_write_l (abfd, (unsigned long) 0);     /* FIXME, reloc */
            image_write_l (abfd, (unsigned long) 0);     /* FIXME, reloc */
          }
          }
        else
        else
          /* FIXME, reloc.  */
          /* FIXME, reloc.  */
          image_write_l (abfd, (unsigned long) (entry->symbol->value));
          image_write_l (abfd, (unsigned long) (entry->symbol->value));
      }
      }
      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;
      break;
 
 
    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;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
      break;
      break;
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Stack operator commands
/* Stack operator commands
   all 32 bit signed arithmetic
   all 32 bit signed arithmetic
   all word just like a stack calculator
   all word just like a stack calculator
   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)
{
{
  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, (int) ptr);
#endif
#endif
 
 
  switch (cmd)
  switch (cmd)
    {
    {
    case ETIR_S_C_OPR_NOP:      /* No-op.  */
    case ETIR_S_C_OPR_NOP:      /* No-op.  */
      break;
      break;
 
 
    case ETIR_S_C_OPR_ADD:      /* Add.  */
    case ETIR_S_C_OPR_ADD:      /* Add.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_SUB:      /* Subtract.  */
    case ETIR_S_C_OPR_SUB:      /* Subtract.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
      _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_MUL:      /* Multiply.  */
    case ETIR_S_C_OPR_MUL:      /* Multiply.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_DIV:      /* Divide.  */
    case ETIR_S_C_OPR_DIV:      /* Divide.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      if (op2 == 0)
      if (op2 == 0)
        _bfd_vms_push (abfd, (uquad) 0, -1);
        _bfd_vms_push (abfd, (uquad) 0, -1);
      else
      else
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_AND:      /* Logical AND.  */
    case ETIR_S_C_OPR_AND:      /* Logical AND.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_IOR:      /* Logical inclusive OR.  */
    case ETIR_S_C_OPR_IOR:      /* Logical inclusive OR.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_EOR:      /* Logical exclusive OR.  */
    case ETIR_S_C_OPR_EOR:      /* Logical exclusive OR.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_NEG:      /* Negate.  */
    case ETIR_S_C_OPR_NEG:      /* Negate.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (-op1), -1);
      _bfd_vms_push (abfd, (uquad) (-op1), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_COM:      /* Complement.  */
    case ETIR_S_C_OPR_COM:      /* Complement.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
      _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_ASH:      /* Arithmetic shift.  */
    case ETIR_S_C_OPR_ASH:      /* Arithmetic shift.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      if (op2 < 0)               /* Shift right.  */
      if (op2 < 0)               /* Shift right.  */
        op1 >>= -op2;
        op1 >>= -op2;
      else                      /* Shift left.  */
      else                      /* Shift left.  */
        op1 <<= op2;
        op1 <<= op2;
      _bfd_vms_push (abfd, (uquad) op1, -1);
      _bfd_vms_push (abfd, (uquad) op1, -1);
      break;
      break;
 
 
    case ETIR_S_C_OPR_INSV:      /* Insert field.   */
    case ETIR_S_C_OPR_INSV:      /* Insert field.   */
      (void) _bfd_vms_pop (abfd, NULL);
      (void) _bfd_vms_pop (abfd, NULL);
    case ETIR_S_C_OPR_USH:       /* Unsigned shift.   */
    case ETIR_S_C_OPR_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;
      break;
 
 
    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
        {
        {
          op1 = (long) _bfd_vms_pop (abfd, NULL);
          op1 = (long) _bfd_vms_pop (abfd, NULL);
          (void) _bfd_vms_pop (abfd, NULL);
          (void) _bfd_vms_pop (abfd, NULL);
          _bfd_vms_push (abfd, (uquad) op1, -1);
          _bfd_vms_push (abfd, (uquad) op1, -1);
        }
        }
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
      break;
      break;
    }
    }
 
 
  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)
{
{
  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, (int) ptr);
#endif
#endif
 
 
  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:
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_set_ptr (abfd, psect, dummy);
      image_set_ptr (abfd, psect, dummy);
      break;
      break;
 
 
      /* 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.  */
    case ETIR_S_C_CTL_AUGRB:
    case ETIR_S_C_CTL_AUGRB:
      dummy = bfd_getl32 (ptr);
      dummy = bfd_getl32 (ptr);
      image_inc_ptr (abfd, dummy);
      image_inc_ptr (abfd, dummy);
      break;
      break;
 
 
      /* Define location: pop index, save location counter under index
      /* Define location: pop index, save location counter under index
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_CTL_DFLOC:
    case ETIR_S_C_CTL_DFLOC:
      dummy = _bfd_vms_pop (abfd, NULL);
      dummy = _bfd_vms_pop (abfd, NULL);
      /* FIXME */
      /* FIXME */
      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, &psect);
      /* FIXME */
      /* FIXME */
      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, &psect);
      /* FIXME.  */
      /* FIXME.  */
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
      (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
      break;
      break;
    }
    }
  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)
{
{
#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, (int) 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));
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      break;
      break;
 
 
      /* 201 Store-conditional Linkage Pair with Procedure Signature
      /* 201 Store-conditional Linkage Pair with Procedure Signature
         arg:   lw      linkage index
         arg:   lw      linkage index
                cs      procedure name
                cs      procedure name
                by      signature length
                by      signature length
                da      signature.  */
                da      signature.  */
    case ETIR_S_C_STC_LP_PSB:
    case ETIR_S_C_STC_LP_PSB:
      image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
      image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
      break;
      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));
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      break;
      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));
      (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
      break;
      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));
      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:
 
 
      /* 206 Store-conditional NOP at pect + offset
      /* 206 Store-conditional NOP at pect + offset
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_NOP_PS:
    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:
    case ETIR_S_C_STC_BSR_GBL:
 
 
      /* 208 Store-conditional BSR at pect + offset
      /* 208 Store-conditional BSR at pect + offset
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_BSR_PS:
    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:
    case ETIR_S_C_STC_LDA_GBL:
 
 
      /* 210 Store-conditional LDA at psect + offset
      /* 210 Store-conditional LDA at psect + offset
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_LDA_PS:
    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:
    case ETIR_S_C_STC_BOH_GBL:
 
 
      /* 212 Store-conditional BSR or Hint at pect + offset
      /* 212 Store-conditional BSR or Hint at pect + offset
         arg: none.  */
         arg: none.  */
    case ETIR_S_C_STC_BOH_PS:
    case ETIR_S_C_STC_BOH_PS:
 
 
      /* 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:
 
 
      /* 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 */
      /* FIXME */
      break;
      break;
 
 
    default:
    default:
#if VMS_DEBUG
#if VMS_DEBUG
      _bfd_vms_debug (3,  "reserved STC cmd %d", cmd);
      _bfd_vms_debug (3,  "reserved STC cmd %d", cmd);
#endif
#endif
      break;
      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)
{
{
  asection *section;
  asection *section;
  char sname[16];
  char sname[16];
  char *name;
  char *name;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "new_section %d\n", idx);
  _bfd_vms_debug (5, "new_section %d\n", idx);
#endif
#endif
  sprintf (sname, SECTION_NAME_TEMPLATE, idx);
  sprintf (sname, SECTION_NAME_TEMPLATE, idx);
 
 
  name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
  name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
  if (name == 0)
  if (name == 0)
    return NULL;
    return NULL;
  strcpy (name, sname);
  strcpy (name, sname);
 
 
  section = bfd_malloc ((bfd_size_type) sizeof (asection));
  section = bfd_malloc ((bfd_size_type) sizeof (asection));
  if (section == 0)
  if (section == 0)
    {
    {
#if VMS_DEBUG
#if VMS_DEBUG
      _bfd_vms_debug (6,  "new_section (%s) failed", name);
      _bfd_vms_debug (6,  "new_section (%s) failed", name);
#endif
#endif
      return NULL;
      return NULL;
    }
    }
 
 
  section->size = 0;
  section->size = 0;
  section->vma = 0;
  section->vma = 0;
  section->contents = 0;
  section->contents = 0;
  section->name = name;
  section->name = name;
  section->index = idx;
  section->index = idx;
 
 
  return section;
  return section;
}
}
 
 
static int
static int
alloc_section (bfd * abfd, unsigned int idx)
alloc_section (bfd * abfd, unsigned int idx)
{
{
  bfd_size_type amt;
  bfd_size_type amt;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (4, "alloc_section %d\n", idx);
  _bfd_vms_debug (4, "alloc_section %d\n", idx);
#endif
#endif
 
 
  amt = idx + 1;
  amt = idx + 1;
  amt *= sizeof (asection *);
  amt *= sizeof (asection *);
  PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
  PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
  if (PRIV (sections) == NULL)
  if (PRIV (sections) == NULL)
    return -1;
    return -1;
 
 
  while (PRIV (section_count) <= idx)
  while (PRIV (section_count) <= idx)
    {
    {
      PRIV (sections)[PRIV (section_count)]
      PRIV (sections)[PRIV (section_count)]
        = new_section (abfd, (int) PRIV (section_count));
        = new_section (abfd, (int) PRIV (section_count));
      if (PRIV (sections)[PRIV (section_count)] == 0)
      if (PRIV (sections)[PRIV (section_count)] == 0)
        return -1;
        return -1;
      PRIV (section_count)++;
      PRIV (section_count)++;
    }
    }
 
 
  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)
{
{
  int cmd = *ptr++;
  int cmd = *ptr++;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "tir_sta %d\n", cmd);
  _bfd_vms_debug (5, "tir_sta %d\n", cmd);
#endif
#endif
 
 
  switch (cmd)
  switch (cmd)
    {
    {
      /* stack */
      /* stack */
    case TIR_S_C_STA_GBL:
    case TIR_S_C_STA_GBL:
      /* 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).  */
      {
      {
        char *name;
        char *name;
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
 
 
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
 
 
        entry = _bfd_vms_enter_symbol (abfd, name);
        entry = _bfd_vms_enter_symbol (abfd, name);
        if (entry == NULL)
        if (entry == NULL)
          return NULL;
          return NULL;
 
 
        _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
        _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
        ptr += *ptr + 1;
        ptr += *ptr + 1;
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_SB:
    case TIR_S_C_STA_SB:
      /* stack signed byte
      /* stack signed byte
         arg: by        value
         arg: by        value
 
 
         stack byte value, sign extend to 32 bit.  */
         stack byte value, sign extend to 32 bit.  */
      _bfd_vms_push (abfd, (uquad) *ptr++, -1);
      _bfd_vms_push (abfd, (uquad) *ptr++, -1);
      break;
      break;
 
 
    case TIR_S_C_STA_SW:
    case TIR_S_C_STA_SW:
      /* stack signed short word
      /* stack signed short word
         arg: sh        value
         arg: sh        value
 
 
         stack 16 bit value, sign extend to 32 bit.  */
         stack 16 bit value, sign extend to 32 bit.  */
      _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
      _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
      ptr += 2;
      ptr += 2;
      break;
      break;
 
 
    case TIR_S_C_STA_LW:
    case TIR_S_C_STA_LW:
      /* stack signed longword
      /* stack signed longword
         arg: lw        value
         arg: lw        value
 
 
         stack 32 bit value.  */
         stack 32 bit value.  */
      _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
      _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
      ptr += 4;
      ptr += 4;
      break;
      break;
 
 
    case TIR_S_C_STA_PB:
    case TIR_S_C_STA_PB:
    case TIR_S_C_STA_WPB:
    case TIR_S_C_STA_WPB:
      /* stack psect base plus byte offset (word index)
      /* stack psect base plus byte offset (word index)
         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;
        unsigned 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 (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, (int) 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:
      /* stack psect base plus word offset (word index)
      /* stack psect base plus word offset (word index)
         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;
        unsigned 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 (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, (int) 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:
      /* stack psect base plus long offset (word index)
      /* stack psect base plus long offset (word index)
         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;
        unsigned 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 (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, (int) psect);
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_UB:
    case TIR_S_C_STA_UB:
      /* stack unsigned byte
      /* stack unsigned byte
         arg: by        value
         arg: by        value
 
 
         stack byte value.  */
         stack byte value.  */
      _bfd_vms_push (abfd, (uquad) *ptr++, -1);
      _bfd_vms_push (abfd, (uquad) *ptr++, -1);
      break;
      break;
 
 
    case TIR_S_C_STA_UW:
    case TIR_S_C_STA_UW:
      /* stack unsigned short word
      /* stack unsigned short word
         arg: sh        value
         arg: sh        value
 
 
         stack 16 bit value.  */
         stack 16 bit value.  */
      _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
      _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
      ptr += 2;
      ptr += 2;
      break;
      break;
 
 
    case TIR_S_C_STA_BFI:
    case TIR_S_C_STA_BFI:
      /* stack byte from image
      /* stack byte from image
         arg: none.  */
         arg: none.  */
      /* FALLTHRU  */
      /* FALLTHRU  */
    case TIR_S_C_STA_WFI:
    case TIR_S_C_STA_WFI:
      /* stack byte from image
      /* stack byte from image
         arg: none.  */
         arg: none.  */
      /* FALLTHRU */
      /* FALLTHRU */
    case TIR_S_C_STA_LFI:
    case TIR_S_C_STA_LFI:
      /* stack byte from image
      /* stack byte from image
         arg: none.  */
         arg: none.  */
      (*_bfd_error_handler) (_("stack-from-image not implemented"));
      (*_bfd_error_handler) (_("stack-from-image not implemented"));
      return NULL;
      return NULL;
 
 
    case TIR_S_C_STA_EPM:
    case TIR_S_C_STA_EPM:
      /* stack entry point mask
      /* stack entry point mask
         arg: cs        symbol name
         arg: cs        symbol name
 
 
         stack (unsigned) entry point mask of symbol
         stack (unsigned) entry point mask of symbol
         err if symbol is no entry point.  */
         err if symbol is no entry point.  */
      {
      {
        char *name;
        char *name;
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
 
 
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
        entry = _bfd_vms_enter_symbol (abfd, name);
        if (entry == NULL)
        if (entry == NULL)
          return NULL;
          return NULL;
 
 
        (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
        (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
        ptr += *ptr + 1;
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_CKARG:
    case TIR_S_C_STA_CKARG:
      /* compare procedure argument
      /* compare procedure argument
         arg: cs        symbol name
         arg: cs        symbol name
                by      argument index
                by      argument index
                da      argument descriptor
                da      argument descriptor
 
 
         compare argument descriptor with symbol argument (ARG$V_PASSMECH)
         compare argument descriptor with symbol argument (ARG$V_PASSMECH)
         and stack TRUE (args match) or FALSE (args dont match) value.  */
         and stack TRUE (args match) or FALSE (args dont match) value.  */
      (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
      (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
      _bfd_vms_push (abfd, (uquad) 1, -1);
      _bfd_vms_push (abfd, (uquad) 1, -1);
      break;
      break;
 
 
    case TIR_S_C_STA_LSY:
    case TIR_S_C_STA_LSY:
      /* stack local symbol value
      /* stack local symbol value
         arg:   sh      environment index
         arg:   sh      environment index
                cs      symbol name.  */
                cs      symbol name.  */
      {
      {
        int envidx;
        int envidx;
        char *name;
        char *name;
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
 
 
        envidx = bfd_getl16 (ptr);
        envidx = bfd_getl16 (ptr);
        ptr += 2;
        ptr += 2;
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
        entry = _bfd_vms_enter_symbol (abfd, name);
        if (entry == NULL)
        if (entry == NULL)
          return NULL;
          return NULL;
        (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
        (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
        ptr += *ptr + 1;
      }
      }
      break;
      break;
 
 
    case TIR_S_C_STA_LIT:
    case TIR_S_C_STA_LIT:
      /* stack literal
      /* stack literal
         arg:   by      literal index
         arg:   by      literal index
 
 
         stack literal.  */
         stack literal.  */
      ptr++;
      ptr++;
      _bfd_vms_push (abfd, (uquad) 0, -1);
      _bfd_vms_push (abfd, (uquad) 0, -1);
      (*_bfd_error_handler) (_("stack-literal not fully implemented"));
      (*_bfd_error_handler) (_("stack-literal not fully implemented"));
      break;
      break;
 
 
    case TIR_S_C_STA_LEPM:
    case TIR_S_C_STA_LEPM:
      /* stack local symbol entry point mask
      /* stack local symbol entry point mask
         arg:   sh      environment index
         arg:   sh      environment index
                cs      symbol name
                cs      symbol name
 
 
         stack (unsigned) entry point mask of symbol
         stack (unsigned) entry point mask of symbol
         err if symbol is no entry point.  */
         err if symbol is no entry point.  */
      {
      {
        int envidx;
        int envidx;
        char *name;
        char *name;
        vms_symbol_entry *entry;
        vms_symbol_entry *entry;
 
 
        envidx = bfd_getl16 (ptr);
        envidx = bfd_getl16 (ptr);
        ptr += 2;
        ptr += 2;
        name = _bfd_vms_save_counted_string (ptr);
        name = _bfd_vms_save_counted_string (ptr);
        entry = _bfd_vms_enter_symbol (abfd, name);
        entry = _bfd_vms_enter_symbol (abfd, name);
        if (entry == NULL)
        if (entry == NULL)
          return NULL;
          return NULL;
        (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
        (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
        _bfd_vms_push (abfd, (uquad) 0, -1);
        _bfd_vms_push (abfd, (uquad) 0, -1);
        ptr += *ptr + 1;
        ptr += *ptr + 1;
      }
      }
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]);
      (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]);
      return NULL;
      return NULL;
      break;
      break;
    }
    }
 
 
  return ptr;
  return ptr;
}
}
 
 
static const char *
static const char *
tir_cmd_name (int cmd)
tir_cmd_name (int cmd)
{
{
  switch (cmd)
  switch (cmd)
    {
    {
    case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB";
    case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB";
    case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW";
    case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW";
    case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL";
    case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL";
    case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS";
    case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS";
    case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB";
    case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB";
    case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW";
    case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW";
    case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB";
    case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB";
    case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW";
    case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW";
    case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR";
    case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR";
    case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV";
    case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV";
    case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT";
    case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT";
    case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF";
    case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF";
    case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT";
    case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT";
    case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH";
    case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH";
    case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH";
    case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH";
    case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC";
    case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC";
    case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC";
    case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC";
    case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL";
    case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL";
 
 
    default:
    default:
      /* These strings have not been added yet.  */
      /* These strings have not been added yet.  */
      abort ();
      abort ();
    }
    }
}
}
 
 
/* tir_sto
/* tir_sto
 
 
   vax store commands
   vax store commands
 
 
   handle sto_xxx commands in tir section
   handle sto_xxx commands in tir section
   ptr points to data area in record
   ptr points to data area in record
 
 
   See table 7-4 of the VAX/VMS linker manual.  */
   See table 7-4 of the VAX/VMS linker manual.  */
 
 
static unsigned char *
static unsigned char *
tir_sto (bfd * abfd, unsigned char *ptr)
tir_sto (bfd * abfd, unsigned char *ptr)
{
{
  unsigned long dummy;
  unsigned long dummy;
  int size;
  int size;
  int psect;
  int psect;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
  _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
#endif
#endif
 
 
  switch (*ptr++)
  switch (*ptr++)
    {
    {
    case TIR_S_C_STO_SB:
    case TIR_S_C_STO_SB:
      /* Store signed byte: pop stack, write byte
      /* Store signed byte: pop stack, write byte
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_write_b (abfd, dummy & 0xff);       /* FIXME: check top bits */
      image_write_b (abfd, dummy & 0xff);       /* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_SW:
    case TIR_S_C_STO_SW:
      /* Store signed word: pop stack, write word
      /* Store signed word: pop stack, write word
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_write_w (abfd, dummy & 0xffff);     /* FIXME: check top bits */
      image_write_w (abfd, dummy & 0xffff);     /* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_LW:
    case TIR_S_C_STO_LW:
      /* Store longword: pop stack, write longword
      /* Store longword: pop stack, write longword
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_write_l (abfd, dummy & 0xffffffff); /* FIXME: check top bits */
      image_write_l (abfd, dummy & 0xffffffff); /* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_BD:
    case TIR_S_C_STO_BD:
      /* Store byte displaced: pop stack, sub lc+1, write byte
      /* Store byte displaced: pop stack, sub lc+1, write byte
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy -= ((PRIV (sections)[psect])->vma + 1);
      dummy -= ((PRIV (sections)[psect])->vma + 1);
      image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
      image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_WD:
    case TIR_S_C_STO_WD:
      /* Store word displaced: pop stack, sub lc+2, write word
      /* Store word displaced: pop stack, sub lc+2, write word
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy -= ((PRIV (sections)[psect])->vma + 2);
      dummy -= ((PRIV (sections)[psect])->vma + 2);
      image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
      image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_LD:
    case TIR_S_C_STO_LD:
      /* Store long displaced: pop stack, sub lc+4, write long
      /* Store long displaced: pop stack, sub lc+4, write long
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy -= ((PRIV (sections)[psect])->vma + 4);
      dummy -= ((PRIV (sections)[psect])->vma + 4);
      image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
      image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_LI:
    case TIR_S_C_STO_LI:
      /* Store short literal: pop stack, write byte
      /* Store short literal: pop stack, write byte
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
      image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
      break;
      break;
 
 
    case TIR_S_C_STO_PIDR:
    case TIR_S_C_STO_PIDR:
      /* Store position independent data reference: pop stack, write longword
      /* Store position independent data reference: pop stack, write longword
         arg: none.
         arg: none.
         FIXME: incomplete !  */
         FIXME: incomplete !  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_write_l (abfd, dummy & 0xffffffff);
      image_write_l (abfd, dummy & 0xffffffff);
      break;
      break;
 
 
    case TIR_S_C_STO_PICR:
    case TIR_S_C_STO_PICR:
      /* Store position independent code reference: pop stack, write longword
      /* Store position independent code reference: pop stack, write longword
         arg: none.
         arg: none.
         FIXME: incomplete !  */
         FIXME: incomplete !  */
      dummy = _bfd_vms_pop (abfd, &psect);
      dummy = _bfd_vms_pop (abfd, &psect);
      image_write_b (abfd, 0x9f);
      image_write_b (abfd, 0x9f);
      image_write_l (abfd, dummy & 0xffffffff);
      image_write_l (abfd, dummy & 0xffffffff);
      break;
      break;
 
 
    case TIR_S_C_STO_RIVB:
    case TIR_S_C_STO_RIVB:
      /* Store repeated immediate variable bytes
      /* Store repeated immediate variable bytes
         1-byte count n field followed by n bytes of data
         1-byte count n field followed by n bytes of data
         pop stack, write n bytes <stack> times.  */
         pop stack, write n bytes <stack> times.  */
      size = *ptr++;
      size = *ptr++;
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      while (dummy-- > 0L)
      while (dummy-- > 0L)
        image_dump (abfd, ptr, size, 0);
        image_dump (abfd, ptr, size, 0);
      ptr += size;
      ptr += size;
      break;
      break;
 
 
    case TIR_S_C_STO_B:
    case TIR_S_C_STO_B:
      /* Store byte from top longword.  */
      /* Store byte from top longword.  */
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      image_write_b (abfd, dummy & 0xff);
      image_write_b (abfd, dummy & 0xff);
      break;
      break;
 
 
    case TIR_S_C_STO_W:
    case TIR_S_C_STO_W:
      /* Store word from top longword.  */
      /* Store word from top longword.  */
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      image_write_w (abfd, dummy & 0xffff);
      image_write_w (abfd, dummy & 0xffff);
      break;
      break;
 
 
    case TIR_S_C_STO_RB:
    case TIR_S_C_STO_RB:
      /* Store repeated byte from top longword.  */
      /* Store repeated byte from top longword.  */
      size = (unsigned long) _bfd_vms_pop (abfd, NULL);
      size = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      while (size-- > 0)
      while (size-- > 0)
        image_write_b (abfd, dummy & 0xff);
        image_write_b (abfd, dummy & 0xff);
      break;
      break;
 
 
    case TIR_S_C_STO_RW:
    case TIR_S_C_STO_RW:
      /* Store repeated word from top longword.  */
      /* Store repeated word from top longword.  */
      size = (unsigned long) _bfd_vms_pop (abfd, NULL);
      size = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
      while (size-- > 0)
      while (size-- > 0)
        image_write_w (abfd, dummy & 0xffff);
        image_write_w (abfd, dummy & 0xffff);
      break;
      break;
 
 
    case TIR_S_C_STO_RSB:
    case TIR_S_C_STO_RSB:
    case TIR_S_C_STO_RSW:
    case TIR_S_C_STO_RSW:
    case TIR_S_C_STO_RL:
    case TIR_S_C_STO_RL:
    case TIR_S_C_STO_VPS:
    case TIR_S_C_STO_VPS:
    case TIR_S_C_STO_USB:
    case TIR_S_C_STO_USB:
    case TIR_S_C_STO_USW:
    case TIR_S_C_STO_USW:
    case TIR_S_C_STO_RUB:
    case TIR_S_C_STO_RUB:
    case TIR_S_C_STO_RUW:
    case TIR_S_C_STO_RUW:
    case TIR_S_C_STO_PIRR:
    case TIR_S_C_STO_PIRR:
      (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1]));
      (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1]));
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]);
      (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]);
      break;
      break;
    }
    }
 
 
  return ptr;
  return ptr;
}
}
 
 
/* Stack operator commands
/* Stack operator commands
   All 32 bit signed arithmetic
   All 32 bit signed arithmetic
   All word just like a stack calculator
   All word just like a stack calculator
   Arguments are popped from stack, results are pushed on stack
   Arguments are popped from stack, results are pushed on stack
 
 
   See table 7-5 of the VAX/VMS linker manual.  */
   See table 7-5 of the VAX/VMS linker manual.  */
 
 
static unsigned char *
static unsigned char *
tir_opr (bfd * abfd, unsigned char *ptr)
tir_opr (bfd * abfd, unsigned char *ptr)
{
{
  long op1, op2;
  long op1, op2;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
  _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
#endif
#endif
 
 
  /* Operation.  */
  /* Operation.  */
  switch (*ptr++)
  switch (*ptr++)
    {
    {
    case TIR_S_C_OPR_NOP: /* No-op.  */
    case TIR_S_C_OPR_NOP: /* No-op.  */
      break;
      break;
 
 
    case TIR_S_C_OPR_ADD: /* Add.  */
    case TIR_S_C_OPR_ADD: /* Add.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_SUB: /* Subtract.  */
    case TIR_S_C_OPR_SUB: /* Subtract.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
      _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_MUL: /* Multiply.  */
    case TIR_S_C_OPR_MUL: /* Multiply.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_DIV: /* Divide.  */
    case TIR_S_C_OPR_DIV: /* Divide.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      if (op2 == 0)
      if (op2 == 0)
        _bfd_vms_push (abfd, (uquad) 0, -1);
        _bfd_vms_push (abfd, (uquad) 0, -1);
      else
      else
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
        _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_AND: /* Logical AND.  */
    case TIR_S_C_OPR_AND: /* Logical AND.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_IOR: /* Logical inclusive OR.  */
    case TIR_S_C_OPR_IOR: /* Logical inclusive OR.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_EOR: /* Logical exclusive OR.  */
    case TIR_S_C_OPR_EOR: /* Logical exclusive OR.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
      _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_NEG: /* Negate.  */
    case TIR_S_C_OPR_NEG: /* Negate.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (-op1), -1);
      _bfd_vms_push (abfd, (uquad) (-op1), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_COM: /* Complement.  */
    case TIR_S_C_OPR_COM: /* Complement.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
      _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
      break;
      break;
 
 
    case TIR_S_C_OPR_INSV: /* Insert field.  */
    case TIR_S_C_OPR_INSV: /* Insert field.  */
      (void) _bfd_vms_pop (abfd, NULL);
      (void) _bfd_vms_pop (abfd, NULL);
      (*_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_OPR_ASH: /* Arithmetic shift.  */
    case TIR_S_C_OPR_ASH: /* Arithmetic shift.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      if (HIGHBIT (op1))        /* Shift right.  */
      if (HIGHBIT (op1))        /* Shift right.  */
        op2 >>= op1;
        op2 >>= op1;
      else                      /* Shift left.  */
      else                      /* Shift left.  */
        op2 <<= op1;
        op2 <<= op1;
      _bfd_vms_push (abfd, (uquad) op2, -1);
      _bfd_vms_push (abfd, (uquad) op2, -1);
      (*_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_OPR_USH: /* Unsigned shift.  */
    case TIR_S_C_OPR_USH: /* Unsigned shift.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      if (HIGHBIT (op1))        /* Shift right.  */
      if (HIGHBIT (op1))        /* Shift right.  */
        op2 >>= op1;
        op2 >>= op1;
      else                      /* Shift left.  */
      else                      /* Shift left.  */
        op2 <<= op1;
        op2 <<= op1;
      _bfd_vms_push (abfd, (uquad) op2, -1);
      _bfd_vms_push (abfd, (uquad) op2, -1);
      (*_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_OPR_ROT: /* Rotate.  */
    case TIR_S_C_OPR_ROT: /* Rotate.  */
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op1 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      op2 = (long) _bfd_vms_pop (abfd, NULL);
      if (HIGHBIT (0))   /* Shift right.  */
      if (HIGHBIT (0))   /* Shift right.  */
        op2 >>= op1;
        op2 >>= op1;
      else              /* Shift left.  */
      else              /* Shift left.  */
        op2 <<= op1;
        op2 <<= op1;
      _bfd_vms_push (abfd, (uquad) op2, -1);
      _bfd_vms_push (abfd, (uquad) op2, -1);
      (*_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_OPR_SEL: /* Select.  */
    case TIR_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
        {
        {
          op1 = (long) _bfd_vms_pop (abfd, NULL);
          op1 = (long) _bfd_vms_pop (abfd, NULL);
          (void) _bfd_vms_pop (abfd, NULL);
          (void) _bfd_vms_pop (abfd, NULL);
          _bfd_vms_push (abfd, (uquad) op1, -1);
          _bfd_vms_push (abfd, (uquad) op1, -1);
        }
        }
      break;
      break;
 
 
    case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location.  */
    case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location.  */
    case TIR_S_C_OPR_DFLIT: /* Define a literal.  */
    case TIR_S_C_OPR_DFLIT: /* Define a literal.  */
      (*_bfd_error_handler) (_("%s: not supported"),
      (*_bfd_error_handler) (_("%s: not supported"),
                             tir_cmd_name (ptr[-1]));
                             tir_cmd_name (ptr[-1]));
      break;
      break;
 
 
    default:
    default:
      (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]);
      (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]);
      break;
      break;
    }
    }
 
 
  return ptr;
  return ptr;
}
}
 
 
/* Control commands
/* Control commands
 
 
   See table 7-6 of the VAX/VMS linker manual.  */
   See table 7-6 of the VAX/VMS linker manual.  */
 
 
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;
  unsigned 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, (int *) &psect);
      if (psect >= PRIV (section_count))
      if (psect >= PRIV (section_count))
        alloc_section (abfd, psect);
        alloc_section (abfd, psect);
      image_set_ptr (abfd, (int) psect, (uquad) dummy);
      image_set_ptr (abfd, (int) 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.  */
      dummy = bfd_getl32 (ptr);
      dummy = bfd_getl32 (ptr);
      image_inc_ptr (abfd, (uquad) dummy);
      image_inc_ptr (abfd, (uquad) dummy);
      break;
      break;
 
 
    case TIR_S_C_CTL_DFLOC:
    case TIR_S_C_CTL_DFLOC:
      /* Define location: pop index, save location counter under index
      /* Define location: pop index, save location counter under index
         arg: none.  */
         arg: none.  */
      dummy = _bfd_vms_pop (abfd, NULL);
      dummy = _bfd_vms_pop (abfd, NULL);
      (*_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_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, (int *) &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, (int *) &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:
      (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]);
      (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]);
      break;
      break;
    }
    }
  return ptr;
  return ptr;
}
}
 
 
/* 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
  struct
  {
  {
    int mincod;
    int mincod;
    int maxcod;
    int maxcod;
    unsigned char * (*explain) (bfd *, unsigned char *);
    unsigned char * (*explain) (bfd *, unsigned char *);
  }
  }
  tir_table[] =
  tir_table[] =
  {
  {
    { 0,          TIR_S_C_MAXSTACOD, tir_sta },
    { 0,          TIR_S_C_MAXSTACOD, tir_sta },
    { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto },
    { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto },
    { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr },
    { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr },
    { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl },
    { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl },
    { -1, -1, NULL }
    { -1, -1, NULL }
  };
  };
  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, (int) ptr);
#endif
#endif
 
 
  if (*ptr & 0x80)
  if (*ptr & 0x80)
    {
    {
      /* Store immediate.  */
      /* Store immediate.  */
      i = 128 - (*ptr++ & 0x7f);
      i = 128 - (*ptr++ & 0x7f);
      image_dump (abfd, ptr, i, 0);
      image_dump (abfd, ptr, i, 0);
      ptr += i;
      ptr += i;
    }
    }
  else
  else
    {
    {
      while (tir_table[i].mincod >= 0)
      while (tir_table[i].mincod >= 0)
        {
        {
          if ( (tir_table[i].mincod <= *ptr)
          if ( (tir_table[i].mincod <= *ptr)
               && (*ptr <= tir_table[i].maxcod))
               && (*ptr <= tir_table[i].maxcod))
            {
            {
              ptr = tir_table[i].explain (abfd, ptr);
              ptr = tir_table[i].explain (abfd, ptr);
              break;
              break;
            }
            }
          i++;
          i++;
        }
        }
      if (tir_table[i].mincod < 0)
      if (tir_table[i].mincod < 0)
        {
        {
          (*_bfd_error_handler) (_("obj code %d not found"), *ptr);
          (*_bfd_error_handler) (_("obj code %d not found"), *ptr);
          ptr = 0;
          ptr = 0;
        }
        }
    }
    }
 
 
  return ptr;
  return ptr;
}
}
 
 
/* 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)
{
{
  static struct
  static struct
  {
  {
    int mincod;
    int mincod;
    int maxcod;
    int maxcod;
    bfd_boolean (*explain) (bfd *, int, unsigned char *);
    bfd_boolean (*explain) (bfd *, int, unsigned char *);
  }
  }
  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 },
    { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
    { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
    { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
    { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
    { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
    { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
    { -1, -1, NULL }
    { -1, -1, NULL }
  };
  };
 
 
  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 %d/%x\n", cmd, cmd);
  _bfd_hexdump (8, ptr, 16, (int) ptr);
  _bfd_hexdump (8, ptr, 16, (int) 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))
            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: = 0\n");
#endif
#endif
  return 0;
  return 0;
}
}
 
 
/* Text Information and Relocation Records (OBJ$C_TIR)
/* Text Information and Relocation Records (OBJ$C_TIR)
   handle tir record.  */
   handle tir record.  */
 
 
static int
static int
analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
{
{
  unsigned char *maxptr;
  unsigned char *maxptr;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
  _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
#endif
#endif
 
 
  maxptr = ptr + length;
  maxptr = ptr + length;
 
 
  while (ptr < maxptr)
  while (ptr < maxptr)
    {
    {
      ptr = tir_cmd (abfd, ptr);
      ptr = tir_cmd (abfd, ptr);
      if (ptr == 0)
      if (ptr == 0)
        return -1;
        return -1;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Text Information and Relocation Records (EOBJ$C_ETIR)
/* Text Information and Relocation Records (EOBJ$C_ETIR)
   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;
  int cmd;
  unsigned char *maxptr;
  unsigned char *maxptr;
  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;
  maxptr = ptr + length;
 
 
  while (ptr < maxptr)
  while (ptr < maxptr)
    {
    {
      cmd = bfd_getl16 (ptr);
      cmd = bfd_getl16 (ptr);
      length = bfd_getl16 (ptr + 2);
      length = bfd_getl16 (ptr + 2);
      result = etir_cmd (abfd, cmd, ptr+4);
      result = etir_cmd (abfd, cmd, ptr+4);
      if (result != 0)
      if (result != 0)
        break;
        break;
      ptr += length;
      ptr += length;
    }
    }
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
  _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
#endif
#endif
 
 
  return result;
  return result;
}
}
 
 
/* Process ETIR record
/* Process ETIR record
   Return 0 on success, -1 on error.  */
   Return 0 on success, -1 on error.  */
 
 
int
int
_bfd_vms_slurp_tir (bfd * abfd, int objtype)
_bfd_vms_slurp_tir (bfd * abfd, int objtype)
{
{
  int result;
  int result;
 
 
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "TIR/ETIR\n");
  _bfd_vms_debug (2, "TIR/ETIR\n");
#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) += 4;      /* Skip type, size.  */
      PRIV (rec_size) -= 4;
      PRIV (rec_size) -= 4;
      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;
      result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
      result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
      break;
      break;
    default:
    default:
      result = -1;
      result = -1;
      break;
      break;
    }
    }
 
 
  return result;
  return result;
}
}
 
 
/* Process EDBG record
/* Process EDBG record
   Return 0 on success, -1 on error
   Return 0 on success, -1 on error
 
 
   Not implemented yet.  */
   Not implemented yet.  */
 
 
int
int
_bfd_vms_slurp_dbg (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
_bfd_vms_slurp_dbg (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "DBG/EDBG\n");
  _bfd_vms_debug (2, "DBG/EDBG\n");
#endif
#endif
 
 
  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
  return 0;
  return 0;
}
}
 
 
/* Process ETBT record
/* Process ETBT record
   Return 0 on success, -1 on error
   Return 0 on success, -1 on error
 
 
   Not implemented yet.  */
   Not implemented yet.  */
 
 
int
int
_bfd_vms_slurp_tbt (bfd * abfd ATTRIBUTE_UNUSED,
_bfd_vms_slurp_tbt (bfd * abfd ATTRIBUTE_UNUSED,
                    int objtype ATTRIBUTE_UNUSED)
                    int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "TBT/ETBT\n");
  _bfd_vms_debug (2, "TBT/ETBT\n");
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* Process LNK record
/* Process LNK record
   Return 0 on success, -1 on error
   Return 0 on success, -1 on error
 
 
   Not implemented yet.  */
   Not implemented yet.  */
 
 
int
int
_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
                    int objtype ATTRIBUTE_UNUSED)
                    int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "LNK\n");
  _bfd_vms_debug (2, "LNK\n");
#endif
#endif
 
 
  return 0;
  return 0;
}
}


/* Start ETIR record for section #index at virtual addr offset.  */
/* Start ETIR record for section #index at virtual addr offset.  */
 
 
static void
static void
start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset)
start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset)
{
{
  if (!justoffset)
  if (!justoffset)
    {
    {
      /* One ETIR per section.  */
      /* One ETIR per section.  */
      _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
      _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
      _bfd_vms_output_push (abfd);
      _bfd_vms_output_push (abfd);
    }
    }
 
 
  /* Push start offset.  */
  /* Push start offset.  */
  _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
  _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
  _bfd_vms_output_long (abfd, (unsigned long) index);
  _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);
  _bfd_vms_output_flush (abfd);
  _bfd_vms_output_flush (abfd);
}
}
 
 
static void
static void
end_etir_record (bfd * abfd)
end_etir_record (bfd * abfd)
{
{
  _bfd_vms_output_pop (abfd);
  _bfd_vms_output_pop (abfd);
  _bfd_vms_output_end (abfd);
  _bfd_vms_output_end (abfd);
}
}
 
 
/* WRITE ETIR SECTION
/* WRITE ETIR SECTION
 
 
   This is still under construction and therefore not documented.  */
   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, vms_section *sptr, bfd_vma vaddr, int index)
{
{
  int size;
  int size;
  int ssize;
  int ssize;
  unsigned char *cptr;
  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", sptr->size);
  _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
  _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
#endif
#endif
 
 
  ssize = sptr->size;
  ssize = sptr->size;
  cptr = sptr->contents;
  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);
          start_etir_record (abfd, index, vaddr, FALSE);
          start_etir_record (abfd, index, vaddr, FALSE);
          /* Get max size.  */
          /* Get max size.  */
          size = _bfd_vms_output_check (abfd, 0);
          size = _bfd_vms_output_check (abfd, 0);
          /* More than what's left ?  */
          /* More than what's left ?  */
          if (size > ssize)
          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));
      _bfd_vms_output_dump (abfd, cptr, size);
      _bfd_vms_output_dump (abfd, cptr, size);
      _bfd_vms_output_flush (abfd);
      _bfd_vms_output_flush (abfd);
 
 
#if VMS_DEBUG
#if VMS_DEBUG
      _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;
      ssize -= size;
      cptr += size;
      cptr += size;
    }
    }
}
}
 
 
/* 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;
  vms_section *sptr;
  int nextoffset;
  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;
  nextoffset = 0;
  PRIV (vms_linkage_index) = 1;
  PRIV (vms_linkage_index) = 1;
 
 
  /* Dump all other sections.  */
  /* Dump all other sections.  */
  section = abfd->sections;
  section = abfd->sections;
 
 
  while (section != NULL)
  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_RELOC)
      if (section->flags & SEC_RELOC)
        {
        {
          int i;
          int i;
 
 
          if ((i = section->reloc_count) <= 0)
          if ((i = section->reloc_count) <= 0)
            (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
            (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
                                   section->name);
                                   section->name);
#if VMS_DEBUG
#if VMS_DEBUG
          else
          else
            {
            {
              arelent **rptr;
              arelent **rptr;
              _bfd_vms_debug (4, "%d relocations:\n", i);
              _bfd_vms_debug (4, "%d relocations:\n", i);
              rptr = section->orelocation;
              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)
      if ((section->flags & SEC_HAS_CONTENTS)
          && (! bfd_is_com_section (section)))
          && (! bfd_is_com_section (section)))
        {
        {
          /* Virtual addr in section.  */
          /* Virtual addr in section.  */
          bfd_vma vaddr;
          bfd_vma vaddr;
 
 
          sptr = _bfd_get_vms_section (abfd, section->index);
          sptr = _bfd_get_vms_section (abfd, section->index);
          if (sptr == NULL)
          if (sptr == NULL)
            {
            {
              bfd_set_error (bfd_error_no_contents);
              bfd_set_error (bfd_error_no_contents);
              return -1;
              return -1;
            }
            }
 
 
          vaddr = (bfd_vma) (sptr->offset);
          vaddr = (bfd_vma) (sptr->offset);
 
 
          start_etir_record (abfd, section->index, (uquad) sptr->offset,
          start_etir_record (abfd, section->index, (uquad) sptr->offset,
                             FALSE);
                             FALSE);
 
 
          while (sptr != NULL)
          while (sptr != NULL)
            {
            {
              /* One STA_PQ, CTL_SETRB per vms_section.  */
              /* One STA_PQ, CTL_SETRB per vms_section.  */
              if (section->flags & SEC_RELOC)
              if (section->flags & SEC_RELOC)
                {
                {
                  /* Check for relocs.  */
                  /* Check for relocs.  */
                  arelent **rptr = section->orelocation;
                  arelent **rptr = section->orelocation;
                  int i = section->reloc_count;
                  int i = section->reloc_count;
 
 
                  for (;;)
                  for (;;)
                    {
                    {
                      bfd_size_type addr = (*rptr)->address;
                      bfd_size_type addr = (*rptr)->address;
                      bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
                      bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
                      if (sptr->offset < addr)
                      if (sptr->offset < addr)
                        {
                        {
                          /* Sptr starts before reloc.  */
                          /* Sptr starts before reloc.  */
                          bfd_size_type before = addr - sptr->offset;
                          bfd_size_type before = addr - sptr->offset;
                          if (sptr->size <= before)
                          if (sptr->size <= before)
                            {
                            {
                              /* Complete before.  */
                              /* Complete before.  */
                              sto_imm (abfd, sptr, vaddr, section->index);
                              sto_imm (abfd, sptr, vaddr, section->index);
                              vaddr += sptr->size;
                              vaddr += sptr->size;
                              break;
                              break;
                            }
                            }
                          else
                          else
                            {
                            {
                              /* Partly before.  */
                              /* Partly before.  */
                              int after = sptr->size - before;
                              int after = sptr->size - before;
 
 
                              sptr->size = before;
                              sptr->size = before;
                              sto_imm (abfd, sptr, vaddr, section->index);
                              sto_imm (abfd, sptr, vaddr, section->index);
                              vaddr += sptr->size;
                              vaddr += sptr->size;
                              sptr->contents += before;
                              sptr->contents += before;
                              sptr->offset += before;
                              sptr->offset += before;
                              sptr->size = after;
                              sptr->size = after;
                            }
                            }
                        }
                        }
                      else if (sptr->offset == addr)
                      else if (sptr->offset == addr)
                        {
                        {
                          /* Sptr starts at reloc.  */
                          /* Sptr starts at reloc.  */
                          asymbol *sym = *(*rptr)->sym_ptr_ptr;
                          asymbol *sym = *(*rptr)->sym_ptr_ptr;
                          asection *sec = sym->section;
                          asection *sec = sym->section;
 
 
                          switch ((*rptr)->howto->type)
                          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);
                                    int slen = strlen ((char *) sym->name);
                                    char *hash;
                                    char *hash;
 
 
                                    if (_bfd_vms_output_check (abfd, slen) < 0)
                                    if (_bfd_vms_output_check (abfd, slen) < 0)
                                      {
                                      {
                                        end_etir_record (abfd);
                                        end_etir_record (abfd);
                                        start_etir_record (abfd,
                                        start_etir_record (abfd,
                                                           section->index,
                                                           section->index,
                                                           vaddr, FALSE);
                                                           vaddr, FALSE);
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                                    _bfd_vms_output_begin (abfd,
                                                           ETIR_S_C_STO_GBL_LW,
                                                           ETIR_S_C_STO_GBL_LW,
                                                           -1);
                                                           -1);
                                    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_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else if (bfd_is_abs_section (sym->section))
                                else if (bfd_is_abs_section (sym->section))
                                  {
                                  {
                                    if (_bfd_vms_output_check (abfd, 16) < 0)
                                    if (_bfd_vms_output_check (abfd, 16) < 0)
                                      {
                                      {
                                        end_etir_record (abfd);
                                        end_etir_record (abfd);
                                        start_etir_record (abfd,
                                        start_etir_record (abfd,
                                                           section->index,
                                                           section->index,
                                                           vaddr, FALSE);
                                                           vaddr, FALSE);
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                                    _bfd_vms_output_begin (abfd,
                                                           ETIR_S_C_STA_LW,
                                                           ETIR_S_C_STA_LW,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_quad (abfd,
                                    _bfd_vms_output_quad (abfd,
                                                          (uquad) sym->value);
                                                          (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_LW,
                                                           ETIR_S_C_STO_LW,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else
                                else
                                  {
                                  {
                                    if (_bfd_vms_output_check (abfd, 32) < 0)
                                    if (_bfd_vms_output_check (abfd, 32) < 0)
                                      {
                                      {
                                        end_etir_record (abfd);
                                        end_etir_record (abfd);
                                        start_etir_record (abfd,
                                        start_etir_record (abfd,
                                                           section->index,
                                                           section->index,
                                                           vaddr, FALSE);
                                                           vaddr, FALSE);
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                                    _bfd_vms_output_begin (abfd,
                                                           ETIR_S_C_STA_PQ,
                                                           ETIR_S_C_STA_PQ,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_long (abfd,
                                    _bfd_vms_output_long (abfd,
                                                          (unsigned long) (sec->index));
                                                          (unsigned long) (sec->index));
                                    _bfd_vms_output_quad (abfd,
                                    _bfd_vms_output_quad (abfd,
                                                          ((uquad) (*rptr)->addend
                                                          ((uquad) (*rptr)->addend
                                                           + (uquad) sym->value));
                                                           + (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_LW,
                                                           ETIR_S_C_STO_LW,
                                                           -1);
                                                           -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);
                                    int slen = strlen ((char *) sym->name);
                                    char *hash;
                                    char *hash;
 
 
                                    if (_bfd_vms_output_check (abfd, slen) < 0)
                                    if (_bfd_vms_output_check (abfd, slen) < 0)
                                      {
                                      {
                                        end_etir_record (abfd);
                                        end_etir_record (abfd);
                                        start_etir_record (abfd,
                                        start_etir_record (abfd,
                                                           section->index,
                                                           section->index,
                                                           vaddr, FALSE);
                                                           vaddr, FALSE);
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                                    _bfd_vms_output_begin (abfd,
                                                           ETIR_S_C_STO_GBL,
                                                           ETIR_S_C_STO_GBL,
                                                           -1);
                                                           -1);
                                    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_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else if (bfd_is_abs_section (sym->section))
                                else if (bfd_is_abs_section (sym->section))
                                  {
                                  {
                                    if (_bfd_vms_output_check (abfd, 16) < 0)
                                    if (_bfd_vms_output_check (abfd, 16) < 0)
                                      {
                                      {
                                        end_etir_record (abfd);
                                        end_etir_record (abfd);
                                        start_etir_record (abfd,
                                        start_etir_record (abfd,
                                                           section->index,
                                                           section->index,
                                                           vaddr, FALSE);
                                                           vaddr, FALSE);
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                                    _bfd_vms_output_begin (abfd,
                                                           ETIR_S_C_STA_QW,
                                                           ETIR_S_C_STA_QW,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_quad (abfd,
                                    _bfd_vms_output_quad (abfd,
                                                          (uquad) sym->value);
                                                          (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,
                                                           ETIR_S_C_STO_QW,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                                else
                                else
                                  {
                                  {
                                    if (_bfd_vms_output_check (abfd, 32) < 0)
                                    if (_bfd_vms_output_check (abfd, 32) < 0)
                                      {
                                      {
                                        end_etir_record (abfd);
                                        end_etir_record (abfd);
                                        start_etir_record (abfd,
                                        start_etir_record (abfd,
                                                           section->index,
                                                           section->index,
                                                           vaddr, FALSE);
                                                           vaddr, FALSE);
                                      }
                                      }
                                    _bfd_vms_output_begin (abfd,
                                    _bfd_vms_output_begin (abfd,
                                                           ETIR_S_C_STA_PQ,
                                                           ETIR_S_C_STA_PQ,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_long (abfd,
                                    _bfd_vms_output_long (abfd,
                                                          (unsigned long) (sec->index));
                                                          (unsigned long) (sec->index));
                                    _bfd_vms_output_quad (abfd,
                                    _bfd_vms_output_quad (abfd,
                                                          ((uquad) (*rptr)->addend
                                                          ((uquad) (*rptr)->addend
                                                           + (uquad) sym->value));
                                                           + (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_OFF,
                                                           ETIR_S_C_STO_OFF,
                                                           -1);
                                                           -1);
                                    _bfd_vms_output_flush (abfd);
                                    _bfd_vms_output_flush (abfd);
                                  }
                                  }
                              }
                              }
                              break;
                              break;
 
 
                            case ALPHA_R_HINT:
                            case ALPHA_R_HINT:
                              {
                              {
                                int hint_size;
                                int hint_size;
                                char *hash ATTRIBUTE_UNUSED;
                                char *hash ATTRIBUTE_UNUSED;
 
 
                                hint_size = sptr->size;
                                hint_size = sptr->size;
                                sptr->size = len;
                                sptr->size = len;
                                sto_imm (abfd, sptr, vaddr, section->index);
                                sto_imm (abfd, sptr, vaddr, section->index);
                                sptr->size = hint_size;
                                sptr->size = hint_size;
                              }
                              }
                              break;
                              break;
                            case ALPHA_R_LINKAGE:
                            case ALPHA_R_LINKAGE:
                              {
                              {
                                char *hash;
                                char *hash;
 
 
                                if (_bfd_vms_output_check (abfd, 64) < 0)
                                if (_bfd_vms_output_check (abfd, 64) < 0)
                                  {
                                  {
                                    end_etir_record (abfd);
                                    end_etir_record (abfd);
                                    start_etir_record (abfd, section->index,
                                    start_etir_record (abfd, section->index,
                                                       vaddr, FALSE);
                                                       vaddr, FALSE);
                                  }
                                  }
                                _bfd_vms_output_begin (abfd,
                                _bfd_vms_output_begin (abfd,
                                                       ETIR_S_C_STC_LP_PSB,
                                                       ETIR_S_C_STC_LP_PSB,
                                                       -1);
                                                       -1);
                                _bfd_vms_output_long (abfd,
                                _bfd_vms_output_long (abfd,
                                                      (unsigned long) PRIV (vms_linkage_index));
                                                      (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:
                              {
                              {
                                int slen = strlen ((char *) sym->name);
                                int slen = strlen ((char *) sym->name);
                                char *hash;
                                char *hash;
                                if (_bfd_vms_output_check (abfd, slen) < 0)
                                if (_bfd_vms_output_check (abfd, slen) < 0)
                                  {
                                  {
                                    end_etir_record (abfd);
                                    end_etir_record (abfd);
                                    start_etir_record (abfd,
                                    start_etir_record (abfd,
                                                       section->index,
                                                       section->index,
                                                       vaddr, FALSE);
                                                       vaddr, FALSE);
                                  }
                                  }
                                _bfd_vms_output_begin (abfd,
                                _bfd_vms_output_begin (abfd,
                                                       ETIR_S_C_STO_CA,
                                                       ETIR_S_C_STO_CA,
                                                       -1);
                                                       -1);
                                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_flush (abfd);
                                _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;
                          vaddr += len;
 
 
                          if (len == sptr->size)
                          if (len == sptr->size)
                            {
                            {
                              break;
                              break;
                            }
                            }
                          else
                          else
                            {
                            {
                              sptr->contents += len;
                              sptr->contents += len;
                              sptr->offset += len;
                              sptr->offset += len;
                              sptr->size -= len;
                              sptr->size -= len;
                              i--;
                              i--;
                              rptr++;
                              rptr++;
                            }
                            }
                        }
                        }
                      else
                      else
                        {
                        {
                          /* Sptr starts after reloc.  */
                          /* Sptr starts after reloc.  */
                          i--;
                          i--;
                          /* Check next reloc.  */
                          /* Check next reloc.  */
                          rptr++;
                          rptr++;
                        }
                        }
 
 
                      if (i == 0)
                      if (i == 0)
                        {
                        {
                          /* All reloc checked.  */
                          /* All reloc checked.  */
                          if (sptr->size > 0)
                          if (sptr->size > 0)
                            {
                            {
                              /* Dump rest.  */
                              /* Dump rest.  */
                              sto_imm (abfd, sptr, vaddr, section->index);
                              sto_imm (abfd, sptr, vaddr, section->index);
                              vaddr += sptr->size;
                              vaddr += sptr->size;
                            }
                            }
                          break;
                          break;
                        }
                        }
                    }
                    }
                }
                }
              else
              else
                {
                {
                  /* No relocs, just dump.  */
                  /* No relocs, just dump.  */
                  sto_imm (abfd, sptr, vaddr, section->index);
                  sto_imm (abfd, sptr, vaddr, section->index);
                  vaddr += sptr->size;
                  vaddr += sptr->size;
                }
                }
 
 
              sptr = sptr->next;
              sptr = sptr->next;
            }
            }
 
 
          end_etir_record (abfd);
          end_etir_record (abfd);
        }
        }
 
 
      section = section->next;
      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.  */
/* Write traceback data for bfd abfd.  */
 
 
int
int
_bfd_vms_write_tbt (bfd * abfd ATTRIBUTE_UNUSED,
_bfd_vms_write_tbt (bfd * abfd ATTRIBUTE_UNUSED,
                    int objtype ATTRIBUTE_UNUSED)
                    int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
  _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* Write debug info for bfd abfd.  */
/* Write debug info for bfd abfd.  */
 
 
int
int
_bfd_vms_write_dbg (bfd * abfd ATTRIBUTE_UNUSED,
_bfd_vms_write_dbg (bfd * abfd ATTRIBUTE_UNUSED,
                    int objtype ATTRIBUTE_UNUSED)
                    int objtype ATTRIBUTE_UNUSED)
{
{
#if VMS_DEBUG
#if VMS_DEBUG
  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 

powered by: WebSVN 2.1.0

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