aboutsummaryrefslogtreecommitdiff
path: root/bfd/vms-tir.c
diff options
context:
space:
mode:
authorTristan Gingold <gingold@adacore.com>2010-04-14 09:24:59 +0000
committerTristan Gingold <gingold@adacore.com>2010-04-14 09:24:59 +0000
commit95e34ef763214988cfaaeb51ca9aeb77ab87be3d (patch)
tree72fa89519c680e1197c24d068bc6603b1e3e240e /bfd/vms-tir.c
parent895fa45f398c6815252ed56c8a1b7992f40ccaa0 (diff)
downloadgdb-95e34ef763214988cfaaeb51ca9aeb77ab87be3d.zip
gdb-95e34ef763214988cfaaeb51ca9aeb77ab87be3d.tar.gz
gdb-95e34ef763214988cfaaeb51ca9aeb77ab87be3d.tar.bz2
2010-04-14 Tristan Gingold <gingold@adacore.com>
* Makefile.am (BFD32_BACKENDS): Remove vms-gsd.lo, vms-hdr.lo, vms-tir.lo, vms.lo and add vms-alpha.lo (BFD32_BACKENDS_CFILES): Remove vms-gsd.c, vms-hdr.c, vms-tir.c, vms.c and add vms-alpha.c * Makefile.in: Regenerate. * configure.in (TDEFINES): Adjust file list for vms_alpha_vec. Remove vms_vax_vec. * configure: Regenerate. * targets.c (vms_vax_vec): Remove the declaration. (_bfd_target_vector): Remove vms_vax_vec. * vms-alpha.c: New file. * vms-gsd.c: Removed, rewritten in vms-alpha.c * vms-hdr.c: Ditto. * vms-tir.c: Ditto. * vms.c: Ditto. * vms-misc.c: Fix indentation and comments. Replace most of #if VMS_DEBUG/vms_debug with vms_debug2. (_bfd_vms_hash_newfunc): Moved to vms-alpha.c (hash_string): Ditto. (_bfd_vms_length_hash_symbol): Ditto. (maybe_adjust_record_pointer_for_object): Ditto. (_bfd_vms_get_object_record): Ditto. (vms_get_remaining_object_record): Ditto. (_bfd_vms_push): Ditto. (_bfd_vms_pop): Ditto. (_bfd_vms_get_header_values): Removed. (_bfd_vms_get_first_record): Removed. (vms_get_remaining_image_record): Removed. (new_symbol): Removed. (_bfd_vms_enter_symbol): Removed. (_bfd_vms_save_sized_string): Use memcpy instead of strncpy. (_bfd_vms_output_begin): Remove rechead parameter. Replace bfd parameter with struct vms_rec_wr. (_bfd_vms_output_push): Removed and replaced by ... (_bfd_vms_output_begin_subrec): ... new function. (_bfd_vms_output_alignment): Replace bfd parameter with struct vms_rec_wr, and adjust. (_bfd_vms_output_check): Ditto (_bfd_vms_output_byte): Ditto. (_bfd_vms_output_short): Ditto. (_bfd_vms_output_long): Ditto. (_bfd_vms_output_quad): Ditto. (_bfd_vms_output_counted): Ditto. (_bfd_vms_output_dump): Ditto. (_bfd_vms_output_fill): Ditto. (_bfd_vms_output_pop): Removed and replaced by ... (_bfd_vms_output_end_subrec): ... new function. (_bfd_vms_output_flush): Removed. (_bfd_vms_output_align): New function. (_bfd_vms_output_end): Add recwr parameter. Adjust for this new parameter. (vms_convert_to_var): New function imported from vms.c (vms_convert_to_var_1): Ditto. (vms_convert_to_var_unix_filename): Ditto. (vms_get_module_name): Ditto. (get_vms_time_string): Ditto. (vms_time_to_time_t): Ditto. (vms_rawtime_to_time_t): Ditto. * vms.h: All macros for the VMS file format are now in include/vms. Prototypes for vms.c, vms-gsd.c, vms-misc.c, vms-hdr.c, vms-tir.c have been removed. (struct vms_symbol_struct, struct stack_struct): Moved to vms-alpha.c (struct fileinfo, struct srecinfo, struct lineinfo): Ditto. (struct funcinfo, struct vms_private_data_struct): Ditto. (struct vms_section_data_struct): Ditto. (struct vms_rec_rd, stryct vms_rec_wr): New declarations. (vms_get_module_name, get_vms_time_string): New declarations. (vms_time_to_time_t, vms_rawtime_to_time_t): Ditto. (_bfd_vms_output_begin_subrec, _bfd_vms_output_end_subrec): Ditto. (_bfd_vms_save_sized_string, _bfd_vms_save_counted_string): Adjusted. (_bfd_vms_output_begin, _bfd_vms_output_alignment): Ditto. (_bfd_vms_output_end,_bfd_vms_output_check): Ditto. (_bfd_vms_output_byte, _bfd_vms_output_short): Ditto. (_bfd_vms_output_long, _bfd_vms_output_quad): Ditto. (_bfd_vms_output_counted, _bfd_vms_output_dump): Ditto. (_bfd_vms_output_fill): Ditto. (bfd_vms_set_section_flags): Ditto.
Diffstat (limited to 'bfd/vms-tir.c')
-rw-r--r--bfd/vms-tir.c2808
1 files changed, 0 insertions, 2808 deletions
diff --git a/bfd/vms-tir.c b/bfd/vms-tir.c
deleted file mode 100644
index 1ecb151..0000000
--- a/bfd/vms-tir.c
+++ /dev/null
@@ -1,2808 +0,0 @@
-/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
- EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007,
- 2008, 2009 Free Software Foundation, Inc.
-
- TIR record handling functions
- ETIR record handling functions
-
- Go and read the openVMS linker manual (esp. appendix B)
- if you don't know what's going on here :-)
-
- Written by Klaus K"ampf (kkaempf@rmi.de)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- MA 02110-1301, USA. */
-
-/* The following type abbreviations are used:
-
- cs counted string (ascii string with length byte)
- by byte (1 byte)
- sh short (2 byte, 16 bit)
- lw longword (4 byte, 32 bit)
- qw quadword (8 byte, 64 bit)
- da data stream */
-
-#include "sysdep.h"
-#include "bfd.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-#include "vms.h"
-
-static int check_section (bfd *, int);
-static void image_set_ptr (bfd *abfd, int psect, uquad offset);
-static void image_inc_ptr (bfd *abfd, uquad offset);
-static void dst_define_location (bfd *abfd, uquad loc);
-static void dst_restore_location (bfd *abfd, uquad loc);
-static unsigned int dst_retrieve_location (bfd *abfd, uquad loc);
-static void dst_check_allocation (bfd *abfd, unsigned int size);
-static void image_dump (bfd *abfd, unsigned char *ptr, int size, int offset);
-static void image_write_b (bfd *abfd, unsigned int value);
-static void image_write_w (bfd *abfd, unsigned int value);
-static void image_write_l (bfd *abfd, unsigned long value);
-static void image_write_q (bfd *abfd, uquad value);
-static bfd_boolean etir_sta (bfd *, int, unsigned char *, int *);
-static bfd_boolean etir_sto (bfd *, int, unsigned char *, int *);
-static bfd_boolean etir_opr (bfd *, int, unsigned char *, int *);
-static bfd_boolean etir_ctl (bfd *, int, unsigned char *, int *);
-static bfd_boolean etir_stc (bfd *, int, unsigned char *, int *);
-static asection *new_section (bfd *, int);
-static int alloc_section (bfd *, unsigned int);
-static int etir_cmd (bfd *, int, unsigned char *, int *);
-static int analyze_tir (bfd *, unsigned char *, unsigned int);
-static int analyze_etir (bfd *, unsigned char *, unsigned int);
-static unsigned char *tir_opr (bfd *, unsigned char *);
-static const char *tir_cmd_name (int);
-static const char *cmd_name (int);
-
-
-static int
-check_section (bfd * abfd, int size)
-{
- bfd_size_type offset;
-
- offset = PRIV (image_ptr) - PRIV (image_section)->contents;
- if (offset + size > PRIV (image_section)->size)
- {
- PRIV (image_section)->contents
- = bfd_realloc_or_free (PRIV (image_section)->contents, offset + size);
- if (PRIV (image_section)->contents == NULL)
- {
- (*_bfd_error_handler) (_("No Mem !"));
- return -1;
- }
- PRIV (image_section)->size = offset + size;
- PRIV (image_ptr) = PRIV (image_section)->contents + offset;
- }
-
- return 0;
-}
-
-/* Routines to fill sections contents during tir/etir read. */
-
-/* Initialize image buffer pointer to be filled. */
-
-static void
-image_set_ptr (bfd * abfd, int psect, uquad offset)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
- psect, PRIV (sections)[psect]->name, offset);
-#endif
-
- PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
- PRIV (image_section) = PRIV (sections)[psect];
-}
-
-/* Increment image buffer pointer by offset. */
-
-static void
-image_inc_ptr (bfd * abfd, uquad offset)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
-#endif
-
- PRIV (image_ptr) += offset;
-}
-
-/* Save current DST location counter under specified index. */
-
-static void
-dst_define_location (bfd *abfd, uquad loc)
-{
- asection *dst_section = PRIV (dst_section);
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "dst_define_location (%d)\n", (int)loc);
-#endif
-
- /* Grow the ptr offset table if necessary. */
- if (loc + 1 > PRIV (dst_ptr_offsets_count))
- {
- PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets),
- (loc + 1) * sizeof (unsigned int));
- PRIV (dst_ptr_offsets_count) = loc + 1;
- }
-
- PRIV (dst_ptr_offsets)[loc] = PRIV (image_ptr) - dst_section->contents;
-}
-
-/* Restore saved DST location counter from specified index. */
-
-static void
-dst_restore_location (bfd *abfd, uquad loc)
-{
- asection *dst_section = PRIV (dst_section);
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "dst_restore_location (%d)\n", (int)loc);
-#endif
-
- PRIV (image_ptr) = dst_section->contents + PRIV (dst_ptr_offsets)[loc];
-}
-
-/* Retrieve saved DST location counter from specified index. */
-
-static unsigned int
-dst_retrieve_location (bfd *abfd, uquad loc)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (4, "dst_retrieve_location (%d)\n", (int)loc);
-#endif
-
- return PRIV (dst_ptr_offsets)[loc];
-}
-
-/* Check that the DST section is big enough for the specified
- amount of bytes. */
-
-static void
-dst_check_allocation (bfd *abfd, unsigned int size)
-{
- asection *dst_section = PRIV (dst_section);
-
- bfd_size_type used = PRIV (image_ptr) - dst_section->contents;
- bfd_size_type left = dst_section->size - used;
-
- /* Grow the DST section as necessary */
- if (size > left)
- {
- dst_section->size *= 2;
- dst_section->contents
- = bfd_realloc (dst_section->contents, dst_section->size);
- PRIV (image_ptr) = dst_section->contents + used;
-
- dst_check_allocation (abfd, size);
- }
-}
-
-/* Dump multiple bytes to section image. */
-
-static void
-image_dump (bfd * abfd,
- unsigned char *ptr,
- int size,
- int offset ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
- PRIV (image_ptr));
- _bfd_hexdump (9, ptr, size, offset);
-#endif
-
- if (PRIV (is_vax) && check_section (abfd, size))
- return;
-
- if (PRIV (dst_section))
- dst_check_allocation (abfd, size);
-
- while (size-- > 0)
- *PRIV (image_ptr)++ = *ptr++;
-}
-
-/* Write byte to section image. */
-
-static void
-image_write_b (bfd * abfd, unsigned int value)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
-#endif
-
- if (PRIV (is_vax) && check_section (abfd, 1))
- return;
-
- if (PRIV (dst_section))
- dst_check_allocation (abfd, 1);
-
- *PRIV (image_ptr)++ = (value & 0xff);
-}
-
-/* Write 2-byte word to image. */
-
-static void
-image_write_w (bfd * abfd, unsigned int value)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
-#endif
-
- if (PRIV (is_vax) && check_section (abfd, 2))
- return;
-
- if (PRIV (dst_section))
- dst_check_allocation (abfd, 2);
-
- bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
- PRIV (image_ptr) += 2;
-}
-
-/* Write 4-byte long to image. */
-
-static void
-image_write_l (bfd * abfd, unsigned long value)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
-#endif
-
- if (PRIV (is_vax) && check_section (abfd, 4))
- return;
-
- if (PRIV (dst_section))
- dst_check_allocation (abfd, 4);
-
- bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
- PRIV (image_ptr) += 4;
-}
-
-/* Write 8-byte quad to image. */
-
-static void
-image_write_q (bfd * abfd, uquad value)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
-#endif
-
- if (PRIV (is_vax) && check_section (abfd, 8))
- return;
-
- if (PRIV (dst_section))
- dst_check_allocation (abfd, 8);
-
- bfd_putl64 (value, PRIV (image_ptr));
- PRIV (image_ptr) += 8;
-}
-
-static const char *
-cmd_name (int cmd)
-{
- switch (cmd)
- {
- case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
- case ETIR_S_C_STA_LW: return "ETIR_S_C_STA_LW";
- case ETIR_S_C_STA_QW: return "ETIR_S_C_STA_QW";
- case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ";
- case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
- case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD";
- case ETIR_S_C_STA_CKARG: return "ETIR_S_C_STA_CKARG";
- case ETIR_S_C_STO_B: return "ETIR_S_C_STO_B";
- case ETIR_S_C_STO_W: return "ETIR_S_C_STO_W";
- case ETIR_S_C_STO_GBL: return "ETIR_S_C_STO_GBL";
- case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
- case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB";
- case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
- case ETIR_S_C_STO_OFF: return "ETIR_S_C_STO_OFF";
- case ETIR_S_C_STO_IMM: return "ETIR_S_C_STO_IMM";
- case ETIR_S_C_STO_IMMR: return "ETIR_S_C_STO_IMMR";
- case ETIR_S_C_STO_LW: return "ETIR_S_C_STO_LW";
- case ETIR_S_C_STO_QW: return "ETIR_S_C_STO_QW";
- case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW";
- case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB";
- case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL";
- case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
- case ETIR_S_C_OPR_ADD: return "ETIR_S_C_OPR_ADD";
- case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV";
- case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
- case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT";
- case ETIR_S_C_OPR_REDEF: return "ETIR_S_C_OPR_REDEF";
- case ETIR_S_C_OPR_DFLIT: return "ETIR_S_C_OPR_DFLIT";
- case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP";
- case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL";
- case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA";
- case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS";
- case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS";
- case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL";
- case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS";
- case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL";
- case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS";
- case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL";
- case ETIR_S_C_STC_LDA_PS: return "ETIR_S_C_STC_LDA_PS";
- case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
- case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
- case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
- case ETIR_S_C_CTL_SETRB: return "ETIR_S_C_CTL_SETRB";
- case ETIR_S_C_STC_LP_PSB: return "ETIR_S_C_STC_LP_PSB";
- case ETIR_S_C_CTL_DFLOC: return "ETIR_S_C_CTL_DFLOC";
- case ETIR_S_C_CTL_STLOC: return "ETIR_S_C_CTL_STLOC";
- case ETIR_S_C_CTL_STKDL: return "ETIR_S_C_CTL_STKDL";
-
- default:
- /* These names have not yet been added to this switch statement. */
- (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
- }
-
- return NULL;
-}
-#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
-
-/* etir_sta
-
- Vms stack commands.
-
- Handle sta_xxx commands in etir section,
- ptr points to data area in record.
-
- See table B-8 of the openVMS linker manual. */
-
-static bfd_boolean
-etir_sta (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- switch (cmd)
- {
- /* Stack global
- arg: cs symbol name
-
- stack 32 bit value of symbol (high bits set to 0). */
- case ETIR_S_C_STA_GBL:
- {
- char *name;
- vms_symbol_entry *entry;
-
- name = _bfd_vms_save_counted_string (ptr);
- entry = (vms_symbol_entry *)
- bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
- if (entry == NULL)
- {
-#if VMS_DEBUG
- _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
- cmd_name (cmd), name);
-#endif
- _bfd_vms_push (abfd, (uquad) 0, -1);
- }
- else
- _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
- }
- *quarter_relocs = 1;
- break;
-
- /* Stack longword
- arg: lw value
-
- stack 32 bit value, sign extend to 64 bit. */
- case ETIR_S_C_STA_LW:
- _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
- /* This one is special as it is both part of the section header
- and of the ALPHA_R_REFLONG relocation. */
- if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_DFLOC)
- *quarter_relocs = 0;
- else if (*quarter_relocs)
- *quarter_relocs += 1;
- else
- *quarter_relocs = 2;
- break;
-
- /* Stack quadword
- arg: qw value
-
- stack 64 bit value of symbol. */
- case ETIR_S_C_STA_QW:
- _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
- if (*quarter_relocs)
- *quarter_relocs += 1;
- else
- *quarter_relocs = 2;
- break;
-
- /* Stack psect base plus quadword offset
- arg: lw section index
- qw signed quadword offset (low 32 bits)
-
- Stack qw argument and section index
- (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB). */
- case ETIR_S_C_STA_PQ:
- {
- uquad dummy;
- int psect;
-
- psect = bfd_getl32 (ptr);
- if ((unsigned int) psect >= PRIV (section_count))
- {
- (*_bfd_error_handler) (_("bad section index in %s"),
- cmd_name (cmd));
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
- dummy = bfd_getl64 (ptr + 4);
- _bfd_vms_push (abfd, dummy, (int) psect);
- }
- /* This one is special as it is both part of the section header
- and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations. */
- if (bfd_getl16 (ptr - 4 + bfd_getl16 (ptr - 2)) == ETIR_S_C_CTL_SETRB)
- *quarter_relocs = 0;
- else
- *quarter_relocs = 2;
- break;
-
- case ETIR_S_C_STA_LI:
- case ETIR_S_C_STA_MOD:
- case ETIR_S_C_STA_CKARG:
- (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
- *quarter_relocs = 0;
- return FALSE;
-
- default:
- (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
- *quarter_relocs = 0;
- return FALSE;
- }
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "etir_sta true\n");
-#endif
-
- return TRUE;
-}
-
-/* etir_sto
-
- vms store commands
-
- handle sto_xxx commands in etir section
- ptr points to data area in record
-
- see table B-9 of the openVMS linker manual. */
-
-static bfd_boolean
-etir_sto (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
-{
- uquad dummy;
- int psect;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- switch (cmd)
- {
- /* Store byte: pop stack, write byte
- arg: -. */
- case ETIR_S_C_STO_B:
- dummy = _bfd_vms_pop (abfd, &psect);
- /* FIXME: check top bits. */
- image_write_b (abfd, (unsigned int) dummy & 0xff);
- *quarter_relocs = 0;
- break;
-
- /* Store word: pop stack, write word
- arg: -. */
- case ETIR_S_C_STO_W:
- dummy = _bfd_vms_pop (abfd, &psect);
- /* FIXME: check top bits */
- image_write_w (abfd, (unsigned int) dummy & 0xffff);
- *quarter_relocs = 0;
- break;
-
- /* Store longword: pop stack, write longword
- arg: -. */
- case ETIR_S_C_STO_LW:
- dummy = _bfd_vms_pop (abfd, &psect);
- dummy += (PRIV (sections)[psect])->vma;
- /* FIXME: check top bits. */
- image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
- if (*quarter_relocs == 2)
- *quarter_relocs = 4;
- else
- *quarter_relocs += 1;
- break;
-
- /* Store quadword: pop stack, write quadword
- arg: -. */
- case ETIR_S_C_STO_QW:
- dummy = _bfd_vms_pop (abfd, &psect);
- dummy += (PRIV (sections)[psect])->vma;
- /* FIXME: check top bits. */
- image_write_q (abfd, dummy);
- if (*quarter_relocs == 2)
- *quarter_relocs = 4;
- else
- *quarter_relocs += 1;
- break;
-
- /* Store immediate repeated: pop stack for repeat count
- arg: lw byte count
- da data. */
- case ETIR_S_C_STO_IMMR:
- {
- int size;
-
- size = bfd_getl32 (ptr);
- dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
- while (dummy-- > 0)
- image_dump (abfd, ptr+4, size, 0);
- }
- *quarter_relocs = 0;
- break;
-
- /* Store global: write symbol value
- arg: cs global symbol name. */
- case ETIR_S_C_STO_GBL:
- {
- vms_symbol_entry *entry;
- char *name;
-
- name = _bfd_vms_save_counted_string (ptr);
- entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
- name, FALSE, FALSE);
- if (entry == NULL)
- /* FIXME, reloc. */
- image_write_q (abfd, (uquad) (0));
- else
- /* FIXME, reloc. */
- image_write_q (abfd, (uquad) (entry->symbol->value));
- }
- *quarter_relocs = 4;
- break;
-
- /* Store code address: write address of entry point
- arg: cs global symbol name (procedure). */
- case ETIR_S_C_STO_CA:
- {
- vms_symbol_entry *entry;
- char *name;
-
- name = _bfd_vms_save_counted_string (ptr);
- entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
- name, FALSE, FALSE);
- if (entry == NULL)
- /* FIXME, reloc. */
- image_write_q (abfd, (uquad) (0));
- else
- /* FIXME, reloc. */
- image_write_q (abfd, (uquad) (entry->symbol->value));
- }
- *quarter_relocs = 4;
- break;
-
- /* Store offset to psect: pop stack, add low 32 bits to base of psect
- arg: none. */
- case ETIR_S_C_STO_OFF:
- {
- uquad q;
- int psect1;
-
- q = _bfd_vms_pop (abfd, & psect1);
- q += (PRIV (sections)[psect1])->vma;
- image_write_q (abfd, q);
- }
- *quarter_relocs += 2;
- break;
-
- /* Store immediate
- arg: lw count of bytes
- da data. */
- case ETIR_S_C_STO_IMM:
- {
- int size;
-
- size = bfd_getl32 (ptr);
- image_dump (abfd, ptr+4, size, 0);
- }
- *quarter_relocs = 0;
- break;
-
- /* This code is 'reserved to digital' according to the openVMS
- linker manual, however it is generated by the DEC C compiler
- and defined in the include file.
- FIXME, since the following is just a guess
- store global longword: store 32bit value of symbol
- arg: cs symbol name. */
- case ETIR_S_C_STO_GBL_LW:
- {
- vms_symbol_entry *entry;
- char *name;
-
- name = _bfd_vms_save_counted_string (ptr);
- entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
- name, FALSE, FALSE);
- if (entry == NULL)
- {
-#if VMS_DEBUG
- _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
-#endif
- image_write_l (abfd, (unsigned long) 0); /* FIXME, reloc */
- }
- else
- /* FIXME, reloc. */
- image_write_l (abfd, (unsigned long) (entry->symbol->value));
- }
- *quarter_relocs = 4;
- break;
-
- case ETIR_S_C_STO_RB:
- case ETIR_S_C_STO_AB:
- case ETIR_S_C_STO_LP_PSB:
- (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
- *quarter_relocs = 0;
- return FALSE;
-
- case ETIR_S_C_STO_HINT_GBL:
- case ETIR_S_C_STO_HINT_PS:
- (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
- *quarter_relocs = 0;
- return FALSE;
-
- default:
- (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
- *quarter_relocs = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Stack operator commands
- all 32 bit signed arithmetic
- all word just like a stack calculator
- arguments are popped from stack, results are pushed on stack
-
- see table B-10 of the openVMS linker manual. */
-
-static bfd_boolean
-etir_opr (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
- int *quarter_relocs)
-{
- long op1, op2;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- /* No relocation uses OPR commands except ETIR_S_C_OPR_ADD. */
- if (cmd == ETIR_S_C_OPR_ADD)
- *quarter_relocs += 1;
- else
- *quarter_relocs = 0;
-
- switch (cmd)
- {
- case ETIR_S_C_OPR_NOP: /* No-op. */
- break;
-
- case ETIR_S_C_OPR_ADD: /* Add. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
- break;
-
- case ETIR_S_C_OPR_SUB: /* Subtract. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
- break;
-
- case ETIR_S_C_OPR_MUL: /* Multiply. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
- break;
-
- case ETIR_S_C_OPR_DIV: /* Divide. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- if (op2 == 0)
- _bfd_vms_push (abfd, (uquad) 0, -1);
- else
- _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
- break;
-
- case ETIR_S_C_OPR_AND: /* Logical AND. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
- break;
-
- case ETIR_S_C_OPR_IOR: /* Logical inclusive OR. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
- break;
-
- case ETIR_S_C_OPR_EOR: /* Logical exclusive OR. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
- break;
-
- case ETIR_S_C_OPR_NEG: /* Negate. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (-op1), -1);
- break;
-
- case ETIR_S_C_OPR_COM: /* Complement. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
- break;
-
- case ETIR_S_C_OPR_ASH: /* Arithmetic shift. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- if (op2 < 0) /* Shift right. */
- op1 >>= -op2;
- else /* Shift left. */
- op1 <<= op2;
- _bfd_vms_push (abfd, (uquad) op1, -1);
- break;
-
- case ETIR_S_C_OPR_INSV: /* Insert field. */
- (void) _bfd_vms_pop (abfd, NULL);
- case ETIR_S_C_OPR_USH: /* Unsigned shift. */
- case ETIR_S_C_OPR_ROT: /* Rotate. */
- case ETIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */
- case ETIR_S_C_OPR_DFLIT: /* Define a literal. */
- (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
- return FALSE;
-
- case ETIR_S_C_OPR_SEL: /* Select. */
- if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
- (void) _bfd_vms_pop (abfd, NULL);
- else
- {
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- (void) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) op1, -1);
- }
- break;
-
- default:
- (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Control commands.
-
- See table B-11 of the openVMS linker manual. */
-
-static bfd_boolean
-etir_ctl (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
-{
- uquad dummy;
- int psect;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- /* No relocation uses CTL commands. */
- *quarter_relocs = 0;
-
- switch (cmd)
- {
- /* Det relocation base: pop stack, set image location counter
- arg: none. */
- case ETIR_S_C_CTL_SETRB:
- dummy = _bfd_vms_pop (abfd, &psect);
- image_set_ptr (abfd, psect, dummy);
- break;
-
- /* Augment relocation base: increment image location counter by offset
- arg: lw offset value. */
- case ETIR_S_C_CTL_AUGRB:
- dummy = bfd_getl32 (ptr);
- image_inc_ptr (abfd, dummy);
- break;
-
- /* Define location: pop index, save location counter under index
- arg: none. */
- case ETIR_S_C_CTL_DFLOC:
- dummy = _bfd_vms_pop (abfd, NULL);
- dst_define_location (abfd, dummy);
- break;
-
- /* Set location: pop index, restore location counter from index
- arg: none. */
- case ETIR_S_C_CTL_STLOC:
- dummy = _bfd_vms_pop (abfd, NULL);
- dst_restore_location (abfd, dummy);
- break;
-
- /* Stack defined location: pop index, push location counter from index
- arg: none. */
- case ETIR_S_C_CTL_STKDL:
- dummy = _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, dst_retrieve_location (abfd, dummy), -1);
- break;
-
- default:
- (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Store conditional commands
-
- See table B-12 and B-13 of the openVMS linker manual. */
-
-static bfd_boolean
-etir_stc (bfd *abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED,
- int *quarter_relocs)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- switch (cmd)
- {
- /* 200 Store-conditional Linkage Pair
- arg: none. */
- case ETIR_S_C_STC_LP:
-
- /* 202 Store-conditional Address at global address
- arg: lw linkage index
- cs global name. */
-
- case ETIR_S_C_STC_GBL:
-
- /* 203 Store-conditional Code Address at global address
- arg: lw linkage index
- cs procedure name. */
- case ETIR_S_C_STC_GCA:
-
- /* 204 Store-conditional Address at psect + offset
- arg: lw linkage index
- lw psect index
- qw offset. */
- case ETIR_S_C_STC_PS:
- (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
- *quarter_relocs = 0;
- return FALSE;
-
- /* 201 Store-conditional Linkage Pair with Procedure Signature
- arg: lw linkage index
- cs procedure name
- by signature length
- da signature. */
-
- case ETIR_S_C_STC_LP_PSB:
- image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
- *quarter_relocs = 4;
- break;
-
- /* 205 Store-conditional NOP at address of global
- arg: none. */
- case ETIR_S_C_STC_NOP_GBL:
- /* ALPHA_R_NOP */
-
- /* 207 Store-conditional BSR at global address
- arg: none. */
-
- case ETIR_S_C_STC_BSR_GBL:
- /* ALPHA_R_BSR */
-
- /* 209 Store-conditional LDA at global address
- arg: none. */
-
- case ETIR_S_C_STC_LDA_GBL:
- /* ALPHA_R_LDA */
-
- /* 211 Store-conditional BSR or Hint at global address
- arg: none. */
-
- case ETIR_S_C_STC_BOH_GBL:
- *quarter_relocs = 4;
- break;
-
- /* 213 Store-conditional NOP,BSR or HINT at global address
- arg: none. */
-
- case ETIR_S_C_STC_NBH_GBL:
-
- /* 206 Store-conditional NOP at pect + offset
- arg: none. */
-
- case ETIR_S_C_STC_NOP_PS:
-
- /* 208 Store-conditional BSR at pect + offset
- arg: none. */
-
- case ETIR_S_C_STC_BSR_PS:
-
- /* 210 Store-conditional LDA at psect + offset
- arg: none. */
-
- case ETIR_S_C_STC_LDA_PS:
-
- /* 212 Store-conditional BSR or Hint at pect + offset
- arg: none. */
-
- case ETIR_S_C_STC_BOH_PS:
-
- /* 214 Store-conditional NOP, BSR or HINT at psect + offset
- arg: none. */
- case ETIR_S_C_STC_NBH_PS:
- (*_bfd_error_handler) ("%s: not supported", cmd_name (cmd));
- *quarter_relocs = 0;
- return FALSE;
-
- default:
- (*_bfd_error_handler) (_("reserved STC cmd %d"), cmd);
- *quarter_relocs = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-static asection *
-new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
-{
- asection *section;
- char sname[16];
- char *name;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "new_section %d\n", idx);
-#endif
- sprintf (sname, SECTION_NAME_TEMPLATE, idx);
-
- name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
- if (name == 0)
- return NULL;
- strcpy (name, sname);
-
- section = bfd_malloc ((bfd_size_type) sizeof (asection));
- if (section == 0)
- {
-#if VMS_DEBUG
- _bfd_vms_debug (6, "new_section (%s) failed", name);
-#endif
- return NULL;
- }
-
- section->size = 0;
- section->vma = 0;
- section->contents = 0;
- section->name = name;
- section->index = idx;
-
- return section;
-}
-
-static int
-alloc_section (bfd * abfd, unsigned int idx)
-{
- bfd_size_type amt;
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "alloc_section %d\n", idx);
-#endif
-
- amt = idx + 1;
- amt *= sizeof (asection *);
- PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
- if (PRIV (sections) == NULL)
- return -1;
-
- while (PRIV (section_count) <= idx)
- {
- PRIV (sections)[PRIV (section_count)]
- = new_section (abfd, (int) PRIV (section_count));
- if (PRIV (sections)[PRIV (section_count)] == 0)
- return -1;
- PRIV (section_count)++;
- }
-
- return 0;
-}
-
-/* tir_sta
-
- Vax stack commands.
-
- Handle sta_xxx commands in tir section,
- ptr points to data area in record.
-
- See table 7-3 of the VAX/VMS linker manual. */
-
-static unsigned char *
-tir_sta (bfd * abfd, unsigned char *ptr)
-{
- int cmd = *ptr++;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "tir_sta %d\n", cmd);
-#endif
-
- switch (cmd)
- {
- /* stack */
- case TIR_S_C_STA_GBL:
- /* stack global
- arg: cs symbol name
-
- stack 32 bit value of symbol (high bits set to 0). */
- {
- char *name;
- vms_symbol_entry *entry;
-
- name = _bfd_vms_save_counted_string (ptr);
-
- entry = _bfd_vms_enter_symbol (abfd, name);
- if (entry == NULL)
- return NULL;
-
- _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
- ptr += *ptr + 1;
- }
- break;
-
- case TIR_S_C_STA_SB:
- /* stack signed byte
- arg: by value
-
- stack byte value, sign extend to 32 bit. */
- _bfd_vms_push (abfd, (uquad) *ptr++, -1);
- break;
-
- case TIR_S_C_STA_SW:
- /* stack signed short word
- arg: sh value
-
- stack 16 bit value, sign extend to 32 bit. */
- _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
- ptr += 2;
- break;
-
- case TIR_S_C_STA_LW:
- /* stack signed longword
- arg: lw value
-
- stack 32 bit value. */
- _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
- ptr += 4;
- break;
-
- case TIR_S_C_STA_PB:
- case TIR_S_C_STA_WPB:
- /* stack psect base plus byte offset (word index)
- arg: by section index
- (sh section index)
- by signed byte offset. */
- {
- unsigned long dummy;
- int psect;
-
- if (cmd == TIR_S_C_STA_PB)
- psect = *ptr++;
- else
- {
- psect = bfd_getl16 (ptr);
- ptr += 2;
- }
-
- if ((unsigned int) psect >= PRIV (section_count))
- alloc_section (abfd, psect);
-
- dummy = (long) *ptr++;
- dummy += (PRIV (sections)[psect])->vma;
- _bfd_vms_push (abfd, (uquad) dummy, psect);
- }
- break;
-
- case TIR_S_C_STA_PW:
- case TIR_S_C_STA_WPW:
- /* stack psect base plus word offset (word index)
- arg: by section index
- (sh section index)
- sh signed short offset. */
- {
- unsigned long dummy;
- int psect;
-
- if (cmd == TIR_S_C_STA_PW)
- psect = *ptr++;
- else
- {
- psect = bfd_getl16 (ptr);
- ptr += 2;
- }
-
- if ((unsigned int) psect >= PRIV (section_count))
- alloc_section (abfd, psect);
-
- dummy = bfd_getl16 (ptr); ptr+=2;
- dummy += (PRIV (sections)[psect])->vma;
- _bfd_vms_push (abfd, (uquad) dummy, psect);
- }
- break;
-
- case TIR_S_C_STA_PL:
- case TIR_S_C_STA_WPL:
- /* stack psect base plus long offset (word index)
- arg: by section index
- (sh section index)
- lw signed longword offset. */
- {
- unsigned long dummy;
- int psect;
-
- if (cmd == TIR_S_C_STA_PL)
- psect = *ptr++;
- else
- {
- psect = bfd_getl16 (ptr);
- ptr += 2;
- }
-
- if ((unsigned int) psect >= PRIV (section_count))
- alloc_section (abfd, psect);
-
- dummy = bfd_getl32 (ptr); ptr += 4;
- dummy += (PRIV (sections)[psect])->vma;
- _bfd_vms_push (abfd, (uquad) dummy, psect);
- }
- break;
-
- case TIR_S_C_STA_UB:
- /* stack unsigned byte
- arg: by value
-
- stack byte value. */
- _bfd_vms_push (abfd, (uquad) *ptr++, -1);
- break;
-
- case TIR_S_C_STA_UW:
- /* stack unsigned short word
- arg: sh value
-
- stack 16 bit value. */
- _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
- ptr += 2;
- break;
-
- case TIR_S_C_STA_BFI:
- /* stack byte from image
- arg: none. */
- /* FALLTHRU */
- case TIR_S_C_STA_WFI:
- /* stack byte from image
- arg: none. */
- /* FALLTHRU */
- case TIR_S_C_STA_LFI:
- /* stack byte from image
- arg: none. */
- (*_bfd_error_handler) (_("stack-from-image not implemented"));
- return NULL;
-
- case TIR_S_C_STA_EPM:
- /* stack entry point mask
- arg: cs symbol name
-
- stack (unsigned) entry point mask of symbol
- err if symbol is no entry point. */
- {
- char *name;
- vms_symbol_entry *entry;
-
- name = _bfd_vms_save_counted_string (ptr);
- entry = _bfd_vms_enter_symbol (abfd, name);
- if (entry == NULL)
- return NULL;
-
- (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
- _bfd_vms_push (abfd, (uquad) 0, -1);
- ptr += *ptr + 1;
- }
- break;
-
- case TIR_S_C_STA_CKARG:
- /* compare procedure argument
- arg: cs symbol name
- by argument index
- da argument descriptor
-
- compare argument descriptor with symbol argument (ARG$V_PASSMECH)
- and stack TRUE (args match) or FALSE (args dont match) value. */
- (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
- _bfd_vms_push (abfd, (uquad) 1, -1);
- break;
-
- case TIR_S_C_STA_LSY:
- /* stack local symbol value
- arg: sh environment index
- cs symbol name. */
- {
- int envidx;
- char *name;
- vms_symbol_entry *entry;
-
- envidx = bfd_getl16 (ptr);
- ptr += 2;
- name = _bfd_vms_save_counted_string (ptr);
- entry = _bfd_vms_enter_symbol (abfd, name);
- if (entry == NULL)
- return NULL;
- (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
- _bfd_vms_push (abfd, (uquad) 0, -1);
- ptr += *ptr + 1;
- }
- break;
-
- case TIR_S_C_STA_LIT:
- /* stack literal
- arg: by literal index
-
- stack literal. */
- ptr++;
- _bfd_vms_push (abfd, (uquad) 0, -1);
- (*_bfd_error_handler) (_("stack-literal not fully implemented"));
- break;
-
- case TIR_S_C_STA_LEPM:
- /* stack local symbol entry point mask
- arg: sh environment index
- cs symbol name
-
- stack (unsigned) entry point mask of symbol
- err if symbol is no entry point. */
- {
- int envidx;
- char *name;
- vms_symbol_entry *entry;
-
- envidx = bfd_getl16 (ptr);
- ptr += 2;
- name = _bfd_vms_save_counted_string (ptr);
- entry = _bfd_vms_enter_symbol (abfd, name);
- if (entry == NULL)
- return NULL;
- (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
- _bfd_vms_push (abfd, (uquad) 0, -1);
- ptr += *ptr + 1;
- }
- break;
-
- default:
- (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]);
- return NULL;
- break;
- }
-
- return ptr;
-}
-
-static const char *
-tir_cmd_name (int cmd)
-{
- switch (cmd)
- {
- case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB";
- case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW";
- case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL";
- case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS";
- case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB";
- case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW";
- case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB";
- case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW";
- case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR";
- case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV";
- case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT";
- case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF";
- case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT";
- case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH";
- case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH";
- case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC";
- case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC";
- case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL";
-
- default:
- /* These strings have not been added yet. */
- abort ();
- }
-}
-
-/* tir_sto
-
- vax store commands
-
- handle sto_xxx commands in tir section
- ptr points to data area in record
-
- See table 7-4 of the VAX/VMS linker manual. */
-
-static unsigned char *
-tir_sto (bfd * abfd, unsigned char *ptr)
-{
- unsigned long dummy;
- int size;
- int psect;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
-#endif
-
- switch (*ptr++)
- {
- case TIR_S_C_STO_SB:
- /* Store signed byte: pop stack, write byte
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_SW:
- /* Store signed word: pop stack, write word
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_LW:
- /* Store longword: pop stack, write longword
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- image_write_l (abfd, dummy & 0xffffffff); /* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_BD:
- /* Store byte displaced: pop stack, sub lc+1, write byte
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- dummy -= ((PRIV (sections)[psect])->vma + 1);
- image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_WD:
- /* Store word displaced: pop stack, sub lc+2, write word
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- dummy -= ((PRIV (sections)[psect])->vma + 2);
- image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_LD:
- /* Store long displaced: pop stack, sub lc+4, write long
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- dummy -= ((PRIV (sections)[psect])->vma + 4);
- image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_LI:
- /* Store short literal: pop stack, write byte
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
- break;
-
- case TIR_S_C_STO_PIDR:
- /* Store position independent data reference: pop stack, write longword
- arg: none.
- FIXME: incomplete ! */
- dummy = _bfd_vms_pop (abfd, &psect);
- image_write_l (abfd, dummy & 0xffffffff);
- break;
-
- case TIR_S_C_STO_PICR:
- /* Store position independent code reference: pop stack, write longword
- arg: none.
- FIXME: incomplete ! */
- dummy = _bfd_vms_pop (abfd, &psect);
- image_write_b (abfd, 0x9f);
- image_write_l (abfd, dummy & 0xffffffff);
- break;
-
- case TIR_S_C_STO_RIVB:
- /* Store repeated immediate variable bytes
- 1-byte count n field followed by n bytes of data
- pop stack, write n bytes <stack> times. */
- size = *ptr++;
- dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
- while (dummy-- > 0L)
- image_dump (abfd, ptr, size, 0);
- ptr += size;
- break;
-
- case TIR_S_C_STO_B:
- /* Store byte from top longword. */
- dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
- image_write_b (abfd, dummy & 0xff);
- break;
-
- case TIR_S_C_STO_W:
- /* Store word from top longword. */
- dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
- image_write_w (abfd, dummy & 0xffff);
- break;
-
- case TIR_S_C_STO_RB:
- /* Store repeated byte from top longword. */
- size = (unsigned long) _bfd_vms_pop (abfd, NULL);
- dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
- while (size-- > 0)
- image_write_b (abfd, dummy & 0xff);
- break;
-
- case TIR_S_C_STO_RW:
- /* Store repeated word from top longword. */
- size = (unsigned long) _bfd_vms_pop (abfd, NULL);
- dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
- while (size-- > 0)
- image_write_w (abfd, dummy & 0xffff);
- break;
-
- case TIR_S_C_STO_RSB:
- case TIR_S_C_STO_RSW:
- case TIR_S_C_STO_RL:
- case TIR_S_C_STO_VPS:
- case TIR_S_C_STO_USB:
- case TIR_S_C_STO_USW:
- case TIR_S_C_STO_RUB:
- case TIR_S_C_STO_RUW:
- case TIR_S_C_STO_PIRR:
- (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1]));
- break;
-
- default:
- (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]);
- break;
- }
-
- return ptr;
-}
-
-/* Stack operator commands
- All 32 bit signed arithmetic
- All word just like a stack calculator
- Arguments are popped from stack, results are pushed on stack
-
- See table 7-5 of the VAX/VMS linker manual. */
-
-static unsigned char *
-tir_opr (bfd * abfd, unsigned char *ptr)
-{
- long op1, op2;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
-#endif
-
- /* Operation. */
- switch (*ptr++)
- {
- case TIR_S_C_OPR_NOP: /* No-op. */
- break;
-
- case TIR_S_C_OPR_ADD: /* Add. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
- break;
-
- case TIR_S_C_OPR_SUB: /* Subtract. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
- break;
-
- case TIR_S_C_OPR_MUL: /* Multiply. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
- break;
-
- case TIR_S_C_OPR_DIV: /* Divide. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- if (op2 == 0)
- _bfd_vms_push (abfd, (uquad) 0, -1);
- else
- _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
- break;
-
- case TIR_S_C_OPR_AND: /* Logical AND. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
- break;
-
- case TIR_S_C_OPR_IOR: /* Logical inclusive OR. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
- break;
-
- case TIR_S_C_OPR_EOR: /* Logical exclusive OR. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
- break;
-
- case TIR_S_C_OPR_NEG: /* Negate. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (-op1), -1);
- break;
-
- case TIR_S_C_OPR_COM: /* Complement. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
- break;
-
- case TIR_S_C_OPR_INSV: /* Insert field. */
- (void) _bfd_vms_pop (abfd, NULL);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- case TIR_S_C_OPR_ASH: /* Arithmetic shift. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- if (HIGHBIT (op1)) /* Shift right. */
- op2 >>= op1;
- else /* Shift left. */
- op2 <<= op1;
- _bfd_vms_push (abfd, (uquad) op2, -1);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- case TIR_S_C_OPR_USH: /* Unsigned shift. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- if (HIGHBIT (op1)) /* Shift right. */
- op2 >>= op1;
- else /* Shift left. */
- op2 <<= op1;
- _bfd_vms_push (abfd, (uquad) op2, -1);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- case TIR_S_C_OPR_ROT: /* Rotate. */
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- op2 = (long) _bfd_vms_pop (abfd, NULL);
- if (HIGHBIT (0)) /* Shift right. */
- op2 >>= op1;
- else /* Shift left. */
- op2 <<= op1;
- _bfd_vms_push (abfd, (uquad) op2, -1);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- case TIR_S_C_OPR_SEL: /* Select. */
- if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
- (void) _bfd_vms_pop (abfd, NULL);
- else
- {
- op1 = (long) _bfd_vms_pop (abfd, NULL);
- (void) _bfd_vms_pop (abfd, NULL);
- _bfd_vms_push (abfd, (uquad) op1, -1);
- }
- break;
-
- case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */
- case TIR_S_C_OPR_DFLIT: /* Define a literal. */
- (*_bfd_error_handler) (_("%s: not supported"),
- tir_cmd_name (ptr[-1]));
- break;
-
- default:
- (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]);
- break;
- }
-
- return ptr;
-}
-
-/* Control commands
-
- See table 7-6 of the VAX/VMS linker manual. */
-
-static unsigned char *
-tir_ctl (bfd * abfd, unsigned char *ptr)
-{
- unsigned long dummy;
- int psect;
-
-#if VMS_DEBUG
- _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
-#endif
-
- switch (*ptr++)
- {
- case TIR_S_C_CTL_SETRB:
- /* Set relocation base: pop stack, set image location counter
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- if ((unsigned int) psect >= PRIV (section_count))
- alloc_section (abfd, psect);
- image_set_ptr (abfd, psect, (uquad) dummy);
- break;
-
- case TIR_S_C_CTL_AUGRB:
- /* Augment relocation base: increment image location counter by offset
- arg: lw offset value. */
- dummy = bfd_getl32 (ptr);
- image_inc_ptr (abfd, (uquad) dummy);
- break;
-
- case TIR_S_C_CTL_DFLOC:
- /* Define location: pop index, save location counter under index
- arg: none. */
- dummy = _bfd_vms_pop (abfd, NULL);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- case TIR_S_C_CTL_STLOC:
- /* Set location: pop index, restore location counter from index
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- case TIR_S_C_CTL_STKDL:
- /* Stack defined location: pop index, push location counter from index
- arg: none. */
- dummy = _bfd_vms_pop (abfd, &psect);
- (*_bfd_error_handler) (_("%s: not fully implemented"),
- tir_cmd_name (ptr[-1]));
- break;
-
- default:
- (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]);
- break;
- }
- return ptr;
-}
-
-/* Handle command from TIR section. */
-
-static unsigned char *
-tir_cmd (bfd * abfd, unsigned char *ptr)
-{
- static const struct
- {
- int mincod;
- int maxcod;
- unsigned char * (*explain) (bfd *, unsigned char *);
- }
- tir_table[] =
- {
- { 0, TIR_S_C_MAXSTACOD, tir_sta },
- { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto },
- { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr },
- { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl },
- { -1, -1, NULL }
- };
- int i = 0;
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- if (*ptr & 0x80)
- {
- /* Store immediate. */
- i = 128 - (*ptr++ & 0x7f);
- image_dump (abfd, ptr, i, 0);
- ptr += i;
- }
- else
- {
- while (tir_table[i].mincod >= 0)
- {
- if ( (tir_table[i].mincod <= *ptr)
- && (*ptr <= tir_table[i].maxcod))
- {
- ptr = tir_table[i].explain (abfd, ptr);
- break;
- }
- i++;
- }
- if (tir_table[i].mincod < 0)
- {
- (*_bfd_error_handler) (_("obj code %d not found"), *ptr);
- ptr = 0;
- }
- }
-
- return ptr;
-}
-
-/* Handle command from ETIR section. */
-
-static int
-etir_cmd (bfd *abfd, int cmd, unsigned char *ptr, int *quarter_relocs)
-{
- static const struct
- {
- int mincod;
- int maxcod;
- bfd_boolean (*explain) (bfd *, int, unsigned char *, int *);
- }
- etir_table[] =
- {
- { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
- { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
- { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
- { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
- { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
- { -1, -1, NULL }
- };
-
- int i = 0;
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "etir_cmd: %s(%d)\n", cmd_name (cmd), cmd);
- _bfd_hexdump (8, ptr, 16, (long) ptr);
-#endif
-
- while (etir_table[i].mincod >= 0)
- {
- if ( (etir_table[i].mincod <= cmd)
- && (cmd <= etir_table[i].maxcod))
- {
- if (!etir_table[i].explain (abfd, cmd, ptr, quarter_relocs))
- return -1;
- break;
- }
- i++;
- }
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "etir_cmd: result = 0\n");
-#endif
- return 0;
-}
-
-/* Text Information and Relocation Records (OBJ$C_TIR)
- handle tir record. */
-
-static int
-analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
-{
- unsigned char *maxptr;
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
-#endif
-
- maxptr = ptr + length;
-
- while (ptr < maxptr)
- {
- ptr = tir_cmd (abfd, ptr);
- if (ptr == 0)
- return -1;
- }
-
- return 0;
-}
-
-/* Text Information and Relocation Records (EOBJ$C_ETIR)
- handle etir record. */
-
-static int
-analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
-{
- unsigned char *maxptr = ptr + length;
- /* Relocations are made of 1, 2 or 4 ETIR commands.
- We therefore count them using quarters. */
- int quarter_relocs = 0;
- int result = 0;
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
-#endif
-
- while (ptr < maxptr)
- {
- int cmd = bfd_getl16 (ptr);
- int cmd_length = bfd_getl16 (ptr + 2);
- result = etir_cmd (abfd, cmd, ptr + 4, &quarter_relocs);
- if (result != 0)
- break;
-
- /* If we have a relocation, we record its length to size
- future buffers and bump the reloc count of the section. */
- if (quarter_relocs)
- {
- vms_section_data (PRIV (image_section))->reloc_size += cmd_length;
- abfd->flags |= HAS_RELOC;
-
- if (quarter_relocs == 4)
- {
- PRIV (image_section)->reloc_count++;
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "-> reloc %d at 0x%x\n",
- PRIV (image_section)->reloc_count-1,
- ptr - (maxptr - length));
-#endif
-
- quarter_relocs = 0;
- }
- else if (quarter_relocs > 4)
- {
-
-#if VMS_DEBUG
- _bfd_vms_debug (4, "Reloc count error (%d) in section %s\n",
- PRIV (image_section)->reloc_count,
- PRIV (image_section)->name);
-#endif
-
- quarter_relocs = 0;
- }
- }
-
- /* If we have a Store Immediate, we reserve space for the
- count argument. */
- else if (cmd == ETIR_S_C_STO_IMM)
- vms_section_data (PRIV (image_section))->reloc_size
- += ETIR_S_C_HEADER_SIZE + 4;
-
- ptr += cmd_length;
- }
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "analyze_etir: result = %d\n", result);
-#endif
-
- return result;
-}
-
-/* Process ETIR record
- Return 0 on success, -1 on error. */
-
-int
-_bfd_vms_slurp_tir (bfd * abfd, int objtype)
-{
- int result;
-
-#if VMS_DEBUG
- _bfd_vms_debug (2, "TIR/ETIR\n");
-#endif
-
- switch (objtype)
- {
- case EOBJ_S_C_ETIR:
- PRIV (vms_rec) += ETIR_S_C_HEADER_SIZE;
- PRIV (rec_size) -= ETIR_S_C_HEADER_SIZE;
- result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
- break;
- case OBJ_S_C_TIR:
- PRIV (vms_rec) += 1; /* Skip type. */
- PRIV (rec_size) -= 1;
- result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
- break;
- default:
- result = -1;
- break;
- }
-
- return result;
-}
-
- /* Slurp relocs from ETIR sections and (temporarily) save them
- in the per-section reloc buffer. */
-
-int
-_bfd_vms_slurp_relocs (bfd *abfd)
-{
- struct vms_section_data_struct *vsd;
- unsigned char *begin = PRIV (vms_rec) + 4;
- unsigned char *end = PRIV (vms_rec) + PRIV (rec_size);
- unsigned char *ptr;
- int cmd, length, slurped_length;
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: %d bytes\n", PRIV (rec_size));
-#endif
-
- for (ptr = begin; ptr < end; ptr += length)
- {
- cmd = bfd_getl16 (ptr);
- length = bfd_getl16 (ptr + 2);
- slurped_length = length;
-
- switch (cmd)
- {
- case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
- /* This one is special as it is both part of the section header
- and of the ALPHA_R_REFLONG and ALPHA_R_REFQUAD relocations. */
- if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_SETRB)
- {
- int psect = bfd_getl32 (ptr + ETIR_S_C_HEADER_SIZE);
- PRIV (image_section) = PRIV (sections)[psect];
- continue;
- }
-
- case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
- /* ALPHA_R_REFQUAD und_section, step 1 */
- break;
-
- case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG und_section, step 2 */
- /* ALPHA_R_REFLONG abs_section, step 1 */
- /* This one is special as it is both part of the section header
- and of the ALPHA_R_REFLONG relocation. */
- if (bfd_getl16 (ptr + length) == ETIR_S_C_CTL_DFLOC)
- {
- PRIV (image_section) = PRIV (dst_section);
- continue;
- }
-
- case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD und_section, step 2 */
- /* ALPHA_R_REFQUAD abs_section, step 1 */
-
- case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
- /* ALPHA_R_REFLONG abs_section, step 2 */
- /* ALPHA_R_REFLONG others, step 2 */
-
- case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
- /* ALPHA_R_REFQUAD abs_section, step 2 */
-
- case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
-
- case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
- /* ALPHA_R_REFQUAD und_section, step 3 */
-
- case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */
- case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
- case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
- case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
- case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
- case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
- case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
- case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
- break;
-
- case ETIR_S_C_STO_IMM:
- if (PRIV (image_section)->reloc_count == 0)
- continue;
- /* This is not a relocation, but we nevertheless slurp the
- count argument. We'll use it to compute the addresses
- of the relocations. */
- slurped_length = ETIR_S_C_HEADER_SIZE + 4;
- break;
-
- default:
- continue;
- }
-
- vsd = vms_section_data (PRIV (image_section));
- memcpy (vsd->reloc_stream + vsd->reloc_offset, ptr, slurped_length);
- vsd->reloc_offset += slurped_length;
- if (vsd->reloc_offset > vsd->reloc_size)
- {
- (*_bfd_error_handler) (_("Reloc size error in section %s"),
- PRIV (image_section)->name);
- return -1;
- }
- }
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "_bfd_vms_slurp_relocs: result = 0\n");
-#endif
-
- return 0;
-}
-
-/* Decode relocs from the reloc buffer of the specified section
- and internalize them in the specified buffer. */
-
-int
-_bfd_vms_decode_relocs (bfd *abfd, arelent *relocs, asection *section,
- asymbol **symbols ATTRIBUTE_UNUSED)
-{
- int saved_cmd, saved_sym_offset, saved_sec_offset, saved_addend_offset;
- int cmd, sym_offset, sec_offset, address_offset, addend_offset;
- struct vms_section_data_struct *vsd = vms_section_data (section);
- bfd_reloc_code_real_type reloc_code;
- vms_symbol_entry *entry;
- bfd_vma vaddr = 0;
- unsigned char *begin = vsd->reloc_stream;
- unsigned char *end = vsd->reloc_stream + vsd->reloc_size;
- unsigned char *ptr, *arg_ptr;
- const char *name;
- int length;
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "_bfd_vms_decode_relocs: %d bytes\n", vsd->reloc_size);
-#endif
-
- #define PUSH_CMD() \
- { \
- saved_cmd = cmd; \
- saved_sym_offset = sym_offset - length; \
- saved_sec_offset = sec_offset - length; \
- saved_addend_offset = addend_offset - length; \
- continue; \
- }
-
- #define POP_CMD() \
- { \
- cmd = saved_cmd; \
- saved_cmd = ETIR_S_C_MAXSTCCOD + 1; \
- sym_offset = saved_sym_offset; \
- sec_offset = saved_sec_offset; \
- addend_offset= saved_addend_offset; \
- }
-
- #define CMD_PUSHED (saved_cmd != ETIR_S_C_MAXSTCCOD + 1)
-
- #define NO_OFFSET -128
-
- saved_cmd = ETIR_S_C_MAXSTCCOD + 1;
- saved_sym_offset = NO_OFFSET;
- saved_sec_offset = NO_OFFSET;
- saved_addend_offset = NO_OFFSET;
-
- for (ptr = begin; ptr < end; ptr += length)
- {
- cmd = bfd_getl16 (ptr);
- length = bfd_getl16 (ptr + 2);
-
- arg_ptr = ptr + ETIR_S_C_HEADER_SIZE;
- sym_offset = NO_OFFSET;
- sec_offset = NO_OFFSET;
- address_offset = NO_OFFSET;
- addend_offset = NO_OFFSET;
-
- switch (cmd)
- {
- case ETIR_S_C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
- /* ALPHA_R_REFQUAD und_section, step 1 */
- sym_offset = 0;
- PUSH_CMD ()
-
- case ETIR_S_C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
- sec_offset = 0;
- addend_offset = 4;
- PUSH_CMD ()
-
- case ETIR_S_C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
- /* ALPHA_R_REFLONG und_section, step 2 */
- if (CMD_PUSHED)
- {
- POP_CMD ()
- if (cmd != ETIR_S_C_STA_GBL)
- {
- (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
- cmd_name (cmd),
- cmd_name (ETIR_S_C_STA_LW));
- return 0;
- }
- cmd = ETIR_S_C_STA_LW;
- }
- addend_offset = 0;
- PUSH_CMD ()
-
- case ETIR_S_C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
- /* ALPHA_R_REFQUAD und_section, step 2 */
- if (CMD_PUSHED)
- {
- POP_CMD ()
- if (cmd != ETIR_S_C_STA_GBL)
- {
- (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
- cmd_name (cmd),
- cmd_name (ETIR_S_C_STA_QW));
- return 0;
- }
- cmd = ETIR_S_C_STA_QW;
- }
- addend_offset = 0;
- PUSH_CMD ()
-
- case ETIR_S_C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
- /* ALPHA_R_REFLONG abs_section, step 2 */
- /* ALPHA_R_REFLONG others, step 2 */
- POP_CMD ()
- if (cmd != ETIR_S_C_OPR_ADD
- && cmd != ETIR_S_C_STA_LW
- && cmd != ETIR_S_C_STA_PQ)
- {
- (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
- cmd_name (cmd), cmd_name (ETIR_S_C_STO_LW));
- return 0;
- }
- reloc_code = BFD_RELOC_32;
- break;
-
- case ETIR_S_C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
- /* ALPHA_R_REFQUAD abs_section, step 2 */
- POP_CMD ()
- if (cmd != ETIR_S_C_OPR_ADD && cmd != ETIR_S_C_STA_QW)
- {
- (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
- cmd_name (cmd), cmd_name (ETIR_S_C_STO_QW));
- return 0;
- }
- reloc_code = BFD_RELOC_64;
- break;
-
- case ETIR_S_C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
- POP_CMD ()
- if (cmd != ETIR_S_C_STA_PQ)
- {
- (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
- cmd_name (cmd), cmd_name (ETIR_S_C_STO_OFF));
- return 0;
- }
- reloc_code = BFD_RELOC_64;
- break;
-
- case ETIR_S_C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
- /* ALPHA_R_REFQUAD und_section, step 3 */
- POP_CMD ()
- if (cmd != ETIR_S_C_STA_LW && cmd != ETIR_S_C_STA_QW)
- {
- (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
- cmd_name (cmd), cmd_name (ETIR_S_C_OPR_ADD));
- return 0;
- }
- cmd = ETIR_S_C_OPR_ADD;
- PUSH_CMD ()
-
- case ETIR_S_C_STO_CA: /* ALPHA_R_CODEADDR */
- reloc_code = BFD_RELOC_ALPHA_CODEADDR;
- sym_offset = 0;
- break;
-
- case ETIR_S_C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
- reloc_code = BFD_RELOC_64;
- sym_offset = 0;
- break;
-
- case ETIR_S_C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
- reloc_code = BFD_RELOC_32;
- sym_offset = 0;
- break;
-
- case ETIR_S_C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
- reloc_code = BFD_RELOC_ALPHA_LINKAGE;
- sym_offset = 4;
- break;
-
- case ETIR_S_C_STC_NOP_GBL: /* ALPHA_R_NOP */
- reloc_code = BFD_RELOC_ALPHA_NOP;
- goto call_reloc;
-
- case ETIR_S_C_STC_BSR_GBL: /* ALPHA_R_BSR */
- reloc_code = BFD_RELOC_ALPHA_BSR;
- goto call_reloc;
-
- case ETIR_S_C_STC_LDA_GBL: /* ALPHA_R_LDA */
- reloc_code = BFD_RELOC_ALPHA_LDA;
- goto call_reloc;
-
- case ETIR_S_C_STC_BOH_GBL: /* ALPHA_R_BOH */
- reloc_code = BFD_RELOC_ALPHA_BOH;
- goto call_reloc;
-
- call_reloc:
- sym_offset = 32;
- address_offset = 8;
- addend_offset = 24;
- break;
-
- case ETIR_S_C_STO_IMM:
- vaddr += bfd_getl32 (arg_ptr);
- length = ETIR_S_C_HEADER_SIZE + 4;
- continue;
-
- default:
- continue;
- }
-
- relocs->howto = bfd_reloc_type_lookup (abfd, reloc_code);
-
- if (sym_offset > NO_OFFSET)
- {
- name = _bfd_vms_save_counted_string (arg_ptr + sym_offset);
- entry = (vms_symbol_entry *)
- bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
- if (entry == NULL)
- {
- (*_bfd_error_handler) (_("Unknown symbol %s in command %s"),
- name, cmd_name (cmd));
- relocs->sym_ptr_ptr = NULL;
- }
- else
- /* ??? This is a hack. We should point in 'symbols'. */
- relocs->sym_ptr_ptr = &entry->symbol;
- }
- else if (sec_offset > NO_OFFSET)
- relocs->sym_ptr_ptr
- = PRIV (sections)[bfd_getl32 (arg_ptr + sec_offset)]->symbol_ptr_ptr;
- else
- relocs->sym_ptr_ptr = NULL;
-
- if (address_offset > NO_OFFSET)
- relocs->address = bfd_getl64 (arg_ptr + address_offset);
- else
- relocs->address = vaddr;
-
- if (addend_offset > NO_OFFSET)
- relocs->addend = bfd_getl64 (arg_ptr + addend_offset);
- else
- relocs->addend = 0;
-
- vaddr += bfd_get_reloc_size (relocs->howto);
- relocs++;
- }
-
- #undef PUSH_CMD
- #undef POP_CMD
- #undef NO_OFFSET
-
-#if VMS_DEBUG
- _bfd_vms_debug (3, "_bfd_vms_decode_relocs: result = 0\n");
-#endif
-
- return 0;
-}
-
-/* Process LNK record
- Return 0 on success, -1 on error
-
- Not implemented yet. */
-
-int
-_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
- int objtype ATTRIBUTE_UNUSED)
-{
-#if VMS_DEBUG
- _bfd_vms_debug (2, "LNK\n");
-#endif
-
- return 0;
-}
-
-/* WRITE ETIR SECTION
-
- This is still under construction and therefore not documented. */
-
-static void start_etir_record (bfd *abfd, int sec_index, uquad offset,
- bfd_boolean justoffset);
-static void start_first_etbt_record (bfd *abfd);
-static void start_another_etbt_record (bfd *abfd);
-static void sto_imm (bfd *abfd, bfd_size_type, unsigned char *, bfd_vma vaddr,
- int sec_index, const char *name);
-static void end_etir_record (bfd *abfd);
-static void etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr,
- int checklen);
-
-/* Start ETIR record for section #index at virtual addr offset. */
-
-static void
-start_etir_record (bfd * abfd, int sec_index, uquad offset, bfd_boolean justoffset)
-{
- if (!justoffset)
- {
- /* One ETIR per section. */
- _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
- _bfd_vms_output_push (abfd);
- }
-
- /* Push start offset. */
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
- _bfd_vms_output_long (abfd, (unsigned long) sec_index);
- _bfd_vms_output_quad (abfd, (uquad) offset);
- _bfd_vms_output_flush (abfd);
-
- /* Start = pop (). */
- _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);
- _bfd_vms_output_flush (abfd);
-}
-
-static void
-end_etir_record (bfd * abfd)
-{
- _bfd_vms_output_pop (abfd);
- _bfd_vms_output_end (abfd);
-}
-
-/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
- address VADDR in section specified by SEC_INDEX and NAME. */
-
-static void
-sto_imm (bfd *abfd, bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr,
- int sec_index, const char *name)
-{
- bfd_size_type size;
-
-#if VMS_DEBUG
- _bfd_vms_debug (8, "sto_imm %d bytes\n", ssize);
- _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
-#endif
-
- while (ssize > 0)
- {
- /* Try all the rest. */
- size = ssize;
-
- if (_bfd_vms_output_check (abfd, size) < 0)
- {
- /* Doesn't fit, split ! */
- end_etir_record (abfd);
-
- if (name [0] && name[1] == 'v' && !strcmp (name, ".vmsdebug"))
- start_another_etbt_record (abfd);
- else
- start_etir_record (abfd, sec_index, vaddr, FALSE);
-
- size = _bfd_vms_output_check (abfd, 0); /* get max size */
- if (size > ssize) /* more than what's left ? */
- size = ssize;
- }
-
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
- _bfd_vms_output_long (abfd, (unsigned long) (size));
- _bfd_vms_output_dump (abfd, cptr, size);
- _bfd_vms_output_flush (abfd);
-
-#if VMS_DEBUG
- _bfd_vms_debug (10, "dumped %d bytes\n", size);
- _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
-#endif
-
- vaddr += size;
- cptr += size;
- ssize -= size;
- }
-}
-
-/* Start ETBT record for section #index at virtual addr offset. */
-
-static void
-start_first_etbt_record (bfd *abfd)
-{
- _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1);
- _bfd_vms_output_push (abfd);
-
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1); /* push start offset */
- _bfd_vms_output_long (abfd, (unsigned long) 0);
- _bfd_vms_output_flush (abfd);
-
- _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_DFLOC, -1); /* start = pop() */
- _bfd_vms_output_flush (abfd);
-}
-
-static void
-start_another_etbt_record (bfd *abfd)
-{
- _bfd_vms_output_begin (abfd, EOBJ_S_C_ETBT, -1);
- _bfd_vms_output_push (abfd);
-}
-
-static void
-etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
-{
- if (_bfd_vms_output_check (abfd, checklen) < 0)
- {
- end_etir_record (abfd);
- if (section->name[0] && section->name[1] == 'v'
- && !strcmp (section->name, ".vmsdebug"))
- start_another_etbt_record (abfd);
- else
- start_etir_record (abfd, section->index, vaddr, FALSE);
- }
-}
-
-/* Return whether RELOC must be deferred till the end. */
-
-static int
-defer_reloc_p (arelent *reloc)
-{
- switch (reloc->howto->type)
- {
- case ALPHA_R_NOP:
- case ALPHA_R_LDA:
- case ALPHA_R_BSR:
- case ALPHA_R_BOH:
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* Write section contents for bfd abfd. */
-
-int
-_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
-{
- asection *section;
-
-#if VMS_DEBUG
- _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
-#endif
-
- _bfd_vms_output_alignment (abfd, 4);
-
- PRIV (vms_linkage_index) = 1;
-
- for (section = abfd->sections; section; section = section->next)
- {
-#if VMS_DEBUG
- _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
- section->index, section->name,
- (int) (section->size));
-#endif
-
- if (!(section->flags & SEC_HAS_CONTENTS)
- || bfd_is_com_section (section))
- continue;
-
- if (!section->contents)
- {
- bfd_set_error (bfd_error_no_contents);
- return -1;
- }
-
- if (section->name[0]
- && section->name[1] == 'v'
- && !strcmp (section->name, ".vmsdebug"))
- start_first_etbt_record (abfd);
- else
- start_etir_record (abfd, section->index, 0, FALSE);
-
- if (section->flags & SEC_RELOC)
- {
- bfd_vma curr_addr = 0;
- unsigned char *curr_data = section->contents;
- bfd_size_type size;
- int pass2_needed = 0;
- int pass2_in_progress = 0;
- unsigned int irel;
-
- if (section->reloc_count <= 0)
- (*_bfd_error_handler)
- (_("SEC_RELOC with no relocs in section %s"), section->name);
-
-#if VMS_DEBUG
- else
- {
- int i = section->reloc_count;
- arelent **rptr = section->orelocation;
- _bfd_vms_debug (4, "%d relocations:\n", i);
- while (i-- > 0)
- {
- _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, "
- "addr %08lx, off %08lx, len %d: %s\n",
- (*(*rptr)->sym_ptr_ptr)->name,
- (*(*rptr)->sym_ptr_ptr)->section->name,
- (long) (*(*rptr)->sym_ptr_ptr)->value,
- (*rptr)->address, (*rptr)->addend,
- bfd_get_reloc_size ((*rptr)->howto),
- ( *rptr)->howto->name);
- rptr++;
- }
- }
-#endif
-
- new_pass:
- for (irel = 0; irel < section->reloc_count; irel++)
- {
- struct evax_private_udata_struct *udata;
- arelent *rptr = section->orelocation [irel];
- bfd_vma addr = rptr->address;
- asymbol *sym = *rptr->sym_ptr_ptr;
- asection *sec = sym->section;
- int defer = defer_reloc_p (rptr);
- unsigned int slen;
- char *hash;
-
- if (pass2_in_progress)
- {
- /* Non-deferred relocs have already been output. */
- if (!defer)
- continue;
- }
- else
- {
- /* Deferred relocs must be output at the very end. */
- if (defer)
- {
- pass2_needed = 1;
- continue;
- }
-
- /* Regular relocs are intertwined with binary data. */
- if (curr_addr > addr)
- (*_bfd_error_handler) (_("Size error in section %s"),
- section->name);
- size = addr - curr_addr;
- sto_imm (abfd, size, curr_data, curr_addr,
- section->index, section->name);
- curr_data += size;
- curr_addr += size;
- }
-
- size = bfd_get_reloc_size (rptr->howto);
-
- switch (rptr->howto->type)
- {
- case ALPHA_R_IGNORE:
- break;
-
- case ALPHA_R_REFLONG:
- if (bfd_is_und_section (sym->section))
- {
- bfd_vma addend = rptr->addend;
- slen = strlen ((char *) sym->name);
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ_S_C_SYMSIZ);
- etir_output_check (abfd, section, curr_addr, slen);
- if (addend)
- {
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
- _bfd_vms_output_counted (abfd, hash);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
- _bfd_vms_output_long (abfd, (unsigned long) addend);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
- _bfd_vms_output_flush (abfd);
- }
- else
- {
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL_LW, -1);
- _bfd_vms_output_counted (abfd, hash);
- _bfd_vms_output_flush (abfd);
- }
- }
- else if (bfd_is_abs_section (sym->section))
- {
- etir_output_check (abfd, section, curr_addr, 16);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_LW, -1);
- _bfd_vms_output_long (abfd, (unsigned long) sym->value);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
- _bfd_vms_output_flush (abfd);
- }
- else
- {
- etir_output_check (abfd, section, curr_addr, 32);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
- _bfd_vms_output_long (abfd, (unsigned long) sec->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->addend
- + (uquad) sym->value);
- _bfd_vms_output_flush (abfd);
- /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
- says that we should have a ETIR_S_C_STO_OFF here.
- But the relocation would not be BFD_RELOC_32 then.
- This case is very likely unreachable. */
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_LW, -1);
- _bfd_vms_output_flush (abfd);
- }
- break;
-
- case ALPHA_R_REFQUAD:
- if (bfd_is_und_section (sym->section))
- {
- bfd_vma addend = rptr->addend;
- slen = strlen ((char *) sym->name);
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ_S_C_SYMSIZ);
- etir_output_check (abfd, section, curr_addr, slen);
- if (addend)
- {
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_GBL, -1);
- _bfd_vms_output_counted (abfd, hash);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1);
- _bfd_vms_output_quad (abfd, (uquad) addend);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_OPR_ADD, -1);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
- _bfd_vms_output_flush (abfd);
- }
- else
- {
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_GBL, -1);
- _bfd_vms_output_counted (abfd, hash);
- _bfd_vms_output_flush (abfd);
- }
- }
- else if (bfd_is_abs_section (sym->section))
- {
- etir_output_check (abfd, section, curr_addr, 16);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_QW, -1);
- _bfd_vms_output_quad (abfd, (uquad) sym->value);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_QW, -1);
- _bfd_vms_output_flush (abfd);
- }
- else
- {
- etir_output_check (abfd, section, curr_addr, 32);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
- _bfd_vms_output_long (abfd, (unsigned long) sec->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->addend
- + (uquad) sym->value);
- _bfd_vms_output_flush (abfd);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_OFF, -1);
- _bfd_vms_output_flush (abfd);
- }
- break;
-
- case ALPHA_R_HINT:
- sto_imm (abfd, size, curr_data, curr_addr,
- section->index, section->name);
- break;
-
- case ALPHA_R_LINKAGE:
- etir_output_check (abfd, section, curr_addr, 64);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LP_PSB, -1);
- _bfd_vms_output_long
- (abfd, (unsigned long) PRIV (vms_linkage_index));
- PRIV (vms_linkage_index) += 2;
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ_S_C_SYMSIZ);
- _bfd_vms_output_counted (abfd, hash);
- _bfd_vms_output_byte (abfd, 0);
- _bfd_vms_output_flush (abfd);
- break;
-
- case ALPHA_R_CODEADDR:
- slen = strlen ((char *) sym->name);
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ_S_C_SYMSIZ);
- etir_output_check (abfd, section, curr_addr, slen);
- _bfd_vms_output_begin (abfd, ETIR_S_C_STO_CA, -1);
- _bfd_vms_output_counted (abfd, hash);
- _bfd_vms_output_flush (abfd);
- break;
-
- case ALPHA_R_NOP:
- udata
- = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
- etir_output_check (abfd, section, curr_addr,
- 32 + 1 + strlen (udata->origname));
- _bfd_vms_output_begin (abfd, ETIR_S_C_STC_NOP_GBL, -1);
- _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->enbsym->section->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->address);
- _bfd_vms_output_long (abfd, (unsigned long) 0x47ff041f);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->enbsym->section->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
- _bfd_vms_output_counted
- (abfd, _bfd_vms_length_hash_symbol
- (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
- _bfd_vms_output_flush (abfd);
- break;
-
- case ALPHA_R_BSR:
- (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc"));
- break;
-
- case ALPHA_R_LDA:
- udata
- = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
- etir_output_check (abfd, section, curr_addr,
- 32 + 1 + strlen (udata->origname));
- _bfd_vms_output_begin (abfd, ETIR_S_C_STC_LDA_GBL, -1);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->lkindex + 1);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->enbsym->section->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->address);
- _bfd_vms_output_long (abfd, (unsigned long) 0x237B0000);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->bsym->section->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
- _bfd_vms_output_counted
- (abfd, _bfd_vms_length_hash_symbol
- (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
- _bfd_vms_output_flush (abfd);
- break;
-
- case ALPHA_R_BOH:
- udata
- = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
- etir_output_check (abfd, section, curr_addr,
- 32 + 1 + strlen (udata->origname));
- _bfd_vms_output_begin (abfd, ETIR_S_C_STC_BOH_GBL, -1);
- _bfd_vms_output_long (abfd, (unsigned long) udata->lkindex);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->enbsym->section->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->address);
- _bfd_vms_output_long (abfd, (unsigned long) 0xD3400000);
- _bfd_vms_output_long
- (abfd, (unsigned long) udata->enbsym->section->index);
- _bfd_vms_output_quad (abfd, (uquad) rptr->addend);
- _bfd_vms_output_counted
- (abfd, _bfd_vms_length_hash_symbol
- (abfd, udata->origname, EOBJ_S_C_SYMSIZ));
- _bfd_vms_output_flush (abfd);
- break;
-
- default:
- (*_bfd_error_handler) (_("Unhandled relocation %s"),
- rptr->howto->name);
- break;
- }
-
- curr_data += size;
- curr_addr += size;
- } /* End of relocs loop. */
-
- if (!pass2_in_progress)
- {
- /* Output rest of section. */
- if (curr_addr > section->size)
- (*_bfd_error_handler) (_("Size error in section %s"),
- section->name);
- size = section->size - curr_addr;
- sto_imm (abfd, size, curr_data, curr_addr,
- section->index, section->name);
- curr_data += size;
- curr_addr += size;
-
- if (pass2_needed)
- {
- pass2_in_progress = 1;
- goto new_pass;
- }
- }
- }
-
- else /* (section->flags & SEC_RELOC) */
- sto_imm (abfd, section->size, section->contents, 0,
- section->index, section->name);
-
- end_etir_record (abfd);
- }
-
- _bfd_vms_output_alignment (abfd, 2);
- return 0;
-}