elflink.c
elflink.h
elfxx-target.h
-evax-alpha.c
-evax-egsd.c
-evax-emh.c
-evax-etir.c
-evax-misc.c
-evax.h
format.c
freebsd.h
gen-aout.c
trad-core.c
vaxnetbsd.c
versados.c
+vms.c
+vms.h
+vms-gsd.c
+vms-hdr.c
+vms-misc.c
+vms-tir.c
xcofflink.c
Things-to-lose:
+Thu Jul 2 14:59:42 1998 Klaus Kaempf <kkaempf@rmi.de>
+
+ Merge of vax/vms (read-only) support
+ * configure.com: Support Vax target.
+ * makefile.vms: Support Vax target.
+ * vms.h: Renamed from evax.h, merged vax/vms (read-only) support.
+ * vms.c: Renamed from evax-alpha.c, merged vax/vms (read-only)
+ support.
+ * vms-hdr.c: Renamed from evax-emh.c, merged vax/vms (read-only)
+ support.
+ * vms-gsd.c: Renamed from evax-egsd.c, merged vax/vms (read-only)
+ support.
+ * vms-tir.c: Renamed from evax-etir.c, merged vax/vms (read-only)
+ support.
+ * vms-misc.c: Renamed from evax-misc.c, merged vax/vms (read-only)
+ support.
+ * libbfd.c (real_read): Use unbuffered read on VMS/Vax.
+ * targets.c (bfd_target_ovax_flavour): New flavour.
+ (vms_alpha_vec): Renamed from evax_alpha_vec.
+ (vms_vax_vec): New.
+ (target_vector): Update accordingly.
+ * config.bfd (alpha*-*-*vms*): Use vms_alpha_vec, not
+ evax_alpha_vec.
+ (vax*-*-*vms*): New target.
+ * Makefile.am: Update for renamed files. Rebuild dependencies.
+ * bfd-in2.h: Rebuild.
+ * configure.in, Makefile.in, aclocal.m4: Rebuild.
+
+Thu Jul 2 13:31:55 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from Matt Semersky <matts@scd.hp.com>:
+ * linker.c (_bfd_generic_final_link): Force a trailing NULL
+ pointer on abfd->outsymbols.
+ (generic_add_output_symbol): Handle NULL sym parameter.
+
Wed Jul 1 17:05:53 1998 Nick Clifton <nickc@cygnus.com>
* elf.c (copy_private_bfd_data): Add support for changing VMA or
targ_selvecs=ecoffalpha_little_vec
;;
alpha*-*-*vms*)
- targ_defvec=evax_alpha_vec
+ targ_defvec=vms_alpha_vec
;;
alpha*-*-*)
targ_defvec=ecoffalpha_little_vec
;;
#endif
+ vax*-*-*vms*)
+ targ_defvec=vms_vax_vec
+ ;;
+
we32k-*-*)
targ_defvec=we32kcoff_vec
;;
exit 1
;;
esac
+
+# If we support any ELF target, then automatically add support for the
+# generic ELF targets. This permits an objdump with some ELF support
+# to be used on an arbitrary ELF file for anything other than
+# relocation information.
+case "${targ_defvec} ${targ_selvecs}" in
+ *bfd_elf64*)
+ targ_selvecs="${targ_selvecs} bfd_elf64_little_generic_vec bfd_elf64_big_generic_vec bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec"
+ ;;
+ *bfd_elf32*)
+ targ_selvecs="${targ_selvecs} bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec"
+ ;;
+esac
+++ /dev/null
-/* evax-alpha.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
- Written by Klaus K"ampf (kkaempf@progis.de)
- of proGIS Softwareentwicklung, Aachen, Germany
-
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "evax.h"
-
-static boolean evax_initialize PARAMS ((bfd *));
-static boolean fill_section_ptr PARAMS ((struct bfd_hash_entry *, PTR));
-static boolean evax_fixup_sections PARAMS ((bfd *));
-static boolean copy_symbols PARAMS ((struct bfd_hash_entry *, PTR));
-static bfd_reloc_status_type reloc_nil
- PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static const struct bfd_target *evax_object_p PARAMS ((bfd *abfd));
-static const struct bfd_target *evax_archive_p PARAMS ((bfd *abfd));
-static boolean evax_mkobject PARAMS ((bfd *abfd));
-static boolean evax_write_object_contents PARAMS ((bfd *abfd));
-static boolean evax_close_and_cleanup PARAMS ((bfd *abfd));
-static boolean evax_bfd_free_cached_info PARAMS ((bfd *abfd));
-static boolean evax_new_section_hook PARAMS ((bfd *abfd, asection *section));
-static boolean evax_get_section_contents
- PARAMS ((bfd *abfd, asection *section, PTR x1, file_ptr x2,
- bfd_size_type x3));
-static boolean evax_get_section_contents_in_window
- PARAMS ((bfd *abfd, asection *section, bfd_window *w, file_ptr offset,
- bfd_size_type count));
-static boolean evax_bfd_copy_private_bfd_data PARAMS ((bfd *src, bfd *dest));
-static boolean evax_bfd_copy_private_section_data
- PARAMS ((bfd *srcbfd, asection *srcsec, bfd *dstbfd, asection *dstsec));
-static boolean evax_bfd_copy_private_symbol_data
- PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym));
-static boolean evax_bfd_print_private_bfd_data
- PARAMS ((bfd *abfd, void *file));
-static char *evax_core_file_failing_command PARAMS ((bfd *abfd));
-static int evax_core_file_failing_signal PARAMS ((bfd *abfd));
-static boolean evax_core_file_matches_executable_p
- PARAMS ((bfd *abfd, bfd *bbfd));
-static boolean evax_slurp_armap PARAMS ((bfd *abfd));
-static boolean evax_slurp_extended_name_table PARAMS ((bfd *abfd));
-static boolean evax_construct_extended_name_table
- PARAMS ((bfd *abfd, char **tabloc, bfd_size_type *tablen,
- const char **name));
-static void evax_truncate_arname
- PARAMS ((bfd *abfd, CONST char *pathname, char *arhdr));
-static boolean evax_write_armap
- PARAMS ((bfd *arch, unsigned int elength, struct orl *map,
- unsigned int orl_count, int stridx));
-static PTR evax_read_ar_hdr PARAMS ((bfd *abfd));
-static bfd *evax_get_elt_at_index PARAMS ((bfd *abfd, symindex index));
-static bfd *evax_openr_next_archived_file PARAMS ((bfd *arch, bfd *prev));
-static boolean evax_update_armap_timestamp PARAMS ((bfd *abfd));
-static int evax_generic_stat_arch_elt PARAMS ((bfd *abfd, struct stat *stat));
-static long evax_get_symtab_upper_bound PARAMS ((bfd *abfd));
-static long evax_get_symtab PARAMS ((bfd *abfd, asymbol **symbols));
-static void evax_print_symbol
- PARAMS ((bfd *abfd, PTR file, asymbol *symbol, bfd_print_symbol_type how));
-static void evax_get_symbol_info
- PARAMS ((bfd *abfd, asymbol *symbol, symbol_info *ret));
-static boolean evax_bfd_is_local_label_name PARAMS ((bfd *abfd, const char *));
-static alent *evax_get_lineno PARAMS ((bfd *abfd, asymbol *symbol));
-static boolean evax_find_nearest_line
- PARAMS ((bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
- const char **file, const char **func, unsigned int *line));
-static asymbol *evax_bfd_make_debug_symbol
- PARAMS ((bfd *abfd, void *ptr, unsigned long size));
-static long evax_read_minisymbols
- PARAMS ((bfd *abfd, boolean dynamic, PTR *minisymsp, unsigned int *sizep));
-static asymbol *evax_minisymbol_to_symbol
- PARAMS ((bfd *abfd, boolean dynamic, const PTR minisym, asymbol *sym));
-static long evax_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
-static long evax_canonicalize_reloc
- PARAMS ((bfd *abfd, asection *srcsec, arelent **location,
- asymbol **symbols));
-static const struct reloc_howto_struct *evax_bfd_reloc_type_lookup
- PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-static boolean evax_set_arch_mach
- PARAMS ((bfd *abfd, enum bfd_architecture arch, unsigned long mach));
-static boolean evax_set_section_contents
- PARAMS ((bfd *abfd, asection *section, PTR location, file_ptr offset,
- bfd_size_type count));
-static int evax_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
-static bfd_byte *evax_bfd_get_relocated_section_contents
- PARAMS ((bfd *abfd, struct bfd_link_info *link_info,
- struct bfd_link_order *link_order, bfd_byte *data,
- boolean relocateable, asymbol **symbols));
-static boolean evax_bfd_relax_section
- PARAMS ((bfd *abfd, asection *section, struct bfd_link_info *link_info,
- boolean *again));
-static boolean evax_bfd_gc_sections
- PARAMS ((bfd *abfd, struct bfd_link_info *link_info));
-static struct bfd_link_hash_table *evax_bfd_link_hash_table_create
- PARAMS ((bfd *abfd));
-static boolean evax_bfd_link_add_symbols
- PARAMS ((bfd *abfd, struct bfd_link_info *link_info));
-static boolean evax_bfd_final_link
- PARAMS ((bfd *abfd, struct bfd_link_info *link_info));
-static boolean evax_bfd_link_split_section
- PARAMS ((bfd *abfd, asection *section));
-static long evax_get_dynamic_symtab_upper_bound PARAMS ((bfd *abfd));
-static long evax_canonicalize_dynamic_symtab
- PARAMS ((bfd *abfd, asymbol **symbols));
-static long evax_get_dynamic_reloc_upper_bound PARAMS ((bfd *abfd));
-static long evax_canonicalize_dynamic_reloc
- PARAMS ((bfd *abfd, arelent **arel, asymbol **symbols));
-static boolean evax_bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
-static boolean evax_bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags));
-
-#define evax_make_empty_symbol _bfd_evax_make_empty_symbol
-\f
-/*===========================================================================*/
-
-const bfd_target evax_alpha_vec =
-{
-
- "evax-alpha", /* name */
- bfd_target_evax_flavour,
- false, /* data byte order is little */
- false, /* header byte order is little */
-
- (HAS_RELOC | HAS_SYMS
- | WP_TEXT | D_PAGED), /* object flags */
- (SEC_ALLOC | SEC_LOAD | SEC_RELOC
- | SEC_READONLY | SEC_CODE | SEC_DATA
- | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */
- 0, /* symbol_leading_char */
- ' ', /* ar_pad_char */
- 15, /* ar_max_namelen */
- bfd_getl64, bfd_getl_signed_64, bfd_putl64,
- bfd_getl32, bfd_getl_signed_32, bfd_putl32,
- bfd_getl16, bfd_getl_signed_16, bfd_putl16,
- bfd_getl64, bfd_getl_signed_64, bfd_putl64,
- bfd_getl32, bfd_getl_signed_32, bfd_putl32,
- bfd_getl16, bfd_getl_signed_16, bfd_putl16,
-
- {_bfd_dummy_target, evax_object_p, /* bfd_check_format */
- evax_archive_p, _bfd_dummy_target},
- {bfd_false, evax_mkobject, /* bfd_set_format */
- _bfd_generic_mkarchive, bfd_false},
- {bfd_false, evax_write_object_contents, /* bfd_write_contents */
- _bfd_write_archive_contents, bfd_false},
-
- BFD_JUMP_TABLE_GENERIC (evax),
- BFD_JUMP_TABLE_COPY (evax),
- BFD_JUMP_TABLE_CORE (evax),
- BFD_JUMP_TABLE_ARCHIVE (evax),
- BFD_JUMP_TABLE_SYMBOLS (evax),
- BFD_JUMP_TABLE_RELOCS (evax),
- BFD_JUMP_TABLE_WRITE (evax),
- BFD_JUMP_TABLE_LINK (evax),
- BFD_JUMP_TABLE_DYNAMIC (evax),
-
- (PTR) 0
-};
-
-\f
-/*===========================================================================*/
-
-/* Initialize private data */
-
-static boolean
-evax_initialize (abfd)
- bfd *abfd;
-{
- int i;
-
- if (abfd->tdata.any != 0)
- return true;
-
- bfd_set_start_address (abfd, (bfd_vma)-1);
-
- abfd->tdata.any = ((struct evax_private_data_struct*)
- bfd_malloc (sizeof (struct evax_private_data_struct)));
- if (abfd->tdata.any == 0)
- return false;
- PRIV(evax_buf) = 0;
- PRIV(buf_size) = 0;
- PRIV(rec_length) = 0;
- PRIV(file_format) = FF_UNKNOWN;
- PRIV(fixup_done) = false;
- PRIV(sections) = NULL;
-
- PRIV(stack) = ((struct stack_struct *)
- bfd_malloc (sizeof (struct stack_struct) * STACKSIZE));
- if (PRIV(stack) == 0)
- {
- evax_init_no_mem1:
- free (abfd->tdata.any);
- abfd->tdata.any = 0;
- return false;
- }
- PRIV(stackptr) = 0;
-
- PRIV(evax_symbol_table) = ((struct bfd_hash_table *)
- bfd_malloc (sizeof (struct bfd_hash_table)));
- if (PRIV(evax_symbol_table) == 0)
- {
- evax_init_no_mem2:
- free (PRIV(stack));
- PRIV(stack) = 0;
- goto evax_init_no_mem1;
- }
-
- if (!bfd_hash_table_init (PRIV(evax_symbol_table), _bfd_evax_hash_newfunc))
- return false;
-
- PRIV(location_stack) = ((struct location_struct *)
- bfd_malloc (sizeof (struct location_struct)
- * LOCATION_SAVE_SIZE));
- if (PRIV(location_stack) == 0)
- {
- evax_init_no_mem3:
- free (PRIV(evax_symbol_table));
- PRIV(evax_symbol_table) = 0;
- goto evax_init_no_mem2;
- }
-
- for (i = 0; i < EVAX_SECTION_COUNT; i++)
- PRIV(evax_section_table)[i] = NULL;
-
- PRIV(output_buf) = (unsigned char *) malloc (MAX_OUTREC_SIZE);
- if (PRIV(output_buf) == 0)
- {
- free (PRIV(location_stack));
- PRIV(location_stack) = 0;
- goto evax_init_no_mem3;
- }
- PRIV(push_level) = 0;
- PRIV(pushed_size) = 0;
- PRIV(length_pos) = 2;
- PRIV(output_size) = 0;
- PRIV(output_alignment) = 1;
-
- return true;
-}
-
-
-/* Fill symbol->section with section ptr
- symbol->section is filled with the section index for defined symbols
- during reading the EGSD section. But we need the pointer to the
- bfd section later.
-
- It has the correct value for referenced (undefined section) symbols
-
- called from bfd_hash_traverse in evax_fixup_sections */
-
-static boolean
-fill_section_ptr (entry, sections)
- struct bfd_hash_entry *entry;
- PTR sections;
-{
- asection *sec;
- asymbol *sym;
-
- sym = ((evax_symbol_entry *)entry)->symbol;
- sec = sym->section;
-
- if (!bfd_is_und_section (sec))
- {
- sec = ((evax_symbol_entry *)entry)->symbol->section =
- ((asection **)sections)[(int)sec];
- }
-
- if (strcmp (sym->name, sec->name) == 0)
- sym->flags |= BSF_SECTION_SYM;
-
- return true;
-}
-
-
-/* Fixup sections
- set up all pointers and arrays, counters and sizes are fixed now
-
- we build a private sections vector for easy access since sections
- are always referenced by an index number.
-
- alloc PRIV(sections) according to abfd->section_count
- copy abfd->sections to PRIV(sections) */
-
-static boolean
-evax_fixup_sections (abfd)
- bfd *abfd;
-{
- asection *s;
-
- if (PRIV(fixup_done))
- return true;
-
- PRIV(sections) = ((asection **)
- bfd_malloc (abfd->section_count * sizeof (asection *)));
- if (PRIV(sections) == 0)
- return false;
- PRIV(egsd_sec_count) = abfd->section_count;
- s = abfd->sections;
- while (s)
- {
- PRIV(sections)[s->index] = s;
- s = s->next;
- }
-
- /*
- * traverse symbol table and fill in all section pointers
- */
-
- bfd_hash_traverse (PRIV(evax_symbol_table), fill_section_ptr,
- (PTR)(PRIV(sections)));
-
- PRIV(fixup_done) = true;
-
- return true;
-}
-
-/*===========================================================================*/
-
-/* Check the format for a file being read.
- Return a (bfd_target *) if it's an object file or zero if not. */
-
-static const struct bfd_target *
-evax_object_p (abfd)
- bfd *abfd;
-{
- int err = 0;
- int prev_type;
-#if EVAX_DEBUG
- evax_debug (1, "evax_object_p(%p)\n", abfd);
-#endif
- if (bfd_seek (abfd, 0L, SEEK_SET))
- {
- bfd_set_error (bfd_error_file_truncated);
- return 0;
- }
-
- prev_type = -1;
-
- do
- {
-#if EVAX_DEBUG
- evax_debug (3, "reading at %08lx\n", bfd_tell(abfd));
-#endif
- if (_bfd_evax_next_record (abfd) < 0)
- {
-#if EVAX_DEBUG
- evax_debug (2, "next_record failed\n");
-#endif
- bfd_set_error (bfd_error_wrong_format);
- return 0;
- }
-
- if ((prev_type == EOBJ_S_C_EGSD) && (PRIV(rec_type) != EOBJ_S_C_EGSD))
- {
- if (evax_fixup_sections (abfd) == false)
- {
-#if EVAX_DEBUG
- evax_debug (2, "evax_fixup_sections failed\n");
-#endif
- bfd_set_error (bfd_error_wrong_format);
- return 0;
- }
- }
-
- prev_type = PRIV(rec_type);
-
- switch (PRIV(rec_type))
- {
- case EOBJ_S_C_EMH:
- err = _bfd_evax_slurp_emh (abfd);
- break;
- case EOBJ_S_C_EEOM:
- err = _bfd_evax_slurp_eeom (abfd);
- break;
- case EOBJ_S_C_EGSD:
- err = _bfd_evax_slurp_egsd (abfd);
- break;
- case EOBJ_S_C_ETIR:
- err = _bfd_evax_slurp_etir (abfd);
- break;
- case EOBJ_S_C_EDBG:
- err = _bfd_evax_slurp_edbg (abfd);
- break;
- case EOBJ_S_C_ETBT:
- err = _bfd_evax_slurp_etbt (abfd);
- break;
- default:
- err = -1;
- }
- if (err != 0)
- {
-#if EVAX_DEBUG
- evax_debug (2, "slurp type %d failed with %d\n", PRIV(rec_type), err);
-#endif
- bfd_set_error (bfd_error_wrong_format);
- return 0;
- }
- }
- while (prev_type != EOBJ_S_C_EEOM);
-
- /* set arch_info to alpha */
-
- {
- const bfd_arch_info_type *arch = bfd_scan_arch ("alpha");
- if (arch == 0)
- {
-#if EVAX_DEBUG
- evax_debug (2, "arch not found\n");
-#endif
- bfd_set_error (bfd_error_wrong_format);
- return 0;
- }
- abfd->arch_info = arch;
- }
-
- return &evax_alpha_vec;
-}
-
-
-/* Check the format for a file being read.
- Return a (bfd_target *) if it's an archive file or zero. */
-
-static const struct bfd_target *
-evax_archive_p (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_archive_p(%p)\n", abfd);
-#endif
-
- if (!evax_initialize (abfd))
- return 0;
-
- return 0;
-}
-
-
-/* Set the format of a file being written. */
-
-static boolean
-evax_mkobject (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_mkobject(%p)\n", abfd);
-#endif
-
- if (!evax_initialize (abfd))
- return 0;
-
- {
- const bfd_arch_info_type *arch = bfd_scan_arch ("alpha");
- if (arch == 0)
- {
- bfd_set_error(bfd_error_wrong_format);
- return 0;
- }
- abfd->arch_info = arch;
- }
-
- return true;
-}
-
-
-/* Write cached information into a file being written, at bfd_close. */
-
-static boolean
-evax_write_object_contents (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_write_object_contents(%p)\n", abfd);
-#endif
-
- if (abfd->section_count > 0) /* we have sections */
- {
- if (_bfd_evax_write_emh (abfd) != 0)
- return false;
- if (_bfd_evax_write_egsd (abfd) != 0)
- return false;
- if (_bfd_evax_write_etir (abfd) != 0)
- return false;
- if (_bfd_evax_write_etbt (abfd) != 0)
- return false;
- if (_bfd_evax_write_eeom (abfd) != 0)
- return false;
- }
- return true;
-}
-
-/*-- 4.1, generic -----------------------------------------------------------*/
-
-/* Called when the BFD is being closed to do any necessary cleanup. */
-
-static boolean
-evax_close_and_cleanup (abfd)
- bfd *abfd;
-{
- asection *sec;
- evax_section *es, *es1;
- int i;
-
-#if EVAX_DEBUG
- evax_debug (1, "evax_close_and_cleanup(%p)\n", abfd);
-#endif
- if (abfd == 0)
- return true;
-
- if (PRIV(evax_buf) != NULL)
- {
- free (PRIV(evax_buf));
- PRIV(evax_buf) = NULL;
- }
- PRIV(buf_size) = 0;
-
- if (PRIV(output_buf) != 0)
- {
- free (PRIV(output_buf));
- PRIV(output_buf) = 0;
- }
-
- sec = abfd->sections;
- while (sec != NULL)
- {
- if (sec->contents)
- free (sec->contents);
- sec = sec->next;
- }
-
- if (PRIV(sections) != NULL)
- {
- free (PRIV(sections));
- PRIV(sections) = NULL;
- }
-
- if (PRIV(evax_symbol_table))
- {
- bfd_hash_table_free (PRIV(evax_symbol_table));
- PRIV(evax_symbol_table) = 0;
- }
-
- if (PRIV(stack))
- {
- free (PRIV(stack));
- PRIV(stack) = 0;
- }
-
- if (PRIV(location_stack))
- {
- free (PRIV(location_stack));
- PRIV(location_stack) = 0;
- }
-
- for (i = 0; i < EVAX_SECTION_COUNT; i++)
- {
- es = PRIV(evax_section_table)[i];
- while (es != NULL)
- {
- es1 = es->next;
- free (es);
- es = es1;
- }
- PRIV(evax_section_table)[i] = NULL;
- }
-
- free (abfd->tdata.any);
- abfd->tdata.any = NULL;
-
- return true;
-}
-
-
-/* Ask the BFD to free all cached information. */
-static boolean
-evax_bfd_free_cached_info (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_free_cached_info(%p)\n", abfd);
-#endif
- return true;
-}
-
-
-/* Called when a new section is created. */
-
-static boolean
-evax_new_section_hook (abfd, section)
- bfd *abfd;
- asection *section;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_new_section_hook(%p, %s)\n", abfd, section->name);
-#endif
- bfd_set_section_alignment(abfd, section, 4);
- return true;
-}
-
-
-/* Read the contents of a section.
- buf points to a buffer of buf_size bytes to be filled with
- section data (starting at offset into section) */
-
-static boolean
-evax_get_section_contents (abfd, section, buf, offset, buf_size)
- bfd *abfd;
- asection *section;
- PTR buf;
- file_ptr offset;
- bfd_size_type buf_size;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_section_contents(%p, %s, %p, off %ld, size %d)\n",
- abfd, section->name, buf, offset, (int)buf_size);
-#endif
-
- /* shouldn't be called, since all sections are IN_MEMORY */
-
- return false;
-}
-
-/* Read the contents of a section.
- buf points to a buffer of buf_size bytes to be filled with
- section data (starting at offset into section) */
-
-static boolean
-evax_get_section_contents_in_window (abfd, section, w, offset, count)
- bfd *abfd;
- asection *section;
- bfd_window *w;
- file_ptr offset;
- bfd_size_type count;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_section_contents_in_window(%p, %s, %p, off %ld, count %d)\n",
- abfd, section->name, w, offset, (int)count);
-#endif
-
- /* shouldn't be called, since all sections are IN_MEMORY */
-
- return false;
-}
-
-/*-- Part 4.2, copy private data --------------------------------------------*/
-
-/* Called to copy BFD general private data from one object file
- to another. */
-
-static boolean
-evax_bfd_copy_private_bfd_data (src, dest)
- bfd *src;
- bfd *dest;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_copy_private_bfd_data(%p, %p)\n", src, dest);
-#endif
- return true;
-}
-
-
-/* Merge private BFD information from the BFD @var{ibfd} to the
- the output file BFD @var{obfd} when linking. Return <<true>>
- on success, <<false>> on error. Possible error returns are:
-
- o <<bfd_error_no_memory>> -
- Not enough memory exists to create private data for @var{obfd}. */
-
-static boolean
-evax_bfd_merge_private_bfd_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
-{
-#if EVAX_DEBUG
- evax_debug (1,"evax_bfd_merge_private_bfd_data(%p, %p)\n", ibfd, obfd);
-#endif
- return true;
-}
-
-
-/* Set private BFD flag information in the BFD @var{abfd}.
- Return <<true>> on success, <<false>> on error. Possible error
- returns are:
-
- o <<bfd_error_no_memory>> -
- Not enough memory exists to create private data for @var{obfd}. */
-
-static boolean
-evax_bfd_set_private_flags (abfd, flags)
- bfd *abfd;
- flagword flags;
-{
-#if EVAX_DEBUG
- evax_debug (1,"evax_bfd_set_private_flags(%p, %lx)\n", abfd, (long)flags);
-#endif
- return true;
-}
-
-
-/* Called to copy BFD private section data from one object file
- to another. */
-
-static boolean
-evax_bfd_copy_private_section_data (srcbfd, srcsec, dstbfd, dstsec)
- bfd *srcbfd;
- asection *srcsec;
- bfd *dstbfd;
- asection *dstsec;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_copy_private_section_data(%p, %s, %p, %s)\n",
- srcbfd, srcsec->name, dstbfd, dstsec->name);
-#endif
- return true;
-}
-
-/* Called to copy BFD private symbol data from one object file
- to another. */
-
-static boolean
-evax_bfd_copy_private_symbol_data (ibfd, isym, obfd, osym)
- bfd *ibfd;
- asymbol *isym;
- bfd *obfd;
- asymbol *osym;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_copy_private_symbol_data(%p, %s, %p, %s)\n",
- ibfd, isym->name, obfd, osym->name);
-#endif
- return true;
-}
-
-/*-- Part 4.3, core file ----------------------------------------------------*/
-
-/* Return a read-only string explaining which program was running
- when it failed and produced the core file abfd. */
-
-static char *
-evax_core_file_failing_command (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_core_file_failing_command(%p)\n", abfd);
-#endif
- return 0;
-}
-
-
-/* Returns the signal number which caused the core dump which
- generated the file the BFD abfd is attached to. */
-
-static int
-evax_core_file_failing_signal (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_core_file_failing_signal(%p)\n", abfd);
-#endif
- return 0;
-}
-
-
-/* Return true if the core file attached to core_bfd was generated
- by a run of the executable file attached to exec_bfd, false otherwise. */
-
-static boolean
-evax_core_file_matches_executable_p (abfd, bbfd)
- bfd *abfd;
- bfd *bbfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_core_file_matches_executable_p(%p, %p)\n", abfd, bbfd);
-#endif
- return false;
-}
-
-/*-- Part 4.4, archive ------------------------------------------------------*/
-
-/* ??? do something with an archive map.
- Return false on error, true otherwise. */
-
-static boolean
-evax_slurp_armap (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_slurp_armap(%p)\n", abfd);
-#endif
- return false;
-}
-
-
-/* ??? do something with an extended name table.
- Return false on error, true otherwise. */
-
-static boolean
-evax_slurp_extended_name_table (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_slurp_extended_name_table(%p)\n", abfd);
-#endif
- return false;
-}
-
-
-/* ??? do something with an extended name table.
- Return false on error, true otherwise. */
-
-static boolean
-evax_construct_extended_name_table (abfd, tabloc, tablen, name)
- bfd *abfd;
- char **tabloc;
- bfd_size_type *tablen;
- const char **name;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_construct_extended_name_table(%p)\n", abfd);
-#endif
- return false;
-}
-
-
-/* Truncate the name of an archive to match system-dependent restrictions */
-
-static void
-evax_truncate_arname (abfd, pathname, arhdr)
- bfd *abfd;
- CONST char *pathname;
- char *arhdr;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_truncate_arname(%p, %s, %s)\n", abfd, pathname, arhdr);
-#endif
- return;
-}
-
-
-/* ??? write archive map */
-
-static boolean
-evax_write_armap (arch, elength, map, orl_count, stridx)
- bfd *arch;
- unsigned int elength;
- struct orl *map;
- unsigned int orl_count;
- int stridx;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_write_armap(%p, %d, %p, %d %d)\n",
- arch, elength, map, orl_count, stridx);
-#endif
- return true;
-}
-
-/* Read archive header ??? */
-
-static PTR
-evax_read_ar_hdr (abfd)
- bfd * abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_read_ar_hdr(%p)\n", abfd);
-#endif
- return (PTR)0;
-}
-
-
-/* Provided a BFD, @var{archive}, containing an archive and NULL, open
- an input BFD on the first contained element and returns that.
- Subsequent calls should pass the archive and the previous return value
- to return a created BFD to the next contained element.
- NULL is returned when there are no more. */
-
-static bfd *
-evax_openr_next_archived_file (arch, prev)
- bfd *arch;
- bfd *prev;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_openr_next_archived_file(%p, %p)\n", arch, prev);
-#endif
- return false;
-}
-
-
-/* Return the BFD which is referenced by the symbol in ABFD indexed by
- INDEX. INDEX should have been returned by bfd_get_next_mapent. */
-
-static bfd *
-evax_get_elt_at_index (abfd, index)
- bfd *abfd;
- symindex index;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_elt_at_index(%p, %p)\n", abfd, index);
-#endif
- return _bfd_generic_get_elt_at_index(abfd, index);
-}
-
-
-/* ???
- -> bfd_generic_stat_arch_elt */
-
-static int
-evax_generic_stat_arch_elt (abfd, stat)
- bfd *abfd;
- struct stat *stat;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_generic_stat_arch_elt(%p, %p)\n", abfd, stat);
-#endif
- return bfd_generic_stat_arch_elt(abfd, stat);
-}
-
-
-/* This is a new function in bfd 2.5 */
-
-static boolean
-evax_update_armap_timestamp (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_update_armap_timestamp(%p)\n", abfd);
-#endif
- return true;
-}
-
-/*-- Part 4.5, symbols --------------------------------------------------------*/
-
-/* Return the number of bytes required to store a vector of pointers
- to asymbols for all the symbols in the BFD abfd, including a
- terminal NULL pointer. If there are no symbols in the BFD,
- then return 0. If an error occurs, return -1. */
-
-static long
-evax_get_symtab_upper_bound (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_symtab_upper_bound(%p), %d symbols\n", abfd, PRIV(egsd_sym_count));
-#endif
- return (PRIV(egsd_sym_count)+1) * sizeof(asymbol *);
-}
-
-
-/* Copy symbols from hash table to symbol vector
-
- called from bfd_hash_traverse in evax_get_symtab
- init counter to 0 if entry == 0 */
-
-static boolean
-copy_symbols (entry, arg)
- struct bfd_hash_entry *entry;
- PTR arg;
-{
- bfd *abfd = (bfd *) arg;
-
- if (entry == NULL) /* init counter */
- PRIV(symnum) = 0;
- else /* fill vector, inc counter */
- PRIV(symcache)[PRIV(symnum)++] = ((evax_symbol_entry *)entry)->symbol;
-
- return true;
-}
-
-
-/* Read the symbols from the BFD abfd, and fills in the vector
- location with pointers to the symbols and a trailing NULL.
-
- return # of symbols read */
-
-static long
-evax_get_symtab (abfd, symbols)
- bfd *abfd;
- asymbol **symbols;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_symtab(%p, <ret>)\n", abfd);
-#endif
-
- /* init counter */
- (void)copy_symbols((struct bfd_hash_entry *)0, abfd);
-
- /* traverse table and fill symbols vector */
-
- PRIV(symcache) = symbols;
- bfd_hash_traverse(PRIV(evax_symbol_table), copy_symbols, (PTR)abfd);
-
- symbols[PRIV(egsd_sym_count)] = NULL;
-
- return PRIV(egsd_sym_count);
-}
-
-
-/* Create a new asymbol structure for the BFD abfd and return a pointer
- to it.
- This routine is necessary because each back end has private information
- surrounding the asymbol. Building your own asymbol and pointing to it
- will not create the private information, and will cause problems later on. */
-
-asymbol *
-_bfd_evax_make_empty_symbol (abfd)
- bfd *abfd;
-{
- asymbol *symbol = (asymbol *)bfd_zalloc(abfd, sizeof(asymbol));
-
-#if EVAX_DEBUG
- evax_debug (1, "_bfd_evax_make_empty_symbol(%p)\n", abfd);
-#endif
-
- if (symbol == 0)
- {
- bfd_set_error (bfd_error_no_memory);
- return 0;
- }
- symbol->the_bfd = abfd;
-
- return symbol;
-}
-
-
-/* Print symbol to file according to how. how is one of
- bfd_print_symbol_name just print the name
- bfd_print_symbol_more print more (???)
- bfd_print_symbol_all print all we know, which is not much right now :-) */
-
-static void
-evax_print_symbol (abfd, file, symbol, how)
- bfd *abfd;
- PTR file;
- asymbol *symbol;
- bfd_print_symbol_type how;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_print_symbol(%p, %p, %p, %d)\n", abfd, file, symbol, how);
-#endif
-
- switch (how)
- {
- case bfd_print_symbol_name:
- case bfd_print_symbol_more:
- fprintf((FILE *)file," %s", symbol->name);
- break;
-
- break;
-
- case bfd_print_symbol_all:
- {
- CONST char *section_name = symbol->section->name;
-
- bfd_print_symbol_vandf((PTR)file,symbol);
-
- fprintf((FILE *)file," %-8s %s", section_name, symbol->name);
- }
- break;
- }
- return;
-}
-
-
-/* Return information about symbol in ret.
-
- fill type, value and name
- type:
- A absolute
- B bss segment symbol
- C common symbol
- D data segment symbol
- f filename
- t a static function symbol
- T text segment symbol
- U undefined
- - debug */
-
-static void
-evax_get_symbol_info (abfd, symbol, ret)
- bfd *abfd;
- asymbol *symbol;
- symbol_info *ret;
-{
- asection *sec;
-
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_symbol_info(%p, %p, <ret>)\n", abfd, symbol);
-#endif
-
- sec = symbol->section;
-
- if (bfd_is_com_section (sec))
- ret->type = 'C';
- else if (bfd_is_abs_section (sec))
- ret->type = 'A';
- else if (bfd_is_und_section (sec))
- ret->type = 'U';
- else if (bfd_is_ind_section (sec))
- ret->type = 'I';
- else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
- ret->type = 'T';
- else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
- ret->type = 'D';
- else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
- ret->type = 'B';
- else
- ret->type = '-';
-
- if (ret->type != 'U')
- ret->value = symbol->value + symbol->section->vma;
- else
- ret->value = 0;
- ret->name = symbol->name;
-
- return;
-}
-
-
-/* Return true if the given symbol sym in the BFD abfd is
- a compiler generated local label, else return false. */
-
-static boolean
-evax_bfd_is_local_label_name (abfd, name)
- bfd *abfd;
- const char *name;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_is_local_label_name(%p, %s)\n", abfd, name);
-#endif
- return name[0] == '$';
-}
-
-
-/* Get source line number for symbol */
-
-static alent *
-evax_get_lineno (abfd, symbol)
- bfd *abfd;
- asymbol *symbol;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_lineno(%p, %p)\n", abfd, symbol);
-#endif
- return 0;
-}
-
-
-/* Provided a BFD, a section and an offset into the section, calculate and
- return the name of the source file and the line nearest to the wanted
- location. */
-
-static boolean
-evax_find_nearest_line (abfd, section, symbols, offset, file, func, line)
- bfd *abfd;
- asection *section;
- asymbol **symbols;
- bfd_vma offset;
- CONST char **file;
- CONST char **func;
- unsigned int *line;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_find_nearest_line(%p, %s, %p, %ld, <ret>, <ret>, <ret>)\n",
- abfd, section->name, symbols, (long int)offset);
-#endif
- return false;
-}
-
-
-/* Back-door to allow format-aware applications to create debug symbols
- while using BFD for everything else. Currently used by the assembler
- when creating COFF files. */
-
-static asymbol *
-evax_bfd_make_debug_symbol (abfd, ptr, size)
- bfd *abfd;
- void *ptr;
- unsigned long size;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_make_debug_symbol(%p, %p, %ld)\n", abfd, ptr, size);
-#endif
- return 0;
-}
-
-
-/* Read minisymbols. For minisymbols, we use the unmodified a.out
- symbols. The minisymbol_to_symbol function translates these into
- BFD asymbol structures. */
-
-static long
-evax_read_minisymbols (abfd, dynamic, minisymsp, sizep)
- bfd *abfd;
- boolean dynamic;
- PTR *minisymsp;
- unsigned int *sizep;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_read_minisymbols(%p, %d, %p, %d)\n", abfd, dynamic, minisymsp, *sizep);
-#endif
- return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
-}
-
-/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
- unmodified a.out symbol. The SYM argument is a structure returned
- by bfd_make_empty_symbol, which we fill in here. */
-
-static asymbol *
-evax_minisymbol_to_symbol (abfd, dynamic, minisym, sym)
- bfd *abfd;
- boolean dynamic;
- const PTR minisym;
- asymbol *sym;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_minisymbol_to_symbol(%p, %d, %p, %p)\n", abfd, dynamic, minisym, sym);
-#endif
- return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
-}
-
-/*-- Part 4.6, relocations --------------------------------------------------*/
-
-/* Return the number of bytes required to store the relocation information
- associated with section sect attached to bfd abfd.
- If an error occurs, return -1. */
-
-static long
-evax_get_reloc_upper_bound (abfd, section)
- bfd *abfd;
- asection *section;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_reloc_upper_bound(%p, %s)\n", abfd, section->name);
-#endif
- return -1L;
-}
-
-
-/* Call the back end associated with the open BFD abfd and translate the
- external form of the relocation information attached to sec into the
- internal canonical form. Place the table into memory at loc, which has
- been preallocated, usually by a call to bfd_get_reloc_upper_bound.
- Returns the number of relocs, or -1 on error. */
-
-static long
-evax_canonicalize_reloc (abfd, section, location, symbols)
- bfd *abfd;
- asection *section;
- arelent **location;
- asymbol **symbols;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_canonicalize_reloc(%p, %s, <ret>, <ret>)\n", abfd, section->name);
-#endif
- return false;
-}
-
-/*---------------------------------------------------------------------------*/
-/* this is just copied from ecoff-alpha, needs to be fixed probably */
-
-/* How to process the various reloc types. */
-
-static bfd_reloc_status_type
-reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
- bfd *abfd;
- arelent *reloc;
- asymbol *sym;
- PTR data;
- asection *sec;
- bfd *output_bfd;
- char **error_message;
-{
-#if EVAX_DEBUG
- evax_debug (1, "reloc_nil(abfd %p, output_bfd %p)\n", abfd, output_bfd);
- evax_debug (2, "In section %s, symbol %s\n",
- sec->name, sym->name);
- evax_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
- reloc->sym_ptr_ptr[0]->name,
- (unsigned long)reloc->address,
- (unsigned long)reloc->addend, reloc->howto->name);
- evax_debug (2, "data at %p\n", data);
-/* _bfd_hexdump (2, data, bfd_get_reloc_size(reloc->howto),0); */
-#endif
-
- return bfd_reloc_ok;
-}
-
-/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
- from smaller values. Start with zero, widen, *then* decrement. */
-#define MINUS_ONE (((bfd_vma)0) - 1)
-
-static reloc_howto_type alpha_howto_table[] =
-{
- HOWTO (ALPHA_R_IGNORE, /* type */
- 0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 8, /* bitsize */
- true, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "IGNORE", /* name */
- true, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- true), /* pcrel_offset */
-
- /* A 64 bit reference to a symbol. */
- HOWTO (ALPHA_R_REFQUAD, /* type */
- 0, /* rightshift */
- 4, /* size (0 = byte, 1 = short, 2 = long) */
- 64, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "REFQUAD", /* name */
- true, /* partial_inplace */
- MINUS_ONE, /* src_mask */
- MINUS_ONE, /* dst_mask */
- false), /* pcrel_offset */
-
- /* A 21 bit branch. The native assembler generates these for
- branches within the text segment, and also fills in the PC
- relative offset in the instruction. */
- HOWTO (ALPHA_R_BRADDR, /* type */
- 2, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 21, /* bitsize */
- true, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "BRADDR", /* name */
- true, /* partial_inplace */
- 0x1fffff, /* src_mask */
- 0x1fffff, /* dst_mask */
- false), /* pcrel_offset */
-
- /* A hint for a jump to a register. */
- HOWTO (ALPHA_R_HINT, /* type */
- 2, /* rightshift */
- 1, /* size (0 = byte, 1 = short, 2 = long) */
- 14, /* bitsize */
- true, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "HINT", /* name */
- true, /* partial_inplace */
- 0x3fff, /* src_mask */
- 0x3fff, /* dst_mask */
- false), /* pcrel_offset */
-
- /* 16 bit PC relative offset. */
- HOWTO (ALPHA_R_SREL16, /* type */
- 0, /* rightshift */
- 1, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- true, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "SREL16", /* name */
- true, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
- false), /* pcrel_offset */
-
- /* 32 bit PC relative offset. */
- HOWTO (ALPHA_R_SREL32, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- true, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "SREL32", /* name */
- true, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- /* A 64 bit PC relative offset. */
- HOWTO (ALPHA_R_SREL64, /* type */
- 0, /* rightshift */
- 4, /* size (0 = byte, 1 = short, 2 = long) */
- 64, /* bitsize */
- true, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "SREL64", /* name */
- true, /* partial_inplace */
- MINUS_ONE, /* src_mask */
- MINUS_ONE, /* dst_mask */
- false), /* pcrel_offset */
-
- /* Push a value on the reloc evaluation stack. */
- HOWTO (ALPHA_R_OP_PUSH, /* type */
- 0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "OP_PUSH", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset */
-
- /* Store the value from the stack at the given address. Store it in
- a bitfield of size r_size starting at bit position r_offset. */
- HOWTO (ALPHA_R_OP_STORE, /* type */
- 0, /* rightshift */
- 4, /* size (0 = byte, 1 = short, 2 = long) */
- 64, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "OP_STORE", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- MINUS_ONE, /* dst_mask */
- false), /* pcrel_offset */
-
- /* Subtract the reloc address from the value on the top of the
- relocation stack. */
- HOWTO (ALPHA_R_OP_PSUB, /* type */
- 0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "OP_PSUB", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset */
-
- /* Shift the value on the top of the relocation stack right by the
- given value. */
- HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
- 0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "OP_PRSHIFT", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset */
-
- /* Hack. Linkage is done by linker. */
- HOWTO (ALPHA_R_LINKAGE, /* type */
- 0, /* rightshift */
- 8, /* size (0 = byte, 1 = short, 2 = long) */
- 256, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "LINKAGE", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset */
-
- /* A 32 bit reference to a symbol. */
- HOWTO (ALPHA_R_REFLONG, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
- reloc_nil, /* special_function */
- "REFLONG", /* name */
- true, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- /* A 64 bit reference to a procedure, written as 32 bit value. */
- HOWTO (ALPHA_R_CODEADDR, /* type */
- 0, /* rightshift */
- 4, /* size (0 = byte, 1 = short, 2 = long) */
- 64, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed,/* complain_on_overflow */
- reloc_nil, /* special_function */
- "CODEADDR", /* name */
- false, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
-};
-
-/* Return a pointer to a howto structure which, when invoked, will perform
- the relocation code on data from the architecture noted. */
-
-static const struct reloc_howto_struct *
-evax_bfd_reloc_type_lookup (abfd, code)
- bfd *abfd;
- bfd_reloc_code_real_type code;
-{
- int alpha_type;
-
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_reloc_type_lookup(%p, %d)\t", abfd, code);
-#endif
-
- switch (code)
- {
- case BFD_RELOC_16: alpha_type = ALPHA_R_SREL16; break;
- case BFD_RELOC_32: alpha_type = ALPHA_R_REFLONG; break;
- case BFD_RELOC_64: alpha_type = ALPHA_R_REFQUAD; break;
- case BFD_RELOC_CTOR: alpha_type = ALPHA_R_REFQUAD; break;
- case BFD_RELOC_23_PCREL_S2: alpha_type = ALPHA_R_BRADDR; break;
- case BFD_RELOC_ALPHA_HINT: alpha_type = ALPHA_R_HINT; break;
- case BFD_RELOC_16_PCREL: alpha_type = ALPHA_R_SREL16; break;
- case BFD_RELOC_32_PCREL: alpha_type = ALPHA_R_SREL32; break;
- case BFD_RELOC_64_PCREL: alpha_type = ALPHA_R_SREL64; break;
- case BFD_RELOC_ALPHA_LINKAGE: alpha_type = ALPHA_R_LINKAGE; break;
- case BFD_RELOC_ALPHA_CODEADDR: alpha_type = ALPHA_R_CODEADDR; break;
- default:
- (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
- return (const struct reloc_howto_struct *) NULL;
- }
-#if EVAX_DEBUG
- evax_debug (2, "reloc is %s\n", alpha_howto_table[alpha_type].name);
-#endif
- return &alpha_howto_table[alpha_type];
-}
-
-
-/*-- Part 4.7, writing an object file ---------------------------------------*/
-
-/* Set the architecture and machine type in BFD abfd to arch and mach.
- Find the correct pointer to a structure and insert it into the arch_info
- pointer. */
-
-static boolean
-evax_set_arch_mach (abfd, arch, mach)
- bfd *abfd;
- enum bfd_architecture arch;
- unsigned long mach;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_set_arch_mach(%p, %d, %ld)\n", abfd, arch, mach);
-#endif
- if (arch != bfd_arch_alpha
- && arch != bfd_arch_unknown)
- return false;
-
- return bfd_default_set_arch_mach (abfd, arch, mach);
-}
-
-
-/* Sets the contents of the section section in BFD abfd to the data starting
- in memory at data. The data is written to the output section starting at
- offset offset for count bytes.
-
- Normally true is returned, else false. Possible error returns are:
- o bfd_error_no_contents - The output section does not have the
- SEC_HAS_CONTENTS attribute, so nothing can be written to it.
- o and some more too */
-
-static boolean
-evax_set_section_contents (abfd, section, location, offset, count)
- bfd *abfd;
- asection *section;
- PTR location;
- file_ptr offset;
- bfd_size_type count;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_set_section_contents(%p, sec %s, loc %p, off %ld, count %d)\n",
- abfd, section->name, location, (long int)offset, (int)count);
- evax_debug (2, "secraw %d, seccooked %d\n", (int)section->_raw_size, (int)section->_cooked_size);
-#endif
- return _bfd_save_evax_section(abfd, section, location, offset, count);
-}
-
-
-/*-- Part 4.8, linker -------------------------------------------------------*/
-
-/* Get the size of the section headers. */
-
-static int
-evax_sizeof_headers (abfd, reloc)
- bfd *abfd;
- boolean reloc;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_sizeof_headers(%p, %s)\n", abfd, (reloc)?"True":"False");
-#endif
- return 0;
-}
-
-
-/* Provides default handling of relocation effort for back ends
- which can't be bothered to do it efficiently. */
-
-static bfd_byte *
-evax_bfd_get_relocated_section_contents (abfd, link_info, link_order, data,
- relocateable, symbols)
- bfd *abfd;
- struct bfd_link_info *link_info;
- struct bfd_link_order *link_order;
- bfd_byte *data;
- boolean relocateable;
- asymbol **symbols;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_get_relocated_section_contents(%p, %p, %p, %p, %s, %p)\n",
- abfd, link_info, link_order, data, (relocateable)?"True":"False", symbols);
-#endif
- return 0;
-}
-
-
-/* ??? */
-
-static boolean
-evax_bfd_relax_section (abfd, section, link_info, again)
- bfd *abfd;
- asection *section;
- struct bfd_link_info *link_info;
- boolean *again;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_relax_section(%p, %s, %p, <ret>)\n",
- abfd, section->name, link_info);
-#endif
- return true;
-}
-
-static boolean
-evax_bfd_gc_sections (abfd, link_info)
- bfd *abfd;
- struct bfd_link_info *link_info;
- const char *entry;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_gc_sections(%p, %p)\n", abfd, link_info);
-#endif
- return true;
-}
-
-
-/* Create a hash table for the linker. Different backends store
- different information in this table. */
-
-static struct bfd_link_hash_table *
-evax_bfd_link_hash_table_create (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_link_hash_table_create(%p)\n", abfd);
-#endif
- return 0;
-}
-
-
-/* Add symbols from this object file into the hash table. */
-
-static boolean
-evax_bfd_link_add_symbols (abfd, link_info)
- bfd *abfd;
- struct bfd_link_info *link_info;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_link_add_symbols(%p, %p)\n", abfd, link_info);
-#endif
- return false;
-}
-
-
-/* Do a link based on the link_order structures attached to each
- section of the BFD. */
-
-static boolean
-evax_bfd_final_link (abfd, link_info)
- bfd *abfd;
- struct bfd_link_info *link_info;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_final_link(%p, %p)\n", abfd, link_info);
-#endif
- return true;
-}
-
-/* Should this section be split up into smaller pieces during linking. */
-
-static boolean
-evax_bfd_link_split_section (abfd, section)
- bfd *abfd;
- asection *section;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_link_split_section(%p, %s)\n", abfd, section->name);
-#endif
- return false;
-}
-
-/*-- Part 4.9, dynamic symbols and relocations ------------------------------*/
-
-/* Get the amount of memory required to hold the dynamic symbols. */
-
-static long
-evax_get_dynamic_symtab_upper_bound (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_dynamic_symtab_upper_bound(%p)\n", abfd);
-#endif
- return 0;
-}
-
-static boolean
-evax_bfd_print_private_bfd_data (abfd, file)
- bfd *abfd;
- void *file;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_bfd_print_private_bfd_data(%p)\n", abfd);
-#endif
- return 0;
-}
-
-
-/* Read in the dynamic symbols. */
-
-static long
-evax_canonicalize_dynamic_symtab (abfd, symbols)
- bfd *abfd;
- asymbol **symbols;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_canonicalize_dynamic_symtab(%p, <ret>)\n", abfd);
-#endif
- return 0L;
-}
-
-
-/* Get the amount of memory required to hold the dynamic relocs. */
-
-static long
-evax_get_dynamic_reloc_upper_bound (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_get_dynamic_reloc_upper_bound(%p)\n", abfd);
-#endif
- return 0L;
-}
-
-
-/* Read in the dynamic relocs. */
-
-static long
-evax_canonicalize_dynamic_reloc (abfd, arel, symbols)
- bfd *abfd;
- arelent **arel;
- asymbol **symbols;
-{
-#if EVAX_DEBUG
- evax_debug (1, "evax_canonicalize_dynamic_reloc(%p)\n", abfd);
-#endif
- return 0L;
-}
+++ /dev/null
-/* evax-egsd.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998 Free Software Foundation Inc.
-
- 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@progis.de)
- of proGIS Softwareentwicklung, Aachen, Germany
-
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-
-#include <ctype.h>
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "evax.h"
-
-/*-----------------------------------------------------------------------------*/
-
-/* sections every evax object file has */
-
-#define EVAX_ABS_NAME "$ABS$"
-#define EVAX_CODE_NAME "$CODE$"
-#define EVAX_LINK_NAME "$LINK$"
-#define EVAX_DATA_NAME "$DATA$"
-#define EVAX_BSS_NAME "$BSS$"
-#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
-#define EVAX_READONLY_NAME "$READONLY$"
-#define EVAX_LITERAL_NAME "$LITERAL$"
-#define EVAX_COMMON_NAME "$COMMON$"
-#define EVAX_LOCAL_NAME "$LOCAL$"
-
-struct sec_flags_struct {
- char *name; /* name of section */
- int eflags_always;
- flagword flags_always; /* flags we set always */
- int eflags_hassize;
- flagword flags_hassize; /* flags we set if the section has a size > 0 */
-};
-
-/* These flags are deccrtl/vaxcrtl (openVMS 6.2) compatible */
-
-static struct sec_flags_struct evax_section_flags[] = {
- { EVAX_ABS_NAME,
- (EGPS_S_V_SHR),
- (SEC_DATA),
- (EGPS_S_V_SHR),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
- { EVAX_CODE_NAME,
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
- (SEC_CODE),
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
- (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
- { EVAX_LITERAL_NAME,
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
- (SEC_DATA|SEC_READONLY),
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
- { EVAX_LINK_NAME,
- (EGPS_S_V_REL|EGPS_S_V_RD),
- (SEC_DATA|SEC_READONLY),
- (EGPS_S_V_REL|EGPS_S_V_RD),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
- { EVAX_DATA_NAME,
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
- (SEC_DATA),
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
- { EVAX_BSS_NAME,
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
- (SEC_NO_FLAGS),
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
- (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
- { EVAX_READONLYADDR_NAME,
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
- (SEC_DATA|SEC_READONLY),
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
- { EVAX_READONLY_NAME,
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
- (SEC_DATA|SEC_READONLY),
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
- { EVAX_LOCAL_NAME,
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
- (SEC_DATA),
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
- { NULL,
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
- (SEC_DATA),
- (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
- (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
-};
-
-/* Retrieve bfd section flags by name and size */
-
-static flagword
-evax_secflag_by_name(name, size)
- char *name;
- int size;
-{
- int i = 0;
-
- while (evax_section_flags[i].name != NULL)
- {
- if (strcmp (name, evax_section_flags[i].name) == 0)
- {
- if (size > 0)
- return evax_section_flags[i].flags_hassize;
- else
- return evax_section_flags[i].flags_always;
- }
- i++;
- }
- if (size > 0)
- return evax_section_flags[i].flags_hassize;
- return evax_section_flags[i].flags_always;
-}
-
-
-/* Retrieve evax section flags by name and size */
-
-static flagword
-evax_esecflag_by_name(name, size)
- char *name;
- int size;
-{
- int i = 0;
-
- while (evax_section_flags[i].name != NULL)
- {
- if (strcmp (name, evax_section_flags[i].name) == 0)
- {
- if (size > 0)
- return evax_section_flags[i].eflags_hassize;
- else
- return evax_section_flags[i].eflags_always;
- }
- i++;
- }
- if (size > 0)
- return evax_section_flags[i].eflags_hassize;
- return evax_section_flags[i].eflags_always;
-}
-
-/*-----------------------------------------------------------------------------*/
-#if EVAX_DEBUG
-/* debug */
-
-struct flagdescstruct { char *name; flagword value; };
-
-/* Convert flag to printable string */
-
-static char *
-flag2str(flagdesc, flags)
- struct flagdescstruct *flagdesc;
- flagword flags;
-{
-
- static char res[64];
- int next = 0;
-
- res[0] = 0;
- while (flagdesc->name != NULL)
- {
- if ((flags & flagdesc->value) != 0)
- {
- if (next)
- strcat(res, ",");
- else
- next = 1;
- strcat (res, flagdesc->name);
- }
- flagdesc++;
- }
- return res;
-}
-#endif
-
-/*-----------------------------------------------------------------------------*/
-/* input routines */
-
-/* Process EGSD record
- return 0 on success, -1 on error */
-
-int
-_bfd_evax_slurp_egsd (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- static struct flagdescstruct gpsflagdesc[] =
- {
- { "PIC", 0x0001 },
- { "LIB", 0x0002 },
- { "OVR", 0x0004 },
- { "REL", 0x0008 },
- { "GBL", 0x0010 },
- { "SHR", 0x0020 },
- { "EXE", 0x0040 },
- { "RD", 0x0080 },
- { "WRT", 0x0100 },
- { "VEC", 0x0200 },
- { "NOMOD", 0x0400 },
- { "COM", 0x0800 },
- { NULL, 0 }
- };
-
- static struct flagdescstruct gsyflagdesc[] =
- {
- { "WEAK", 0x0001 },
- { "DEF", 0x0002 },
- { "UNI", 0x0004 },
- { "REL", 0x0008 },
- { "COMM", 0x0010 },
- { "VECEP", 0x0020 },
- { "NORM", 0x0040 },
- { NULL, 0 }
- };
-#endif
-
- int gsd_type, gsd_size;
- asection *section;
- unsigned char *evax_rec;
- flagword new_flags, old_flags;
- char *name;
- asymbol *symbol;
- evax_symbol_entry *entry;
- unsigned long base_addr;
- unsigned long align_addr;
-
-#if EVAX_DEBUG
- evax_debug (2, "EGSD\n");
-#endif
-
- PRIV(evax_rec) += 8; /* skip type, size, l_temp */
- PRIV(rec_size) -= 8;
-
- /* calculate base address for each section */
- base_addr = 0L;
-
- abfd->symcount = 0;
-
- while (PRIV(rec_size) > 0)
- {
- evax_rec = PRIV(evax_rec);
- _bfd_evax_get_header_values (abfd, evax_rec, &gsd_type, &gsd_size);
- switch (gsd_type)
- {
- case EGSD_S_C_PSC:
- {
- /* program section definition */
-
- name = _bfd_evax_save_counted_string ((char *)evax_rec+12);
- section = bfd_make_section (abfd, name);
- if (!section)
- return -1;
- old_flags = bfd_getl16 (evax_rec + 6);
- section->_raw_size = bfd_getl32 (evax_rec + 8); /* allocation */
- new_flags = evax_secflag_by_name (name, (int) section->_raw_size);
- if (old_flags & EGPS_S_V_REL)
- new_flags |= SEC_RELOC;
- if (!bfd_set_section_flags (abfd, section, new_flags))
- return -1;
- section->alignment_power = evax_rec[4];
- align_addr = (1 << section->alignment_power);
- if ((base_addr % align_addr) != 0)
- base_addr += (align_addr - (base_addr % align_addr));
- section->vma = (bfd_vma)base_addr;
- base_addr += section->_raw_size;
- section->contents = ((unsigned char *)
- bfd_malloc (section->_raw_size));
- if (section->contents == NULL)
- return -1;
- memset (section->contents, 0, (size_t) section->_raw_size);
- section->_cooked_size = section->_raw_size;
-#if EVAX_DEBUG
- evax_debug(3, "egsd psc %d (%s, flags %04x=%s) ",
- section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
- evax_debug(3, "%d bytes at 0x%08lx (mem %p)\n",
- section->_raw_size, section->vma, section->contents);
-#endif
- }
- break;
-
- case EGSD_S_C_SYM:
- {
- /* symbol specification (definition or reference) */
-
- symbol = _bfd_evax_make_empty_symbol (abfd);
- if (symbol == 0)
- return -1;
-
- old_flags = bfd_getl16 (evax_rec + 6);
- new_flags = BSF_NO_FLAGS;
-
- if (old_flags & EGSY_S_V_WEAK)
- new_flags |= BSF_WEAK;
-
- if (evax_rec[6] & EGSY_S_V_DEF) /* symbol definition */
- {
- symbol->name =
- _bfd_evax_save_counted_string ((char *)evax_rec+32);
- if (old_flags & EGSY_S_V_NORM)
- { /* proc def */
- new_flags |= BSF_FUNCTION;
- }
- symbol->value = bfd_getl64 (evax_rec+8);
- symbol->section = (asection *)((unsigned long) bfd_getl32 (evax_rec+28));
-#if EVAX_DEBUG
- evax_debug(3, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
- symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
-#endif
- }
- else /* symbol reference */
- {
- symbol->name =
- _bfd_evax_save_counted_string ((char *)evax_rec+8);
-#if EVAX_DEBUG
- evax_debug(3, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
- symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
-#endif
- symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
- }
-
- symbol->flags = new_flags;
-
- /* save symbol in evax_symbol_table */
-
- entry = (evax_symbol_entry *) bfd_hash_lookup (PRIV(evax_symbol_table), symbol->name, true, false);
- if (entry == (evax_symbol_entry *)NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return -1;
- }
- if (entry->symbol != (asymbol *)NULL)
- { /* FIXME ?, DEC C generates this */
-#if EVAX_DEBUG
- evax_debug(3, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
-#endif
- }
- else
- {
- entry->symbol = symbol;
- PRIV(egsd_sym_count)++;
- abfd->symcount++;
- }
- }
- break;
-
- case EGSD_S_C_IDC:
- break;
-
- default:
- (*_bfd_error_handler) (_("unknown egsd subtype %d"), gsd_type);
- bfd_set_error (bfd_error_bad_value);
- return -1;
-
- } /* switch */
-
- PRIV(rec_size) -= gsd_size;
- PRIV(evax_rec) += gsd_size;
-
- } /* while (recsize > 0) */
-
- if (abfd->symcount > 0)
- abfd->flags |= HAS_SYMS;
-
- return 0;
-}
-
-/*-----------------------------------------------------------------------------*/
-/* output routines */
-
-/* Write section and symbol directory of bfd abfd */
-
-int
-_bfd_evax_write_egsd (abfd)
- bfd *abfd;
-{
- asection *section;
- asymbol *symbol;
- int symnum;
- int last_index = -1;
- char dummy_name[10];
- char *sname;
- flagword new_flags, old_flags;
- char *nptr, *uptr;
-
-#if EVAX_DEBUG
- evax_debug (2, "evax_write_egsd(%p)\n", abfd);
-#endif
-
- /* output sections */
-
- section = abfd->sections;
-#if EVAX_DEBUG
- evax_debug (3, "%d sections found\n", abfd->section_count);
-#endif
-
- /* egsd is quadword aligned */
-
- _bfd_evax_output_alignment (abfd, 8);
-
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1);
- _bfd_evax_output_long (abfd, 0);
- _bfd_evax_output_push (abfd); /* prepare output for subrecords */
-
- while (section != 0)
- {
-#if EVAX_DEBUG
- evax_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);
-#endif
-
- /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */
- if (_bfd_evax_output_check (abfd, 64) < 0)
- {
- _bfd_evax_output_pop (abfd);
- _bfd_evax_output_end (abfd);
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1);
- _bfd_evax_output_long (abfd, 0);
- _bfd_evax_output_push (abfd); /* prepare output for subrecords */
- }
-
- /* Create dummy sections to keep consecutive indices */
-
- while (section->index - last_index > 1)
- {
-#if EVAX_DEBUG
- evax_debug (3, "index %d, last %d\n", section->index, last_index);
-#endif
- _bfd_evax_output_begin (abfd, EGSD_S_C_PSC, -1);
- _bfd_evax_output_short (abfd, 0);
- _bfd_evax_output_short (abfd, 0);
- _bfd_evax_output_long (abfd, 0);
- sprintf (dummy_name, ".DUMMY%02d", last_index);
- _bfd_evax_output_counted (abfd, dummy_name);
- _bfd_evax_output_flush (abfd);
- last_index++;
- }
-
- /* Don't know if this is neccesary for the linker but for now it keeps
- evax_slurp_egsd happy */
-
- sname = (char *)section->name;
- if (*sname == '.')
- {
- sname++;
- if ((*sname == 't') && (strcmp (sname, "text") == 0))
- sname = EVAX_CODE_NAME;
- else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
- sname = EVAX_DATA_NAME;
- else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
- sname = EVAX_BSS_NAME;
- else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
- sname = EVAX_LINK_NAME;
- else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
- sname = EVAX_READONLY_NAME;
- else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
- sname = EVAX_LITERAL_NAME;
- else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
- sname = EVAX_COMMON_NAME;
- else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
- sname = EVAX_LOCAL_NAME;
- }
- else
- sname = _bfd_evax_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
-
- _bfd_evax_output_begin (abfd, EGSD_S_C_PSC, -1);
- _bfd_evax_output_short (abfd, section->alignment_power & 0xff);
- if (bfd_is_com_section (section))
- {
- new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM);
- }
- else
- {
- new_flags = evax_esecflag_by_name (sname, section->_raw_size);
- }
- _bfd_evax_output_short (abfd, new_flags);
- _bfd_evax_output_long (abfd, section->_raw_size);
- _bfd_evax_output_counted (abfd, sname);
- _bfd_evax_output_flush (abfd);
-
- last_index = section->index;
- section = section->next;
- }
-
- /* output symbols */
-
-#if EVAX_DEBUG
- evax_debug (3, "%d symbols found\n", abfd->symcount);
-#endif
-
- bfd_set_start_address (abfd, (bfd_vma)-1);
-
- for (symnum = 0; symnum < abfd->symcount; symnum++)
- {
-
- symbol = abfd->outsymbols[symnum];
- if (*(symbol->name) == '_')
- {
- if (strcmp (symbol->name, "__main") == 0)
- bfd_set_start_address (abfd, (bfd_vma)symbol->value);
- }
- old_flags = symbol->flags;
-
- if (old_flags & BSF_FILE)
- continue;
-
- if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */
- && (!bfd_is_und_section (symbol->section))) /* and not xref */
- continue; /* dont output */
-
- /* 13 bytes egsd, max 64 chars name -> should be 77 bytes */
-
- if (_bfd_evax_output_check (abfd, 80) < 0)
- {
- _bfd_evax_output_pop (abfd);
- _bfd_evax_output_end (abfd);
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1);
- _bfd_evax_output_long (abfd, 0);
- _bfd_evax_output_push (abfd); /* prepare output for subrecords */
- }
-
- _bfd_evax_output_begin (abfd, EGSD_S_C_SYM, -1);
-
- _bfd_evax_output_short (abfd, 0); /* data type, alignment */
-
- new_flags = 0;
-
- if (old_flags & BSF_WEAK)
- new_flags |= EGSY_S_V_WEAK;
- if (bfd_is_com_section (symbol->section)) /* .comm */
- new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
-
- if (old_flags & BSF_FUNCTION)
- {
- new_flags |= EGSY_S_V_NORM;
- new_flags |= EGSY_S_V_REL;
- }
- if (old_flags & (BSF_GLOBAL|BSF_WEAK))
- {
- new_flags |= EGSY_S_V_DEF;
- if (!bfd_is_abs_section (symbol->section))
- new_flags |= EGSY_S_V_REL;
- }
- _bfd_evax_output_short (abfd, new_flags);
-
- if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */
- {
- if (old_flags & BSF_FUNCTION)
- {
- _bfd_evax_output_quad (abfd, symbol->value);
- _bfd_evax_output_quad (abfd,
- ((asymbol *)(symbol->udata.p))->value);
- _bfd_evax_output_long (abfd,
- (((asymbol *)(symbol->udata.p))
- ->section->index));
- _bfd_evax_output_long (abfd, symbol->section->index);
- }
- else
- {
- _bfd_evax_output_quad (abfd, symbol->value); /* L_VALUE */
- _bfd_evax_output_quad (abfd, 0); /* L_CODE_ADDRESS */
- _bfd_evax_output_long (abfd, 0); /* L_CA_PSINDX */
- _bfd_evax_output_long (abfd, symbol->section->index);/* L_PSINDX */
- }
- }
- _bfd_evax_output_counted (abfd, _bfd_evax_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
-
- _bfd_evax_output_flush (abfd);
-
- }
-
- _bfd_evax_output_alignment (abfd, 8);
- _bfd_evax_output_pop (abfd);
- _bfd_evax_output_end (abfd);
-
- return 0;
-}
+++ /dev/null
-/* evax-emh.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
-
- EMH record handling functions
- and
- EEOM record handling functions
-
- Written by Klaus K"ampf (kkaempf@progis.de)
- of proGIS Softwareentwicklung, Aachen, Germany
-
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include <ctype.h>
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "evax.h"
-
-/*---------------------------------------------------------------------------*/
-
-
-/* Read & process emh record
- return 0 on success, -1 on error */
-
-int
-_bfd_evax_slurp_emh (abfd)
- bfd *abfd;
-{
- unsigned char *ptr;
- unsigned char *evax_rec;
-
- evax_rec = PRIV(evax_rec);
-
-#if EVAX_DEBUG
- evax_debug(2, "EMH\n");
-#endif
-
- switch (bfd_getl16 (evax_rec + 4))
- {
-
- case EMH_S_C_MHD:
- /*
- * module header
- */
- PRIV(emh_data).emh_b_strlvl = evax_rec[6];
- PRIV(emh_data).emh_l_arch1 = bfd_getl32 (evax_rec + 8);
- PRIV(emh_data).emh_l_arch2 = bfd_getl32 (evax_rec + 12);
- PRIV(emh_data).emh_l_recsiz = bfd_getl32 (evax_rec + 16);
- PRIV(emh_data).emh_t_name =
- _bfd_evax_save_counted_string ((char *)evax_rec + 20);
- ptr = evax_rec + 20 + evax_rec[20] + 1;
- PRIV(emh_data).emh_t_version =
- _bfd_evax_save_counted_string ((char *)ptr);
- ptr += *ptr + 1;
- PRIV(emh_data).emh_t_date =
- _bfd_evax_save_sized_string ((char *)ptr, 17);
-
- break;
-
- case EMH_S_C_LNM:
- /*
- *
- */
- PRIV(emh_data).emh_c_lnm =
- _bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6));
- break;
-
- case EMH_S_C_SRC:
- /*
- *
- */
- PRIV(emh_data).emh_c_src =
- _bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6));
- break;
-
- case EMH_S_C_TTL:
- /*
- *
- */
- PRIV(emh_data).emh_c_ttl =
- _bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6));
- break;
-
- case EMH_S_C_CPR:
- /*
- *
- */
- break;
-
- case EMH_S_C_MTC:
- /*
- *
- */
- break;
-
- case EMH_S_C_GTX:
- /*
- *
- */
- break;
-
- default:
- bfd_set_error (bfd_error_wrong_format);
- return -1;
-
- } /* switch */
-
- return 0;
-}
-
-
-/*-----------------------------------------------------------------------------*/
-/* Output routines. */
-
-
-/* Manufacure a VMS like time on a unix based system.
- stolen from obj-vms.c */
-
-static unsigned char *
-get_vms_time_string ()
-{
- static unsigned char tbuf[18];
-#ifndef VMS
-#include <time.h>
-
- char *pnt;
- time_t timeb;
- time (&timeb);
- pnt = ctime (&timeb);
- pnt[3] = 0;
- pnt[7] = 0;
- pnt[10] = 0;
- pnt[16] = 0;
- pnt[24] = 0;
- sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
-#else
-#include <starlet.h>
- struct
- {
- int Size;
- unsigned char *Ptr;
- } Descriptor;
- Descriptor.Size = 17;
- Descriptor.Ptr = tbuf;
- SYS$ASCTIM (0, &Descriptor, 0, 0);
-#endif /* not VMS */
-
-#if EVAX_DEBUG
- evax_debug (6, "vmstimestring:'%s'\n", tbuf);
-#endif
-
- return tbuf;
-}
-
-
-/* write object header for bfd abfd */
-
-int
-_bfd_evax_write_emh (abfd)
- bfd *abfd;
-{
- asymbol *symbol;
- int symnum;
- int had_case = 0;
- int had_file = 0;
-
-
-#if EVAX_DEBUG
- evax_debug (2, "evax_write_emh(%p)\n", abfd);
-#endif
-
- _bfd_evax_output_alignment (abfd, 2);
-
- /* MHD */
-
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
- _bfd_evax_output_short (abfd, EOBJ_S_C_STRLVL);
- _bfd_evax_output_long (abfd, 0);
- _bfd_evax_output_long (abfd, 0);
- _bfd_evax_output_long (abfd, MAX_OUTREC_SIZE);
-
- if (bfd_get_filename (abfd) != 0)
- {
- /* strip path and suffix information */
-
- char *fname, *fout, *fptr;
-
- fptr = bfd_get_filename (abfd);
- fname = (char *) alloca (strlen (fptr) + 1);
- strcpy (fname, fptr);
- fout = strrchr (fname, ']');
- if (fout == 0)
- fout = strchr (fname, ':');
- if (fout != 0)
- fout++;
- else
- fout = fname;
-
- /* strip .obj suffix */
-
- fptr = strrchr (fname, '.');
- if ((fptr != 0)
- && (strcasecmp (fptr, ".OBJ") == 0))
- *fptr = 0;
-
- fptr = fout;
- while (*fptr != 0)
- {
- if (islower (*fptr))
- *fptr = toupper (*fptr);
- fptr++;
- if ((*fptr == ';')
- || ((fptr - fout) > 31))
- *fptr = 0;
- }
- _bfd_evax_output_counted (abfd, fout);
- }
- else
- _bfd_evax_output_counted (abfd, "NONAME");
-
- _bfd_evax_output_counted (abfd, BFD_VERSION);
- _bfd_evax_output_dump (abfd, get_vms_time_string (), 17);
- _bfd_evax_output_fill (abfd, 0, 17);
- _bfd_evax_output_flush (abfd);
-
- /* LMN */
-
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
- _bfd_evax_output_dump (abfd, (unsigned char *)"GAS proGIS", 10);
- _bfd_evax_output_flush (abfd);
-
- /* SRC */
-
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
-
- for (symnum = 0; symnum < abfd->symcount; symnum++)
- {
- symbol = abfd->outsymbols[symnum];
-
- if (symbol->flags & BSF_FILE)
- {
- char *s;
-
- if (strncmp ((char *)symbol->name, "<CASE:", 6) == 0)
- {
- PRIV(flag_hash_long_names) = symbol->name[6] - '0';
- PRIV(flag_show_after_trunc) = symbol->name[7] - '0';
-
- if (had_file)
- break;
- had_case = 1;
- continue;
- }
-
- _bfd_evax_output_dump (abfd, (unsigned char *)symbol->name, strlen (symbol->name));
- if (had_case)
- break;
- had_file = 1;
- }
- }
-
- if (symnum == abfd->symcount)
- _bfd_evax_output_dump (abfd, (unsigned char *)"noname", 6);
-
- _bfd_evax_output_flush (abfd);
-
- /* TTL */
-
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
- _bfd_evax_output_dump (abfd, (unsigned char *)"TTL", 3);
- _bfd_evax_output_flush (abfd);
-
- /* CPR */
-
- _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
- _bfd_evax_output_dump (abfd,
- (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
- 39);
- _bfd_evax_output_flush (abfd);
-
- return 0;
-}
-
-/*-----------------------------------------------------------------------------*/
-
-/* Process EEOM record
- return 0 on success, -1 on error */
-
-int
-_bfd_evax_slurp_eeom (abfd)
- bfd *abfd;
-{
- unsigned char *evax_rec;
-
-#if EVAX_DEBUG
- evax_debug(2, "EEOM\n");
-#endif
-
- evax_rec = PRIV(evax_rec);
-
- PRIV(eeom_data).eeom_l_total_lps = bfd_getl32 (evax_rec + 4);
- PRIV(eeom_data).eeom_b_comcod = *(evax_rec + 8);
- if (PRIV(eeom_data).eeom_b_comcod > 1)
- {
- (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
- bfd_set_error (bfd_error_bad_value);
- return -1;
- }
- PRIV(eeom_data).eeom_has_transfer = false;
- if (PRIV(rec_size) > 10)
- {
- PRIV(eeom_data).eeom_has_transfer = true;
- PRIV(eeom_data).eeom_b_tfrflg = *(evax_rec + 9);
- PRIV(eeom_data).eeom_l_psindx = bfd_getl32 (evax_rec + 12);
- PRIV(eeom_data).eeom_l_tfradr = bfd_getl32 (evax_rec + 16);
-
- abfd->start_address = PRIV(eeom_data).eeom_l_tfradr;
- }
- return 0;
-}
-
-
-/* Write eom record for bfd abfd */
-
-int
-_bfd_evax_write_eeom (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (2, "evax_write_eeom(%p)\n", abfd);
-#endif
-
- _bfd_evax_output_begin (abfd,EOBJ_S_C_EEOM, -1);
- _bfd_evax_output_long (abfd, (unsigned long)(PRIV(evax_linkage_index) >> 1));
- _bfd_evax_output_byte (abfd, 0); /* completion code */
- _bfd_evax_output_byte (abfd, 0); /* fill byte */
-
- if (bfd_get_start_address (abfd) != (bfd_vma)-1)
- {
- asection *section;
-
- section = bfd_get_section_by_name (abfd, ".link");
- if (section == 0)
- {
- bfd_set_error (bfd_error_nonrepresentable_section);
- return -1;
- }
- _bfd_evax_output_short (abfd, 0);
- _bfd_evax_output_long (abfd, (unsigned long)(section->index));
- _bfd_evax_output_long (abfd,
- (unsigned long) bfd_get_start_address (abfd));
- _bfd_evax_output_long (abfd, 0);
- }
-
- _bfd_evax_output_end (abfd);
- return 0;
-}
+++ /dev/null
-/* evax-etir.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
- 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@progis.de)
- of proGIS Softwareentwicklung, Aachen, Germany
-
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <ctype.h>
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "evax.h"
-
-#if 0
-static void location_save
- PARAMS ((bfd *abfd, unsigned long index, unsigned long loc, int section));
-static unsigned long location_restore
- PARAMS ((bfd *abfd, unsigned long index, int *section));
-#endif /* 0 */
-
-static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset));
-static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset));
-static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));
-static void image_write_b PARAMS ((bfd *abfd, unsigned int value));
-static void image_write_w PARAMS ((bfd *abfd, unsigned int value));
-static void image_write_l PARAMS ((bfd *abfd, unsigned long value));
-static void image_write_q PARAMS ((bfd *abfd, uquad value));
-
-/*-----------------------------------------------------------------------------*/
-
-#if 0
-
-/* Save location counter at index */
-
-static void
-location_save (abfd, index, loc, section)
- bfd *abfd;
- unsigned long index;
- unsigned long loc;
- int section;
-{
- PRIV(location_stack)[index].value = loc;
- PRIV(location_stack)[index].psect = section;
-
- return;
-}
-
-/* Restore location counter from index */
-
-static unsigned long
-location_restore (abfd, index, section)
- bfd *abfd;
- unsigned long index;
- int *section;
-{
- if (section != NULL)
- *section = PRIV(location_stack)[index].psect;
- return PRIV(location_stack)[index].value;
-}
-
-#endif /* 0 */
-\f
-/* routines to fill sections contents during etir read */
-
-/* Initialize image buffer pointer to be filled */
-
-static void
-image_set_ptr (abfd, psect, offset)
- bfd *abfd;
- int psect;
- uquad offset;
-{
-#if EVAX_DEBUG
- evax_debug (4, "image_set_ptr(%d=%s, %d)\n",
- psect, PRIV(sections)[psect]->name, offset);
-#endif
-
- PRIV(image_ptr) = PRIV(sections)[psect]->contents + offset;
- return;
-}
-
-
-/* Increment image buffer pointer by offset */
-
-static void
-image_inc_ptr (abfd, offset)
- bfd *abfd;
- uquad offset;
-{
-#if EVAX_DEBUG
- evax_debug (4, "image_inc_ptr(%d)\n", offset);
-#endif
-
- PRIV(image_ptr) += offset;
-
- return;
-}
-
-
-/* Dump multiple bytes to section image */
-
-static void
-image_dump (abfd, ptr, size, offset)
- bfd *abfd;
- unsigned char *ptr;
- int size;
- int offset;
-{
-#if EVAX_DEBUG
- evax_debug (6, "image_dump from (%p, %d) to (%p)\n", ptr, size, PRIV(image_ptr));
- _bfd_hexdump (7, ptr, size, offset);
-#endif
-
- while (size-- > 0)
- *PRIV(image_ptr)++ = *ptr++;
- return;
-}
-
-
-/* Write byte to section image */
-
-static void
-image_write_b (abfd, value)
- bfd *abfd;
- unsigned int value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "image_write_b(%02x)\n", (int)value);
-#endif
-
- *PRIV(image_ptr)++ = (value & 0xff);
- return;
-}
-
-
-/* Write 2-byte word to image */
-
-static void
-image_write_w (abfd, value)
- bfd *abfd;
- unsigned int value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "image_write_w(%04x)\n", (int)value);
-#endif
-
- bfd_putl16 (value, PRIV(image_ptr));
- PRIV(image_ptr) += 2;
-
- return;
-}
-
-
-/* Write 4-byte long to image */
-
-static void
-image_write_l (abfd, value)
- bfd *abfd;
- unsigned long value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "image_write_l(%08lx)\n", value);
-#endif
-
- bfd_putl32 (value, PRIV(image_ptr));
- PRIV(image_ptr) += 4;
-
- return;
-}
-
-
-/* Write 4-byte long to image */
-
-static void
-image_write_q (abfd, value)
- bfd *abfd;
- uquad value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "image_write_q(%016lx)\n", value);
-#endif
-
- bfd_putl64 (value, PRIV(image_ptr));
- PRIV(image_ptr) += 8;
-
- return;
-}
-\f
-
-#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
-
-/* etir_sta
-
- evax 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 boolean
-etir_sta (abfd, cmd, ptr)
- bfd *abfd;
- int cmd;
- unsigned char *ptr;
-{
-
- switch (cmd)
- {
- /* stack */
-
- /* 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;
- evax_symbol_entry *entry;
-
- name = _bfd_evax_save_counted_string ((char *)ptr);
- entry = (evax_symbol_entry *)
- bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
- if (entry == (evax_symbol_entry *)NULL)
- {
-#if EVAX_DEBUG
- evax_debug (3, "ETIR_S_C_STA_GBL: no symbol \"%s\"\n", name);
-#endif
- return false;
- }
- else
- {
- _bfd_evax_push (abfd, (uquad)(entry->symbol->value), -1);
- }
- }
- break;
-
- /* stack longword
- arg: lw value
-
- stack 32 bit value, sign extend to 64 bit */
-
- case ETIR_S_C_STA_LW:
- _bfd_evax_push (abfd, (uquad)bfd_getl32 (ptr), -1);
- break;
-
- /* stack global
- arg: qw value
-
- stack 64 bit value of symbol */
-
- case ETIR_S_C_STA_QW:
- _bfd_evax_push (abfd, (uquad)bfd_getl64(ptr), -1);
- 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 (psect >= PRIV(egsd_sec_count))
- {
- (*_bfd_error_handler) (_("Bad section index in ETIR_S_C_STA_PQ"));
- bfd_set_error (bfd_error_bad_value);
- return false;
- }
- dummy = bfd_getl64 (ptr+4);
- _bfd_evax_push (abfd, dummy, psect);
- }
- break;
-
- /* all not supported */
-
- case ETIR_S_C_STA_LI:
- case ETIR_S_C_STA_MOD:
- case ETIR_S_C_STA_CKARG:
-
- (*_bfd_error_handler) (_("Unsupported STA cmd %d"), cmd);
- return false;
- break;
-
- default:
- (*_bfd_error_handler) (_("Reserved STA cmd %d"), cmd);
- return false;
- break;
- }
- return true;
-}
-
-
-/*
- etir_sto
-
- evax 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 boolean
-etir_sto (abfd, cmd, ptr)
- bfd *abfd;
- int cmd;
- unsigned char *ptr;
-{
- uquad dummy;
- int psect;
-
- switch (cmd)
- {
-
- /* store byte: pop stack, write byte
- arg: - */
-
- case ETIR_S_C_STO_B:
- dummy = _bfd_evax_pop (abfd, &psect);
-#if 0
- if (is_share) /* FIXME */
- (*_bfd_error_handler) ("ETIR_S_C_STO_B: byte fixups not supported");
-#endif
- image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
- break;
-
- /* store word: pop stack, write word
- arg: - */
-
- case ETIR_S_C_STO_W:
- dummy = _bfd_evax_pop (abfd, &psect);
-#if 0
- if (is_share) /* FIXME */
- (*_bfd_error_handler) ("ETIR_S_C_STO_B: word fixups not supported");
-#endif
- image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
- break;
-
- /* store longword: pop stack, write longword
- arg: - */
-
- case ETIR_S_C_STO_LW:
- dummy = _bfd_evax_pop (abfd, &psect);
- dummy += (PRIV(sections)[psect])->vma;
- image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
-#if 0 /* FIXME */
- if (is_rel)
- evax_debug (3, "ETIR_S_C_STO_LW: Relocation !\n");
- if (is_share)
- evax_debug (3, "ETIR_S_C_STO_LW: Fix-up share !\n");
-#endif
- break;
-
- /* store quadword: pop stack, write quadword
- arg: - */
-
- case ETIR_S_C_STO_QW:
- dummy = _bfd_evax_pop (abfd, &psect);
- dummy += (PRIV(sections)[psect])->vma;
- image_write_q(abfd, dummy); /* FIXME: check top bits */
-#if 0 /* FIXME */
- if (is_rel)
- evax_debug (3, "ETIR_S_C_STO_LW: Relocation !\n");
- if (is_share)
- evax_debug (3, "ETIR_S_C_STO_LW: Fix-up share !\n");
-#endif
- break;
-
- /* store immediate repeated: pop stack for repeat count
- arg: lw byte count
- da data */
-
- case ETIR_S_C_STO_IMMR:
- {
- unsigned long size;
-
- size = bfd_getl32 (ptr);
- dummy = (unsigned long)_bfd_evax_pop (abfd, NULL);
- while (dummy-- > 0L)
- image_dump (abfd, ptr+4, size, 0);
- }
- break;
-
- /* store global: write symbol value
- arg: cs global symbol name */
-
- case ETIR_S_C_STO_GBL:
- {
- evax_symbol_entry *entry;
- char *name;
-
- name = _bfd_evax_save_counted_string ((char *)ptr);
- entry = (evax_symbol_entry *)bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
- if (entry == (evax_symbol_entry *)NULL)
- {
- (*_bfd_error_handler) (_("ETIR_S_C_STO_GBL: no symbol \"%s\""),
- name);
- return false;
- }
- else
- image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
- }
- break;
-
- /* store code address: write address of entry point
- arg: cs global symbol name (procedure) */
-
- case ETIR_S_C_STO_CA:
- {
- evax_symbol_entry *entry;
- char *name;
-
- name = _bfd_evax_save_counted_string ((char *)ptr);
- entry = (evax_symbol_entry *) bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
- if (entry == (evax_symbol_entry *)NULL)
- {
- (*_bfd_error_handler) (_("ETIR_S_C_STO_CA: no symbol \"%s\""),
- name);
- return false;
- }
- else
- image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
- }
- break;
-
- /* not supported */
-
- case ETIR_S_C_STO_RB:
- case ETIR_S_C_STO_AB:
- (*_bfd_error_handler) (_("ETIR_S_C_STO_RB/AB: Not supported"));
- break;
-
- /* store offset to psect: pop stack, add low 32 bits to base of psect
- arg: - */
-
- case ETIR_S_C_STO_OFF:
- {
- uquad q;
- int psect;
-
- q = _bfd_evax_pop (abfd, &psect);
- q += (PRIV(sections)[psect])->vma;
- image_write_q (abfd, q);
- }
- 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);
- }
- 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:
- {
- evax_symbol_entry *entry;
- char *name;
-
- name = _bfd_evax_save_counted_string ((char *)ptr);
- entry = (evax_symbol_entry *)bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
- if (entry == (evax_symbol_entry *)NULL)
- {
-#if EVAX_DEBUG
- evax_debug (3, "ETIR_S_C_STO_GBL_LW: no symbol \"%s\"\n", name);
-#endif
- return false;
- }
- else
- image_write_l (abfd, (unsigned long)(entry->symbol->value)); /* FIXME, reloc */
- }
- break;
-
- /* not supported */
-
- case ETIR_S_C_STO_LP_PSB:
- (*_bfd_error_handler) (_("ETIR_S_C_STO_LP_PSB: Not supported"));
- break;
-
- /* */
-
- case ETIR_S_C_STO_HINT_GBL:
- (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_GBL: not implemented"));
- break;
-
- /* */
-
- case ETIR_S_C_STO_HINT_PS:
- (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_PS: not implemented"));
- break;
-
- default:
- (*_bfd_error_handler) (_("Reserved STO cmd %d"), cmd);
- break;
- }
-
- 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 boolean
-etir_opr (abfd, cmd, ptr)
- bfd *abfd;
- int cmd;
- unsigned char *ptr;
-{
- long op1, op2;
-
- switch (cmd)
- {
- /* operation */
-
- /* no-op */
-
- case ETIR_S_C_OPR_NOP:
- break;
-
- /* add */
-
- case ETIR_S_C_OPR_ADD:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op1 + op2), -1);
- break;
-
- /* subtract */
-
- case ETIR_S_C_OPR_SUB:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op2 - op1), -1);
- break;
-
- /* multiply */
-
- case ETIR_S_C_OPR_MUL:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op1 * op2), -1);
- break;
-
- /* divide */
-
- case ETIR_S_C_OPR_DIV:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- if (op2 == 0)
- _bfd_evax_push (abfd, (uquad)0L, -1);
- else
- _bfd_evax_push (abfd, (uquad)(op2 / op1), -1);
- break;
-
- /* logical and */
-
- case ETIR_S_C_OPR_AND:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op1 & op2), -1);
- break;
-
- /* logical inclusive or */
-
- case ETIR_S_C_OPR_IOR:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op1 | op2), -1);
- break;
-
- /* logical exclusive or */
-
- case ETIR_S_C_OPR_EOR:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op1 ^ op2), -1);
- break;
-
- /* negate */
-
- case ETIR_S_C_OPR_NEG:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(-op1), -1);
- break;
-
- /* complement */
-
- case ETIR_S_C_OPR_COM:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)(op1 ^ -1L), -1);
- break;
-
- /* insert field */
-
- case ETIR_S_C_OPR_INSV:
- (void)_bfd_evax_pop (abfd, NULL);
- (*_bfd_error_handler) (_("ETIR_S_C_OPR_INSV: Not supported"));
- break;
-
- /* arithmetic shift */
-
- case ETIR_S_C_OPR_ASH:
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- op2 = (long)_bfd_evax_pop (abfd, NULL);
- if (op2 < 0) /* shift right */
- op1 >>= -op2;
- else /* shift left */
- op1 <<= op2;
- _bfd_evax_push (abfd, (uquad)op1, -1);
- break;
-
- /* unsigned shift */
-
- case ETIR_S_C_OPR_USH:
- (*_bfd_error_handler) (_("ETIR_S_C_OPR_USH: Not supported"));
- break;
-
- /* rotate */
-
- case ETIR_S_C_OPR_ROT:
- (*_bfd_error_handler) (_("ETIR_S_C_OPR_ROT: Not supported"));
- break;
-
- /* select */
-
- case ETIR_S_C_OPR_SEL:
- if ((long)_bfd_evax_pop (abfd, NULL) & 0x01L)
- (void)_bfd_evax_pop (abfd, NULL);
- else
- {
- op1 = (long)_bfd_evax_pop (abfd, NULL);
- (void)_bfd_evax_pop (abfd, NULL);
- _bfd_evax_push (abfd, (uquad)op1, -1);
- }
- break;
-
- /* redefine symbol to current location */
-
- case ETIR_S_C_OPR_REDEF:
- (*_bfd_error_handler) (_("ETIR_S_C_OPR_REDEF: Not supported"));
- break;
-
- /* define a literal */
-
- case ETIR_S_C_OPR_DFLIT:
- (*_bfd_error_handler) (_("ETIR_S_C_OPR_DFLIT: Not supported"));
- break;
-
- default:
- (*_bfd_error_handler) (_("Reserved OPR cmd %d"), cmd);
- break;
- }
-
- return true;
-}
-
-
-/* control commands
-
- see table B-11 of the openVMS linker manual */
-
-static boolean
-etir_ctl (abfd, cmd, ptr)
- bfd *abfd;
- int cmd;
- unsigned char *ptr;
-{
- uquad dummy;
- int psect;
-
- switch (cmd)
- {
- /* set relocation base: pop stack, set image location counter
- arg: - */
-
- case ETIR_S_C_CTL_SETRB:
- dummy = _bfd_evax_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: - */
-
- case ETIR_S_C_CTL_DFLOC:
- dummy = _bfd_evax_pop (abfd, NULL);
- /* FIXME */
- break;
-
- /* set location: pop index, restore location counter from index
- arg: - */
-
- case ETIR_S_C_CTL_STLOC:
- dummy = _bfd_evax_pop (abfd, &psect);
- /* FIXME */
- break;
-
- /* stack defined location: pop index, push location counter from index
- arg: - */
-
- case ETIR_S_C_CTL_STKDL:
- dummy = _bfd_evax_pop (abfd, &psect);
- /* FIXME */
- break;
-
- default:
- (*_bfd_error_handler) (_("Reserved CTL cmd %d"), cmd);
- break;
- }
- return true;
-}
-
-
-/* store conditional commands
-
- see table B-12 and B-13 of the openVMS linker manual */
-
-static boolean
-etir_stc (abfd, cmd, ptr)
- bfd *abfd;
- int cmd;
- unsigned char *ptr;
-{
-
- switch (cmd)
- {
- /* 200 Store-conditional Linkage Pair
- arg: */
-
- case ETIR_S_C_STC_LP:
- (*_bfd_error_handler) (_("ETIR_S_C_STC_LP: not supported"));
- break;
-
- /* 201 Store-conditional Linkage Pair with Procedure Signature
- arg: lw linkage index
- cs procedure name
- by signature length
- da signature */
-
- case ETIR_S_C_STC_LP_PSB:
- image_inc_ptr (abfd, 16); /* skip entry,procval */
- break;
-
- /* 202 Store-conditional Address at global address
- arg: lw linkage index
- cs global name */
-
- case ETIR_S_C_STC_GBL:
- (*_bfd_error_handler) (_("ETIR_S_C_STC_GBL: not supported"));
- break;
-
- /* 203 Store-conditional Code Address at global address
- arg: lw linkage index
- cs procedure name */
-
- case ETIR_S_C_STC_GCA:
- (*_bfd_error_handler) (_("ETIR_S_C_STC_GCA: not supported"));
- break;
-
- /* 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) (_("ETIR_S_C_STC_PS: not supported"));
- break;
-
- /* 205 Store-conditional NOP at address of global
- arg: */
-
- case ETIR_S_C_STC_NOP_GBL:
-
- /* 206 Store-conditional NOP at pect + offset
- arg: */
-
- case ETIR_S_C_STC_NOP_PS:
-
- /* 207 Store-conditional BSR at global address
- arg: */
-
- case ETIR_S_C_STC_BSR_GBL:
-
- /* 208 Store-conditional BSR at pect + offset
- arg: */
-
- case ETIR_S_C_STC_BSR_PS:
-
- /* 209 Store-conditional LDA at global address
- arg: */
-
- case ETIR_S_C_STC_LDA_GBL:
-
- /* 210 Store-conditional LDA at psect + offset
- arg: */
-
- case ETIR_S_C_STC_LDA_PS:
-
- /* 211 Store-conditional BSR or Hint at global address
- arg: */
-
- case ETIR_S_C_STC_BOH_GBL:
-
- /* 212 Store-conditional BSR or Hint at pect + offset
- arg: */
-
- case ETIR_S_C_STC_BOH_PS:
-
- /* 213 Store-conditional NOP,BSR or HINT at global address
- arg: */
-
- case ETIR_S_C_STC_NBH_GBL:
-
- /* 214 Store-conditional NOP,BSR or HINT at psect + offset
- arg: */
-
- case ETIR_S_C_STC_NBH_PS:
-/* FIXME (*_bfd_error_handler) ("ETIR_S_C_STC_xx: (%d) not supported", cmd); */
- break;
-
- default:
-#if EVAX_DEBUG
- evax_debug (3, "Reserved STC cmd %d", cmd);
-#endif
- break;
- }
- return true;
-}
-
-
-/* handle command from ETIR section */
-
-static boolean
-tir_cmd (abfd, cmd, ptr)
- bfd *abfd;
- int cmd;
- unsigned char *ptr;
-{
- static struct {
- int mincod;
- int maxcod;
- boolean (*explain) PARAMS((bfd *, int, unsigned char *));
- } tir_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;
- boolean res = true;
-
- while (tir_table[i].mincod >= 0)
- {
- if ( (tir_table[i].mincod <= cmd)
- && (cmd <= tir_table[i].maxcod))
- {
- res = tir_table[i].explain (abfd, cmd, ptr);
- break;
- }
- i++;
- }
-
- return res;
-}
-
-
-/* Text Information and Relocation Records (OBJ$C_TIR)
- handle etir record */
-
-static boolean
-analyze_etir (abfd, ptr, length)
- bfd *abfd;
- unsigned char *ptr;
- unsigned int length;
-{
- int cmd;
- unsigned char *maxptr;
- boolean res = true;
-
- maxptr = ptr + length;
-
- while (ptr < maxptr)
- {
- cmd = bfd_getl16 (ptr);
- length = bfd_getl16 (ptr + 2);
- res = tir_cmd (abfd, cmd, ptr+4);
- if (!res)
- break;
- ptr += length;
- }
- return res;
-}
-
-
-/* process ETIR record
-
- return 0 on success, -1 on error */
-
-int
-_bfd_evax_slurp_etir (abfd)
- bfd *abfd;
-{
-
-#if EVAX_DEBUG
- evax_debug (2, "ETIR\n");
-#endif
-
- PRIV(evax_rec) += 4; /* skip type, size */
- PRIV(rec_size) -= 4;
- if (analyze_etir (abfd, PRIV(evax_rec), PRIV(rec_size)))
- return 0;
-
- return -1;
-}
-
-
-/* process EDBG record
- return 0 on success, -1 on error
-
- not implemented yet */
-
-int
-_bfd_evax_slurp_edbg (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (2, "EDBG\n");
-#endif
-
- abfd->flags |= (HAS_DEBUG | HAS_LINENO);
- return 0;
-}
-
-
-/* process ETBT record
- return 0 on success, -1 on error
-
- not implemented yet */
-
-int
-_bfd_evax_slurp_etbt (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (2, "ETBT\n");
-#endif
-
- return 0;
-}
-\f
-/*----------------------------------------------------------------------*/
-/* */
-/* WRITE ETIR SECTION */
-/* */
-/* this is still under construction and therefore not documented */
-/* */
-/*----------------------------------------------------------------------*/
-
-static void start_etir_record PARAMS ((bfd *abfd, int index, uquad offset, boolean justoffset));
-static void sto_imm PARAMS ((bfd *abfd, evax_section *sptr, bfd_vma vaddr, int index));
-static void end_etir_record PARAMS ((bfd *abfd));
-
-static void
-sto_imm (abfd, sptr, vaddr, index)
- bfd *abfd;
- evax_section *sptr;
- bfd_vma vaddr;
- int index;
-{
- int size;
- int ssize;
- unsigned char *cptr;
-
-#if EVAX_DEBUG
- evax_debug (8, "sto_imm %d bytes\n", sptr->size);
- _bfd_hexdump (9, sptr->contents, (int)sptr->size, (int)vaddr);
-#endif
-
- ssize = sptr->size;
- cptr = sptr->contents;
-
- while (ssize > 0)
- {
-
- size = ssize; /* try all the rest */
-
- if (_bfd_evax_output_check (abfd, size) < 0)
- { /* doesn't fit, split ! */
- end_etir_record (abfd);
- start_etir_record (abfd, index, vaddr, false);
- size = _bfd_evax_output_check (abfd, 0); /* get max size */
- if (size > ssize) /* more than what's left ? */
- size = ssize;
- }
-
- _bfd_evax_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
- _bfd_evax_output_long (abfd, (unsigned long)(size));
- _bfd_evax_output_dump (abfd, cptr, size);
- _bfd_evax_output_flush (abfd);
-
-#if EVAX_DEBUG
- evax_debug (10, "dumped %d bytes\n", size);
- _bfd_hexdump (10, cptr, (int)size, (int)vaddr);
-#endif
-
- vaddr += size;
- ssize -= size;
- cptr += size;
- }
-
- return;
-}
-
-/*-------------------------------------------------------------------*/
-
-/* start ETIR record for section #index at virtual addr offset. */
-
-static void
-start_etir_record (abfd, index, offset, justoffset)
- bfd *abfd;
- int index;
- uquad offset;
- boolean justoffset;
-{
- if (!justoffset)
- {
- _bfd_evax_output_begin (abfd, EOBJ_S_C_ETIR, -1); /* one ETIR per section */
- _bfd_evax_output_push (abfd);
- }
-
- _bfd_evax_output_begin (abfd, ETIR_S_C_STA_PQ, -1); /* push start offset */
- _bfd_evax_output_long (abfd, (unsigned long)index);
- _bfd_evax_output_quad (abfd, (uquad)offset);
- _bfd_evax_output_flush (abfd);
-
- _bfd_evax_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1); /* start = pop() */
- _bfd_evax_output_flush (abfd);
-
- return;
-}
-
-
-/* end etir record */
-static void
-end_etir_record (abfd)
- bfd *abfd;
-{
- _bfd_evax_output_pop (abfd);
- _bfd_evax_output_end (abfd);
-}
-
-/* write section contents for bfd abfd */
-
-int
-_bfd_evax_write_etir (abfd)
- bfd *abfd;
-{
- asection *section;
- evax_section *sptr;
- int nextoffset;
-
-#if EVAX_DEBUG
- evax_debug (2, "evax_write_etir(%p)\n", abfd);
-#endif
-
- _bfd_evax_output_alignment (abfd, 4);
-
- nextoffset = 0;
- PRIV(evax_linkage_index) = 1;
-
- /* dump all other sections */
-
- section = abfd->sections;
-
- while (section != NULL)
- {
-
-#if EVAX_DEBUG
- evax_debug (4, "writing %d. section '%s' (%d bytes)\n", section->index, section->name, (int)(section->_raw_size));
-#endif
-
- if (section->flags & SEC_RELOC)
- {
- int i;
-
- if ((i = section->reloc_count) <= 0)
- {
- (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
- section->name);
- }
-#if EVAX_DEBUG
- else
- {
- arelent **rptr;
- evax_debug (4, "%d relocations:\n", i);
- rptr = section->orelocation;
- while (i-- > 0)
- {
- evax_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
- }
-
- if ((section->flags & SEC_HAS_CONTENTS)
- && (! bfd_is_com_section (section)))
- {
- bfd_vma vaddr; /* virtual addr in section */
-
- sptr = _bfd_get_evax_section (abfd, section->index);
- if (sptr == NULL)
- {
- bfd_set_error (bfd_error_no_contents);
- return -1;
- }
-
- vaddr = (bfd_vma)(sptr->offset);
-
- start_etir_record (abfd, section->index, (uquad) sptr->offset,
- false);
-
- while (sptr != NULL) /* one STA_PQ, CTL_SETRB per evax_section */
- {
-
- if (section->flags & SEC_RELOC) /* check for relocs */
- {
- arelent **rptr = section->orelocation;
- int i = section->reloc_count;
- for (;;)
- {
- bfd_size_type addr = (*rptr)->address;
- int len = bfd_get_reloc_size ((*rptr)->howto);
- if (sptr->offset < addr) /* sptr starts before reloc */
- {
- int before = addr - sptr->offset;
- if (sptr->size <= before) /* complete before */
- {
- sto_imm (abfd, sptr, vaddr, section->index);
- vaddr += sptr->size;
- break;
- }
- else /* partly before */
- {
- int after = sptr->size - before;
- sptr->size = before;
- sto_imm (abfd, sptr, vaddr, section->index);
- vaddr += sptr->size;
- sptr->contents += before;
- sptr->offset += before;
- sptr->size = after;
- }
- }
- else if (sptr->offset == addr) /* sptr starts at reloc */
- {
- asymbol *sym = *(*rptr)->sym_ptr_ptr;
- asection *sec = sym->section;
-
- switch ((*rptr)->howto->type)
- {
- case ALPHA_R_IGNORE:
- break;
-
- case ALPHA_R_REFLONG:
- {
- if (bfd_is_und_section (sym->section))
- {
- if (_bfd_evax_output_check (abfd,
- strlen((char *)sym->name))
- < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_GBL_LW,
- -1);
- _bfd_evax_output_counted (abfd,
- _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
- _bfd_evax_output_flush (abfd);
- }
- else if (bfd_is_abs_section (sym->section))
- {
- if (_bfd_evax_output_check (abfd, 16) < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STA_LW,
- -1);
- _bfd_evax_output_quad (abfd,
- (uquad)sym->value);
- _bfd_evax_output_flush (abfd);
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_LW,
- -1);
- _bfd_evax_output_flush (abfd);
- }
- else
- {
- if (_bfd_evax_output_check (abfd, 32) < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STA_PQ,
- -1);
- _bfd_evax_output_long (abfd,
- (unsigned long)(sec->index));
- _bfd_evax_output_quad (abfd,
- ((uquad)(*rptr)->addend
- + (uquad)sym->value));
- _bfd_evax_output_flush (abfd);
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_LW,
- -1);
- _bfd_evax_output_flush (abfd);
- }
- }
- break;
-
- case ALPHA_R_REFQUAD:
- {
- if (bfd_is_und_section (sym->section))
- {
- if (_bfd_evax_output_check (abfd,
- strlen((char *)sym->name))
- < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_GBL,
- -1);
- _bfd_evax_output_counted (abfd,
- _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
- _bfd_evax_output_flush (abfd);
- }
- else if (bfd_is_abs_section (sym->section))
- {
- if (_bfd_evax_output_check (abfd, 16) < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STA_QW,
- -1);
- _bfd_evax_output_quad (abfd,
- (uquad)sym->value);
- _bfd_evax_output_flush (abfd);
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_QW,
- -1);
- _bfd_evax_output_flush (abfd);
- }
- else
- {
- if (_bfd_evax_output_check (abfd, 32) < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STA_PQ,
- -1);
- _bfd_evax_output_long (abfd,
- (unsigned long)(sec->index));
- _bfd_evax_output_quad (abfd,
- ((uquad)(*rptr)->addend
- + (uquad)sym->value));
- _bfd_evax_output_flush (abfd);
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_OFF,
- -1);
- _bfd_evax_output_flush (abfd);
- }
- }
- break;
-
- case ALPHA_R_HINT:
- {
- int hint_size;
-
- hint_size = sptr->size;
- sptr->size = len;
- sto_imm (abfd, sptr, vaddr, section->index);
- sptr->size = hint_size;
-#if 0
- evax_output_begin(abfd, ETIR_S_C_STO_HINT_GBL, -1);
- evax_output_long(abfd, (unsigned long)(sec->index));
- evax_output_quad(abfd, (uquad)addr);
-
- evax_output_counted(abfd, _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
- evax_output_flush(abfd);
-#endif
- }
- break;
- case ALPHA_R_LINKAGE:
- {
- if (_bfd_evax_output_check (abfd, 64) < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd, section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STC_LP_PSB,
- -1);
- _bfd_evax_output_long (abfd,
- (unsigned long)PRIV(evax_linkage_index));
- PRIV(evax_linkage_index) += 2;
- _bfd_evax_output_counted (abfd,
- _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
- _bfd_evax_output_byte (abfd, 0);
- _bfd_evax_output_flush (abfd);
- }
- break;
-
- case ALPHA_R_CODEADDR:
- {
- if (_bfd_evax_output_check (abfd,
- strlen((char *)sym->name))
- < 0)
- {
- end_etir_record (abfd);
- start_etir_record (abfd,
- section->index,
- vaddr, false);
- }
- _bfd_evax_output_begin (abfd,
- ETIR_S_C_STO_CA,
- -1);
- _bfd_evax_output_counted (abfd,
- _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
- _bfd_evax_output_flush (abfd);
- }
- break;
-
- default:
- (*_bfd_error_handler) (_("Unhandled relocation %s"),
- (*rptr)->howto->name);
- break;
- }
-
- vaddr += len;
-
- if (len == sptr->size)
- {
- break;
- }
- else
- {
- sptr->contents += len;
- sptr->offset += len;
- sptr->size -= len;
- i--;
- rptr++;
- }
- }
- else /* sptr starts after reloc */
- {
- i--; /* check next reloc */
- rptr++;
- }
-
- if (i==0) /* all reloc checked */
- {
- if (sptr->size > 0)
- {
- sto_imm (abfd, sptr, vaddr, section->index); /* dump rest */
- vaddr += sptr->size;
- }
- break;
- }
- } /* for (;;) */
- } /* if SEC_RELOC */
- else /* no relocs, just dump */
- {
- sto_imm (abfd, sptr, vaddr, section->index);
- vaddr += sptr->size;
- }
-
- sptr = sptr->next;
-
- } /* while (sptr != 0) */
-
- end_etir_record (abfd);
-
- } /* has_contents */
-
- section = section->next;
- }
-
- _bfd_evax_output_alignment(abfd, 2);
- return 0;
-}
-
-
-/* write traceback data for bfd abfd */
-
-int
-_bfd_evax_write_etbt (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (2, "evax_write_etbt(%p)\n", abfd);
-#endif
-
- return 0;
-}
-
-
-/* write debug info for bfd abfd */
-
-int
-_bfd_evax_write_edbg (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (2, "evax_write_edbg(%p)\n", abfd);
-#endif
-
- return 0;
-}
+++ /dev/null
-/* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
-
- Written by Klaus K"ampf (kkaempf@progis.de)
- of proGIS Softwareentwicklung, Aachen, Germany
-
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-
-#if __STDC__
-#include <stdarg.h>
-#endif
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bfdlink.h"
-#include "libbfd.h"
-
-#include "evax.h"
-
-/*-----------------------------------------------------------------------------*/
-#if EVAX_DEBUG
-/* debug functions */
-
-/* debug function for all evax extensions
- evaluates environment variable EVAX_DEBUG for a
- numerical value on the first call
- all error levels below this value are printed
-
- levels:
- 1 toplevel bfd calls (functions from the bfd vector)
- 2 functions called by bfd calls
- ...
- 9 almost everything
-
- level is also identation level. Indentation is performed
- if level > 0
- */
-
-#if __STDC__
-void
-_bfd_evax_debug (int level, char *format, ...)
-{
- static int min_level = -1;
- static FILE *output = NULL;
- char *eptr;
- va_list args;
- int abslvl = (level > 0)?level:-level;
-
- if (min_level == -1)
- {
- if ((eptr = getenv("EVAX_DEBUG")) != NULL)
- {
- min_level = atoi(eptr);
- output = stderr;
- }
- else
- min_level = 0;
- }
- if (output == NULL)
- return;
- if (abslvl > min_level)
- return;
-
- while(--level>0)
- fprintf(output, " ");
- va_start(args, format);
- vfprintf(output, format, args);
- fflush(output);
- va_end(args);
-
- return;
-}
-
-#else /* not __STDC__ */
-
-void
-_bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6)
- int level;
- char *format;
- long a1; long a2; long a3;
- long a4; long a5; long a6;
-{
- static int min_level = -1;
- static FILE *output = NULL;
- char *eptr;
-
- if (min_level == -1)
- {
- if ((eptr = getenv("EVAX_DEBUG")) != NULL)
- {
- min_level = atoi(eptr);
- output = stderr;
- }
- else
- min_level = 0;
- }
- if (output == NULL)
- return;
- if (level > min_level)
- return;
-
- while(--level>0)
- fprintf(output, " ");
- fprintf(output, format, a1, a2, a3, a4, a5, a6);
- fflush(output);
-
- return;
-}
-#endif /* __STDC__ */
-
-
-/* a debug function
- hex dump 'size' bytes starting at 'ptr' */
-
-void
-_bfd_hexdump (level, ptr, size, offset)
- int level;
- unsigned char *ptr;
- int size;
- int offset;
-{
- unsigned char *lptr = ptr;
- int count = 0;
- long start = offset;
-
- while (size-- > 0)
- {
- if ((count%16) == 0)
- evax_debug (level, "%08lx:", start);
- evax_debug (-level, " %02x", *ptr++);
- count++;
- start++;
- if (size == 0)
- {
- while ((count%16) != 0)
- {
- evax_debug (-level, " ");
- count++;
- }
- }
- if ((count%16) == 0)
- {
- evax_debug (-level, " ");
- while (lptr < ptr)
- {
- evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
- lptr++;
- }
- evax_debug (-level, "\n");
- }
- }
- if ((count%16) != 0)
- evax_debug (-level, "\n");
-
- return;
-}
-#endif
-
-\f
-/* hash functions
-
- These are needed when reading an object file. */
-
-/* allocate new evax_hash_entry
- keep the symbol name and a pointer to the bfd symbol in the table */
-
-struct bfd_hash_entry *
-_bfd_evax_hash_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
-{
- evax_symbol_entry *ret = (evax_symbol_entry *)entry;
-
-#if EVAX_DEBUG
- evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string);
-#endif
-
- if (ret == (evax_symbol_entry *)NULL)
- ret = ((evax_symbol_entry *) bfd_hash_allocate (table, sizeof (evax_symbol_entry)));
- if (ret == (evax_symbol_entry *)NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return (struct bfd_hash_entry *)NULL;
- }
- ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
-
- ret->symbol = (asymbol *)NULL;
-
- return (struct bfd_hash_entry *)ret;
-}
-
-\f
-/* object file input functions */
-
-/* Return type and length from record header (buf) */
-
-void
-_bfd_evax_get_header_values (abfd, buf, type, length)
- bfd *abfd;
- unsigned char *buf;
- int *type;
- int *length;
-{
- if (type != 0)
- *type = bfd_getl16 (buf);
- buf += 2;
- if (length != 0)
- *length = bfd_getl16 (buf);
-
- return;
-}
-
-
-/* Get next record from object file to evax_buf
- set PRIV(buf_size) and return it
-
- this is a little tricky since it should be portable.
-
- the openVMS/AXP object file has 'variable length' which means that
- read() returns data in chunks of (hopefully) correct and expected
- size. The linker (and other tools on vms) depend on that. Unix doesn't
- know about 'formatted' files, so reading and writing such an object
- file in a unix environment is not trivial.
-
- With the tool 'file' (available on all vms ftp sites), one
- can view and change the attributes of a file. Changing from
- 'variable length' to 'fixed length, 512 bytes' reveals the
- record length at the first 2 bytes of every record. The same
- happens during the transfer of object files from vms to unix,
- at least with ucx, dec's implementation of tcp/ip.
-
- The EVAX format repeats the length at bytes 2 & 3 of every record.
-
- On the first call (file_format == FF_UNKNOWN) we check if
- the first and the third byte pair (!) of the record match.
- If they do it's an object file in an unix environment or with
- wrong attributes (FF_FOREIGN), else we should be in a vms
- environment where read() returns the record size (FF_NATIVE).
-
- reading is always done in 2 steps.
- first just the record header is read and the length extracted
- by get_header_values
- then the read buffer is adjusted and the remaining bytes are
- read in.
-
- all file i/o is always done on even file positions */
-
-int
-_bfd_evax_get_record (abfd)
- bfd *abfd;
-{
- int test_len, test_start, remaining;
- unsigned char *evax_buf;
-
-#if EVAX_DEBUG
- evax_debug (8, "_bfd_evax_get_record\n");
-#endif
-
- /* minimum is 6 bytes
- (2 bytes length, 2 bytes record id, 2 bytes length repeated) */
-
- if (PRIV(buf_size) == 0)
- {
- PRIV(evax_buf) = (unsigned char *) malloc (6);
-#if EVAX_DEBUG
- evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf));
-#endif
- }
-
- evax_buf = PRIV(evax_buf);
-
- if (evax_buf == 0)
- {
-#if EVAX_DEBUG
- evax_debug (9, "can't alloc evax_buf\n");
-#endif
- bfd_set_error (bfd_error_no_memory);
- return -1;
- }
-
- switch (PRIV(file_format))
- {
- case FF_UNKNOWN:
- case FF_FOREIGN:
- test_len = 6; /* probe 6 bytes */
- test_start = 2; /* where the record starts */
- break;
-
- case FF_NATIVE:
- test_len = 4;
- test_start = 0;
- break;
- }
-
- /* skip odd alignment byte */
-#if 0
- if (PRIV(file_format) == FF_FOREIGN)
- {
-#endif
- if (bfd_tell (abfd) & 1)
- {
-#if EVAX_DEBUG
- evax_debug (10, "skip odd\n");
-#endif
- if (bfd_read (PRIV(evax_buf), 1, 1, abfd) != 1)
- {
-#if EVAX_DEBUG
- evax_debug (9, "skip odd failed\n");
-#endif
- bfd_set_error (bfd_error_file_truncated);
- return 0;
- }
- }
-#if 0
- }
-#endif
- /* read the record header */
-
- if (bfd_read (PRIV(evax_buf), 1, test_len, abfd) != test_len)
- {
-#if EVAX_DEBUG
- evax_debug (9, "can't bfd_read test %d bytes\n", test_len);
-#endif
- bfd_set_error (bfd_error_file_truncated);
- return 0;
- }
-
- /* check file format on first call */
-
- if (PRIV(file_format) == FF_UNKNOWN)
- { /* record length repeats ? */
- if ( (evax_buf[0] == evax_buf[4])
- && (evax_buf[1] == evax_buf[5]))
- {
- PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */
- test_start = 2;
- }
- else
- {
- PRIV(file_format) = FF_NATIVE; /* N: native environment */
- test_start = 0;
- }
-#if EVAX_DEBUG
- evax_debug (10, "File format is %s\n", (PRIV(file_format) == FF_FOREIGN)?"foreign":"native");
-#endif
- }
-
- /* extract evax record length */
-
- _bfd_evax_get_header_values (abfd, evax_buf+test_start, NULL,
- &PRIV(rec_length));
-
- if (PRIV(rec_length) <= 0)
- {
- bfd_set_error (bfd_error_file_truncated);
- return 0;
- }
-
- /* that's what the linker manual says */
-
- if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
- {
- bfd_set_error (bfd_error_file_truncated);
- return 0;
- }
-
- /* adjust the buffer */
-
- if (PRIV(rec_length) > PRIV(buf_size))
- {
- PRIV(evax_buf) = (unsigned char *) realloc (evax_buf, PRIV(rec_length));
-#if EVAX_DEBUG
- evax_debug (3, "adjusted the buffer (%p) from %d to %d\n", PRIV(evax_buf), PRIV(buf_size), PRIV(rec_length));
-#endif
- evax_buf = PRIV(evax_buf);
- if (evax_buf == 0)
- {
-#if EVAX_DEBUG
- evax_debug (9, "can't realloc evax_buf to %d bytes\n", PRIV(rec_length));
-#endif
- bfd_set_error (bfd_error_no_memory);
- return -1;
- }
- PRIV(buf_size) = PRIV(rec_length);
- }
-
- /* read the remaining record */
-
- remaining = PRIV(rec_length) - test_len + test_start;
-
- if (bfd_read (evax_buf + test_len, 1, remaining, abfd) != remaining)
- {
-#if EVAX_DEBUG
- evax_debug (9, "can't bfd_read remaining %d bytes\n", remaining);
-#endif
- bfd_set_error (bfd_error_file_truncated);
- return 0;
- }
-
- PRIV(evax_rec) = evax_buf + test_start;
-
- return PRIV(rec_length);
-}
-
-
-/* get next EVAX record from file
- update evax_rec and rec_length to new (remaining) values */
-
-int
-_bfd_evax_next_record (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n",
- PRIV(rec_length), PRIV(rec_size));
-#endif
-
- if (PRIV(rec_length) > 0)
- {
- PRIV(evax_rec) += PRIV(rec_size);
- }
- else
- {
- if (_bfd_evax_get_record (abfd) <= 0)
- return -1;
- }
- _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type),
- &PRIV(rec_size));
- PRIV(rec_length) -= PRIV(rec_size);
-
-#if EVAX_DEBUG
- evax_debug (8, "_bfd_evax_next_record: rec %p, size %d, length %d, type %d\n",
- PRIV(evax_rec), PRIV(rec_size), PRIV(rec_length),
- PRIV(rec_type));
-#endif
-
- return PRIV(rec_type);
-}
-
-
-\f
-/* Copy sized string (string with fixed length) to new allocated area
- size is string length (size of record) */
-
-char *
-_bfd_evax_save_sized_string (str, size)
- char *str;
- int size;
-{
- char *newstr = bfd_malloc (size + 1);
-
- if (newstr == NULL)
- return 0;
- strncpy (newstr, str, size);
- newstr[size] = 0;
-
- return newstr;
-}
-
-/* Copy counted string (string with length at first byte) to new allocated area
- ptr points to length byte on entry */
-
-char *
-_bfd_evax_save_counted_string (ptr)
- char *ptr;
-{
- int len = *ptr++;
-
- return _bfd_evax_save_sized_string (ptr, len);
-}
-
-\f
-/* stack routines for EVAX ETIR commands */
-
-/* Push value and section index */
-
-void
-_bfd_evax_push (abfd, val, psect)
- bfd *abfd;
- uquad val;
- int psect;
-{
- static int last_psect;
-
-#if EVAX_DEBUG
- evax_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
-#endif
-
- if (psect >= 0)
- last_psect = psect;
-
- PRIV(stack[PRIV(stackptr)]).value = val;
- PRIV(stack[PRIV(stackptr)]).psect = last_psect;
- PRIV(stackptr)++;
- if (PRIV(stackptr) >= STACKSIZE)
- {
- bfd_set_error (bfd_error_bad_value);
- exit(1);
- }
- return;
-}
-
-
-/* Pop value and section index */
-
-uquad
-_bfd_evax_pop (abfd, psect)
- bfd *abfd;
- int *psect;
-{
- uquad value;
-
- if (PRIV(stackptr) == 0)
- {
- bfd_set_error (bfd_error_bad_value);
- exit(1);
- }
- PRIV(stackptr)--;
- value = PRIV(stack[PRIV(stackptr)]).value;
- if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
- *psect = PRIV(stack[PRIV(stackptr)]).psect;
-
-#if EVAX_DEBUG
- evax_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
-#endif
-
- return value;
-}
-
-\f
-/* object file output functions */
-
-/* GAS tends to write sections in little chunks (bfd_set_section_contents)
- which we can't use directly. So we save the little chunks in linked
- lists (one per section) and write them later. */
-
-/* Add a new evax_section structure to evax_section_table
- - forward chaining - */
-
-static evax_section *
-add_new_contents (abfd, section)
- bfd *abfd;
- sec_ptr section;
-{
- evax_section *sptr, *newptr;
-
- sptr = PRIV(evax_section_table)[section->index];
- if (sptr != NULL)
- return sptr;
-
- newptr = (evax_section *) bfd_malloc (sizeof (evax_section));
- if (newptr == (evax_section *) NULL)
- return NULL;
- newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
- if (newptr->contents == (unsigned char *)NULL)
- return NULL;
- newptr->offset = 0;
- newptr->size = section->_raw_size;
- newptr->next = 0;
- PRIV(evax_section_table)[section->index] = newptr;
- return newptr;
-}
-
-
-/* Save section data & offset to an evax_section structure
- evax_section_table[] holds the evax_section chain */
-
-boolean
-_bfd_save_evax_section (abfd, section, data, offset, count)
- bfd *abfd;
- sec_ptr section;
- PTR data;
- file_ptr offset;
- bfd_size_type count;
-{
- evax_section *sptr;
-
- if (section->index >= EVAX_SECTION_COUNT)
- {
- bfd_set_error (bfd_error_nonrepresentable_section);
- return false;
- }
- if (count == (bfd_size_type)0)
- return true;
- sptr = add_new_contents (abfd, section);
- if (sptr == NULL)
- return false;
- memcpy (sptr->contents + offset, data, (size_t) count);
-
- return true;
-}
-
-
-/* Get evax_section pointer to saved contents for section # index */
-
-evax_section *
-_bfd_get_evax_section (abfd, index)
- bfd *abfd;
- int index;
-{
- if (index >= EVAX_SECTION_COUNT)
- {
- bfd_set_error (bfd_error_nonrepresentable_section);
- return NULL;
- }
- return PRIV(evax_section_table)[index];
-}
-
-\f
-/* Object output routines */
-
-/* Begin new record or record header
- write 2 bytes rectype
- write 2 bytes record length (filled in at flush)
- write 2 bytes header type (ommitted if rechead == -1) */
-
-void
-_bfd_evax_output_begin (abfd, rectype, rechead)
- bfd *abfd;
- int rectype;
- int rechead;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype,
- rechead);
-#endif
-
- _bfd_evax_output_short (abfd,rectype);
-
- /* save current output position to fill in lenght later */
-
- if (PRIV(push_level) > 0)
- PRIV(length_pos) = PRIV(output_size);
-
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n",
- PRIV(length_pos));
-#endif
-
- _bfd_evax_output_short (abfd,0); /* placeholder for length */
-
- if (rechead != -1)
- _bfd_evax_output_short (abfd,rechead);
-
- return;
-}
-
-
-/* Set record/subrecord alignment */
-
-void
-_bfd_evax_output_alignment (abfd, alignto)
- bfd *abfd;
- int alignto;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto);
-#endif
-
- PRIV(output_alignment) = alignto;
- return;
-}
-
-
-/* Prepare for subrecord fields */
-
-void
-_bfd_evax_output_push (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size));
-#endif
-
- PRIV(push_level)++;
- PRIV(pushed_size) = PRIV(output_size);
- return;
-}
-
-
-/* End of subrecord fields */
-
-void
-_bfd_evax_output_pop (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
-#endif
-
- _bfd_evax_output_flush (abfd);
- PRIV(length_pos) = 2;
-
-#if EVAX_DEBUG
- evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos));
-#endif
-
- PRIV(pushed_size) = 0;
- PRIV(push_level)--;
- return;
-}
-
-
-/* Flush unwritten output, ends current record */
-
-void
-_bfd_evax_output_flush (abfd)
- bfd *abfd;
-{
- int real_size = PRIV(output_size);
- int aligncount;
- int length;
-
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
- real_size, PRIV(pushed_size), PRIV(length_pos));
-#endif
-
- if (PRIV(push_level) > 0)
- length = real_size - PRIV(pushed_size);
- else
- length = real_size;
-
- if (length == 0)
- return;
- aligncount = (PRIV(output_alignment)
- - (length % PRIV(output_alignment))) % PRIV(output_alignment);
-
-#if EVAX_DEBUG
- evax_debug (6, "align: adding %d bytes\n", aligncount);
-#endif
-
- while(aligncount-- > 0)
- {
- PRIV(output_buf)[real_size++] = 0;
-#if 0
- /* this is why I *love* vms: inconsistency :-}
- alignment is added to the subrecord length
- but not to the record length */
- if (PRIV(push_level) > 0)
-#endif
- length++;
- }
-
- /* put length to buffer */
- PRIV(output_size) = PRIV(length_pos);
- _bfd_evax_output_short (abfd, (unsigned int)length);
-
- if (PRIV(push_level) == 0)
- {
-#ifndef VMS
- /* write length first, see FF_FOREIGN in the input routines */
- fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
-#endif
- fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
-
- PRIV(output_size) = 0;
- }
- else
- {
- PRIV(output_size) = real_size;
- PRIV(pushed_size) = PRIV(output_size);
- }
-
- return;
-}
-
-
-/* End record output */
-
-void
-_bfd_evax_output_end (abfd)
- bfd *abfd;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_end\n");
-#endif
-
- _bfd_evax_output_flush (abfd);
-
- return;
-}
-
-
-/* check remaining buffer size
-
- return what's left. */
-
-int
-_bfd_evax_output_check (abfd, size)
- bfd *abfd;
- int size;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_check(%d)\n", size);
-#endif
-
- return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
-}
-
-
-/* Output byte (8 bit) value */
-
-void
-_bfd_evax_output_byte (abfd, value)
- bfd *abfd;
- unsigned int value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value);
-#endif
-
- bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
- PRIV(output_size) += 1;
- return;
-}
-
-
-/* Output short (16 bit) value */
-
-void
-_bfd_evax_output_short (abfd, value)
- bfd *abfd;
- unsigned int value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_short (%04x)\n", value);
-#endif
-
- bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
- PRIV(output_size) += 2;
- return;
-}
-
-
-/* Output long (32 bit) value */
-
-void
-_bfd_evax_output_long (abfd, value)
- bfd *abfd;
- unsigned long value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value);
-#endif
-
- bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
- PRIV(output_size) += 4;
- return;
-}
-
-
-/* Output quad (64 bit) value */
-
-void
-_bfd_evax_output_quad (abfd, value)
- bfd *abfd;
- uquad value;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value);
-#endif
-
- bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
- PRIV(output_size) += 8;
- return;
-}
-
-
-/* Output c-string as counted string */
-
-void
-_bfd_evax_output_counted (abfd, value)
- bfd *abfd;
- char *value;
-{
-int len;
-
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_counted(%s)\n", value);
-#endif
-
- len = strlen (value);
- if (len == 0)
- {
- (*_bfd_error_handler) (_("_bfd_evax_output_counted called with zero bytes"));
- return;
- }
- if (len > 255)
- {
- (*_bfd_error_handler) (_("_bfd_evax_output_counted called with too many bytes"));
- return;
- }
- _bfd_evax_output_byte (abfd, len & 0xff);
- _bfd_evax_output_dump (abfd, (unsigned char *)value, len);
-}
-
-
-/* Output character area */
-
-void
-_bfd_evax_output_dump (abfd, data, length)
- bfd *abfd;
- unsigned char *data;
- int length;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_dump(%d)\n", length);
-#endif
-
- if (length == 0)
- return;
-
- memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
- PRIV(output_size) += length;
-
- return;
-}
-
-
-/* Output count bytes of value */
-
-void
-_bfd_evax_output_fill (abfd, value, count)
- bfd *abfd;
- int value;
- int count;
-{
-#if EVAX_DEBUG
- evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count);
-#endif
-
- if (count == 0)
- return;
- memset (PRIV(output_buf) + PRIV(output_size), value, count);
- PRIV(output_size) += count;
-
- return;
-}
-
-/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
-
-static int
-hash_string (ptr)
- const char *ptr;
-{
- register const unsigned char *p = (unsigned char *) ptr;
- register const unsigned char *end = p + strlen (ptr);
- register unsigned char c;
- register int hash = 0;
-
- while (p != end)
- {
- c = *p++;
- hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
- }
- return hash;
-}
-
-/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
-
-char *
-_bfd_evax_length_hash_symbol (abfd, in, maxlen)
- bfd *abfd;
- const char *in;
- int maxlen;
-{
- long int init;
- long int result;
- int in_len;
- char *pnt = 0;
- char *new_name;
- const char *old_name;
- int i;
- static char outbuf[EOBJ_S_C_SYMSIZ+1];
- char *out = outbuf;
-
-#if EVAX_DEBUG
- evax_debug(4, "_bfd_evax_length_hash_symbol \"%s\"\n", in);
-#endif
-
- if (maxlen > EOBJ_S_C_SYMSIZ)
- maxlen = EOBJ_S_C_SYMSIZ;
-
- new_name = out; /* save this for later. */
-
- /* We may need to truncate the symbol, save the hash for later. */
-
- in_len = strlen (in);
-
- result = (in_len > maxlen) ? hash_string (in) : 0;
-
- old_name = in;
-
- /* Do the length checking. */
-
- if (in_len <= maxlen)
- {
- i = in_len;
- }
- else
- {
- if (PRIV(flag_hash_long_names))
- i = maxlen-9;
- else
- i = maxlen;
- }
-
- strncpy (out, in, i);
- in += i;
- out += i;
-
- if ((in_len > maxlen)
- && PRIV(flag_hash_long_names))
- sprintf (out, "_%08x", result);
- else
- *out = 0;
-
-#if EVAX_DEBUG
- evax_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
-#endif
-
- if (in_len > maxlen
- && PRIV(flag_hash_long_names)
- && PRIV(flag_show_after_trunc))
- printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
-
- return outbuf;
-}
-
+++ /dev/null
-/* evax.h -- Header file for ALPHA EVAX (openVMS/Alpha) support.
- Copyright 1996, 1997 Free Software Foundation, Inc.
-
- Written by Klaus K"ampf (kkaempf@progis.de)
- of proGIS Softwareentwicklung, Aachen, Germany
-
-This file is part of BFD, the Binary File Descriptor library.
-
-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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef EVAX_H
-#define EVAX_H
-
-/* EVAX Text, information and relocation record (ETIR) definitions. */
-
-#define ETIR_S_C_MINSTACOD 0 /* Minimum store code */
-#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value */
-#define ETIR_S_C_STA_LW 1 /* Stack longword */
-#define ETIR_S_C_STA_QW 2 /* Stack quadword */
-#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset */
-#define ETIR_S_C_STA_LI 4 /* Stack literal */
-#define ETIR_S_C_STA_MOD 5 /* Stack module */
-#define ETIR_S_C_STA_CKARG 6 /* Check Arguments */
-#define ETIR_S_C_MAXSTACOD 6 /* Maximum stack code */
-#define ETIR_S_C_MINSTOCOD 50 /* Minimum store code */
-#define ETIR_S_C_STO_B 50 /* Store byte */
-#define ETIR_S_C_STO_W 51 /* Store word */
-#define ETIR_S_C_STO_LW 52 /* Store longword */
-#define ETIR_S_C_STO_QW 53 /* Store quadword */
-#define ETIR_S_C_STO_IMMR 54 /* Store immediate Repeated */
-#define ETIR_S_C_STO_GBL 55 /* Store global */
-#define ETIR_S_C_STO_CA 56 /* Store code address */
-#define ETIR_S_C_STO_RB 57 /* Store relative branch */
-#define ETIR_S_C_STO_AB 58 /* Store absolute branch */
-#define ETIR_S_C_STO_OFF 59 /* Store offset within psect */
-#define ETIR_S_C_STO_IMM 61 /* Store immediate */
-#define ETIR_S_C_STO_GBL_LW 62 /* Store global Longword */
-#define ETIR_S_C_STO_LP_PSB 63 /* STO_LP_PSB not valid in level 2 use STC_LP_PSB */
-#define ETIR_S_C_STO_HINT_GBL 64 /* Store 14 bit HINT at global address */
-#define ETIR_S_C_STO_HINT_PS 65 /* Store 14 bit HINT at psect + offset */
-#define ETIR_S_C_MAXSTOCOD 65 /* Maximum store code */
-#define ETIR_S_C_MINOPRCOD 100 /* Minimum operate code */
-#define ETIR_S_C_OPR_NOP 100 /* No-op */
-#define ETIR_S_C_OPR_ADD 101 /* Add */
-#define ETIR_S_C_OPR_SUB 102 /* Subtract */
-#define ETIR_S_C_OPR_MUL 103 /* Multiply */
-#define ETIR_S_C_OPR_DIV 104 /* Divide */
-#define ETIR_S_C_OPR_AND 105 /* Logical AND */
-#define ETIR_S_C_OPR_IOR 106 /* Logical inclusive OR */
-#define ETIR_S_C_OPR_EOR 107 /* Logical exclusive OR */
-#define ETIR_S_C_OPR_NEG 108 /* Negate */
-#define ETIR_S_C_OPR_COM 109 /* Complement */
-#define ETIR_S_C_OPR_INSV 110 /* Insert bit field */
-#define ETIR_S_C_OPR_ASH 111 /* Arithmetic shift */
-#define ETIR_S_C_OPR_USH 112 /* Unsigned shift */
-#define ETIR_S_C_OPR_ROT 113 /* Rotate */
-#define ETIR_S_C_OPR_SEL 114 /* Select one of three longwords on top of stack */
-#define ETIR_S_C_OPR_REDEF 115 /* Redefine this symbol after pass 2 */
-#define ETIR_S_C_OPR_DFLIT 116 /* Define a literal */
-#define ETIR_S_C_MAXOPRCOD 116 /* Maximum operate code */
-#define ETIR_S_C_MINCTLCOD 150 /* Minimum control code */
-#define ETIR_S_C_CTL_SETRB 150 /* Set relocation base */
-#define ETIR_S_C_CTL_AUGRB 151 /* Augment relocation base */
-#define ETIR_S_C_CTL_DFLOC 152 /* Define debug location */
-#define ETIR_S_C_CTL_STLOC 153 /* Set debug location */
-#define ETIR_S_C_CTL_STKDL 154 /* Stack debug location */
-#define ETIR_S_C_MAXCTLCOD 154 /* Maximum control code */
-#define ETIR_S_C_MINSTCCOD 200 /* Minimum store-conditional code */
-#define ETIR_S_C_STC_LP 200 /* Store-conditional Linkage Pair */
-#define ETIR_S_C_STC_LP_PSB 201 /* Store-conditional Linkage Pair with Procedure Signature */
-#define ETIR_S_C_STC_GBL 202 /* Store-conditional Address at global address */
-#define ETIR_S_C_STC_GCA 203 /* Store-conditional Code Address at global address */
-#define ETIR_S_C_STC_PS 204 /* Store-conditional Address at psect + offset */
-#define ETIR_S_C_STC_NOP_GBL 205 /* Store-conditional NOP at address of global */
-#define ETIR_S_C_STC_NOP_PS 206 /* Store-conditional NOP at pect + offset */
-#define ETIR_S_C_STC_BSR_GBL 207 /* Store-conditional BSR at global address */
-#define ETIR_S_C_STC_BSR_PS 208 /* Store-conditional BSR at pect + offset */
-#define ETIR_S_C_STC_LDA_GBL 209 /* Store-conditional LDA at global address */
-#define ETIR_S_C_STC_LDA_PS 210 /* Store-conditional LDA at psect + offset */
-#define ETIR_S_C_STC_BOH_GBL 211 /* Store-conditional BSR or Hint at global address */
-#define ETIR_S_C_STC_BOH_PS 212 /* Store-conditional BSR or Hint at pect + offset */
-#define ETIR_S_C_STC_NBH_GBL 213 /* Store-conditional NOP,BSR or HINT at global address */
-#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset */
-#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code */
-
-/* EVAX Global symbol definition record (EGSD). */
-
-#define EGSD_S_K_ENTRIES 2 /* Offset to first entry in record */
-#define EGSD_S_C_ENTRIES 2 /* Offset to first entry in record */
-#define EGSD_S_C_PSC 0 /* Psect definition */
-#define EGSD_S_C_SYM 1 /* Symbol specification */
-#define EGSD_S_C_IDC 2 /* Random entity check */
-#define EGSD_S_C_SPSC 5 /* Shareable image psect definition */
-#define EGSD_S_C_SYMV 6 /* Vectored (dual-valued) versions of SYM, */
-#define EGSD_S_C_SYMM 7 /* Masked versions of SYM, */
-#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM */
-#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined */
-
-#define EGPS_S_V_PIC 0x0001
-#define EGPS_S_V_LIB 0x0002
-#define EGPS_S_V_OVR 0x0004
-#define EGPS_S_V_REL 0x0008
-#define EGPS_S_V_GBL 0x0010
-#define EGPS_S_V_SHR 0x0020
-#define EGPS_S_V_EXE 0x0040
-#define EGPS_S_V_RD 0x0080
-#define EGPS_S_V_WRT 0x0100
-#define EGPS_S_V_VEC 0x0200
-#define EGPS_S_V_NOMOD 0x0400
-#define EGPS_S_V_COM 0x0800
-
-#define EGSY_S_V_WEAK 0x0001
-#define EGSY_S_V_DEF 0x0002
-#define EGSY_S_V_UNI 0x0004
-#define EGSY_S_V_REL 0x0008
-#define EGSY_S_V_COMM 0x0010
-#define EGSY_S_V_VECEP 0x0020
-#define EGSY_S_V_NORM 0x0040
-
-/* EVAX Module header record (EMH) definitions. */
-
-#define EMH_S_C_MHD 0 /* Main header record */
-#define EMH_S_C_LNM 1 /* Language name and version */
-#define EMH_S_C_SRC 2 /* Source file specification */
-#define EMH_S_C_TTL 3 /* Title text of module */
-#define EMH_S_C_CPR 4 /* Copyright notice */
-#define EMH_S_C_MTC 5 /* Maintenance status */
-#define EMH_S_C_GTX 6 /* General text */
-#define EMH_S_C_MAXHDRTYP 6 /* Maximum allowable type */
-
-/* evax-alpha.c. */
-
-extern asymbol *_bfd_evax_make_empty_symbol PARAMS ((bfd *abfd));
-
-/* evax-egsd.c. */
-
-extern int _bfd_evax_slurp_egsd PARAMS ((bfd *abfd));
-extern int _bfd_evax_write_egsd PARAMS ((bfd *abfd));
-
-/* evax-emh.c. */
-
-extern int _bfd_evax_slurp_emh PARAMS ((bfd *abfd));
-extern int _bfd_evax_write_emh PARAMS ((bfd *abfd));
-extern int _bfd_evax_slurp_eeom PARAMS ((bfd *abfd));
-extern int _bfd_evax_write_eeom PARAMS ((bfd *abfd));
-
-/* evax-etir.c. */
-
-extern int _bfd_evax_slurp_etir PARAMS ((bfd *abfd));
-extern int _bfd_evax_slurp_edbg PARAMS ((bfd *abfd));
-extern int _bfd_evax_slurp_etbt PARAMS ((bfd *abfd));
-
-extern int _bfd_evax_write_etir PARAMS ((bfd *abfd));
-extern int _bfd_evax_write_etbt PARAMS ((bfd *abfd));
-extern int _bfd_evax_write_edbg PARAMS ((bfd *abfd));
-
-/* The r_type field in a reloc is one of the following values. */
-#define ALPHA_R_IGNORE 0
-#define ALPHA_R_REFQUAD 1
-#define ALPHA_R_BRADDR 2
-#define ALPHA_R_HINT 3
-#define ALPHA_R_SREL16 4
-#define ALPHA_R_SREL32 5
-#define ALPHA_R_SREL64 6
-#define ALPHA_R_OP_PUSH 7
-#define ALPHA_R_OP_STORE 8
-#define ALPHA_R_OP_PSUB 9
-#define ALPHA_R_OP_PRSHIFT 10
-#define ALPHA_R_LINKAGE 11
-#define ALPHA_R_REFLONG 12
-#define ALPHA_R_CODEADDR 13
-
-/* Object language definitions. */
-
-#define EOBJ_S_C_EMH 8 /*EVAX module header record */
-#define EOBJ_S_C_EEOM 9 /*EVAX end of module record */
-#define EOBJ_S_C_EGSD 10 /*EVAX global symbol definition record */
-#define EOBJ_S_C_ETIR 11 /*EVAX text information record */
-#define EOBJ_S_C_EDBG 12 /*EVAX Debugger information record */
-#define EOBJ_S_C_ETBT 13 /*EVAX Traceback information record */
-#define EOBJ_S_C_MAXRECTYP 13 /*Last assigned record type */
-#define EOBJ_S_K_SUBTYP 4
-#define EOBJ_S_C_SUBTYP 4
-#define EOBJ_S_C_MAXRECSIZ 8192 /*Maximum legal record size */
-#define EOBJ_S_C_STRLVL 2 /*Structure level */
-#define EOBJ_S_C_SYMSIZ 64 /*Maximum symbol length */
-#define EOBJ_S_C_SECSIZ 31 /*Maximum section name length */
-#define EOBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
-#define EOBJ_S_C_PSCALILIM 16 /*Maximum p-sect alignment */
-
-/* Miscellaneous definitions. */
-
-#if __GNUC__
-typedef unsigned long long uquad;
-#else
-typedef unsigned long uquad;
-#endif
-
-#define MAX_OUTREC_SIZE 4096
-#define MIN_OUTREC_LUFT 64
-
-typedef struct _evax_section {
- unsigned char *contents;
- bfd_vma offset;
- bfd_size_type size;
- struct _evax_section *next;
-} evax_section;
-
-extern boolean _bfd_save_evax_section
- PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
- bfd_size_type count));
-extern evax_section *_bfd_get_evax_section PARAMS ((bfd *abfd, int index));
-
-typedef struct _evax_reloc {
- struct _evax_reloc *next;
- arelent *reloc;
- asection *section;
-} evax_reloc;
-
-/* evax module header */
-
-struct emh_struc {
- int emh_b_strlvl;
- long emh_l_arch1;
- long emh_l_arch2;
- long emh_l_recsiz;
- char *emh_t_name;
- char *emh_t_version;
- char *emh_t_date;
- char *emh_c_lnm;
- char *emh_c_src;
- char *emh_c_ttl;
-};
-
-
-/* evax end of module */
-
-struct eeom_struc {
- long eeom_l_total_lps;
- unsigned char eeom_b_comcod;
- boolean eeom_has_transfer;
- unsigned char eeom_b_tfrflg;
- long eeom_l_psindx;
- long eeom_l_tfradr;
-};
-
-enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE };
-
-typedef struct evax_symbol_struct {
- struct bfd_hash_entry bfd_hash;
- asymbol *symbol;
-} evax_symbol_entry;
-
-/* stack value for push/pop commands */
-
-struct stack_struct {
- uquad value;
- int psect;
-};
-#define STACKSIZE 50
-
-/* location stack definitions for CTL_DFLOC, CTL_STLOC, and CTL_STKDL */
-
-struct location_struct {
- unsigned long value;
- int psect;
-};
-#define LOCATION_SAVE_SIZE 32
-
-#define EVAX_SECTION_COUNT 1024
-
-struct evax_private_data_struct {
- boolean fixup_done; /* Flag to indicate if all
- section pointers and PRIV(sections)
- are set up correctly */
- unsigned char *evax_buf; /* buffer to record */
- int buf_size; /* max size of buffer */
- unsigned char *evax_rec; /* actual record ptr */
- int rec_length; /* remaining record length */
- int rec_size; /* actual record size */
- int rec_type; /* actual record type */
- enum file_format_enum file_format;
-
- struct emh_struc emh_data; /* data from EMH record */
- struct eeom_struc eeom_data; /* data from EEOM record */
- int egsd_sec_count; /* # of EGSD sections */
- asection **sections; /* vector of EGSD sections */
- int egsd_sym_count; /* # of EGSD symbols */
- asymbol **symbols; /* vector of EGSD symbols */
- struct proc_value *procedure;
-
- struct stack_struct *stack;
- int stackptr;
-
- evax_section *evax_section_table[EVAX_SECTION_COUNT];
-
- struct bfd_hash_table *evax_symbol_table;
- struct symbol_cache_entry **symcache;
- int symnum;
-
- struct location_struct *location_stack;
-
- unsigned char *image_ptr; /* a pointer to section->contents */
-
- unsigned char pdsc[8]; /* procedure descriptor */
-
- /* Output routine storage */
-
- unsigned char *output_buf; /* output data */
- int push_level;
- int pushed_size;
- int length_pos;
- int output_size;
- int output_alignment;
-
- /* linkage index counter
- used by conditional store commands (ETIR_S_C_STC_) */
-
- int evax_linkage_index;
-
- /* see tc-alpha.c of gas for a description. */
- int flag_hash_long_names; /* -+, hash instead of truncate */
- int flag_show_after_trunc; /* -H, show hashing/truncation */
-};
-
-#define PRIV(name) ((struct evax_private_data_struct *)abfd->tdata.any)->name
-
-#if EVAX_DEBUG
-extern void _bfd_evax_debug PARAMS((int level, char *format, ...));
-extern void _bfd_hexdump
- PARAMS ((int level, unsigned char *ptr, int size, int offset));
-
-#define evax_debug _bfd_evax_debug
-
-#endif
-
-extern struct bfd_hash_entry *_bfd_evax_hash_newfunc
- PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
- const char *string));
-extern void _bfd_evax_get_header_values
- PARAMS ((bfd *abfd, unsigned char *buf, int *type, int *length));
-extern int _bfd_evax_get_record PARAMS ((bfd *abfd));
-extern int _bfd_evax_next_record PARAMS ((bfd *abfd));
-
-extern char *_bfd_evax_save_sized_string PARAMS ((char *str, int size));
-extern char *_bfd_evax_save_counted_string PARAMS ((char *ptr));
-extern void _bfd_evax_push PARAMS ((bfd *abfd, uquad val, int psect));
-extern uquad _bfd_evax_pop PARAMS ((bfd *abfd, int *psect));
-
-extern boolean _bfd_save_evax_section
- PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
- bfd_size_type count));
-extern void _bfd_evax_output_begin
- PARAMS ((bfd *abfd, int rectype, int rechead));
-extern void _bfd_evax_output_alignment PARAMS ((bfd *abfd, int alignto));
-extern void _bfd_evax_output_push PARAMS ((bfd *abfd));
-extern void _bfd_evax_output_pop PARAMS ((bfd *abfd));
-extern void _bfd_evax_output_flush PARAMS ((bfd *abfd));
-extern void _bfd_evax_output_end PARAMS ((bfd *abfd));
-extern int _bfd_evax_output_check PARAMS ((bfd *abfd, int size));
-extern void _bfd_evax_output_byte PARAMS ((bfd *abfd, unsigned int value));
-extern void _bfd_evax_output_short PARAMS ((bfd *abfd, unsigned int value));
-extern void _bfd_evax_output_long PARAMS ((bfd *abfd, unsigned long value));
-extern void _bfd_evax_output_quad PARAMS ((bfd *abfd, uquad value));
-extern void _bfd_evax_output_counted PARAMS ((bfd *abfd, char *value));
-extern void _bfd_evax_output_dump PARAMS ((bfd *abfd, unsigned char *data,
- int length));
-extern void _bfd_evax_output_fill PARAMS ((bfd *abfd, int value, int length));
-extern char *_bfd_evax_length_hash_symbol PARAMS ((bfd *abfd, const char *in, int maxlen));
-
-#endif /* EVAX_H */
elf64.c
elfcode.h
elflink.c
-evax-alpha.c
-evax-egsd.c
-evax-emh.c
-evax-etir.c
-evax-misc.c
-evax.h
format.c
genlink.h
go32stub.h
trad-core.c
vaxnetbsd.c
versados.c
+vms-gsd.c
+vms-hdr.c
+vms-misc.c
+vms-tir.c
+vms.c
+vms.h
xcofflink.c
--- /dev/null
+/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation Inc.
+
+ 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+/*-----------------------------------------------------------------------------*/
+
+/* typical sections for vax object files */
+
+#define VAX_CODE_NAME "$CODE"
+#define VAX_DATA_NAME "$DATA"
+#define VAX_ADDRESS_DATA_NAME "$ADDRESS_DATA"
+
+/* typical sections for evax object files */
+
+#define EVAX_ABS_NAME "$ABS$"
+#define EVAX_CODE_NAME "$CODE$"
+#define EVAX_LINK_NAME "$LINK$"
+#define EVAX_DATA_NAME "$DATA$"
+#define EVAX_BSS_NAME "$BSS$"
+#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
+#define EVAX_READONLY_NAME "$READONLY$"
+#define EVAX_LITERAL_NAME "$LITERAL$"
+#define EVAX_COMMON_NAME "$COMMON$"
+#define EVAX_LOCAL_NAME "$LOCAL$"
+
+struct sec_flags_struct {
+ char *name; /* name of section */
+ int vflags_always;
+ flagword flags_always; /* flags we set always */
+ int vflags_hassize;
+ flagword flags_hassize; /* flags we set if the section has a size > 0 */
+};
+
+/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible */
+
+static struct sec_flags_struct vax_section_flags[] = {
+ { VAX_CODE_NAME,
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
+ (SEC_CODE),
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
+ (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { VAX_DATA_NAME,
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_DATA),
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { VAX_ADDRESS_DATA_NAME,
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
+ (SEC_DATA|SEC_READONLY),
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { NULL,
+ (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_DATA),
+ (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
+};
+
+
+/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible */
+
+static struct sec_flags_struct evax_section_flags[] = {
+ { EVAX_ABS_NAME,
+ (EGPS_S_V_SHR),
+ (SEC_DATA),
+ (EGPS_S_V_SHR),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_CODE_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
+ (SEC_CODE),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
+ (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_LITERAL_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_LINK_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_DATA_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
+ (SEC_DATA),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_BSS_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
+ (SEC_NO_FLAGS),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
+ (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_READONLYADDR_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_READONLY_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_LOCAL_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_DATA),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { NULL,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_DATA),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
+};
+
+/* Retrieve bfd section flags by name and size */
+
+static flagword
+vms_secflag_by_name (abfd, section_flags, name, size)
+ bfd *abfd;
+ struct sec_flags_struct *section_flags;
+ char *name;
+ int size;
+{
+ int i = 0;
+
+ while (section_flags[i].name != NULL)
+ {
+ if ((PRIV(is_vax)?
+ strcasecmp (name, section_flags[i].name):
+ strcmp (name, section_flags[i].name)) == 0)
+ {
+ if (size > 0)
+ return section_flags[i].flags_hassize;
+ else
+ return section_flags[i].flags_always;
+ }
+ i++;
+ }
+ if (size > 0)
+ return section_flags[i].flags_hassize;
+ return section_flags[i].flags_always;
+}
+
+
+/* Retrieve vms section flags by name and size */
+
+static flagword
+vms_esecflag_by_name (section_flags, name, size)
+ struct sec_flags_struct *section_flags;
+ char *name;
+ int size;
+{
+ int i = 0;
+
+ while (section_flags[i].name != NULL)
+ {
+ if (strcmp (name, section_flags[i].name) == 0)
+ {
+ if (size > 0)
+ return section_flags[i].vflags_hassize;
+ else
+ return section_flags[i].vflags_always;
+ }
+ i++;
+ }
+ if (size > 0)
+ return section_flags[i].vflags_hassize;
+ return section_flags[i].vflags_always;
+}
+
+/*-----------------------------------------------------------------------------*/
+#if VMS_DEBUG
+/* debug */
+
+struct flagdescstruct { char *name; flagword value; };
+
+/* Convert flag to printable string */
+
+static char *
+flag2str(flagdesc, flags)
+ struct flagdescstruct *flagdesc;
+ flagword flags;
+{
+
+ static char res[64];
+ int next = 0;
+
+ res[0] = 0;
+ while (flagdesc->name != NULL)
+ {
+ if ((flags & flagdesc->value) != 0)
+ {
+ if (next)
+ strcat(res, ",");
+ else
+ next = 1;
+ strcat (res, flagdesc->name);
+ }
+ flagdesc++;
+ }
+ return res;
+}
+#endif
+
+/*-----------------------------------------------------------------------------*/
+/* input routines */
+
+/* Process GSD/EGSD record
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_gsd (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ static struct flagdescstruct gpsflagdesc[] =
+ {
+ { "PIC", 0x0001 },
+ { "LIB", 0x0002 },
+ { "OVR", 0x0004 },
+ { "REL", 0x0008 },
+ { "GBL", 0x0010 },
+ { "SHR", 0x0020 },
+ { "EXE", 0x0040 },
+ { "RD", 0x0080 },
+ { "WRT", 0x0100 },
+ { "VEC", 0x0200 },
+ { "NOMOD", 0x0400 },
+ { "COM", 0x0800 },
+ { NULL, 0 }
+ };
+
+ static struct flagdescstruct gsyflagdesc[] =
+ {
+ { "WEAK", 0x0001 },
+ { "DEF", 0x0002 },
+ { "UNI", 0x0004 },
+ { "REL", 0x0008 },
+ { "COMM", 0x0010 },
+ { "VECEP", 0x0020 },
+ { "NORM", 0x0040 },
+ { NULL, 0 }
+ };
+#endif
+
+ int gsd_type, gsd_size;
+ asection *section;
+ unsigned char *vms_rec;
+ flagword new_flags, old_flags;
+ char *name;
+ asymbol *symbol;
+ vms_symbol_entry *entry;
+ unsigned long base_addr;
+ unsigned long align_addr;
+ static int psect_idx = 0;
+
+#if VMS_DEBUG
+ vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);
+#endif
+
+ switch (objtype)
+ {
+ case EOBJ_S_C_EGSD:
+ PRIV(vms_rec) += 8; /* skip type, size, l_temp */
+ PRIV(rec_size) -= 8;
+ break;
+ case OBJ_S_C_GSD:
+ PRIV(vms_rec) += 1;
+ PRIV(rec_size) -= 1;
+ break;
+ default:
+ return -1;
+ }
+
+ /* calculate base address for each section */
+ base_addr = 0L;
+
+ abfd->symcount = 0;
+
+ while (PRIV(rec_size) > 0)
+ {
+ vms_rec = PRIV(vms_rec);
+
+ if (objtype == OBJ_S_C_GSD)
+ {
+ gsd_type = *vms_rec;
+ }
+ else
+ {
+ _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
+ gsd_type += EVAX_OFFSET;
+ }
+
+#if VMS_DEBUG
+ vms_debug (3, "gsd_type %d\n", gsd_type);
+#endif
+
+ switch (gsd_type)
+ {
+ case GSD_S_C_PSC:
+ {
+ /*
+ * program section definition
+ */
+
+ asection *old_section = 0;
+
+#if VMS_DEBUG
+ vms_debug (4, "GSD_S_C_PSC\n");
+#endif
+ /* If this section isn't a bfd section. */
+
+ if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1)))
+ {
+ /* check for temporary section from TIR record. */
+
+ if (psect_idx < PRIV(section_count))
+ old_section = PRIV(sections)[psect_idx];
+ else
+ old_section = 0;
+ }
+
+ name = _bfd_vms_save_counted_string (vms_rec + 8);
+ section = bfd_make_section (abfd, name);
+ if (!section)
+ {
+ fprintf (stderr, "bfd_make_section (%s) failed\n", name);
+ return -1;
+ }
+ old_flags = bfd_getl16 (vms_rec + 2);
+ section->_raw_size = bfd_getl32(vms_rec + 4); /* allocation */
+ new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->_raw_size);
+ if (old_flags & EGPS_S_V_REL)
+ new_flags |= SEC_RELOC;
+ if (old_flags & GPS_S_M_OVR)
+ new_flags |= SEC_IS_COMMON;
+ if (!bfd_set_section_flags (abfd, section, new_flags))
+ {
+ fprintf (stderr, "bfd_set_section_flags (%s, %x) failed\n", name, new_flags);
+ return -1;
+ }
+ section->alignment_power = vms_rec[1];
+ align_addr = (1 << section->alignment_power);
+ if ((base_addr % align_addr) != 0)
+ base_addr += (align_addr - (base_addr % align_addr));
+ section->vma = (bfd_vma)base_addr;
+ base_addr += section->_raw_size;
+
+ /* global section is common symbol */
+
+ if (old_flags & GPS_S_M_GBL)
+ {
+ entry = _bfd_vms_enter_symbol (abfd, name);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ symbol = entry->symbol;
+
+ symbol->value = 0;
+ symbol->section = section;
+ symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON);
+ }
+
+ /* copy saved contents if old_section set */
+
+ if (old_section != 0)
+ {
+ section->contents = old_section->contents;
+ if (section->_raw_size < old_section->_raw_size)
+ {
+ fprintf (stderr, "Size mismatch section %s=%d, %s=%d\n", old_section->name, old_section->_raw_size, section->name, section->_raw_size);
+ return -1;
+ }
+ else if (section->_raw_size > old_section->_raw_size)
+ {
+ section->contents = ((unsigned char *)
+ bfd_realloc (old_section->contents, section->_raw_size));
+ if (section->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ section->contents = ((unsigned char *)
+ bfd_malloc (section->_raw_size));
+ if (section->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ memset (section->contents, 0, (size_t)section->_raw_size);
+ }
+ section->_cooked_size = section->_raw_size;
+#if VMS_DEBUG
+ vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
+ section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
+ vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
+ section->_raw_size, section->vma, section->contents);
+#endif
+
+ gsd_size = vms_rec[8] + 9;
+
+ psect_idx++;
+ }
+ break;
+
+ case GSD_S_C_EPM:
+ case GSD_S_C_EPMW:
+#if VMS_DEBUG
+ vms_debug(4, "gsd epm\n");
+#endif
+ /*FALLTHRU*/
+ case GSD_S_C_SYM:
+ case GSD_S_C_SYMW:
+ {
+ int name_offset, value_offset;
+
+ /*
+ * symbol specification (definition or reference)
+ */
+
+#if VMS_DEBUG
+ vms_debug (4, "GSD_S_C_SYM(W)\n");
+#endif
+ old_flags = bfd_getl16 (vms_rec + 2);
+ new_flags = BSF_NO_FLAGS;
+
+ if (old_flags & GSY_S_M_WEAK)
+ new_flags |= BSF_WEAK;
+
+ switch (gsd_type)
+ {
+ case GSD_S_C_EPM:
+ name_offset = 11;
+ value_offset = 5;
+ new_flags |= BSF_FUNCTION;
+ break;
+ case GSD_S_C_EPMW:
+ name_offset = 12;
+ value_offset = 6;
+ new_flags |= BSF_FUNCTION;
+ break;
+ case GSD_S_C_SYM:
+ if (old_flags & GSY_S_M_DEF) /* symbol definition */
+ name_offset = 9;
+ else
+ name_offset = 4;
+ value_offset = 5;
+ break;
+ case GSD_S_C_SYMW:
+ if (old_flags & GSY_S_M_DEF) /* symbol definition */
+ name_offset = 10;
+ else
+ name_offset = 5;
+ value_offset = 6;
+ break;
+ }
+
+ /* save symbol in vms_symbol_table */
+
+ entry = _bfd_vms_enter_symbol (abfd,
+ _bfd_vms_save_counted_string (vms_rec + name_offset));
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ symbol = entry->symbol;
+
+ if (old_flags & GSY_S_M_DEF) /* symbol definition */
+ {
+ int psect;
+
+ symbol->value = bfd_getl32 (vms_rec+value_offset);
+ if ((gsd_type == GSD_S_C_SYMW)
+ || (gsd_type == GSD_S_C_EPMW))
+ psect = bfd_getl16 (vms_rec + value_offset - 2);
+ else
+ psect = vms_rec[value_offset-1];
+
+ symbol->section = (asection *)psect;
+#if VMS_DEBUG
+ vms_debug(4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount,
+ symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
+#endif
+ }
+ else /* symbol reference */
+ {
+ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
+#if VMS_DEBUG
+ vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount,
+ symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
+#endif
+ }
+
+ gsd_size = vms_rec[name_offset] + name_offset + 1;
+ symbol->flags = new_flags;
+ }
+
+ break;
+
+ case GSD_S_C_PRO:
+ case GSD_S_C_PROW:
+#if VMS_DEBUG
+ vms_debug(4, "gsd pro\n");
+#endif
+ break;
+ case GSD_S_C_IDC:
+#if VMS_DEBUG
+ vms_debug(4, "gsd idc\n");
+#endif
+ break;
+ case GSD_S_C_ENV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd env\n");
+#endif
+ break;
+ case GSD_S_C_LSY:
+#if VMS_DEBUG
+ vms_debug(4, "gsd lsy\n");
+#endif
+ break;
+ case GSD_S_C_LEPM:
+#if VMS_DEBUG
+ vms_debug(4, "gsd lepm\n");
+#endif
+ break;
+ case GSD_S_C_LPRO:
+#if VMS_DEBUG
+ vms_debug(4, "gsd lpro\n");
+#endif
+ break;
+ case GSD_S_C_SPSC:
+#if VMS_DEBUG
+ vms_debug(4, "gsd spsc\n");
+#endif
+ break;
+ case GSD_S_C_SYMV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd symv\n");
+#endif
+ break;
+ case GSD_S_C_EPMV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd epmv\n");
+#endif
+ break;
+ case GSD_S_C_PROV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd prov\n");
+#endif
+ break;
+
+ case EGSD_S_C_PSC + EVAX_OFFSET:
+ {
+ /* program section definition */
+
+ name = _bfd_vms_save_counted_string (vms_rec+12);
+ section = bfd_make_section (abfd, name);
+ if (!section)
+ return -1;
+ old_flags = bfd_getl16 (vms_rec + 6);
+ section->_raw_size = bfd_getl32 (vms_rec + 8); /* allocation */
+ new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, (int) section->_raw_size);
+ if (old_flags & EGPS_S_V_REL)
+ new_flags |= SEC_RELOC;
+ if (!bfd_set_section_flags (abfd, section, new_flags))
+ return -1;
+ section->alignment_power = vms_rec[4];
+ align_addr = (1 << section->alignment_power);
+ if ((base_addr % align_addr) != 0)
+ base_addr += (align_addr - (base_addr % align_addr));
+ section->vma = (bfd_vma)base_addr;
+ base_addr += section->_raw_size;
+ section->contents = ((unsigned char *)
+ bfd_malloc (section->_raw_size));
+ if (section->contents == NULL)
+ return -1;
+ memset (section->contents, 0, (size_t) section->_raw_size);
+ section->_cooked_size = section->_raw_size;
+#if VMS_DEBUG
+ vms_debug(4, "egsd psc %d (%s, flags %04x=%s) ",
+ section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
+ vms_debug(4, "%d bytes at 0x%08lx (mem %p)\n",
+ section->_raw_size, section->vma, section->contents);
+#endif
+ }
+ break;
+
+ case EGSD_S_C_SYM + EVAX_OFFSET:
+ {
+ /* symbol specification (definition or reference) */
+
+ symbol = _bfd_vms_make_empty_symbol (abfd);
+ if (symbol == 0)
+ return -1;
+
+ old_flags = bfd_getl16 (vms_rec + 6);
+ new_flags = BSF_NO_FLAGS;
+
+ if (old_flags & EGSY_S_V_WEAK)
+ new_flags |= BSF_WEAK;
+
+ if (vms_rec[6] & EGSY_S_V_DEF) /* symbol definition */
+ {
+ symbol->name =
+ _bfd_vms_save_counted_string (vms_rec+32);
+ if (old_flags & EGSY_S_V_NORM)
+ { /* proc def */
+ new_flags |= BSF_FUNCTION;
+ }
+ symbol->value = bfd_getl64 (vms_rec+8);
+ symbol->section = (asection *)((unsigned long) bfd_getl32 (vms_rec+28));
+#if VMS_DEBUG
+ vms_debug(4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
+ symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
+#endif
+ }
+ else /* symbol reference */
+ {
+ symbol->name =
+ _bfd_vms_save_counted_string (vms_rec+8);
+#if VMS_DEBUG
+ vms_debug(4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
+ symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
+#endif
+ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
+ }
+
+ symbol->flags = new_flags;
+
+ /* save symbol in vms_symbol_table */
+
+ entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), symbol->name, true, false);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ if (entry->symbol != (asymbol *)NULL)
+ { /* FIXME ?, DEC C generates this */
+#if VMS_DEBUG
+ vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
+#endif
+ }
+ else
+ {
+ entry->symbol = symbol;
+ PRIV(gsd_sym_count)++;
+ abfd->symcount++;
+ }
+ }
+ break;
+
+ case EGSD_S_C_IDC + EVAX_OFFSET:
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type);
+ bfd_set_error (bfd_error_bad_value);
+ return -1;
+
+ } /* switch */
+
+ PRIV(rec_size) -= gsd_size;
+ PRIV(vms_rec) += gsd_size;
+
+ } /* while (recsize > 0) */
+
+ if (abfd->symcount > 0)
+ abfd->flags |= HAS_SYMS;
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------*/
+/* output routines */
+
+/* Write section and symbol directory of bfd abfd */
+
+int
+_bfd_vms_write_gsd (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ asection *section;
+ asymbol *symbol;
+ int symnum;
+ int last_index = -1;
+ char dummy_name[10];
+ char *sname;
+ flagword new_flags, old_flags;
+ char *nptr, *uptr;
+
+#if VMS_DEBUG
+ vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
+#endif
+
+ /* output sections */
+
+ section = abfd->sections;
+#if VMS_DEBUG
+ vms_debug (3, "%d sections found\n", abfd->section_count);
+#endif
+
+ /* egsd is quadword aligned */
+
+ _bfd_vms_output_alignment (abfd, 8);
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_push (abfd); /* prepare output for subrecords */
+
+ while (section != 0)
+ {
+#if VMS_DEBUG
+ vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);
+#endif
+
+ /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */
+ if (_bfd_vms_output_check (abfd, 64) < 0)
+ {
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_push (abfd); /* prepare output for subrecords */
+ }
+
+ /* Create dummy sections to keep consecutive indices */
+
+ while (section->index - last_index > 1)
+ {
+#if VMS_DEBUG
+ vms_debug (3, "index %d, last %d\n", section->index, last_index);
+#endif
+ _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
+ _bfd_vms_output_short (abfd, 0);
+ _bfd_vms_output_short (abfd, 0);
+ _bfd_vms_output_long (abfd, 0);
+ sprintf (dummy_name, ".DUMMY%02d", last_index);
+ _bfd_vms_output_counted (abfd, dummy_name);
+ _bfd_vms_output_flush (abfd);
+ last_index++;
+ }
+
+ /* Don't know if this is neccesary for the linker but for now it keeps
+ vms_slurp_gsd happy */
+
+ sname = (char *)section->name;
+ if (*sname == '.')
+ {
+ sname++;
+ if ((*sname == 't') && (strcmp (sname, "text") == 0))
+ sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
+ else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
+ sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
+ else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
+ sname = EVAX_BSS_NAME;
+ else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
+ sname = EVAX_LINK_NAME;
+ else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
+ sname = EVAX_READONLY_NAME;
+ else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
+ sname = EVAX_LITERAL_NAME;
+ else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
+ sname = EVAX_COMMON_NAME;
+ else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
+ sname = EVAX_LOCAL_NAME;
+ }
+ else
+ sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
+
+ _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
+ _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
+ if (bfd_is_com_section (section))
+ {
+ new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM);
+ }
+ else
+ {
+ new_flags = vms_esecflag_by_name (evax_section_flags, sname, section->_raw_size);
+ }
+ _bfd_vms_output_short (abfd, new_flags);
+ _bfd_vms_output_long (abfd, section->_raw_size);
+ _bfd_vms_output_counted (abfd, sname);
+ _bfd_vms_output_flush (abfd);
+
+ last_index = section->index;
+ section = section->next;
+ }
+
+ /* output symbols */
+
+#if VMS_DEBUG
+ vms_debug (3, "%d symbols found\n", abfd->symcount);
+#endif
+
+ bfd_set_start_address (abfd, (bfd_vma)-1);
+
+ for (symnum = 0; symnum < abfd->symcount; symnum++)
+ {
+
+ symbol = abfd->outsymbols[symnum];
+ if (*(symbol->name) == '_')
+ {
+ if (strcmp (symbol->name, "__main") == 0)
+ bfd_set_start_address (abfd, (bfd_vma)symbol->value);
+ }
+ old_flags = symbol->flags;
+
+ if (old_flags & BSF_FILE)
+ continue;
+
+ if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */
+ && (!bfd_is_und_section (symbol->section))) /* and not xref */
+ continue; /* dont output */
+
+ /* 13 bytes egsd, max 64 chars name -> should be 77 bytes */
+
+ if (_bfd_vms_output_check (abfd, 80) < 0)
+ {
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_push (abfd); /* prepare output for subrecords */
+ }
+
+ _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
+
+ _bfd_vms_output_short (abfd, 0); /* data type, alignment */
+
+ new_flags = 0;
+
+ if (old_flags & BSF_WEAK)
+ new_flags |= EGSY_S_V_WEAK;
+ if (bfd_is_com_section (symbol->section)) /* .comm */
+ new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
+
+ if (old_flags & BSF_FUNCTION)
+ {
+ new_flags |= EGSY_S_V_NORM;
+ new_flags |= EGSY_S_V_REL;
+ }
+ if (old_flags & (BSF_GLOBAL|BSF_WEAK))
+ {
+ new_flags |= EGSY_S_V_DEF;
+ if (!bfd_is_abs_section (symbol->section))
+ new_flags |= EGSY_S_V_REL;
+ }
+ _bfd_vms_output_short (abfd, new_flags);
+
+ if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */
+ {
+ if (old_flags & BSF_FUNCTION)
+ {
+ _bfd_vms_output_quad (abfd, symbol->value);
+ _bfd_vms_output_quad (abfd,
+ ((asymbol *)(symbol->udata.p))->value);
+ _bfd_vms_output_long (abfd,
+ (((asymbol *)(symbol->udata.p))
+ ->section->index));
+ _bfd_vms_output_long (abfd, symbol->section->index);
+ }
+ else
+ {
+ _bfd_vms_output_quad (abfd, symbol->value); /* L_VALUE */
+ _bfd_vms_output_quad (abfd, 0); /* L_CODE_ADDRESS */
+ _bfd_vms_output_long (abfd, 0); /* L_CA_PSINDX */
+ _bfd_vms_output_long (abfd, symbol->section->index);/* L_PSINDX */
+ }
+ }
+ _bfd_vms_output_counted (abfd, _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
+
+ _bfd_vms_output_flush (abfd);
+
+ }
+
+ _bfd_vms_output_alignment (abfd, 8);
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+
+ return 0;
+}
--- /dev/null
+/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ HDR record handling functions
+ EMH record handling functions
+ and
+ EOM record handling functions
+ EEOM record handling functions
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+/*---------------------------------------------------------------------------*/
+
+
+/* Read & process emh record
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_hdr (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ unsigned char *ptr;
+ unsigned char *vms_rec;
+ int subtype;
+
+ vms_rec = PRIV(vms_rec);
+
+#if VMS_DEBUG
+ vms_debug(2, "HDR/EMH\n");
+#endif
+
+ switch (objtype)
+ {
+ case OBJ_S_C_HDR:
+ subtype = vms_rec[1];
+ break;
+ case EOBJ_S_C_EMH:
+ subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
+ break;
+ default:
+ subtype = -1;
+ }
+
+#if VMS_DEBUG
+ vms_debug(3, "subtype %d\n", subtype);
+#endif
+
+ switch (subtype)
+ {
+
+ case MHD_S_C_MHD:
+ /*
+ * module header
+ */
+ PRIV(hdr_data).hdr_b_strlvl = vms_rec[2];
+ PRIV(hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
+ PRIV(hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
+ ptr = vms_rec + 5 + vms_rec[5] + 1;
+ PRIV(hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
+ ptr += *ptr + 1;
+ PRIV(hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
+
+ break;
+
+ case MHD_S_C_LNM:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
+ break;
+
+ case MHD_S_C_SRC:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
+ break;
+
+ case MHD_S_C_TTL:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
+ break;
+
+ case MHD_S_C_CPR:
+ /*
+ *
+ */
+ break;
+
+ case MHD_S_C_MTC:
+ /*
+ *
+ */
+ break;
+
+ case MHD_S_C_GTX:
+ /*
+ *
+ */
+ break;
+
+ case EMH_S_C_MHD + EVAX_OFFSET:
+ /*
+ * module header
+ */
+ PRIV(hdr_data).hdr_b_strlvl = vms_rec[6];
+ PRIV(hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
+ PRIV(hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
+ PRIV(hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
+ PRIV(hdr_data).hdr_t_name =
+ _bfd_vms_save_counted_string (vms_rec + 20);
+ ptr = vms_rec + 20 + vms_rec[20] + 1;
+ PRIV(hdr_data).hdr_t_version =
+ _bfd_vms_save_counted_string (ptr);
+ ptr += *ptr + 1;
+ PRIV(hdr_data).hdr_t_date =
+ _bfd_vms_save_sized_string (ptr, 17);
+
+ break;
+
+ case EMH_S_C_LNM + EVAX_OFFSET:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_lnm =
+ _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
+ break;
+
+ case EMH_S_C_SRC + EVAX_OFFSET:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_src =
+ _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
+ break;
+
+ case EMH_S_C_TTL + EVAX_OFFSET:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_ttl =
+ _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
+ break;
+
+ case EMH_S_C_CPR + EVAX_OFFSET:
+ /*
+ *
+ */
+ break;
+
+ case EMH_S_C_MTC + EVAX_OFFSET:
+ /*
+ *
+ */
+ break;
+
+ case EMH_S_C_GTX + EVAX_OFFSET:
+ /*
+ *
+ */
+ break;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+
+ } /* switch */
+
+ return 0;
+}
+
+
+/*-----------------------------------------------------------------------------*/
+/* Output routines. */
+
+
+/* Manufacure a VMS like time on a unix based system.
+ stolen from obj-vms.c */
+
+static unsigned char *
+get_vms_time_string ()
+{
+ static unsigned char tbuf[18];
+#ifndef VMS
+#include <time.h>
+
+ char *pnt;
+ time_t timeb;
+ time (&timeb);
+ pnt = ctime (&timeb);
+ pnt[3] = 0;
+ pnt[7] = 0;
+ pnt[10] = 0;
+ pnt[16] = 0;
+ pnt[24] = 0;
+ sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
+#else
+#include <starlet.h>
+ struct
+ {
+ int Size;
+ unsigned char *Ptr;
+ } Descriptor;
+ Descriptor.Size = 17;
+ Descriptor.Ptr = tbuf;
+ SYS$ASCTIM (0, &Descriptor, 0, 0);
+#endif /* not VMS */
+
+#if VMS_DEBUG
+ vms_debug (6, "vmstimestring:'%s'\n", tbuf);
+#endif
+
+ return tbuf;
+}
+
+
+/* write object header for bfd abfd */
+
+int
+_bfd_vms_write_hdr (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ asymbol *symbol;
+ int symnum;
+ int had_case = 0;
+ int had_file = 0;
+
+
+#if VMS_DEBUG
+ vms_debug (2, "vms_write_hdr (%p)\n", abfd);
+#endif
+
+ _bfd_vms_output_alignment (abfd, 2);
+
+ /* MHD */
+
+ if (objtype == OBJ_S_C_HDR)
+ {
+ }
+ else
+ {
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
+ _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
+ }
+
+ if (bfd_get_filename (abfd) != 0)
+ {
+ /* strip path and suffix information */
+
+ char *fname, *fout, *fptr;
+
+ fptr = bfd_get_filename (abfd);
+ fname = (char *) alloca (strlen (fptr) + 1);
+ strcpy (fname, fptr);
+ fout = strrchr (fname, ']');
+ if (fout == 0)
+ fout = strchr (fname, ':');
+ if (fout != 0)
+ fout++;
+ else
+ fout = fname;
+
+ /* strip .obj suffix */
+
+ fptr = strrchr (fname, '.');
+ if ((fptr != 0)
+ && (strcasecmp (fptr, ".OBJ") == 0))
+ *fptr = 0;
+
+ fptr = fout;
+ while (*fptr != 0)
+ {
+ if (islower (*fptr))
+ *fptr = toupper (*fptr);
+ fptr++;
+ if ((*fptr == ';')
+ || ((fptr - fout) > 31))
+ *fptr = 0;
+ }
+ _bfd_vms_output_counted (abfd, fout);
+ }
+ else
+ _bfd_vms_output_counted (abfd, "NONAME");
+
+ _bfd_vms_output_counted (abfd, BFD_VERSION);
+ _bfd_vms_output_dump (abfd, get_vms_time_string (), 17);
+ _bfd_vms_output_fill (abfd, 0, 17);
+ _bfd_vms_output_flush (abfd);
+
+ /* LMN */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
+ _bfd_vms_output_dump (abfd, (unsigned char *)"GAS proGIS", 10);
+ _bfd_vms_output_flush (abfd);
+
+ /* SRC */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
+
+ for (symnum = 0; symnum < abfd->symcount; symnum++)
+ {
+ symbol = abfd->outsymbols[symnum];
+
+ if (symbol->flags & BSF_FILE)
+ {
+ char *s;
+
+ if (strncmp ((char *)symbol->name, "<CASE:", 6) == 0)
+ {
+ PRIV(flag_hash_long_names) = symbol->name[6] - '0';
+ PRIV(flag_show_after_trunc) = symbol->name[7] - '0';
+
+ if (had_file)
+ break;
+ had_case = 1;
+ continue;
+ }
+
+ _bfd_vms_output_dump (abfd, (unsigned char *)symbol->name, strlen (symbol->name));
+ if (had_case)
+ break;
+ had_file = 1;
+ }
+ }
+
+ if (symnum == abfd->symcount)
+ _bfd_vms_output_dump (abfd, (unsigned char *)"noname", 6);
+
+ _bfd_vms_output_flush (abfd);
+
+ /* TTL */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
+ _bfd_vms_output_dump (abfd, (unsigned char *)"TTL", 3);
+ _bfd_vms_output_flush (abfd);
+
+ /* CPR */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
+ _bfd_vms_output_dump (abfd,
+ (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
+ 39);
+ _bfd_vms_output_flush (abfd);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------*/
+
+/* Process EOM/EEOM record
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_eom (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ unsigned char *vms_rec;
+
+#if VMS_DEBUG
+ vms_debug(2, "EOM/EEOM\n");
+#endif
+
+ vms_rec = PRIV(vms_rec);
+
+ if ((objtype == OBJ_S_C_EOM)
+ || (objtype == OBJ_S_C_EOMW))
+ {
+ }
+ else
+ {
+ PRIV(eom_data).eom_l_total_lps = bfd_getl32 (vms_rec + 4);
+ PRIV(eom_data).eom_b_comcod = *(vms_rec + 8);
+ if (PRIV(eom_data).eom_b_comcod > 1)
+ {
+ (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
+ bfd_set_error (bfd_error_bad_value);
+ return -1;
+ }
+ PRIV(eom_data).eom_has_transfer = false;
+ if (PRIV(rec_size) > 10)
+ {
+ PRIV(eom_data).eom_has_transfer = true;
+ PRIV(eom_data).eom_b_tfrflg = *(vms_rec + 9);
+ PRIV(eom_data).eom_l_psindx = bfd_getl32 (vms_rec + 12);
+ PRIV(eom_data).eom_l_tfradr = bfd_getl32 (vms_rec + 16);
+
+ abfd->start_address = PRIV(eom_data).eom_l_tfradr;
+ }
+ }
+ return 0;
+}
+
+
+/* Write eom record for bfd abfd */
+
+int
+_bfd_vms_write_eom (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
+#endif
+
+ _bfd_vms_output_begin (abfd, objtype, -1);
+ _bfd_vms_output_long (abfd, (unsigned long)(PRIV(vms_linkage_index) >> 1));
+ _bfd_vms_output_byte (abfd, 0); /* completion code */
+ _bfd_vms_output_byte (abfd, 0); /* fill byte */
+
+ if (bfd_get_start_address (abfd) != (bfd_vma)-1)
+ {
+ asection *section;
+
+ section = bfd_get_section_by_name (abfd, ".link");
+ if (section == 0)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return -1;
+ }
+ _bfd_vms_output_short (abfd, 0);
+ _bfd_vms_output_long (abfd, (unsigned long)(section->index));
+ _bfd_vms_output_long (abfd,
+ (unsigned long) bfd_get_start_address (abfd));
+ _bfd_vms_output_long (abfd, 0);
+ }
+
+ _bfd_vms_output_end (abfd);
+ return 0;
+}
--- /dev/null
+/* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#if __STDC__
+#include <stdarg.h>
+#endif
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+/*-----------------------------------------------------------------------------*/
+#if VMS_DEBUG
+/* debug functions */
+
+/* debug function for all vms extensions
+ evaluates environment variable VMS_DEBUG for a
+ numerical value on the first call
+ all error levels below this value are printed
+
+ levels:
+ 1 toplevel bfd calls (functions from the bfd vector)
+ 2 functions called by bfd calls
+ ...
+ 9 almost everything
+
+ level is also identation level. Indentation is performed
+ if level > 0
+ */
+
+#if __STDC__
+void
+_bfd_vms_debug (int level, char *format, ...)
+{
+ static int min_level = -1;
+ static FILE *output = NULL;
+ char *eptr;
+ va_list args;
+ int abslvl = (level > 0)?level:-level;
+
+ if (min_level == -1)
+ {
+ if ((eptr = getenv("VMS_DEBUG")) != NULL)
+ {
+ min_level = atoi(eptr);
+ output = stderr;
+ }
+ else
+ min_level = 0;
+ }
+ if (output == NULL)
+ return;
+ if (abslvl > min_level)
+ return;
+
+ while(--level>0)
+ fprintf(output, " ");
+ va_start(args, format);
+ vfprintf(output, format, args);
+ fflush(output);
+ va_end(args);
+
+ return;
+}
+
+#else /* not __STDC__ */
+
+void
+_bfd_vms_debug (level, format, a1, a2, a3, a4, a5, a6)
+ int level;
+ char *format;
+ long a1; long a2; long a3;
+ long a4; long a5; long a6;
+{
+ static int min_level = -1;
+ static FILE *output = NULL;
+ char *eptr;
+
+ if (min_level == -1)
+ {
+ if ((eptr = getenv("VMS_DEBUG")) != NULL)
+ {
+ min_level = atoi(eptr);
+ output = stderr;
+ }
+ else
+ min_level = 0;
+ }
+ if (output == NULL)
+ return;
+ if (level > min_level)
+ return;
+
+ while(--level>0)
+ fprintf(output, " ");
+ fprintf(output, format, a1, a2, a3, a4, a5, a6);
+ fflush(output);
+
+ return;
+}
+#endif /* __STDC__ */
+
+
+/* a debug function
+ hex dump 'size' bytes starting at 'ptr' */
+
+void
+_bfd_hexdump (level, ptr, size, offset)
+ int level;
+ unsigned char *ptr;
+ int size;
+ int offset;
+{
+ unsigned char *lptr = ptr;
+ int count = 0;
+ long start = offset;
+
+ while (size-- > 0)
+ {
+ if ((count%16) == 0)
+ vms_debug (level, "%08lx:", start);
+ vms_debug (-level, " %02x", *ptr++);
+ count++;
+ start++;
+ if (size == 0)
+ {
+ while ((count%16) != 0)
+ {
+ vms_debug (-level, " ");
+ count++;
+ }
+ }
+ if ((count%16) == 0)
+ {
+ vms_debug (-level, " ");
+ while (lptr < ptr)
+ {
+ vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
+ lptr++;
+ }
+ vms_debug (-level, "\n");
+ }
+ }
+ if ((count%16) != 0)
+ vms_debug (-level, "\n");
+
+ return;
+}
+#endif
+
+\f
+/* hash functions
+
+ These are needed when reading an object file. */
+
+/* allocate new vms_hash_entry
+ keep the symbol name and a pointer to the bfd symbol in the table */
+
+struct bfd_hash_entry *
+_bfd_vms_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ vms_symbol_entry *ret;
+
+#if VMS_DEBUG
+ vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry, table, string);
+#endif
+
+ if (entry == (struct bfd_hash_entry *)NULL)
+ {
+ ret = (vms_symbol_entry *)
+ bfd_hash_allocate (table, sizeof (vms_symbol_entry));
+ if (ret == (vms_symbol_entry *) NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return (struct bfd_hash_entry *)NULL;
+ }
+ }
+
+ /* Call the allocation method of the base class. */
+
+ ret = (vms_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
+#endif
+
+ ret->symbol = (asymbol *)NULL;
+
+ return (struct bfd_hash_entry *)ret;
+}
+
+\f
+/* object file input functions */
+
+/* Return type and length from record header (buf) on Alpha. */
+
+void
+_bfd_vms_get_header_values (abfd, buf, type, length)
+ bfd *abfd;
+ unsigned char *buf;
+ int *type;
+ int *length;
+{
+ if (type != 0)
+ *type = bfd_getl16 (buf);
+ buf += 2;
+ if (length != 0)
+ *length = bfd_getl16 (buf);
+
+#if VMS_DEBUG
+ vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0));
+#endif
+
+
+ return;
+}
+
+
+/* Get next record from object file to vms_buf
+ set PRIV(buf_size) and return it
+
+ this is a little tricky since it should be portable.
+
+ the openVMS object file has 'variable length' which means that
+ read() returns data in chunks of (hopefully) correct and expected
+ size. The linker (and other tools on vms) depend on that. Unix doesn't
+ know about 'formatted' files, so reading and writing such an object
+ file in a unix environment is not trivial.
+
+ With the tool 'file' (available on all vms ftp sites), one
+ can view and change the attributes of a file. Changing from
+ 'variable length' to 'fixed length, 512 bytes' reveals the
+ record length at the first 2 bytes of every record. The same
+ happens during the transfer of object files from vms to unix,
+ at least with ucx, dec's implementation of tcp/ip.
+
+ The vms format repeats the length at bytes 2 & 3 of every record.
+
+ On the first call (file_format == FF_UNKNOWN) we check if
+ the first and the third byte pair (!) of the record match.
+ If they do it's an object file in an unix environment or with
+ wrong attributes (FF_FOREIGN), else we should be in a vms
+ environment where read() returns the record size (FF_NATIVE).
+
+ reading is always done in 2 steps.
+ first just the record header is read and the length extracted
+ by get_header_values
+ then the read buffer is adjusted and the remaining bytes are
+ read in.
+
+ all file i/o is always done on even file positions */
+
+int
+_bfd_vms_get_record (abfd)
+ bfd *abfd;
+{
+ int test_len, test_start, remaining;
+ unsigned char *vms_buf;
+
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_get_record\n");
+#endif
+
+ /* minimum is 6 bytes on Alpha
+ (2 bytes length, 2 bytes record id, 2 bytes length repeated)
+
+ on VAX there's no length information in the record
+ so start with OBJ_S_C_MAXRECSIZ */
+
+ if (PRIV(buf_size) == 0)
+ {
+ if (PRIV(is_vax))
+ {
+ PRIV(vms_buf) = (unsigned char *) malloc (OBJ_S_C_MAXRECSIZ);
+ PRIV(buf_size) = OBJ_S_C_MAXRECSIZ;
+ PRIV(file_format) = FF_VAX;
+ }
+ else
+ PRIV(vms_buf) = (unsigned char *) malloc (6);
+ }
+
+ vms_buf = PRIV(vms_buf);
+
+ if (vms_buf == 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+
+ switch (PRIV(file_format))
+ {
+ case FF_UNKNOWN:
+ case FF_FOREIGN:
+ test_len = 6; /* probe 6 bytes */
+ test_start = 2; /* where the record starts */
+ break;
+
+ case FF_NATIVE:
+ test_len = 4;
+ test_start = 0;
+ break;
+
+ case FF_VAX:
+ test_len = 0;
+ test_start = 0;
+ break;
+ }
+
+ /* skip odd alignment byte */
+
+ if (bfd_tell (abfd) & 1)
+ {
+ if (bfd_read (PRIV(vms_buf), 1, 1, abfd) != 1)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+ }
+
+ /* read the record header on Alpha. */
+
+ if ((test_len != 0)
+ && (bfd_read (PRIV(vms_buf), 1, test_len, abfd) != test_len))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* check file format on first call */
+
+ if (PRIV(file_format) == FF_UNKNOWN)
+ { /* record length repeats ? */
+ if ( (vms_buf[0] == vms_buf[4])
+ && (vms_buf[1] == vms_buf[5]))
+ {
+ PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */
+ test_start = 2;
+ }
+ else
+ {
+ PRIV(file_format) = FF_NATIVE; /* N: native environment */
+ test_start = 0;
+ }
+ }
+
+ if (PRIV(is_vax))
+ {
+ PRIV(rec_length) = bfd_read (vms_buf, 1, PRIV(buf_size), abfd);
+ if (PRIV(rec_length) <= 0)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+ PRIV(vms_rec) = vms_buf;
+ }
+ else /* Alpha */
+ {
+ /* extract vms record length */
+
+ _bfd_vms_get_header_values (abfd, vms_buf+test_start, NULL,
+ &PRIV(rec_length));
+
+ if (PRIV(rec_length) <= 0)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* that's what the linker manual says */
+
+ if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* adjust the buffer */
+
+ if (PRIV(rec_length) > PRIV(buf_size))
+ {
+ PRIV(vms_buf) = (unsigned char *) realloc (vms_buf, PRIV(rec_length));
+ vms_buf = PRIV(vms_buf);
+ if (vms_buf == 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ PRIV(buf_size) = PRIV(rec_length);
+ }
+
+ /* read the remaining record */
+
+ remaining = PRIV(rec_length) - test_len + test_start;
+
+#if VMS_DEBUG
+ vms_debug (10, "bfd_read remaining %d\n", remaining);
+#endif
+ if (bfd_read (vms_buf + test_len, 1, remaining, abfd) != remaining)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+ PRIV(vms_rec) = vms_buf + test_start;
+ }
+
+#if VMS_DEBUG
+ vms_debug (11, "bfd_read rec_length %d\n", PRIV(rec_length));
+#endif
+
+ return PRIV(rec_length);
+}
+
+
+/* get next vms record from file
+ update vms_rec and rec_length to new (remaining) values */
+
+int
+_bfd_vms_next_record (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
+ PRIV(rec_length), PRIV(rec_size));
+#endif
+
+ if (PRIV(rec_length) > 0)
+ {
+ PRIV(vms_rec) += PRIV(rec_size);
+ }
+ else
+ {
+ if (_bfd_vms_get_record (abfd) <= 0)
+ return -1;
+ }
+
+ if (PRIV(is_vax))
+ {
+ PRIV(rec_type) = *(PRIV(vms_rec));
+ PRIV(rec_size) = PRIV(rec_length);
+ }
+ else
+ {
+ _bfd_vms_get_header_values (abfd, PRIV(vms_rec), &PRIV(rec_type),
+ &PRIV(rec_size));
+ }
+ PRIV(rec_length) -= PRIV(rec_size);
+
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
+ PRIV(vms_rec), PRIV(rec_size), PRIV(rec_length),
+ PRIV(rec_type));
+#endif
+
+ return PRIV(rec_type);
+}
+
+
+\f
+/* Copy sized string (string with fixed length) to new allocated area
+ size is string length (size of record) */
+
+char *
+_bfd_vms_save_sized_string (str, size)
+ unsigned char *str;
+ int size;
+{
+ char *newstr = bfd_malloc (size + 1);
+
+ if (newstr == NULL)
+ return 0;
+ strncpy (newstr, (char *)str, size);
+ newstr[size] = 0;
+
+ return newstr;
+}
+
+/* Copy counted string (string with length at first byte) to new allocated area
+ ptr points to length byte on entry */
+
+char *
+_bfd_vms_save_counted_string (ptr)
+ unsigned char *ptr;
+{
+ int len = *ptr++;
+
+ return _bfd_vms_save_sized_string (ptr, len);
+}
+
+\f
+/* stack routines for vms ETIR commands */
+
+/* Push value and section index */
+
+void
+_bfd_vms_push (abfd, val, psect)
+ bfd *abfd;
+ uquad val;
+ int psect;
+{
+ static int last_psect;
+
+#if VMS_DEBUG
+ vms_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
+#endif
+
+ if (psect >= 0)
+ last_psect = psect;
+
+ PRIV(stack[PRIV(stackptr)]).value = val;
+ PRIV(stack[PRIV(stackptr)]).psect = last_psect;
+ PRIV(stackptr)++;
+ if (PRIV(stackptr) >= STACKSIZE)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV(stackptr));
+ exit (1);
+ }
+ return;
+}
+
+
+/* Pop value and section index */
+
+uquad
+_bfd_vms_pop (abfd, psect)
+ bfd *abfd;
+ int *psect;
+{
+ uquad value;
+
+ if (PRIV(stackptr) == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
+ exit (1);
+ }
+ PRIV(stackptr)--;
+ value = PRIV(stack[PRIV(stackptr)]).value;
+ if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
+ *psect = PRIV(stack[PRIV(stackptr)]).psect;
+
+#if VMS_DEBUG
+ vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
+#endif
+
+ return value;
+}
+
+\f
+/* object file output functions */
+
+/* GAS tends to write sections in little chunks (bfd_set_section_contents)
+ which we can't use directly. So we save the little chunks in linked
+ lists (one per section) and write them later. */
+
+/* Add a new vms_section structure to vms_section_table
+ - forward chaining - */
+
+static vms_section *
+add_new_contents (abfd, section)
+ bfd *abfd;
+ sec_ptr section;
+{
+ vms_section *sptr, *newptr;
+
+ sptr = PRIV(vms_section_table)[section->index];
+ if (sptr != NULL)
+ return sptr;
+
+ newptr = (vms_section *) bfd_malloc (sizeof (vms_section));
+ if (newptr == (vms_section *) NULL)
+ return NULL;
+ newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
+ if (newptr->contents == (unsigned char *)NULL)
+ return NULL;
+ newptr->offset = 0;
+ newptr->size = section->_raw_size;
+ newptr->next = 0;
+ PRIV(vms_section_table)[section->index] = newptr;
+ return newptr;
+}
+
+
+/* Save section data & offset to an vms_section structure
+ vms_section_table[] holds the vms_section chain */
+
+boolean
+_bfd_save_vms_section (abfd, section, data, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR data;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ vms_section *sptr;
+
+ if (section->index >= VMS_SECTION_COUNT)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ if (count == (bfd_size_type)0)
+ return true;
+ sptr = add_new_contents (abfd, section);
+ if (sptr == NULL)
+ return false;
+ memcpy (sptr->contents + offset, data, (size_t) count);
+
+ return true;
+}
+
+
+/* Get vms_section pointer to saved contents for section # index */
+
+vms_section *
+_bfd_get_vms_section (abfd, index)
+ bfd *abfd;
+ int index;
+{
+ if (index >= VMS_SECTION_COUNT)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return NULL;
+ }
+ return PRIV(vms_section_table)[index];
+}
+
+\f
+/* Object output routines */
+
+/* Begin new record or record header
+ write 2 bytes rectype
+ write 2 bytes record length (filled in at flush)
+ write 2 bytes header type (ommitted if rechead == -1) */
+
+void
+_bfd_vms_output_begin (abfd, rectype, rechead)
+ bfd *abfd;
+ int rectype;
+ int rechead;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype,
+ rechead);
+#endif
+
+ _bfd_vms_output_short (abfd,rectype);
+
+ /* save current output position to fill in lenght later */
+
+ if (PRIV(push_level) > 0)
+ PRIV(length_pos) = PRIV(output_size);
+
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
+ PRIV(length_pos));
+#endif
+
+ _bfd_vms_output_short (abfd,0); /* placeholder for length */
+
+ if (rechead != -1)
+ _bfd_vms_output_short (abfd,rechead);
+
+ return;
+}
+
+
+/* Set record/subrecord alignment */
+
+void
+_bfd_vms_output_alignment (abfd, alignto)
+ bfd *abfd;
+ int alignto;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto);
+#endif
+
+ PRIV(output_alignment) = alignto;
+ return;
+}
+
+
+/* Prepare for subrecord fields */
+
+void
+_bfd_vms_output_push (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV(output_size));
+#endif
+
+ PRIV(push_level)++;
+ PRIV(pushed_size) = PRIV(output_size);
+ return;
+}
+
+
+/* End of subrecord fields */
+
+void
+_bfd_vms_output_pop (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
+#endif
+
+ _bfd_vms_output_flush (abfd);
+ PRIV(length_pos) = 2;
+
+#if VMS_DEBUG
+ vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV(length_pos));
+#endif
+
+ PRIV(pushed_size) = 0;
+ PRIV(push_level)--;
+ return;
+}
+
+
+/* Flush unwritten output, ends current record */
+
+void
+_bfd_vms_output_flush (abfd)
+ bfd *abfd;
+{
+ int real_size = PRIV(output_size);
+ int aligncount;
+ int length;
+
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
+ real_size, PRIV(pushed_size), PRIV(length_pos));
+#endif
+
+ if (PRIV(push_level) > 0)
+ length = real_size - PRIV(pushed_size);
+ else
+ length = real_size;
+
+ if (length == 0)
+ return;
+ aligncount = (PRIV(output_alignment)
+ - (length % PRIV(output_alignment))) % PRIV(output_alignment);
+
+#if VMS_DEBUG
+ vms_debug (6, "align: adding %d bytes\n", aligncount);
+#endif
+
+ while(aligncount-- > 0)
+ {
+ PRIV(output_buf)[real_size++] = 0;
+#if 0
+ /* this is why I *love* vms: inconsistency :-}
+ alignment is added to the subrecord length
+ but not to the record length */
+ if (PRIV(push_level) > 0)
+#endif
+ length++;
+ }
+
+ /* put length to buffer */
+ PRIV(output_size) = PRIV(length_pos);
+ _bfd_vms_output_short (abfd, (unsigned int)length);
+
+ if (PRIV(push_level) == 0)
+ {
+#ifndef VMS
+ /* write length first, see FF_FOREIGN in the input routines */
+ fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
+#endif
+ fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
+
+ PRIV(output_size) = 0;
+ }
+ else
+ {
+ PRIV(output_size) = real_size;
+ PRIV(pushed_size) = PRIV(output_size);
+ }
+
+ return;
+}
+
+
+/* End record output */
+
+void
+_bfd_vms_output_end (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_end\n");
+#endif
+
+ _bfd_vms_output_flush (abfd);
+
+ return;
+}
+
+
+/* check remaining buffer size
+
+ return what's left. */
+
+int
+_bfd_vms_output_check (abfd, size)
+ bfd *abfd;
+ int size;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_check(%d)\n", size);
+#endif
+
+ return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
+}
+
+
+/* Output byte (8 bit) value */
+
+void
+_bfd_vms_output_byte (abfd, value)
+ bfd *abfd;
+ unsigned int value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value);
+#endif
+
+ bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 1;
+ return;
+}
+
+
+/* Output short (16 bit) value */
+
+void
+_bfd_vms_output_short (abfd, value)
+ bfd *abfd;
+ unsigned int value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
+#endif
+
+ bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 2;
+ return;
+}
+
+
+/* Output long (32 bit) value */
+
+void
+_bfd_vms_output_long (abfd, value)
+ bfd *abfd;
+ unsigned long value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
+#endif
+
+ bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 4;
+ return;
+}
+
+
+/* Output quad (64 bit) value */
+
+void
+_bfd_vms_output_quad (abfd, value)
+ bfd *abfd;
+ uquad value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value);
+#endif
+
+ bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 8;
+ return;
+}
+
+
+/* Output c-string as counted string */
+
+void
+_bfd_vms_output_counted (abfd, value)
+ bfd *abfd;
+ char *value;
+{
+int len;
+
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_counted(%s)\n", value);
+#endif
+
+ len = strlen (value);
+ if (len == 0)
+ {
+ (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
+ return;
+ }
+ if (len > 255)
+ {
+ (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
+ return;
+ }
+ _bfd_vms_output_byte (abfd, len & 0xff);
+ _bfd_vms_output_dump (abfd, (unsigned char *)value, len);
+}
+
+
+/* Output character area */
+
+void
+_bfd_vms_output_dump (abfd, data, length)
+ bfd *abfd;
+ unsigned char *data;
+ int length;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_dump(%d)\n", length);
+#endif
+
+ if (length == 0)
+ return;
+
+ memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
+ PRIV(output_size) += length;
+
+ return;
+}
+
+
+/* Output count bytes of value */
+
+void
+_bfd_vms_output_fill (abfd, value, count)
+ bfd *abfd;
+ int value;
+ int count;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value, count);
+#endif
+
+ if (count == 0)
+ return;
+ memset (PRIV(output_buf) + PRIV(output_size), value, count);
+ PRIV(output_size) += count;
+
+ return;
+}
+
+/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
+
+static int
+hash_string (ptr)
+ const char *ptr;
+{
+ register const unsigned char *p = (unsigned char *) ptr;
+ register const unsigned char *end = p + strlen (ptr);
+ register unsigned char c;
+ register int hash = 0;
+
+ while (p != end)
+ {
+ c = *p++;
+ hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
+ }
+ return hash;
+}
+
+/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
+
+char *
+_bfd_vms_length_hash_symbol (abfd, in, maxlen)
+ bfd *abfd;
+ const char *in;
+ int maxlen;
+{
+ long int init;
+ long int result;
+ int in_len;
+ char *pnt = 0;
+ char *new_name;
+ const char *old_name;
+ int i;
+ static char outbuf[EOBJ_S_C_SYMSIZ+1];
+ char *out = outbuf;
+
+#if VMS_DEBUG
+ vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
+#endif
+
+ if (maxlen > EOBJ_S_C_SYMSIZ)
+ maxlen = EOBJ_S_C_SYMSIZ;
+
+ new_name = out; /* save this for later. */
+
+ /* We may need to truncate the symbol, save the hash for later. */
+
+ in_len = strlen (in);
+
+ result = (in_len > maxlen) ? hash_string (in) : 0;
+
+ old_name = in;
+
+ /* Do the length checking. */
+
+ if (in_len <= maxlen)
+ {
+ i = in_len;
+ }
+ else
+ {
+ if (PRIV(flag_hash_long_names))
+ i = maxlen-9;
+ else
+ i = maxlen;
+ }
+
+ strncpy (out, in, i);
+ in += i;
+ out += i;
+
+ if ((in_len > maxlen)
+ && PRIV(flag_hash_long_names))
+ sprintf (out, "_%08x", result);
+ else
+ *out = 0;
+
+#if VMS_DEBUG
+ vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
+#endif
+
+ if (in_len > maxlen
+ && PRIV(flag_hash_long_names)
+ && PRIV(flag_show_after_trunc))
+ printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
+
+ return outbuf;
+}
+
+
+/* Allocate and initialize a new symbol. */
+
+static asymbol *
+new_symbol (abfd, name)
+ bfd *abfd;
+ char *name;
+{
+ asymbol *symbol;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (7, "new_symbol %s\n", name);
+#endif
+
+ symbol = _bfd_vms_make_empty_symbol (abfd);
+ if (symbol == 0)
+ return symbol;
+ symbol->name = name;
+ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
+
+ return symbol;
+}
+
+
+/* Allocate and enter a new private symbol. */
+
+vms_symbol_entry *
+_bfd_vms_enter_symbol (abfd, name)
+ bfd *abfd;
+ char *name;
+{
+ vms_symbol_entry *entry;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name);
+#endif
+
+ entry = (vms_symbol_entry *)
+ bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false);
+ if (entry == 0)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "creating hash entry for %s\n", name);
+#endif
+ entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, true, false);
+ if (entry != 0)
+ {
+ asymbol *symbol;
+ symbol = new_symbol (abfd, name);
+ if (symbol != 0)
+ {
+ entry->symbol = symbol;
+ PRIV(gsd_sym_count)++;
+ abfd->symcount++;
+ }
+ else
+ entry = 0;
+ }
+ else
+ (*_bfd_error_handler) (_("failed to enter %s"), name);
+ }
+ else
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "found hash entry for %s\n", name);
+#endif
+ }
+
+#if VMS_DEBUG
+ _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
+#endif
+ return entry;
+}
--- /dev/null
+/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset));
+static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset));
+static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));
+static void image_write_b PARAMS ((bfd *abfd, unsigned int value));
+static void image_write_w PARAMS ((bfd *abfd, unsigned int value));
+static void image_write_l PARAMS ((bfd *abfd, unsigned long value));
+static void image_write_q PARAMS ((bfd *abfd, uquad value));
+
+/*-----------------------------------------------------------------------------*/
+
+static int
+check_section (abfd, size)
+ bfd *abfd;
+ int size;
+{
+ int offset;
+
+ offset = PRIV(image_ptr) - PRIV(image_section)->contents;
+ if ((offset + size) > PRIV(image_section)->_raw_size)
+ {
+ PRIV(image_section)->contents = bfd_realloc (PRIV(image_section)->contents, offset + size);
+ if (PRIV(image_section)->contents == 0)
+ {
+ (*_bfd_error_handler) (_("No Mem !"));
+ return -1;
+ }
+ PRIV(image_section)->_raw_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 (abfd, psect, offset)
+ 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];
+ return;
+}
+
+
+/* Increment image buffer pointer by offset */
+
+static void
+image_inc_ptr (abfd, offset)
+ bfd *abfd;
+ uquad offset;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
+#endif
+
+ PRIV(image_ptr) += offset;
+
+ return;
+}
+
+
+/* Dump multiple bytes to section image */
+
+static void
+image_dump (abfd, ptr, size, offset)
+ bfd *abfd;
+ unsigned char *ptr;
+ int size;
+ int offset;
+{
+#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;
+
+ while (size-- > 0)
+ *PRIV(image_ptr)++ = *ptr++;
+ return;
+}
+
+
+/* Write byte to section image */
+
+static void
+image_write_b (abfd, value)
+ 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;
+
+ *PRIV(image_ptr)++ = (value & 0xff);
+ return;
+}
+
+
+/* Write 2-byte word to image */
+
+static void
+image_write_w (abfd, value)
+ 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;
+
+ bfd_putl16 (value, PRIV(image_ptr));
+ PRIV(image_ptr) += 2;
+
+ return;
+}
+
+
+/* Write 4-byte long to image */
+
+static void
+image_write_l (abfd, value)
+ 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;
+
+ bfd_putl32 (value, PRIV(image_ptr));
+ PRIV(image_ptr) += 4;
+
+ return;
+}
+
+
+/* Write 8-byte quad to image */
+
+static void
+image_write_q (abfd, value)
+ 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;
+
+ bfd_putl64 (value, PRIV(image_ptr));
+ PRIV(image_ptr) += 8;
+
+ return;
+}
+\f
+
+#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 boolean
+etir_sta (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* stack */
+
+ /* 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 == (vms_symbol_entry *)NULL)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "ETIR_S_C_STA_GBL: no symbol \"%s\"\n", name);
+#endif
+ _bfd_vms_push (abfd, (uquad)0, -1);
+ }
+ else
+ {
+ _bfd_vms_push (abfd, (uquad)(entry->symbol->value), -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);
+ break;
+
+ /* stack global
+ arg: qw value
+
+ stack 64 bit value of symbol */
+
+ case ETIR_S_C_STA_QW:
+ _bfd_vms_push (abfd, (uquad)bfd_getl64(ptr), -1);
+ 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 (psect >= PRIV(section_count))
+ {
+ (*_bfd_error_handler) (_("Bad section index in ETIR_S_C_STA_PQ"));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ dummy = bfd_getl64 (ptr+4);
+ _bfd_vms_push (abfd, dummy, psect);
+ }
+ break;
+
+ /* all not supported */
+
+ case ETIR_S_C_STA_LI:
+ case ETIR_S_C_STA_MOD:
+ case ETIR_S_C_STA_CKARG:
+
+ (*_bfd_error_handler) (_("Unsupported STA cmd %d"), cmd);
+ return false;
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STA cmd %d"), cmd);
+ return false;
+ break;
+ }
+#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 boolean
+etir_sto (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ uquad dummy;
+ int psect;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+
+ /* store byte: pop stack, write byte
+ arg: - */
+
+ case ETIR_S_C_STO_B:
+ dummy = _bfd_vms_pop (abfd, &psect);
+#if 0
+ if (is_share) /* FIXME */
+ (*_bfd_error_handler) ("ETIR_S_C_STO_B: byte fixups not supported");
+#endif
+ image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
+ break;
+
+ /* store word: pop stack, write word
+ arg: - */
+
+ case ETIR_S_C_STO_W:
+ dummy = _bfd_vms_pop (abfd, &psect);
+#if 0
+ if (is_share) /* FIXME */
+ (*_bfd_error_handler) ("ETIR_S_C_STO_B: word fixups not supported");
+#endif
+ image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
+ 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;
+ image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
+ 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;
+ image_write_q (abfd, dummy); /* FIXME: check top bits */
+ break;
+
+ /* store immediate repeated: pop stack for repeat count
+ arg: lw byte count
+ da data */
+
+ case ETIR_S_C_STO_IMMR:
+ {
+ unsigned long size;
+
+ size = bfd_getl32 (ptr);
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ while (dummy-- > 0L)
+ image_dump (abfd, ptr+4, size, 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 == (vms_symbol_entry *)NULL)
+ {
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_GBL: no symbol \"%s\""),
+ name);
+ return false;
+ }
+ else
+ image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
+ }
+ 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 == (vms_symbol_entry *)NULL)
+ {
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_CA: no symbol \"%s\""),
+ name);
+ return false;
+ }
+ else
+ image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
+ }
+ break;
+
+ /* not supported */
+
+ case ETIR_S_C_STO_RB:
+ case ETIR_S_C_STO_AB:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_RB/AB: Not supported"));
+ break;
+
+ /* store offset to psect: pop stack, add low 32 bits to base of psect
+ arg: - */
+
+ case ETIR_S_C_STO_OFF:
+ {
+ uquad q;
+ int psect;
+
+ q = _bfd_vms_pop (abfd, &psect);
+ q += (PRIV(sections)[psect])->vma;
+ image_write_q (abfd, q);
+ }
+ 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);
+ }
+ 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 == (vms_symbol_entry *)NULL)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "ETIR_S_C_STO_GBL_LW: no symbol \"%s\"\n", name);
+#endif
+ image_write_l (abfd, (unsigned long)0); /* FIXME, reloc */
+ }
+ else
+ image_write_l (abfd, (unsigned long)(entry->symbol->value)); /* FIXME, reloc */
+ }
+ break;
+
+ /* not supported */
+
+ case ETIR_S_C_STO_LP_PSB:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_LP_PSB: Not supported"));
+ break;
+
+ /* */
+
+ case ETIR_S_C_STO_HINT_GBL:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_GBL: not implemented"));
+ break;
+
+ /* */
+
+ case ETIR_S_C_STO_HINT_PS:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_PS: not implemented"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STO cmd %d"), cmd);
+ break;
+ }
+
+ 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 boolean
+etir_opr (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ long op1, op2;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* operation */
+
+ /* no-op */
+
+ case ETIR_S_C_OPR_NOP:
+ break;
+
+ /* add */
+
+ case ETIR_S_C_OPR_ADD:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 + op2), -1);
+ break;
+
+ /* subtract */
+
+ case ETIR_S_C_OPR_SUB:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op2 - op1), -1);
+ break;
+
+ /* multiply */
+
+ case ETIR_S_C_OPR_MUL:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 * op2), -1);
+ break;
+
+ /* divide */
+
+ case ETIR_S_C_OPR_DIV:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (op2 == 0)
+ _bfd_vms_push (abfd, (uquad)0L, -1);
+ else
+ _bfd_vms_push (abfd, (uquad)(op2 / op1), -1);
+ break;
+
+ /* logical and */
+
+ case ETIR_S_C_OPR_AND:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 & op2), -1);
+ break;
+
+ /* logical inclusive or */
+
+ case ETIR_S_C_OPR_IOR:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 | op2), -1);
+ break;
+
+ /* logical exclusive or */
+
+ case ETIR_S_C_OPR_EOR:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 ^ op2), -1);
+ break;
+
+ /* negate */
+
+ case ETIR_S_C_OPR_NEG:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(-op1), -1);
+ break;
+
+ /* complement */
+
+ case ETIR_S_C_OPR_COM:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 ^ -1L), -1);
+ break;
+
+ /* insert field */
+
+ case ETIR_S_C_OPR_INSV:
+ (void)_bfd_vms_pop (abfd, NULL);
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_INSV: Not supported"));
+ break;
+
+ /* arithmetic shift */
+
+ case ETIR_S_C_OPR_ASH:
+ 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;
+
+ /* unsigned shift */
+
+ case ETIR_S_C_OPR_USH:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_USH: Not supported"));
+ break;
+
+ /* rotate */
+
+ case ETIR_S_C_OPR_ROT:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_ROT: Not supported"));
+ break;
+
+ /* select */
+
+ case ETIR_S_C_OPR_SEL:
+ 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;
+
+ /* redefine symbol to current location */
+
+ case ETIR_S_C_OPR_REDEF:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_REDEF: Not supported"));
+ break;
+
+ /* define a literal */
+
+ case ETIR_S_C_OPR_DFLIT:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_DFLIT: Not supported"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved OPR cmd %d"), cmd);
+ break;
+ }
+
+ return true;
+}
+
+
+/* control commands
+
+ see table B-11 of the openVMS linker manual */
+
+static boolean
+etir_ctl (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ uquad dummy;
+ int psect;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* set relocation base: pop stack, set image location counter
+ arg: - */
+
+ 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: - */
+
+ case ETIR_S_C_CTL_DFLOC:
+ dummy = _bfd_vms_pop (abfd, NULL);
+ /* FIXME */
+ break;
+
+ /* set location: pop index, restore location counter from index
+ arg: - */
+
+ case ETIR_S_C_CTL_STLOC:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ /* FIXME */
+ break;
+
+ /* stack defined location: pop index, push location counter from index
+ arg: - */
+
+ case ETIR_S_C_CTL_STKDL:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ /* FIXME */
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved CTL cmd %d"), cmd);
+ break;
+ }
+ return true;
+}
+
+
+/* store conditional commands
+
+ see table B-12 and B-13 of the openVMS linker manual */
+
+static boolean
+etir_stc (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* 200 Store-conditional Linkage Pair
+ arg: */
+
+ case ETIR_S_C_STC_LP:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_LP: not supported"));
+ break;
+
+ /* 201 Store-conditional Linkage Pair with Procedure Signature
+ arg: lw linkage index
+ cs procedure name
+ by signature length
+ da signature */
+
+ case ETIR_S_C_STC_LP_PSB:
+ image_inc_ptr (abfd, 16); /* skip entry,procval */
+ break;
+
+ /* 202 Store-conditional Address at global address
+ arg: lw linkage index
+ cs global name */
+
+ case ETIR_S_C_STC_GBL:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_GBL: not supported"));
+ break;
+
+ /* 203 Store-conditional Code Address at global address
+ arg: lw linkage index
+ cs procedure name */
+
+ case ETIR_S_C_STC_GCA:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_GCA: not supported"));
+ break;
+
+ /* 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) (_("ETIR_S_C_STC_PS: not supported"));
+ break;
+
+ /* 205 Store-conditional NOP at address of global
+ arg: */
+
+ case ETIR_S_C_STC_NOP_GBL:
+
+ /* 206 Store-conditional NOP at pect + offset
+ arg: */
+
+ case ETIR_S_C_STC_NOP_PS:
+
+ /* 207 Store-conditional BSR at global address
+ arg: */
+
+ case ETIR_S_C_STC_BSR_GBL:
+
+ /* 208 Store-conditional BSR at pect + offset
+ arg: */
+
+ case ETIR_S_C_STC_BSR_PS:
+
+ /* 209 Store-conditional LDA at global address
+ arg: */
+
+ case ETIR_S_C_STC_LDA_GBL:
+
+ /* 210 Store-conditional LDA at psect + offset
+ arg: */
+
+ case ETIR_S_C_STC_LDA_PS:
+
+ /* 211 Store-conditional BSR or Hint at global address
+ arg: */
+
+ case ETIR_S_C_STC_BOH_GBL:
+
+ /* 212 Store-conditional BSR or Hint at pect + offset
+ arg: */
+
+ case ETIR_S_C_STC_BOH_PS:
+
+ /* 213 Store-conditional NOP,BSR or HINT at global address
+ arg: */
+
+ case ETIR_S_C_STC_NBH_GBL:
+
+ /* 214 Store-conditional NOP,BSR or HINT at psect + offset
+ arg: */
+
+ case ETIR_S_C_STC_NBH_PS:
+/* FIXME (*_bfd_error_handler) ("ETIR_S_C_STC_xx: (%d) not supported", cmd); */
+ break;
+
+ default:
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "Reserved STC cmd %d", cmd);
+#endif
+ break;
+ }
+ return true;
+}
+
+
+static asection *
+new_section (abfd, idx)
+ bfd *abfd;
+ 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 (strlen (sname) + 1);
+ if (name == 0)
+ return 0;
+ strcpy (name, sname);
+
+ section = bfd_malloc (sizeof (asection));
+ if (section == 0)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "bfd_make_section (%s) failed", name);
+#endif
+ return 0;
+ }
+
+ section->_raw_size = 0;
+ section->vma = 0;
+ section->contents = 0;
+ section->_cooked_size = 0;
+ section->name = name;
+ section->index = idx;
+
+ return section;
+}
+
+
+static int
+alloc_section (abfd, idx)
+ bfd *abfd;
+ int idx;
+{
+ asection *section;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "alloc_section %d\n", idx);
+#endif
+
+ PRIV(sections) = ((asection **)
+ bfd_realloc (PRIV(sections), (idx+1) * sizeof (asection *)));
+ if (PRIV(sections) == 0)
+ return -1;
+
+ while (PRIV(section_count) <= idx)
+ {
+ PRIV(sections)[PRIV(section_count)] = new_section (abfd, 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 == (vms_symbol_entry *)NULL)
+ return 0;
+
+ _bfd_vms_push (abfd, (unsigned long)(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, (long)*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, (long)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, (long)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 (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+
+ dummy = (long)*ptr++;
+ dummy += (PRIV(sections)[psect])->vma;
+ _bfd_vms_push (abfd, 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 (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+
+ dummy = bfd_getl16(ptr); ptr+=2;
+ dummy += (PRIV(sections)[psect])->vma;
+ _bfd_vms_push (abfd, 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 (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+
+ dummy = bfd_getl32 (ptr); ptr += 4;
+ dummy += (PRIV(sections)[psect])->vma;
+ _bfd_vms_push (abfd, dummy, psect);
+ }
+ break;
+
+ case TIR_S_C_STA_UB:
+ /*
+ * stack unsigned byte
+ * arg: by value
+ *
+ * stack byte value
+ */
+ _bfd_vms_push (abfd, (unsigned long)*ptr++, -1);
+ break;
+
+ case TIR_S_C_STA_UW:
+ /*
+ * stack unsigned short word
+ * arg: sh value
+ *
+ * stack 16 bit value
+ */
+ _bfd_vms_push (abfd, (unsigned long)bfd_getl16(ptr), -1);
+ ptr += 2;
+ break;
+
+ case TIR_S_C_STA_BFI:
+ /*
+ * stack byte from image
+ * arg: -
+ *
+ */
+ /*FALLTHRU*/
+ case TIR_S_C_STA_WFI:
+ /*
+ * stack byte from image
+ * arg: -
+ *
+ */
+ /*FALLTHRU*/
+ case TIR_S_C_STA_LFI:
+ /*
+ * stack byte from image
+ * arg: -
+ *
+ */
+ (*_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 == (vms_symbol_entry *)NULL)
+ return 0;
+
+ (*_bfd_error_handler) (_("Stack-entry-mask not fully implemented"));
+ _bfd_vms_push (abfd, 0L, -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, 1L, -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 == (vms_symbol_entry *)NULL)
+ return 0;
+ (*_bfd_error_handler) (_("Stack-local-symbol not fully implemented"));
+ _bfd_vms_push (abfd, 0L, -1);
+ ptr += *ptr + 1;
+ }
+ break;
+
+ case TIR_S_C_STA_LIT:
+ /*
+ * stack literal
+ * arg: by literal index
+ *
+ * stack literal
+ */
+ ptr++;
+ _bfd_vms_push (abfd, 0L, -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 == (vms_symbol_entry *)NULL)
+ return 0;
+ (*_bfd_error_handler) (_("Stack-local-symbol-entry-point-mask not fully implemented"));
+ _bfd_vms_push (abfd, 0L, -1);
+ ptr += *ptr + 1;
+ }
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STA cmd %d"), ptr[-1]);
+ return NULL;
+ break;
+ }
+
+ return ptr;
+}
+
+
+/*
+ * 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: -
+ */
+ 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: -
+ */
+ 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: -
+ */
+ 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: -
+ */
+ 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: -
+ */
+ 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: -
+ */
+ 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: -
+ */
+ 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: -
+ * 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: -
+ * 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) (_("Unimplemented STO cmd %d"), 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
+
+ switch (*ptr++)
+ {
+ /* operation */
+ 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, (unsigned long)(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, (unsigned long)(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, (unsigned long)(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, (unsigned long)0L, -1);
+ else
+ _bfd_vms_push (abfd, (unsigned long)(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, (unsigned long)(op1 & op2), -1);
+ break;
+
+ case TIR_S_C_OPR_IOR:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ /*
+ * logical inclusive or
+ */
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(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, (unsigned long)(op1 ^ op2), -1);
+ break;
+
+ case TIR_S_C_OPR_NEG:
+ /*
+ * negate
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(-op1), -1);
+ break;
+
+ case TIR_S_C_OPR_COM:
+ /*
+ * complement
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 ^ -1L), -1);
+ break;
+
+ case TIR_S_C_OPR_INSV:
+ /*
+ * insert field
+ */
+ (void)_bfd_vms_pop (abfd, NULL);
+ (*_bfd_error_handler) ("TIR_S_C_OPR_INSV incomplete");
+ 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, (unsigned long)op2, -1);
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_ASH incomplete"));
+ 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, (unsigned long)op2, -1);
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_USH incomplete"));
+ 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, (unsigned long)op2, -1);
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_ROT incomplete"));
+ 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, (unsigned long)op1, -1);
+ }
+ break;
+
+ case TIR_S_C_OPR_REDEF:
+ /*
+ * redefine symbol to current location
+ */
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_REDEF not supported"));
+ break;
+
+ case TIR_S_C_OPR_DFLIT:
+ /*
+ * define a literal
+ */
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_DFLIT not supported"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved OPR cmd %d"), ptr[-1]);
+ break;
+ }
+
+ return ptr;
+}
+
+
+static unsigned char *
+tir_ctl (bfd *abfd, unsigned char *ptr)
+/*
+ * control commands
+ *
+ * see table 7-6 of the VAX/VMS linker manual
+ */
+{
+ 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: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ if (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+ image_set_ptr (abfd, psect, 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, dummy);
+ break;
+ case TIR_S_C_CTL_DFLOC:
+ /*
+ * define location: pop index, save location counter under index
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, NULL);
+ (*_bfd_error_handler) (_("TIR_S_C_CTL_DFLOC not fully implemented"));
+ break;
+ case TIR_S_C_CTL_STLOC:
+ /*
+ * set location: pop index, restore location counter from index
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ (*_bfd_error_handler) (_("TIR_S_C_CTL_STLOC not fully implemented"));
+ break;
+ case TIR_S_C_CTL_STKDL:
+ /*
+ * stack defined location: pop index, push location counter from index
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ (*_bfd_error_handler) (_("TIR_S_C_CTL_STKDL not fully implemented"));
+ 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)
+{
+ 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, (int)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 (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ static struct {
+ int mincod;
+ int maxcod;
+ boolean (*explain) PARAMS((bfd *, int, unsigned char *));
+ } 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 %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)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))
+ return -1;
+ break;
+ }
+ i++;
+ }
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "etir_cmd: = 0\n");
+#endif
+ return 0;
+}
+
+
+/* Text Information and Relocation Records (OBJ$C_TIR)
+ handle tir record */
+
+static int
+analyze_tir (abfd, ptr, length)
+ 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 (abfd, ptr, length)
+ bfd *abfd;
+ unsigned char *ptr;
+ unsigned int length;
+{
+ int cmd;
+ unsigned char *maxptr;
+ int result = 0;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
+#endif
+
+ maxptr = ptr + length;
+
+ while (ptr < maxptr)
+ {
+ cmd = bfd_getl16 (ptr);
+ length = bfd_getl16 (ptr + 2);
+ result = etir_cmd (abfd, cmd, ptr+4);
+ if (result != 0)
+ break;
+ ptr += length;
+ }
+
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
+#endif
+
+ return result;
+}
+
+
+/* process ETIR record
+
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_tir (abfd, objtype)
+ 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) += 4; /* skip type, size */
+ PRIV(rec_size) -= 4;
+ result = analyze_etir (abfd, PRIV(vms_rec), 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), PRIV(rec_size));
+ break;
+ default:
+ result = -1;
+ break;
+ }
+
+ return result;
+}
+
+
+/* process EDBG record
+ return 0 on success, -1 on error
+
+ not implemented yet */
+
+int
+_bfd_vms_slurp_dbg (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "DBG/EDBG\n");
+#endif
+
+ abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+ return 0;
+}
+
+
+/* process ETBT record
+ return 0 on success, -1 on error
+
+ not implemented yet */
+
+int
+_bfd_vms_slurp_tbt (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "TBT/ETBT\n");
+#endif
+
+ return 0;
+}
+
+
+/* process LNK record
+ return 0 on success, -1 on error
+
+ not implemented yet */
+
+int
+_bfd_vms_slurp_lnk (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "LNK\n");
+#endif
+
+ return 0;
+}
+\f
+/*----------------------------------------------------------------------*/
+/* */
+/* WRITE ETIR SECTION */
+/* */
+/* this is still under construction and therefore not documented */
+/* */
+/*----------------------------------------------------------------------*/
+
+static void start_etir_record PARAMS ((bfd *abfd, int index, uquad offset, boolean justoffset));
+static void sto_imm PARAMS ((bfd *abfd, vms_section *sptr, bfd_vma vaddr, int index));
+static void end_etir_record PARAMS ((bfd *abfd));
+
+static void
+sto_imm (abfd, sptr, vaddr, index)
+ bfd *abfd;
+ vms_section *sptr;
+ bfd_vma vaddr;
+ int index;
+{
+ int size;
+ int ssize;
+ unsigned char *cptr;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
+ _bfd_hexdump (9, sptr->contents, (int)sptr->size, (int)vaddr);
+#endif
+
+ ssize = sptr->size;
+ cptr = sptr->contents;
+
+ while (ssize > 0)
+ {
+
+ size = ssize; /* try all the rest */
+
+ if (_bfd_vms_output_check (abfd, size) < 0)
+ { /* doesn't fit, split ! */
+ end_etir_record (abfd);
+ start_etir_record (abfd, 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;
+ ssize -= size;
+ cptr += size;
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------*/
+
+/* start ETIR record for section #index at virtual addr offset. */
+
+static void
+start_etir_record (abfd, index, offset, justoffset)
+ bfd *abfd;
+ int index;
+ uquad offset;
+ boolean justoffset;
+{
+ if (!justoffset)
+ {
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1); /* one ETIR per section */
+ _bfd_vms_output_push (abfd);
+ }
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1); /* push start offset */
+ _bfd_vms_output_long (abfd, (unsigned long)index);
+ _bfd_vms_output_quad (abfd, (uquad)offset);
+ _bfd_vms_output_flush (abfd);
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1); /* start = pop () */
+ _bfd_vms_output_flush (abfd);
+
+ return;
+}
+
+
+/* end etir record */
+static void
+end_etir_record (abfd)
+ bfd *abfd;
+{
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+}
+
+/* write section contents for bfd abfd */
+
+int
+_bfd_vms_write_tir (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ asection *section;
+ vms_section *sptr;
+ int nextoffset;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
+#endif
+
+ _bfd_vms_output_alignment (abfd, 4);
+
+ nextoffset = 0;
+ PRIV(vms_linkage_index) = 1;
+
+ /* dump all other sections */
+
+ section = abfd->sections;
+
+ while (section != NULL)
+ {
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n", section->index, section->name, (int)(section->_raw_size));\r
+#endif
+
+ if (section->flags & SEC_RELOC)
+ {
+ int i;
+
+ if ((i = section->reloc_count) <= 0)
+ {
+ (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
+ section->name);
+ }
+#if VMS_DEBUG
+ else
+ {
+ arelent **rptr;
+ _bfd_vms_debug (4, "%d relocations:\n", i);
+ rptr = section->orelocation;
+ 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
+ }
+
+ if ((section->flags & SEC_HAS_CONTENTS)
+ && (! bfd_is_com_section (section)))
+ {
+ bfd_vma vaddr; /* virtual addr in section */
+
+ sptr = _bfd_get_vms_section (abfd, section->index);
+ if (sptr == NULL)
+ {
+ bfd_set_error (bfd_error_no_contents);
+ return -1;
+ }
+
+ vaddr = (bfd_vma)(sptr->offset);
+
+ start_etir_record (abfd, section->index, (uquad) sptr->offset,
+ false);
+
+ while (sptr != NULL) /* one STA_PQ, CTL_SETRB per vms_section */
+ {
+
+ if (section->flags & SEC_RELOC) /* check for relocs */
+ {
+ arelent **rptr = section->orelocation;
+ int i = section->reloc_count;
+ for (;;)
+ {
+ bfd_size_type addr = (*rptr)->address;
+ int len = bfd_get_reloc_size ((*rptr)->howto);
+ if (sptr->offset < addr) /* sptr starts before reloc */
+ {
+ int before = addr - sptr->offset;
+ if (sptr->size <= before) /* complete before */
+ {
+ sto_imm (abfd, sptr, vaddr, section->index);
+ vaddr += sptr->size;
+ break;
+ }
+ else /* partly before */
+ {
+ int after = sptr->size - before;
+ sptr->size = before;
+ sto_imm (abfd, sptr, vaddr, section->index);
+ vaddr += sptr->size;
+ sptr->contents += before;
+ sptr->offset += before;
+ sptr->size = after;
+ }
+ }
+ else if (sptr->offset == addr) /* sptr starts at reloc */
+ {
+ asymbol *sym = *(*rptr)->sym_ptr_ptr;
+ asection *sec = sym->section;
+
+ switch ((*rptr)->howto->type)
+ {
+ case ALPHA_R_IGNORE:
+ break;
+
+ case ALPHA_R_REFLONG:
+ {
+ if (bfd_is_und_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd,
+ strlen((char *)sym->name))
+ < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_GBL_LW,
+ -1);
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd, 16) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STA_LW,
+ -1);
+ _bfd_vms_output_quad (abfd,
+ (uquad)sym->value);
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_LW,
+ -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ else
+ {
+ if (_bfd_vms_output_check (abfd, 32) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _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_LW,
+ -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ }
+ break;
+
+ case ALPHA_R_REFQUAD:
+ {
+ if (bfd_is_und_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd,
+ strlen((char *)sym->name))
+ < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_GBL,
+ -1);
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd, 16) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _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
+ {
+ if (_bfd_vms_output_check (abfd, 32) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _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:
+ {
+ int hint_size;
+
+ hint_size = sptr->size;
+ sptr->size = len;
+ sto_imm (abfd, sptr, vaddr, section->index);
+ sptr->size = hint_size;
+#if 0
+ vms_output_begin(abfd, ETIR_S_C_STO_HINT_GBL, -1);
+ vms_output_long(abfd, (unsigned long)(sec->index));
+ vms_output_quad(abfd, (uquad)addr);
+
+ vms_output_counted(abfd, _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ vms_output_flush(abfd);
+#endif
+ }
+ break;
+ case ALPHA_R_LINKAGE:
+ {
+ if (_bfd_vms_output_check (abfd, 64) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd, section->index,
+ vaddr, false);
+ }
+ _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;
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_byte (abfd, 0);
+ _bfd_vms_output_flush (abfd);
+ }
+ break;
+
+ case ALPHA_R_CODEADDR:
+ {
+ if (_bfd_vms_output_check (abfd,
+ strlen((char *)sym->name))
+ < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_CA,
+ -1);
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ }
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Unhandled relocation %s"),
+ (*rptr)->howto->name);
+ break;
+ }
+
+ vaddr += len;
+
+ if (len == sptr->size)
+ {
+ break;
+ }
+ else
+ {
+ sptr->contents += len;
+ sptr->offset += len;
+ sptr->size -= len;
+ i--;
+ rptr++;
+ }
+ }
+ else /* sptr starts after reloc */
+ {
+ i--; /* check next reloc */
+ rptr++;
+ }
+
+ if (i==0) /* all reloc checked */
+ {
+ if (sptr->size > 0)
+ {
+ sto_imm (abfd, sptr, vaddr, section->index); /* dump rest */
+ vaddr += sptr->size;
+ }
+ break;
+ }
+ } /* for (;;) */
+ } /* if SEC_RELOC */
+ else /* no relocs, just dump */
+ {
+ sto_imm (abfd, sptr, vaddr, section->index);
+ vaddr += sptr->size;
+ }
+
+ sptr = sptr->next;
+
+ } /* while (sptr != 0) */
+
+ end_etir_record (abfd);
+
+ } /* has_contents */
+
+ section = section->next;
+ }
+
+ _bfd_vms_output_alignment(abfd, 2);
+ return 0;
+}
+
+
+/* write traceback data for bfd abfd */
+
+int
+_bfd_vms_write_tbt (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
+#endif
+
+ return 0;
+}
+
+
+/* write debug info for bfd abfd */
+
+int
+_bfd_vms_write_dbg (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
+#endif
+
+ return 0;
+}
--- /dev/null
+#undef vms
+/* vms.h -- Header file for VMS (Alpha and Vax) support.
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef VMS_H
+#define VMS_H
+
+
+/* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object language) */
+
+/* VMS Text, information and relocation record (TIR/ETIR) definitions. */
+
+#define TIR_S_C_STA_GBL 0
+#define TIR_S_C_STA_SB 1
+#define TIR_S_C_STA_SW 2
+#define TIR_S_C_STA_LW 3
+#define TIR_S_C_STA_PB 4
+#define TIR_S_C_STA_PW 5
+#define TIR_S_C_STA_PL 6
+#define TIR_S_C_STA_UB 7
+#define TIR_S_C_STA_UW 8
+#define TIR_S_C_STA_BFI 9
+#define TIR_S_C_STA_WFI 10
+#define TIR_S_C_STA_LFI 11
+#define TIR_S_C_STA_EPM 12
+#define TIR_S_C_STA_CKARG 13
+#define TIR_S_C_STA_WPB 14
+#define TIR_S_C_STA_WPW 15
+#define TIR_S_C_STA_WPL 16
+#define TIR_S_C_STA_LSY 17
+#define TIR_S_C_STA_LIT 18
+#define TIR_S_C_STA_LEPM 19
+#define TIR_S_C_MAXSTACOD 19
+#define TIR_S_C_MINSTOCOD 20
+#define TIR_S_C_STO_SB 20
+#define TIR_S_C_STO_SW 21
+#define TIR_S_C_STO_L 22
+#define TIR_S_C_STO_LW 22
+#define TIR_S_C_STO_BD 23
+#define TIR_S_C_STO_WD 24
+#define TIR_S_C_STO_LD 25
+#define TIR_S_C_STO_LI 26
+#define TIR_S_C_STO_PIDR 27
+#define TIR_S_C_STO_PICR 28
+#define TIR_S_C_STO_RSB 29
+#define TIR_S_C_STO_RSW 30
+#define TIR_S_C_STO_RL 31
+#define TIR_S_C_STO_VPS 32
+#define TIR_S_C_STO_USB 33
+#define TIR_S_C_STO_USW 34
+#define TIR_S_C_STO_RUB 35
+#define TIR_S_C_STO_RUW 36
+#define TIR_S_C_STO_B 37
+#define TIR_S_C_STO_W 38
+#define TIR_S_C_STO_RB 39
+#define TIR_S_C_STO_RW 40
+#define TIR_S_C_STO_RIVB 41
+#define TIR_S_C_STO_PIRR 42
+#define TIR_S_C_MAXSTOCOD 42
+#define TIR_S_C_MINOPRCOD 50
+#define TIR_S_C_OPR_NOP 50
+#define TIR_S_C_OPR_ADD 51
+#define TIR_S_C_OPR_SUB 52
+#define TIR_S_C_OPR_MUL 53
+#define TIR_S_C_OPR_DIV 54
+#define TIR_S_C_OPR_AND 55
+#define TIR_S_C_OPR_IOR 56
+#define TIR_S_C_OPR_EOR 57
+#define TIR_S_C_OPR_NEG 58
+#define TIR_S_C_OPR_COM 59
+#define TIR_S_C_OPR_INSV 60
+#define TIR_S_C_OPR_ASH 61
+#define TIR_S_C_OPR_USH 62
+#define TIR_S_C_OPR_ROT 63
+#define TIR_S_C_OPR_SEL 64
+#define TIR_S_C_OPR_REDEF 65
+#define TIR_S_C_OPR_DFLIT 66
+#define TIR_S_C_MAXOPRCOD 66
+#define TIR_S_C_MINCTLCOD 80
+#define TIR_S_C_CTL_SETRB 80
+#define TIR_S_C_CTL_AUGRB 81
+#define TIR_S_C_CTL_DFLOC 82
+#define TIR_S_C_CTL_STLOC 83
+#define TIR_S_C_CTL_STKDL 84
+#define TIR_S_C_MAXCTLCOD 84
+
+#define ETIR_S_C_MINSTACOD 0 /* Minimum store code */
+#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value */
+#define ETIR_S_C_STA_LW 1 /* Stack longword */
+#define ETIR_S_C_STA_QW 2 /* Stack quadword */
+#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset */
+#define ETIR_S_C_STA_LI 4 /* Stack literal */
+#define ETIR_S_C_STA_MOD 5 /* Stack module */
+#define ETIR_S_C_STA_CKARG 6 /* Check Arguments */
+#define ETIR_S_C_MAXSTACOD 6 /* Maximum stack code */
+#define ETIR_S_C_MINSTOCOD 50 /* Minimum store code */
+#define ETIR_S_C_STO_B 50 /* Store byte */
+#define ETIR_S_C_STO_W 51 /* Store word */
+#define ETIR_S_C_STO_LW 52 /* Store longword */
+#define ETIR_S_C_STO_QW 53 /* Store quadword */
+#define ETIR_S_C_STO_IMMR 54 /* Store immediate Repeated */
+#define ETIR_S_C_STO_GBL 55 /* Store global */
+#define ETIR_S_C_STO_CA 56 /* Store code address */
+#define ETIR_S_C_STO_RB 57 /* Store relative branch */
+#define ETIR_S_C_STO_AB 58 /* Store absolute branch */
+#define ETIR_S_C_STO_OFF 59 /* Store offset within psect */
+#define ETIR_S_C_STO_IMM 61 /* Store immediate */
+#define ETIR_S_C_STO_GBL_LW 62 /* Store global Longword */
+#define ETIR_S_C_STO_LP_PSB 63 /* STO_LP_PSB not valid in level 2 use STC_LP_PSB */
+#define ETIR_S_C_STO_HINT_GBL 64 /* Store 14 bit HINT at global address */
+#define ETIR_S_C_STO_HINT_PS 65 /* Store 14 bit HINT at psect + offset */
+#define ETIR_S_C_MAXSTOCOD 65 /* Maximum store code */
+#define ETIR_S_C_MINOPRCOD 100 /* Minimum operate code */
+#define ETIR_S_C_OPR_NOP 100 /* No-op */
+#define ETIR_S_C_OPR_ADD 101 /* Add */
+#define ETIR_S_C_OPR_SUB 102 /* Subtract */
+#define ETIR_S_C_OPR_MUL 103 /* Multiply */
+#define ETIR_S_C_OPR_DIV 104 /* Divide */
+#define ETIR_S_C_OPR_AND 105 /* Logical AND */
+#define ETIR_S_C_OPR_IOR 106 /* Logical inclusive OR */
+#define ETIR_S_C_OPR_EOR 107 /* Logical exclusive OR */
+#define ETIR_S_C_OPR_NEG 108 /* Negate */
+#define ETIR_S_C_OPR_COM 109 /* Complement */
+#define ETIR_S_C_OPR_INSV 110 /* Insert bit field */
+#define ETIR_S_C_OPR_ASH 111 /* Arithmetic shift */
+#define ETIR_S_C_OPR_USH 112 /* Unsigned shift */
+#define ETIR_S_C_OPR_ROT 113 /* Rotate */
+#define ETIR_S_C_OPR_SEL 114 /* Select one of three longwords on top of stack */
+#define ETIR_S_C_OPR_REDEF 115 /* Redefine this symbol after pass 2 */
+#define ETIR_S_C_OPR_DFLIT 116 /* Define a literal */
+#define ETIR_S_C_MAXOPRCOD 116 /* Maximum operate code */
+#define ETIR_S_C_MINCTLCOD 150 /* Minimum control code */
+#define ETIR_S_C_CTL_SETRB 150 /* Set relocation base */
+#define ETIR_S_C_CTL_AUGRB 151 /* Augment relocation base */
+#define ETIR_S_C_CTL_DFLOC 152 /* Define debug location */
+#define ETIR_S_C_CTL_STLOC 153 /* Set debug location */
+#define ETIR_S_C_CTL_STKDL 154 /* Stack debug location */
+#define ETIR_S_C_MAXCTLCOD 154 /* Maximum control code */
+#define ETIR_S_C_MINSTCCOD 200 /* Minimum store-conditional code */
+#define ETIR_S_C_STC_LP 200 /* Store-conditional Linkage Pair */
+#define ETIR_S_C_STC_LP_PSB 201 /* Store-conditional Linkage Pair with Procedure Signature */
+#define ETIR_S_C_STC_GBL 202 /* Store-conditional Address at global address */
+#define ETIR_S_C_STC_GCA 203 /* Store-conditional Code Address at global address */
+#define ETIR_S_C_STC_PS 204 /* Store-conditional Address at psect + offset */
+#define ETIR_S_C_STC_NOP_GBL 205 /* Store-conditional NOP at address of global */
+#define ETIR_S_C_STC_NOP_PS 206 /* Store-conditional NOP at pect + offset */
+#define ETIR_S_C_STC_BSR_GBL 207 /* Store-conditional BSR at global address */
+#define ETIR_S_C_STC_BSR_PS 208 /* Store-conditional BSR at pect + offset */
+#define ETIR_S_C_STC_LDA_GBL 209 /* Store-conditional LDA at global address */
+#define ETIR_S_C_STC_LDA_PS 210 /* Store-conditional LDA at psect + offset */
+#define ETIR_S_C_STC_BOH_GBL 211 /* Store-conditional BSR or Hint at global address */
+#define ETIR_S_C_STC_BOH_PS 212 /* Store-conditional BSR or Hint at pect + offset */
+#define ETIR_S_C_STC_NBH_GBL 213 /* Store-conditional NOP,BSR or HINT at global address */
+#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset */
+#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code */
+
+/* VMS Global symbol definition record (GSD/EGSD). */
+
+#define GSD_S_K_ENTRIES 1
+#define GSD_S_C_ENTRIES 1
+#define GSD_S_C_PSC 0
+#define GSD_S_C_SYM 1
+#define GSD_S_C_EPM 2
+#define GSD_S_C_PRO 3
+#define GSD_S_C_SYMW 4
+#define GSD_S_C_EPMW 5
+#define GSD_S_C_PROW 6
+#define GSD_S_C_IDC 7
+#define GSD_S_C_ENV 8
+#define GSD_S_C_LSY 9
+#define GSD_S_C_LEPM 10
+#define GSD_S_C_LPRO 11
+#define GSD_S_C_SPSC 12
+#define GSD_S_C_SYMV 13
+#define GSD_S_C_EPMV 14
+#define GSD_S_C_PROV 15
+#define GSD_S_C_MAXRECTYP 15
+
+#define EGSD_S_K_ENTRIES 2 /* Offset to first entry in record */
+#define EGSD_S_C_ENTRIES 2 /* Offset to first entry in record */
+#define EGSD_S_C_PSC 0 /* Psect definition */
+#define EGSD_S_C_SYM 1 /* Symbol specification */
+#define EGSD_S_C_IDC 2 /* Random entity check */
+#define EGSD_S_C_SPSC 5 /* Shareable image psect definition */
+#define EGSD_S_C_SYMV 6 /* Vectored (dual-valued) versions of SYM, */
+#define EGSD_S_C_SYMM 7 /* Masked versions of SYM, */
+#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM */
+#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined */
+
+#define GPS_S_M_PIC 1
+#define GPS_S_M_LIB 2
+#define GPS_S_M_OVR 4
+#define GPS_S_M_REL 8
+#define GPS_S_M_GBL 16
+#define GPS_S_M_SHR 32
+#define GPS_S_M_EXE 64
+#define GPS_S_M_RD 128
+#define GPS_S_M_WRT 256
+#define GPS_S_M_VEC 512
+#define GPS_S_K_NAME 9
+#define GPS_S_C_NAME 9
+
+#define EGPS_S_V_PIC 0x0001
+#define EGPS_S_V_LIB 0x0002
+#define EGPS_S_V_OVR 0x0004
+#define EGPS_S_V_REL 0x0008
+#define EGPS_S_V_GBL 0x0010
+#define EGPS_S_V_SHR 0x0020
+#define EGPS_S_V_EXE 0x0040
+#define EGPS_S_V_RD 0x0080
+#define EGPS_S_V_WRT 0x0100
+#define EGPS_S_V_VEC 0x0200
+#define EGPS_S_V_NOMOD 0x0400
+#define EGPS_S_V_COM 0x0800
+
+#define GSY_S_M_WEAK 1
+#define GSY_S_M_DEF 2
+#define GSY_S_M_UNI 4
+#define GSY_S_M_REL 8
+
+#define EGSY_S_V_WEAK 0x0001
+#define EGSY_S_V_DEF 0x0002
+#define EGSY_S_V_UNI 0x0004
+#define EGSY_S_V_REL 0x0008
+#define EGSY_S_V_COMM 0x0010
+#define EGSY_S_V_VECEP 0x0020
+#define EGSY_S_V_NORM 0x0040
+
+#define LSY_S_M_DEF 2
+#define LSY_S_M_REL 8
+
+#define ENV_S_M_DEF 1
+#define ENV_S_M_NESTED 2
+
+/*
+ * Debugger symbol definitions: These are done by hand, as no
+ * machine-readable version seems
+ * to be available.
+ */
+#define DST_S_C_C 7 /* Language == "C" */
+#define DST_S_C_CXX 15 /* Language == "C++" */
+#define DST_S_C_VERSION 153
+#define DST_S_C_SOURCE 155 /* Source file */
+#define DST_S_C_PROLOG 162
+#define DST_S_C_BLKBEG 176 /* Beginning of block */
+#define DST_S_C_BLKEND 177 /* End of block */
+#define DST_S_C_ENTRY 181
+#define DST_S_C_PSECT 184
+#define DST_S_C_LINE_NUM 185 /* Line Number */
+#define DST_S_C_LBLORLIT 186
+#define DST_S_C_LABEL 187
+#define DST_S_C_MODBEG 188 /* Beginning of module */
+#define DST_S_C_MODEND 189 /* End of module */
+#define DST_S_C_RTNBEG 190 /* Beginning of routine */
+#define DST_S_C_RTNEND 191 /* End of routine */
+#define DST_S_C_DELTA_PC_W 1 /* Incr PC */
+#define DST_S_C_INCR_LINUM 2 /* Incr Line # */
+#define DST_S_C_INCR_LINUM_W 3 /* Incr Line # */
+#define DST_S_C_SET_LINUM_INCR 4
+#define DST_S_C_SET_LINUM_INCR_W 5
+#define DST_S_C_RESET_LINUM_INCR 6
+#define DST_S_C_BEG_STMT_MODE 7
+#define DST_S_C_END_STMT_MODE 8
+#define DST_S_C_SET_LINE_NUM 9 /* Set Line # */
+#define DST_S_C_SET_PC 10
+#define DST_S_C_SET_PC_W 11
+#define DST_S_C_SET_PC_L 12
+#define DST_S_C_SET_STMTNUM 13
+#define DST_S_C_TERM 14 /* End of lines */
+#define DST_S_C_TERM_W 15 /* End of lines */
+#define DST_S_C_SET_ABS_PC 16 /* Set PC */
+#define DST_S_C_DELTA_PC_L 17 /* Incr PC */
+#define DST_S_C_INCR_LINUM_L 18 /* Incr Line # */
+#define DST_S_C_SET_LINUM_B 19 /* Set Line # */
+#define DST_S_C_SET_LINUM_L 20 /* Set Line # */
+#define DST_S_C_TERM_L 21 /* End of lines */
+/* these are used with DST_S_C_SOURCE */
+#define DST_S_C_SRC_DECLFILE 1 /* Declare source file */
+#define DST_S_C_SRC_SETFILE 2 /* Set source file */
+#define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value */
+#define DST_S_C_SRC_SETREC_W 4 /* Set record, word value */
+#define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter */
+#define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter */
+#define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record */
+/* the following are the codes for the various data types. Anything not on
+ * the list is included under 'advanced_type'
+ */
+#define DBG_S_C_UCHAR 0x02
+#define DBG_S_C_USINT 0x03
+#define DBG_S_C_ULINT 0x04
+#define DBG_S_C_UQUAD 0x05
+#define DBG_S_C_SCHAR 0x06
+#define DBG_S_C_SSINT 0x07
+#define DBG_S_C_SLINT 0x08
+#define DBG_S_C_SQUAD 0x09
+#define DBG_S_C_REAL4 0x0a
+#define DBG_S_C_REAL8 0x0b /* D_float double */
+#define DBG_S_C_COMPLX4 0x0c /* 2xF_float complex float */
+#define DBG_S_C_COMPLX8 0x0d /* 2xD_float complex double */
+#define DBG_S_C_REAL8_G 0x1b /* G_float double */
+#define DBG_S_C_COMPLX8_G 0x1d /* 2xG_float complex double */
+#define DBG_S_C_FUNCTION_ADDR 0x17
+#define DBG_S_C_ADVANCED_TYPE 0xa3
+/* Some of these are just for future reference. [pr]
+ */
+#define DBG_S_C_UBITA 0x01 /* unsigned, aligned bit field */
+#define DBG_S_C_UBITU 0x22 /* unsigned, unaligned bit field */
+#define DBG_S_C_SBITA 0x29 /* signed, aligned bit field */
+#define DBG_S_C_SBITU 0x2a /* signed, unaligned bit field */
+#define DBG_S_C_CSTRING 0x2e /* asciz ('\0' terminated) string */
+#define DBG_S_C_WCHAR 0x38 /* wchar_t */
+/* These are descriptor class codes.
+ */
+#define DSC_K_CLASS_S 0x01 /* static (fixed length) */
+#define DSC_K_CLASS_D 0x02 /* dynamic string (not via malloc!) */
+#define DSC_K_CLASS_A 0x04 /* array */
+#define DSC_K_CLASS_UBS 0x0d /* unaligned bit string */
+/* These are the codes that are used to generate the definitions of struct
+ * union and enum records
+ */
+#define DBG_S_C_ENUM_ITEM 0xa4
+#define DBG_S_C_ENUM_START 0xa5
+#define DBG_S_C_ENUM_END 0xa6
+#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */
+#define DBG_S_C_STRUCT_START 0xab
+#define DBG_S_C_STRUCT_END 0xac
+#define DST_K_TYPSPEC 0xaf /* type specification */
+/* These codes are used in the generation of the symbol definition records
+ */
+#define DST_K_VFLAGS_NOVAL 0x80 /* struct definition only */
+#define DST_K_VFLAGS_DSC 0xfa /* descriptor used */
+#define DST_K_VFLAGS_TVS 0xfb /* trailing value specified */
+#define DST_K_VS_FOLLOWS 0xfd /* value spec follows */
+#define DST_K_VFLAGS_BITOFFS 0xff /* value contains bit offset */
+#define DST_K_VALKIND_LITERAL 0
+#define DST_K_VALKIND_ADDR 1
+#define DST_K_VALKIND_DESC 2
+#define DST_K_VALKIND_REG 3
+#define DST_K_REG_VAX_AP 0x0c /* R12 */
+#define DST_K_REG_VAX_FP 0x0d /* R13 */
+#define DST_K_REG_VAX_SP 0x0e /* R14 */
+#define DST_V_VALKIND 0 /* offset of valkind field */
+#define DST_V_INDIRECT 2 /* offset to indirect bit */
+#define DST_V_DISP 3 /* offset to displacement bit */
+#define DST_V_REGNUM 4 /* offset to register number */
+#define DST_M_INDIRECT (1<<DST_V_INDIRECT)
+#define DST_M_DISP (1<<DST_V_DISP)
+#define DBG_C_FUNCTION_PARAM /* 0xc9 */ \
+ (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_AP<<DST_V_REGNUM))
+#define DBG_C_LOCAL_SYM /* 0xd9 */ \
+ (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_FP<<DST_V_REGNUM))
+/* Kinds of value specifications
+ */
+#define DST_K_VS_ALLOC_SPLIT 3 /* split lifetime */
+/* Kinds of type specifications
+ */
+#define DST_K_TS_ATOM 0x01 /* atomic type specification */
+#define DST_K_TS_DSC 0x02 /* descriptor type spec */
+#define DST_K_TS_IND 0x03 /* indirect type specification */
+#define DST_K_TS_TPTR 0x04 /* typed pointer type spec */
+#define DST_K_TS_PTR 0x05 /* pointer type spec */
+#define DST_K_TS_ARRAY 0x07 /* array type spec */
+#define DST_K_TS_NOV_LENG 0x0e /* novel length type spec */
+/* These are the codes that are used in the suffix records to determine the
+ * actual data type
+ */
+#define DBG_S_C_BASIC DST_K_TS_ATOM
+#define DBG_S_C_BASIC_ARRAY DST_K_TS_DSC
+#define DBG_S_C_STRUCT DST_K_TS_IND
+#define DBG_S_C_POINTER DST_K_TS_TPTR
+#define DBG_S_C_VOID DST_K_TS_PTR
+#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
+
+/* VMS Module header record (EMH) definitions. */
+
+#define MHD_S_C_MHD 0
+#define MHD_S_C_LNM 1
+#define MHD_S_C_SRC 2
+#define MHD_S_C_TTL 3
+#define MHD_S_C_CPR 4
+#define MHD_S_C_MTC 5
+#define MHD_S_C_GTX 6
+#define MHD_S_C_MAXHDRTYP 6
+
+#define EMH_S_C_MHD 0 /* Main header record */
+#define EMH_S_C_LNM 1 /* Language name and version */
+#define EMH_S_C_SRC 2 /* Source file specification */
+#define EMH_S_C_TTL 3 /* Title text of module */
+#define EMH_S_C_CPR 4 /* Copyright notice */
+#define EMH_S_C_MTC 5 /* Maintenance status */
+#define EMH_S_C_GTX 6 /* General text */
+#define EMH_S_C_MAXHDRTYP 6 /* Maximum allowable type */
+
+/* vms.c. */
+
+extern asymbol *_bfd_vms_make_empty_symbol PARAMS ((bfd *abfd));
+
+/* vms-gsd.c. */
+
+extern int _bfd_vms_slurp_gsd PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_gsd PARAMS ((bfd *abfd, int objtype));
+
+/* vms-mhd.c. */
+
+extern int _bfd_vms_slurp_hdr PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_hdr PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_eom PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_eom PARAMS ((bfd *abfd, int objtype));
+
+/* vms-tir.c. */
+
+extern int _bfd_vms_slurp_tir PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_dbg PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_tbt PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_lnk PARAMS ((bfd *abfd, int objtype));
+
+extern int _bfd_vms_write_tir PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_tbt PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_dbg PARAMS ((bfd *abfd, int objtype));
+
+/* The r_type field in a reloc is one of the following values. */
+#define ALPHA_R_IGNORE 0
+#define ALPHA_R_REFQUAD 1
+#define ALPHA_R_BRADDR 2
+#define ALPHA_R_HINT 3
+#define ALPHA_R_SREL16 4
+#define ALPHA_R_SREL32 5
+#define ALPHA_R_SREL64 6
+#define ALPHA_R_OP_PUSH 7
+#define ALPHA_R_OP_STORE 8
+#define ALPHA_R_OP_PSUB 9
+#define ALPHA_R_OP_PRSHIFT 10
+#define ALPHA_R_LINKAGE 11
+#define ALPHA_R_REFLONG 12
+#define ALPHA_R_CODEADDR 13
+
+/* Object language definitions. */
+
+#define OBJ_S_C_HDR 0 /*VAX module header record */
+#define OBJ_S_C_GSD 1 /*VAX global symbol definition record */
+#define OBJ_S_C_TIR 2 /*VAX text information record */
+#define OBJ_S_C_EOM 3 /*VAX end of module record */
+#define OBJ_S_C_DBG 4 /*VAX Debugger information record */
+#define OBJ_S_C_TBT 5 /*VAX Traceback information record */
+#define OBJ_S_C_LNK 6 /*VAX linker options record */
+#define OBJ_S_C_EOMW 7 /*VAX end of module word-psect record */
+#define OBJ_S_C_MAXRECTYP 7 /*VAX Last assigned record type */
+#define EOBJ_S_C_EMH 8 /*EVAX module header record */
+#define EOBJ_S_C_EEOM 9 /*EVAX end of module record */
+#define EOBJ_S_C_EGSD 10 /*EVAX global symbol definition record */
+#define EOBJ_S_C_ETIR 11 /*EVAX text information record */
+#define EOBJ_S_C_EDBG 12 /*EVAX Debugger information record */
+#define EOBJ_S_C_ETBT 13 /*EVAX Traceback information record */
+#define EOBJ_S_C_MAXRECTYP 13 /*EVAX Last assigned record type */
+#define OBJ_S_K_SUBTYP 1
+#define OBJ_S_C_SUBTYP 1
+#define EOBJ_S_K_SUBTYP 4
+#define EOBJ_S_C_SUBTYP 4
+#define OBJ_S_C_MAXRECSIZ 2048 /*Maximum legal record size */
+#define EOBJ_S_C_MAXRECSIZ 8192 /*Maximum legal record size */
+#define OBJ_S_C_STRLVL 0 /*Structure level */
+#define EOBJ_S_C_STRLVL 2 /*Structure level */
+#define OBJ_S_C_SYMSIZ 31 /*Maximum symbol length */
+#define EOBJ_S_C_SYMSIZ 64 /*Maximum symbol length */
+#define EOBJ_S_C_SECSIZ 31 /*Maximum section name length */
+#define OBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
+#define EOBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
+#define OBJ_S_C_PSCALILIM 9 /*Maximum p-sect alignment */
+#define EOBJ_S_C_PSCALILIM 16 /*Maximum p-sect alignment */
+
+#define EVAX_OFFSET 256 /*type offset for EVAX codes in switch */
+/* Miscellaneous definitions. */
+
+#if __GNUC__
+typedef unsigned long long uquad;
+#else
+typedef unsigned long uquad;
+#endif
+
+#define MAX_OUTREC_SIZE 4096
+#define MIN_OUTREC_LUFT 64
+
+typedef struct _vms_section {
+ unsigned char *contents;
+ bfd_vma offset;
+ bfd_size_type size;
+ struct _vms_section *next;
+} vms_section;
+
+extern boolean _bfd_save_vms_section
+ PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
+ bfd_size_type count));
+extern vms_section *_bfd_get_vms_section PARAMS ((bfd *abfd, int index));
+
+typedef struct _vms_reloc {
+ struct _vms_reloc *next;
+ arelent *reloc;
+ asection *section;
+} vms_reloc;
+
+/* vms module header */
+
+struct hdr_struc {
+ int hdr_b_strlvl;
+ long hdr_l_arch1;
+ long hdr_l_arch2;
+ long hdr_l_recsiz;
+ char *hdr_t_name;
+ char *hdr_t_version;
+ char *hdr_t_date;
+ char *hdr_c_lnm;
+ char *hdr_c_src;
+ char *hdr_c_ttl;
+};
+
+
+/* vms end of module */
+
+struct eom_struc {
+ long eom_l_total_lps;
+ unsigned char eom_b_comcod;
+ boolean eom_has_transfer;
+ unsigned char eom_b_tfrflg;
+ long eom_l_psindx;
+ long eom_l_tfradr;
+};
+
+enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE, FF_VAX };
+
+typedef struct vms_symbol_struct {
+ struct bfd_hash_entry bfd_hash;
+ asymbol *symbol;
+} vms_symbol_entry;
+
+/* stack value for push/pop commands */
+
+struct stack_struct {
+ uquad value;
+ int psect;
+};
+#define STACKSIZE 8192
+
+/* location stack definitions for CTL_DFLOC, CTL_STLOC, and CTL_STKDL */
+
+struct location_struct {
+ unsigned long value;
+ int psect;
+};
+#define LOCATION_SAVE_SIZE 32
+
+#define VMS_SECTION_COUNT 1024
+
+struct vms_private_data_struct {
+ int is_vax;
+ boolean fixup_done; /* Flag to indicate if all
+ section pointers and PRIV(sections)
+ are set up correctly */
+ unsigned char *vms_buf; /* buffer to record */
+ int buf_size; /* max size of buffer */
+ unsigned char *vms_rec; /* actual record ptr */
+ int rec_length; /* remaining record length */
+ int rec_size; /* actual record size */
+ int rec_type; /* actual record type */
+ enum file_format_enum file_format;
+
+ struct hdr_struc hdr_data; /* data from HDR/EMH record */
+ struct eom_struc eom_data; /* data from EOM/EEOM record */
+ int section_count; /* # of sections in following array */
+ asection **sections; /* array of GSD/EGSD sections */
+ int gsd_sym_count; /* # of GSD/EGSD symbols */
+ asymbol **symbols; /* vector of GSD/EGSD symbols */
+ struct proc_value *procedure;
+
+ struct stack_struct *stack;
+ int stackptr;
+
+ vms_section *vms_section_table[VMS_SECTION_COUNT];
+
+ struct bfd_hash_table *vms_symbol_table;
+ struct symbol_cache_entry **symcache;
+ int symnum;
+
+ struct location_struct *location_stack;
+
+ asection *image_section; /* section for image_ptr */
+ unsigned char *image_ptr; /* a pointer to section->contents */
+
+ unsigned char pdsc[8]; /* procedure descriptor */
+
+ /* Output routine storage */
+
+ unsigned char *output_buf; /* output data */
+ int push_level;
+ int pushed_size;
+ int length_pos;
+ int output_size;
+ int output_alignment;
+
+ /* linkage index counter
+ used by conditional store commands (ETIR_S_C_STC_) */
+
+ int vms_linkage_index;
+
+ /* see tc-alpha.c of gas for a description. */
+ int flag_hash_long_names; /* -+, hash instead of truncate */
+ int flag_show_after_trunc; /* -H, show hashing/truncation */
+};
+
+#define PRIV(name) ((struct vms_private_data_struct *)abfd->tdata.any)->name
+
+#define SECTION_NAME_TEMPLATE "__SEC__%d"
+
+#if VMS_DEBUG
+extern void _bfd_vms_debug PARAMS((int level, char *format, ...));
+extern void _bfd_hexdump
+ PARAMS ((int level, unsigned char *ptr, int size, int offset));
+
+#define vms_debug _bfd_vms_debug
+#endif
+
+extern struct bfd_hash_entry *_bfd_vms_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string));
+extern void _bfd_vms_get_header_values
+ PARAMS ((bfd *abfd, unsigned char *buf, int *type, int *length));
+extern int _bfd_vms_get_record PARAMS ((bfd *abfd));
+extern int _bfd_vms_next_record PARAMS ((bfd *abfd));
+
+extern char *_bfd_vms_save_sized_string PARAMS ((unsigned char *str, int size));
+extern char *_bfd_vms_save_counted_string PARAMS ((unsigned char *ptr));
+extern void _bfd_vms_push PARAMS ((bfd *abfd, uquad val, int psect));
+extern uquad _bfd_vms_pop PARAMS ((bfd *abfd, int *psect));
+
+extern boolean _bfd_save_vms_section
+ PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
+ bfd_size_type count));
+extern void _bfd_vms_output_begin
+ PARAMS ((bfd *abfd, int rectype, int rechead));
+extern void _bfd_vms_output_alignment PARAMS ((bfd *abfd, int alignto));
+extern void _bfd_vms_output_push PARAMS ((bfd *abfd));
+extern void _bfd_vms_output_pop PARAMS ((bfd *abfd));
+extern void _bfd_vms_output_flush PARAMS ((bfd *abfd));
+extern void _bfd_vms_output_end PARAMS ((bfd *abfd));
+extern int _bfd_vms_output_check PARAMS ((bfd *abfd, int size));
+extern void _bfd_vms_output_byte PARAMS ((bfd *abfd, unsigned int value));
+extern void _bfd_vms_output_short PARAMS ((bfd *abfd, unsigned int value));
+extern void _bfd_vms_output_long PARAMS ((bfd *abfd, unsigned long value));
+extern void _bfd_vms_output_quad PARAMS ((bfd *abfd, uquad value));
+extern void _bfd_vms_output_counted PARAMS ((bfd *abfd, char *value));
+extern void _bfd_vms_output_dump PARAMS ((bfd *abfd, unsigned char *data,
+ int length));
+extern void _bfd_vms_output_fill PARAMS ((bfd *abfd, int value, int length));
+extern char *_bfd_vms_length_hash_symbol PARAMS ((bfd *abfd, const char *in, int maxlen));
+
+extern vms_symbol_entry *_bfd_vms_enter_symbol PARAMS ((bfd *abfd, char *name));
+
+#endif /* VMS_H */