From 0dc4c667aceab372c5500045bd76a4c93af315ca Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 2 Jul 1998 18:41:08 +0000 Subject: [PATCH] Thu Jul 2 14:59:42 1998 Klaus Kaempf 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. --- bfd/.Sanitize | 12 +- bfd/ChangeLog | 35 + bfd/config.bfd | 19 +- bfd/evax-alpha.c | 1795 ---------------------- bfd/evax-egsd.c | 596 -------- bfd/evax-emh.c | 372 ----- bfd/evax-etir.c | 1508 ------------------- bfd/evax.h | 383 ----- bfd/po/POTFILES.in | 12 +- bfd/vms-gsd.c | 920 ++++++++++++ bfd/vms-hdr.c | 461 ++++++ bfd/{evax-misc.c => vms-misc.c} | 549 ++++--- bfd/vms-tir.c | 2489 +++++++++++++++++++++++++++++++ bfd/vms.h | 675 +++++++++ 14 files changed, 4935 insertions(+), 4891 deletions(-) delete mode 100644 bfd/evax-alpha.c delete mode 100644 bfd/evax-egsd.c delete mode 100644 bfd/evax-emh.c delete mode 100644 bfd/evax-etir.c delete mode 100644 bfd/evax.h create mode 100644 bfd/vms-gsd.c create mode 100644 bfd/vms-hdr.c rename bfd/{evax-misc.c => vms-misc.c} (57%) create mode 100644 bfd/vms-tir.c create mode 100644 bfd/vms.h diff --git a/bfd/.Sanitize b/bfd/.Sanitize index 4abfe9de760..d8c7c33b48d 100644 --- a/bfd/.Sanitize +++ b/bfd/.Sanitize @@ -179,12 +179,6 @@ elfcore.h 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 @@ -287,6 +281,12 @@ tekhex.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: diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2287a35db41..7d180e6b77e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,38 @@ +Thu Jul 2 14:59:42 1998 Klaus Kaempf + + 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 + + Based on patch from Matt Semersky : + * 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 * elf.c (copy_private_bfd_data): Add support for changing VMA or diff --git a/bfd/config.bfd b/bfd/config.bfd index 05ef334902e..3155cdf8b47 100755 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -76,7 +76,7 @@ case "${targ}" in targ_selvecs=ecoffalpha_little_vec ;; alpha*-*-*vms*) - targ_defvec=evax_alpha_vec + targ_defvec=vms_alpha_vec ;; alpha*-*-*) targ_defvec=ecoffalpha_little_vec @@ -610,6 +610,10 @@ case "${targ}" in ;; #endif + vax*-*-*vms*) + targ_defvec=vms_vax_vec + ;; + we32k-*-*) targ_defvec=we32kcoff_vec ;; @@ -648,3 +652,16 @@ case "${targ}" in 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 diff --git a/bfd/evax-alpha.c b/bfd/evax-alpha.c deleted file mode 100644 index 48bde0c19f6..00000000000 --- a/bfd/evax-alpha.c +++ /dev/null @@ -1,1795 +0,0 @@ -/* 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 - -/*===========================================================================*/ - -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 -}; - - -/*===========================================================================*/ - -/* 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 <> - on success, <> on error. Possible error returns are: - - o <> - - 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 <> on success, <> on error. Possible error - returns are: - - o <> - - 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, )\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, )\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, , , )\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, , )\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, )\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, )\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; -} diff --git a/bfd/evax-egsd.c b/bfd/evax-egsd.c deleted file mode 100644 index 567fe46e144..00000000000 --- a/bfd/evax-egsd.c +++ /dev/null @@ -1,596 +0,0 @@ -/* 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 - -#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; -} diff --git a/bfd/evax-emh.c b/bfd/evax-emh.c deleted file mode 100644 index 79a63d2adbb..00000000000 --- a/bfd/evax-emh.c +++ /dev/null @@ -1,372 +0,0 @@ -/* 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 - -#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 - - 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 - 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, "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; -} diff --git a/bfd/evax-etir.c b/bfd/evax-etir.c deleted file mode 100644 index 3f7339b8fbd..00000000000 --- a/bfd/evax-etir.c +++ /dev/null @@ -1,1508 +0,0 @@ -/* 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 - -#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 */ - -/* 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; -} - - -#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; -} - -/*----------------------------------------------------------------------*/ -/* */ -/* 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; -} diff --git a/bfd/evax.h b/bfd/evax.h deleted file mode 100644 index 945989899f6..00000000000 --- a/bfd/evax.h +++ /dev/null @@ -1,383 +0,0 @@ -/* 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 */ diff --git a/bfd/po/POTFILES.in b/bfd/po/POTFILES.in index f16781a19e3..a582f28d305 100644 --- a/bfd/po/POTFILES.in +++ b/bfd/po/POTFILES.in @@ -109,12 +109,6 @@ elf64-sparc.c 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 @@ -197,4 +191,10 @@ tekhex.c 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 diff --git a/bfd/vms-gsd.c b/bfd/vms-gsd.c new file mode 100644 index 00000000000..6a52462a06d --- /dev/null +++ b/bfd/vms-gsd.c @@ -0,0 +1,920 @@ +/* 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 + +#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; +} diff --git a/bfd/vms-hdr.c b/bfd/vms-hdr.c new file mode 100644 index 00000000000..01d20aabefa --- /dev/null +++ b/bfd/vms-hdr.c @@ -0,0 +1,461 @@ +/* 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 + +#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 + + 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 + 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, "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; +} diff --git a/bfd/evax-misc.c b/bfd/vms-misc.c similarity index 57% rename from bfd/evax-misc.c rename to bfd/vms-misc.c index 4dc74ed8825..a5fdae4cc28 100644 --- a/bfd/evax-misc.c +++ b/bfd/vms-misc.c @@ -1,8 +1,8 @@ -/* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/Alpha) files. +/* 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@progis.de) - of proGIS Softwareentwicklung, Aachen, Germany + 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 @@ -28,14 +28,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfdlink.h" #include "libbfd.h" -#include "evax.h" +#include "vms.h" /*-----------------------------------------------------------------------------*/ -#if EVAX_DEBUG +#if VMS_DEBUG /* debug functions */ -/* debug function for all evax extensions - evaluates environment variable EVAX_DEBUG for a +/* 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 @@ -51,7 +51,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if __STDC__ void -_bfd_evax_debug (int level, char *format, ...) +_bfd_vms_debug (int level, char *format, ...) { static int min_level = -1; static FILE *output = NULL; @@ -61,7 +61,7 @@ _bfd_evax_debug (int level, char *format, ...) if (min_level == -1) { - if ((eptr = getenv("EVAX_DEBUG")) != NULL) + if ((eptr = getenv("VMS_DEBUG")) != NULL) { min_level = atoi(eptr); output = stderr; @@ -87,7 +87,7 @@ _bfd_evax_debug (int level, char *format, ...) #else /* not __STDC__ */ void -_bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6) +_bfd_vms_debug (level, format, a1, a2, a3, a4, a5, a6) int level; char *format; long a1; long a2; long a3; @@ -99,7 +99,7 @@ _bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6) if (min_level == -1) { - if ((eptr = getenv("EVAX_DEBUG")) != NULL) + if ((eptr = getenv("VMS_DEBUG")) != NULL) { min_level = atoi(eptr); output = stderr; @@ -139,31 +139,31 @@ _bfd_hexdump (level, ptr, size, offset) while (size-- > 0) { if ((count%16) == 0) - evax_debug (level, "%08lx:", start); - evax_debug (-level, " %02x", *ptr++); + vms_debug (level, "%08lx:", start); + vms_debug (-level, " %02x", *ptr++); count++; start++; if (size == 0) { while ((count%16) != 0) { - evax_debug (-level, " "); + vms_debug (-level, " "); count++; } } if ((count%16) == 0) { - evax_debug (-level, " "); + vms_debug (-level, " "); while (lptr < ptr) { - evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr); + vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr); lptr++; } - evax_debug (-level, "\n"); + vms_debug (-level, "\n"); } } if ((count%16) != 0) - evax_debug (-level, "\n"); + vms_debug (-level, "\n"); return; } @@ -174,29 +174,38 @@ _bfd_hexdump (level, ptr, size, offset) These are needed when reading an object file. */ -/* allocate new evax_hash_entry +/* allocate new vms_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) +_bfd_vms_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; + vms_symbol_entry *ret; -#if EVAX_DEBUG - evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string); +#if VMS_DEBUG + vms_debug (5, "_bfd_vms_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) + if (entry == (struct bfd_hash_entry *)NULL) { - bfd_set_error (bfd_error_no_memory); - return (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; + } } - ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string); + + /* 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; @@ -206,10 +215,10 @@ _bfd_evax_hash_newfunc (entry, table, string) /* object file input functions */ -/* Return type and length from record header (buf) */ +/* Return type and length from record header (buf) on Alpha. */ void -_bfd_evax_get_header_values (abfd, buf, type, length) +_bfd_vms_get_header_values (abfd, buf, type, length) bfd *abfd; unsigned char *buf; int *type; @@ -221,16 +230,21 @@ _bfd_evax_get_header_values (abfd, buf, type, length) 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 evax_buf +/* 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/AXP object file has 'variable length' which means that + 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 @@ -243,7 +257,7 @@ _bfd_evax_get_header_values (abfd, buf, type, length) 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. + 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. @@ -260,34 +274,38 @@ _bfd_evax_get_header_values (abfd, buf, type, length) all file i/o is always done on even file positions */ int -_bfd_evax_get_record (abfd) +_bfd_vms_get_record (abfd) bfd *abfd; { int test_len, test_start, remaining; - unsigned char *evax_buf; + unsigned char *vms_buf; -#if EVAX_DEBUG - evax_debug (8, "_bfd_evax_get_record\n"); +#if VMS_DEBUG + vms_debug (8, "_bfd_vms_get_record\n"); #endif - /* minimum is 6 bytes - (2 bytes length, 2 bytes record id, 2 bytes length repeated) */ + /* 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) { - PRIV(evax_buf) = (unsigned char *) malloc (6); -#if EVAX_DEBUG - evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf)); -#endif + 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); } - evax_buf = PRIV(evax_buf); + vms_buf = PRIV(vms_buf); - if (evax_buf == 0) + if (vms_buf == 0) { -#if EVAX_DEBUG - evax_debug (9, "can't alloc evax_buf\n"); -#endif bfd_set_error (bfd_error_no_memory); return -1; } @@ -296,45 +314,37 @@ _bfd_evax_get_record (abfd) { case FF_UNKNOWN: case FF_FOREIGN: - test_len = 6; /* probe 6 bytes */ - test_start = 2; /* where the record starts */ + 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 0 - if (PRIV(file_format) == FF_FOREIGN) + + if (bfd_tell (abfd) & 1) { -#endif - if (bfd_tell (abfd) & 1) + if (bfd_read (PRIV(vms_buf), 1, 1, 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; - } + 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) + /* read the record header on Alpha. */ + + if ((test_len != 0) + && (bfd_read (PRIV(vms_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; } @@ -343,8 +353,8 @@ _bfd_evax_get_record (abfd) if (PRIV(file_format) == FF_UNKNOWN) { /* record length repeats ? */ - if ( (evax_buf[0] == evax_buf[4]) - && (evax_buf[1] == evax_buf[5])) + if ( (vms_buf[0] == vms_buf[4]) + && (vms_buf[1] == vms_buf[5])) { PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */ test_start = 2; @@ -354,97 +364,113 @@ _bfd_evax_get_record (abfd) 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) + if (PRIV(is_vax)) { - bfd_set_error (bfd_error_file_truncated); - return 0; + 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 */ - /* that's what the linker manual says */ + _bfd_vms_get_header_values (abfd, vms_buf+test_start, NULL, + &PRIV(rec_length)); - if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ) - { - bfd_set_error (bfd_error_file_truncated); - return 0; - } + if (PRIV(rec_length) <= 0) + { + bfd_set_error (bfd_error_file_truncated); + return 0; + } - /* adjust the buffer */ + /* that's what the linker manual says */ - 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 (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ) { -#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; + bfd_set_error (bfd_error_file_truncated); + return 0; } - PRIV(buf_size) = PRIV(rec_length); - } - /* read the remaining record */ + /* 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); + } - remaining = PRIV(rec_length) - test_len + test_start; + /* read the remaining record */ - 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); + remaining = PRIV(rec_length) - test_len + test_start; + +#if VMS_DEBUG + vms_debug (10, "bfd_read remaining %d\n", remaining); #endif - bfd_set_error (bfd_error_file_truncated); - return 0; + 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; } - PRIV(evax_rec) = evax_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 EVAX record from file - update evax_rec and rec_length to new (remaining) values */ +/* get next vms record from file + update vms_rec and rec_length to new (remaining) values */ int -_bfd_evax_next_record (abfd) +_bfd_vms_next_record (abfd) bfd *abfd; { -#if EVAX_DEBUG - evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n", +#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(evax_rec) += PRIV(rec_size); + PRIV(vms_rec) += PRIV(rec_size); } else { - if (_bfd_evax_get_record (abfd) <= 0) + if (_bfd_vms_get_record (abfd) <= 0) return -1; } - _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type), - &PRIV(rec_size)); + + 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 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), +#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 @@ -457,15 +483,15 @@ _bfd_evax_next_record (abfd) size is string length (size of record) */ char * -_bfd_evax_save_sized_string (str, size) - char *str; +_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, str, size); + strncpy (newstr, (char *)str, size); newstr[size] = 0; return newstr; @@ -475,29 +501,29 @@ _bfd_evax_save_sized_string (str, size) ptr points to length byte on entry */ char * -_bfd_evax_save_counted_string (ptr) - char *ptr; +_bfd_vms_save_counted_string (ptr) + unsigned char *ptr; { int len = *ptr++; - return _bfd_evax_save_sized_string (ptr, len); + return _bfd_vms_save_sized_string (ptr, len); } -/* stack routines for EVAX ETIR commands */ +/* stack routines for vms ETIR commands */ /* Push value and section index */ void -_bfd_evax_push (abfd, val, psect) +_bfd_vms_push (abfd, val, psect) bfd *abfd; uquad val; int psect; { static int last_psect; -#if EVAX_DEBUG - evax_debug (4, "\n", val, psect, PRIV(stackptr)); +#if VMS_DEBUG + vms_debug (4, "\n", val, psect, PRIV(stackptr)); #endif if (psect >= 0) @@ -509,7 +535,8 @@ _bfd_evax_push (abfd, val, psect) if (PRIV(stackptr) >= STACKSIZE) { bfd_set_error (bfd_error_bad_value); - exit(1); + (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV(stackptr)); + exit (1); } return; } @@ -518,7 +545,7 @@ _bfd_evax_push (abfd, val, psect) /* Pop value and section index */ uquad -_bfd_evax_pop (abfd, psect) +_bfd_vms_pop (abfd, psect) bfd *abfd; int *psect; { @@ -527,15 +554,16 @@ _bfd_evax_pop (abfd, psect) if (PRIV(stackptr) == 0) { bfd_set_error (bfd_error_bad_value); - exit(1); + (*_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 EVAX_DEBUG - evax_debug (4, "\n", value, PRIV(stack[PRIV(stackptr)]).psect); +#if VMS_DEBUG + vms_debug (4, "\n", value, PRIV(stack[PRIV(stackptr)]).psect); #endif return value; @@ -548,22 +576,22 @@ _bfd_evax_pop (abfd, psect) 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 +/* Add a new vms_section structure to vms_section_table - forward chaining - */ -static evax_section * +static vms_section * add_new_contents (abfd, section) bfd *abfd; sec_ptr section; { - evax_section *sptr, *newptr; + vms_section *sptr, *newptr; - sptr = PRIV(evax_section_table)[section->index]; + sptr = PRIV(vms_section_table)[section->index]; if (sptr != NULL) return sptr; - newptr = (evax_section *) bfd_malloc (sizeof (evax_section)); - if (newptr == (evax_section *) NULL) + 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) @@ -571,25 +599,25 @@ add_new_contents (abfd, section) newptr->offset = 0; newptr->size = section->_raw_size; newptr->next = 0; - PRIV(evax_section_table)[section->index] = newptr; + PRIV(vms_section_table)[section->index] = newptr; return newptr; } -/* Save section data & offset to an evax_section structure - evax_section_table[] holds the evax_section chain */ +/* Save section data & offset to an vms_section structure + vms_section_table[] holds the vms_section chain */ boolean -_bfd_save_evax_section (abfd, section, data, offset, count) +_bfd_save_vms_section (abfd, section, data, offset, count) bfd *abfd; sec_ptr section; PTR data; file_ptr offset; bfd_size_type count; { - evax_section *sptr; + vms_section *sptr; - if (section->index >= EVAX_SECTION_COUNT) + if (section->index >= VMS_SECTION_COUNT) { bfd_set_error (bfd_error_nonrepresentable_section); return false; @@ -605,19 +633,19 @@ _bfd_save_evax_section (abfd, section, data, offset, count) } -/* Get evax_section pointer to saved contents for section # index */ +/* Get vms_section pointer to saved contents for section # index */ -evax_section * -_bfd_get_evax_section (abfd, index) +vms_section * +_bfd_get_vms_section (abfd, index) bfd *abfd; int index; { - if (index >= EVAX_SECTION_COUNT) + if (index >= VMS_SECTION_COUNT) { bfd_set_error (bfd_error_nonrepresentable_section); return NULL; } - return PRIV(evax_section_table)[index]; + return PRIV(vms_section_table)[index]; } @@ -629,32 +657,32 @@ _bfd_get_evax_section (abfd, index) write 2 bytes header type (ommitted if rechead == -1) */ void -_bfd_evax_output_begin (abfd, rectype, rechead) +_bfd_vms_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, +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype, rechead); #endif - _bfd_evax_output_short (abfd,rectype); + _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 EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n", +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n", PRIV(length_pos)); #endif - _bfd_evax_output_short (abfd,0); /* placeholder for length */ + _bfd_vms_output_short (abfd,0); /* placeholder for length */ if (rechead != -1) - _bfd_evax_output_short (abfd,rechead); + _bfd_vms_output_short (abfd,rechead); return; } @@ -663,12 +691,12 @@ _bfd_evax_output_begin (abfd, rectype, rechead) /* Set record/subrecord alignment */ void -_bfd_evax_output_alignment (abfd, alignto) +_bfd_vms_output_alignment (abfd, alignto) bfd *abfd; int alignto; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto); +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto); #endif PRIV(output_alignment) = alignto; @@ -679,11 +707,11 @@ _bfd_evax_output_alignment (abfd, alignto) /* Prepare for subrecord fields */ void -_bfd_evax_output_push (abfd) +_bfd_vms_output_push (abfd) bfd *abfd; { -#if EVAX_DEBUG - evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size)); +#if VMS_DEBUG + vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV(output_size)); #endif PRIV(push_level)++; @@ -695,18 +723,18 @@ _bfd_evax_output_push (abfd) /* End of subrecord fields */ void -_bfd_evax_output_pop (abfd) +_bfd_vms_output_pop (abfd) bfd *abfd; { -#if EVAX_DEBUG - evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size)); +#if VMS_DEBUG + vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV(pushed_size)); #endif - _bfd_evax_output_flush (abfd); + _bfd_vms_output_flush (abfd); PRIV(length_pos) = 2; -#if EVAX_DEBUG - evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos)); +#if VMS_DEBUG + vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV(length_pos)); #endif PRIV(pushed_size) = 0; @@ -718,15 +746,15 @@ _bfd_evax_output_pop (abfd) /* Flush unwritten output, ends current record */ void -_bfd_evax_output_flush (abfd) +_bfd_vms_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", +#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 @@ -740,8 +768,8 @@ _bfd_evax_output_flush (abfd) aligncount = (PRIV(output_alignment) - (length % PRIV(output_alignment))) % PRIV(output_alignment); -#if EVAX_DEBUG - evax_debug (6, "align: adding %d bytes\n", aligncount); +#if VMS_DEBUG + vms_debug (6, "align: adding %d bytes\n", aligncount); #endif while(aligncount-- > 0) @@ -758,7 +786,7 @@ _bfd_evax_output_flush (abfd) /* put length to buffer */ PRIV(output_size) = PRIV(length_pos); - _bfd_evax_output_short (abfd, (unsigned int)length); + _bfd_vms_output_short (abfd, (unsigned int)length); if (PRIV(push_level) == 0) { @@ -783,14 +811,14 @@ _bfd_evax_output_flush (abfd) /* End record output */ void -_bfd_evax_output_end (abfd) +_bfd_vms_output_end (abfd) bfd *abfd; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_end\n"); +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_end\n"); #endif - _bfd_evax_output_flush (abfd); + _bfd_vms_output_flush (abfd); return; } @@ -801,12 +829,12 @@ _bfd_evax_output_end (abfd) return what's left. */ int -_bfd_evax_output_check (abfd, size) +_bfd_vms_output_check (abfd, size) bfd *abfd; int size; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_check(%d)\n", 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)); @@ -816,12 +844,12 @@ _bfd_evax_output_check (abfd, size) /* Output byte (8 bit) value */ void -_bfd_evax_output_byte (abfd, value) +_bfd_vms_output_byte (abfd, value) bfd *abfd; unsigned int value; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_byte(%02x)\n", 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)); @@ -833,12 +861,12 @@ _bfd_evax_output_byte (abfd, value) /* Output short (16 bit) value */ void -_bfd_evax_output_short (abfd, value) +_bfd_vms_output_short (abfd, value) bfd *abfd; unsigned int value; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_short (%04x)\n", 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)); @@ -850,12 +878,12 @@ _bfd_evax_output_short (abfd, value) /* Output long (32 bit) value */ void -_bfd_evax_output_long (abfd, value) +_bfd_vms_output_long (abfd, value) bfd *abfd; unsigned long value; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_long (%08lx)\n", 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)); @@ -867,12 +895,12 @@ _bfd_evax_output_long (abfd, value) /* Output quad (64 bit) value */ void -_bfd_evax_output_quad (abfd, value) +_bfd_vms_output_quad (abfd, value) bfd *abfd; uquad value; { -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", 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)); @@ -884,42 +912,42 @@ _bfd_evax_output_quad (abfd, value) /* Output c-string as counted string */ void -_bfd_evax_output_counted (abfd, value) +_bfd_vms_output_counted (abfd, value) bfd *abfd; char *value; { int len; -#if EVAX_DEBUG - evax_debug (6, "_bfd_evax_output_counted(%s)\n", value); +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_counted(%s)\n", value); #endif len = strlen (value); if (len == 0) { - (*_bfd_error_handler) (_("_bfd_evax_output_counted called with zero bytes")); + (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes")); return; } if (len > 255) { - (*_bfd_error_handler) (_("_bfd_evax_output_counted called with too many bytes")); + (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes")); return; } - _bfd_evax_output_byte (abfd, len & 0xff); - _bfd_evax_output_dump (abfd, (unsigned char *)value, len); + _bfd_vms_output_byte (abfd, len & 0xff); + _bfd_vms_output_dump (abfd, (unsigned char *)value, len); } /* Output character area */ void -_bfd_evax_output_dump (abfd, data, length) +_bfd_vms_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); +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_dump(%d)\n", length); #endif if (length == 0) @@ -935,13 +963,13 @@ _bfd_evax_output_dump (abfd, data, length) /* Output count bytes of value */ void -_bfd_evax_output_fill (abfd, value, count) +_bfd_vms_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); +#if VMS_DEBUG + vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value, count); #endif if (count == 0) @@ -974,7 +1002,7 @@ hash_string (ptr) /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */ char * -_bfd_evax_length_hash_symbol (abfd, in, maxlen) +_bfd_vms_length_hash_symbol (abfd, in, maxlen) bfd *abfd; const char *in; int maxlen; @@ -989,8 +1017,8 @@ _bfd_evax_length_hash_symbol (abfd, in, maxlen) 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); +#if VMS_DEBUG + vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in); #endif if (maxlen > EOBJ_S_C_SYMSIZ) @@ -1030,8 +1058,8 @@ _bfd_evax_length_hash_symbol (abfd, in, maxlen) else *out = 0; -#if EVAX_DEBUG - evax_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf); +#if VMS_DEBUG + vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf); #endif if (in_len > maxlen @@ -1042,3 +1070,76 @@ _bfd_evax_length_hash_symbol (abfd, in, maxlen) 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; +} diff --git a/bfd/vms-tir.c b/bfd/vms-tir.c new file mode 100644 index 00000000000..782f52bfc04 --- /dev/null +++ b/bfd/vms-tir.c @@ -0,0 +1,2489 @@ +/* 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 + +#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; +} + + +#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 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; +} + +/*----------------------------------------------------------------------*/ +/* */ +/* 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)); +#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; +} diff --git a/bfd/vms.h b/bfd/vms.h new file mode 100644 index 00000000000..d6bdd02a720 --- /dev/null +++ b/bfd/vms.h @@ -0,0 +1,675 @@ +#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<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 */ -- 2.30.2