diff options
Diffstat (limited to 'bfd/vms-gsd.c')
-rw-r--r-- | bfd/vms-gsd.c | 920 |
1 files changed, 0 insertions, 920 deletions
diff --git a/bfd/vms-gsd.c b/bfd/vms-gsd.c deleted file mode 100644 index 6a52462a06d..00000000000 --- a/bfd/vms-gsd.c +++ /dev/null @@ -1,920 +0,0 @@ -/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and - EVAX (openVMS/Alpha) files. - Copyright 1996, 1997, 1998 Free Software Foundation Inc. - - go and read the openVMS linker manual (esp. appendix B) - if you don't know what's going on here :-) - - Written by Klaus K"ampf (kkaempf@rmi.de) - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include <ctype.h> - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" - -#include "vms.h" - -/*-----------------------------------------------------------------------------*/ - -/* typical sections for vax object files */ - -#define VAX_CODE_NAME "$CODE" -#define VAX_DATA_NAME "$DATA" -#define VAX_ADDRESS_DATA_NAME "$ADDRESS_DATA" - -/* typical sections for evax object files */ - -#define EVAX_ABS_NAME "$ABS$" -#define EVAX_CODE_NAME "$CODE$" -#define EVAX_LINK_NAME "$LINK$" -#define EVAX_DATA_NAME "$DATA$" -#define EVAX_BSS_NAME "$BSS$" -#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$" -#define EVAX_READONLY_NAME "$READONLY$" -#define EVAX_LITERAL_NAME "$LITERAL$" -#define EVAX_COMMON_NAME "$COMMON$" -#define EVAX_LOCAL_NAME "$LOCAL$" - -struct sec_flags_struct { - char *name; /* name of section */ - int vflags_always; - flagword flags_always; /* flags we set always */ - int vflags_hassize; - flagword flags_hassize; /* flags we set if the section has a size > 0 */ -}; - -/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible */ - -static struct sec_flags_struct vax_section_flags[] = { - { VAX_CODE_NAME, - (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD), - (SEC_CODE), - (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD), - (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { VAX_DATA_NAME, - (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT), - (SEC_DATA), - (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { VAX_ADDRESS_DATA_NAME, - (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD), - (SEC_DATA|SEC_READONLY), - (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, - { NULL, - (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT), - (SEC_DATA), - (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) } -}; - - -/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible */ - -static struct sec_flags_struct evax_section_flags[] = { - { EVAX_ABS_NAME, - (EGPS_S_V_SHR), - (SEC_DATA), - (EGPS_S_V_SHR), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { EVAX_CODE_NAME, - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE), - (SEC_CODE), - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE), - (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { EVAX_LITERAL_NAME, - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD), - (SEC_DATA|SEC_READONLY), - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, - { EVAX_LINK_NAME, - (EGPS_S_V_REL|EGPS_S_V_RD), - (SEC_DATA|SEC_READONLY), - (EGPS_S_V_REL|EGPS_S_V_RD), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, - { EVAX_DATA_NAME, - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD), - (SEC_DATA), - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { EVAX_BSS_NAME, - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD), - (SEC_NO_FLAGS), - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD), - (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { EVAX_READONLYADDR_NAME, - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD), - (SEC_DATA|SEC_READONLY), - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, - { EVAX_READONLY_NAME, - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD), - (SEC_DATA|SEC_READONLY), - (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, - { EVAX_LOCAL_NAME, - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), - (SEC_DATA), - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, - { NULL, - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), - (SEC_DATA), - (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), - (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) } -}; - -/* Retrieve bfd section flags by name and size */ - -static flagword -vms_secflag_by_name (abfd, section_flags, name, size) - bfd *abfd; - struct sec_flags_struct *section_flags; - char *name; - int size; -{ - int i = 0; - - while (section_flags[i].name != NULL) - { - if ((PRIV(is_vax)? - strcasecmp (name, section_flags[i].name): - strcmp (name, section_flags[i].name)) == 0) - { - if (size > 0) - return section_flags[i].flags_hassize; - else - return section_flags[i].flags_always; - } - i++; - } - if (size > 0) - return section_flags[i].flags_hassize; - return section_flags[i].flags_always; -} - - -/* Retrieve vms section flags by name and size */ - -static flagword -vms_esecflag_by_name (section_flags, name, size) - struct sec_flags_struct *section_flags; - char *name; - int size; -{ - int i = 0; - - while (section_flags[i].name != NULL) - { - if (strcmp (name, section_flags[i].name) == 0) - { - if (size > 0) - return section_flags[i].vflags_hassize; - else - return section_flags[i].vflags_always; - } - i++; - } - if (size > 0) - return section_flags[i].vflags_hassize; - return section_flags[i].vflags_always; -} - -/*-----------------------------------------------------------------------------*/ -#if VMS_DEBUG -/* debug */ - -struct flagdescstruct { char *name; flagword value; }; - -/* Convert flag to printable string */ - -static char * -flag2str(flagdesc, flags) - struct flagdescstruct *flagdesc; - flagword flags; -{ - - static char res[64]; - int next = 0; - - res[0] = 0; - while (flagdesc->name != NULL) - { - if ((flags & flagdesc->value) != 0) - { - if (next) - strcat(res, ","); - else - next = 1; - strcat (res, flagdesc->name); - } - flagdesc++; - } - return res; -} -#endif - -/*-----------------------------------------------------------------------------*/ -/* input routines */ - -/* Process GSD/EGSD record - return 0 on success, -1 on error */ - -int -_bfd_vms_slurp_gsd (abfd, objtype) - bfd *abfd; - int objtype; -{ -#if VMS_DEBUG - static struct flagdescstruct gpsflagdesc[] = - { - { "PIC", 0x0001 }, - { "LIB", 0x0002 }, - { "OVR", 0x0004 }, - { "REL", 0x0008 }, - { "GBL", 0x0010 }, - { "SHR", 0x0020 }, - { "EXE", 0x0040 }, - { "RD", 0x0080 }, - { "WRT", 0x0100 }, - { "VEC", 0x0200 }, - { "NOMOD", 0x0400 }, - { "COM", 0x0800 }, - { NULL, 0 } - }; - - static struct flagdescstruct gsyflagdesc[] = - { - { "WEAK", 0x0001 }, - { "DEF", 0x0002 }, - { "UNI", 0x0004 }, - { "REL", 0x0008 }, - { "COMM", 0x0010 }, - { "VECEP", 0x0020 }, - { "NORM", 0x0040 }, - { NULL, 0 } - }; -#endif - - int gsd_type, gsd_size; - asection *section; - unsigned char *vms_rec; - flagword new_flags, old_flags; - char *name; - asymbol *symbol; - vms_symbol_entry *entry; - unsigned long base_addr; - unsigned long align_addr; - static int psect_idx = 0; - -#if VMS_DEBUG - vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype); -#endif - - switch (objtype) - { - case EOBJ_S_C_EGSD: - PRIV(vms_rec) += 8; /* skip type, size, l_temp */ - PRIV(rec_size) -= 8; - break; - case OBJ_S_C_GSD: - PRIV(vms_rec) += 1; - PRIV(rec_size) -= 1; - break; - default: - return -1; - } - - /* calculate base address for each section */ - base_addr = 0L; - - abfd->symcount = 0; - - while (PRIV(rec_size) > 0) - { - vms_rec = PRIV(vms_rec); - - if (objtype == OBJ_S_C_GSD) - { - gsd_type = *vms_rec; - } - else - { - _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size); - gsd_type += EVAX_OFFSET; - } - -#if VMS_DEBUG - vms_debug (3, "gsd_type %d\n", gsd_type); -#endif - - switch (gsd_type) - { - case GSD_S_C_PSC: - { - /* - * program section definition - */ - - asection *old_section = 0; - -#if VMS_DEBUG - vms_debug (4, "GSD_S_C_PSC\n"); -#endif - /* If this section isn't a bfd section. */ - - if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1))) - { - /* check for temporary section from TIR record. */ - - if (psect_idx < PRIV(section_count)) - old_section = PRIV(sections)[psect_idx]; - else - old_section = 0; - } - - name = _bfd_vms_save_counted_string (vms_rec + 8); - section = bfd_make_section (abfd, name); - if (!section) - { - fprintf (stderr, "bfd_make_section (%s) failed\n", name); - return -1; - } - old_flags = bfd_getl16 (vms_rec + 2); - section->_raw_size = bfd_getl32(vms_rec + 4); /* allocation */ - new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->_raw_size); - if (old_flags & EGPS_S_V_REL) - new_flags |= SEC_RELOC; - if (old_flags & GPS_S_M_OVR) - new_flags |= SEC_IS_COMMON; - if (!bfd_set_section_flags (abfd, section, new_flags)) - { - fprintf (stderr, "bfd_set_section_flags (%s, %x) failed\n", name, new_flags); - return -1; - } - section->alignment_power = vms_rec[1]; - align_addr = (1 << section->alignment_power); - if ((base_addr % align_addr) != 0) - base_addr += (align_addr - (base_addr % align_addr)); - section->vma = (bfd_vma)base_addr; - base_addr += section->_raw_size; - - /* global section is common symbol */ - - if (old_flags & GPS_S_M_GBL) - { - entry = _bfd_vms_enter_symbol (abfd, name); - if (entry == (vms_symbol_entry *)NULL) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - symbol = entry->symbol; - - symbol->value = 0; - symbol->section = section; - symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON); - } - - /* copy saved contents if old_section set */ - - if (old_section != 0) - { - section->contents = old_section->contents; - if (section->_raw_size < old_section->_raw_size) - { - fprintf (stderr, "Size mismatch section %s=%d, %s=%d\n", old_section->name, old_section->_raw_size, section->name, section->_raw_size); - return -1; - } - else if (section->_raw_size > old_section->_raw_size) - { - section->contents = ((unsigned char *) - bfd_realloc (old_section->contents, section->_raw_size)); - if (section->contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - } - } - else - { - section->contents = ((unsigned char *) - bfd_malloc (section->_raw_size)); - if (section->contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - memset (section->contents, 0, (size_t)section->_raw_size); - } - section->_cooked_size = section->_raw_size; -#if VMS_DEBUG - vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ", - section->index, name, old_flags, flag2str (gpsflagdesc, old_flags)); - vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n", - section->_raw_size, section->vma, section->contents); -#endif - - gsd_size = vms_rec[8] + 9; - - psect_idx++; - } - break; - - case GSD_S_C_EPM: - case GSD_S_C_EPMW: -#if VMS_DEBUG - vms_debug(4, "gsd epm\n"); -#endif - /*FALLTHRU*/ - case GSD_S_C_SYM: - case GSD_S_C_SYMW: - { - int name_offset, value_offset; - - /* - * symbol specification (definition or reference) - */ - -#if VMS_DEBUG - vms_debug (4, "GSD_S_C_SYM(W)\n"); -#endif - old_flags = bfd_getl16 (vms_rec + 2); - new_flags = BSF_NO_FLAGS; - - if (old_flags & GSY_S_M_WEAK) - new_flags |= BSF_WEAK; - - switch (gsd_type) - { - case GSD_S_C_EPM: - name_offset = 11; - value_offset = 5; - new_flags |= BSF_FUNCTION; - break; - case GSD_S_C_EPMW: - name_offset = 12; - value_offset = 6; - new_flags |= BSF_FUNCTION; - break; - case GSD_S_C_SYM: - if (old_flags & GSY_S_M_DEF) /* symbol definition */ - name_offset = 9; - else - name_offset = 4; - value_offset = 5; - break; - case GSD_S_C_SYMW: - if (old_flags & GSY_S_M_DEF) /* symbol definition */ - name_offset = 10; - else - name_offset = 5; - value_offset = 6; - break; - } - - /* save symbol in vms_symbol_table */ - - entry = _bfd_vms_enter_symbol (abfd, - _bfd_vms_save_counted_string (vms_rec + name_offset)); - if (entry == (vms_symbol_entry *)NULL) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - symbol = entry->symbol; - - if (old_flags & GSY_S_M_DEF) /* symbol definition */ - { - int psect; - - symbol->value = bfd_getl32 (vms_rec+value_offset); - if ((gsd_type == GSD_S_C_SYMW) - || (gsd_type == GSD_S_C_EPMW)) - psect = bfd_getl16 (vms_rec + value_offset - 2); - else - psect = vms_rec[value_offset-1]; - - symbol->section = (asection *)psect; -#if VMS_DEBUG - vms_debug(4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount, - symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str(gsyflagdesc, old_flags)); -#endif - } - else /* symbol reference */ - { - symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); -#if VMS_DEBUG - vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount, - symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags)); -#endif - } - - gsd_size = vms_rec[name_offset] + name_offset + 1; - symbol->flags = new_flags; - } - - break; - - case GSD_S_C_PRO: - case GSD_S_C_PROW: -#if VMS_DEBUG - vms_debug(4, "gsd pro\n"); -#endif - break; - case GSD_S_C_IDC: -#if VMS_DEBUG - vms_debug(4, "gsd idc\n"); -#endif - break; - case GSD_S_C_ENV: -#if VMS_DEBUG - vms_debug(4, "gsd env\n"); -#endif - break; - case GSD_S_C_LSY: -#if VMS_DEBUG - vms_debug(4, "gsd lsy\n"); -#endif - break; - case GSD_S_C_LEPM: -#if VMS_DEBUG - vms_debug(4, "gsd lepm\n"); -#endif - break; - case GSD_S_C_LPRO: -#if VMS_DEBUG - vms_debug(4, "gsd lpro\n"); -#endif - break; - case GSD_S_C_SPSC: -#if VMS_DEBUG - vms_debug(4, "gsd spsc\n"); -#endif - break; - case GSD_S_C_SYMV: -#if VMS_DEBUG - vms_debug(4, "gsd symv\n"); -#endif - break; - case GSD_S_C_EPMV: -#if VMS_DEBUG - vms_debug(4, "gsd epmv\n"); -#endif - break; - case GSD_S_C_PROV: -#if VMS_DEBUG - vms_debug(4, "gsd prov\n"); -#endif - break; - - case EGSD_S_C_PSC + EVAX_OFFSET: - { - /* program section definition */ - - name = _bfd_vms_save_counted_string (vms_rec+12); - section = bfd_make_section (abfd, name); - if (!section) - return -1; - old_flags = bfd_getl16 (vms_rec + 6); - section->_raw_size = bfd_getl32 (vms_rec + 8); /* allocation */ - new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, (int) section->_raw_size); - if (old_flags & EGPS_S_V_REL) - new_flags |= SEC_RELOC; - if (!bfd_set_section_flags (abfd, section, new_flags)) - return -1; - section->alignment_power = vms_rec[4]; - align_addr = (1 << section->alignment_power); - if ((base_addr % align_addr) != 0) - base_addr += (align_addr - (base_addr % align_addr)); - section->vma = (bfd_vma)base_addr; - base_addr += section->_raw_size; - section->contents = ((unsigned char *) - bfd_malloc (section->_raw_size)); - if (section->contents == NULL) - return -1; - memset (section->contents, 0, (size_t) section->_raw_size); - section->_cooked_size = section->_raw_size; -#if VMS_DEBUG - vms_debug(4, "egsd psc %d (%s, flags %04x=%s) ", - section->index, name, old_flags, flag2str(gpsflagdesc, old_flags)); - vms_debug(4, "%d bytes at 0x%08lx (mem %p)\n", - section->_raw_size, section->vma, section->contents); -#endif - } - break; - - case EGSD_S_C_SYM + EVAX_OFFSET: - { - /* symbol specification (definition or reference) */ - - symbol = _bfd_vms_make_empty_symbol (abfd); - if (symbol == 0) - return -1; - - old_flags = bfd_getl16 (vms_rec + 6); - new_flags = BSF_NO_FLAGS; - - if (old_flags & EGSY_S_V_WEAK) - new_flags |= BSF_WEAK; - - if (vms_rec[6] & EGSY_S_V_DEF) /* symbol definition */ - { - symbol->name = - _bfd_vms_save_counted_string (vms_rec+32); - if (old_flags & EGSY_S_V_NORM) - { /* proc def */ - new_flags |= BSF_FUNCTION; - } - symbol->value = bfd_getl64 (vms_rec+8); - symbol->section = (asection *)((unsigned long) bfd_getl32 (vms_rec+28)); -#if VMS_DEBUG - vms_debug(4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount, - symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags)); -#endif - } - else /* symbol reference */ - { - symbol->name = - _bfd_vms_save_counted_string (vms_rec+8); -#if VMS_DEBUG - vms_debug(4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, - symbol->name, old_flags, flag2str(gsyflagdesc, old_flags)); -#endif - symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); - } - - symbol->flags = new_flags; - - /* save symbol in vms_symbol_table */ - - entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), symbol->name, true, false); - if (entry == (vms_symbol_entry *)NULL) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - if (entry->symbol != (asymbol *)NULL) - { /* FIXME ?, DEC C generates this */ -#if VMS_DEBUG - vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name); -#endif - } - else - { - entry->symbol = symbol; - PRIV(gsd_sym_count)++; - abfd->symcount++; - } - } - break; - - case EGSD_S_C_IDC + EVAX_OFFSET: - break; - - default: - (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type); - bfd_set_error (bfd_error_bad_value); - return -1; - - } /* switch */ - - PRIV(rec_size) -= gsd_size; - PRIV(vms_rec) += gsd_size; - - } /* while (recsize > 0) */ - - if (abfd->symcount > 0) - abfd->flags |= HAS_SYMS; - - return 0; -} - -/*-----------------------------------------------------------------------------*/ -/* output routines */ - -/* Write section and symbol directory of bfd abfd */ - -int -_bfd_vms_write_gsd (abfd, objtype) - bfd *abfd; - int objtype; -{ - asection *section; - asymbol *symbol; - int symnum; - int last_index = -1; - char dummy_name[10]; - char *sname; - flagword new_flags, old_flags; - char *nptr, *uptr; - -#if VMS_DEBUG - vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype); -#endif - - /* output sections */ - - section = abfd->sections; -#if VMS_DEBUG - vms_debug (3, "%d sections found\n", abfd->section_count); -#endif - - /* egsd is quadword aligned */ - - _bfd_vms_output_alignment (abfd, 8); - - _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); - _bfd_vms_output_long (abfd, 0); - _bfd_vms_output_push (abfd); /* prepare output for subrecords */ - - while (section != 0) - { -#if VMS_DEBUG - vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size); -#endif - - /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */ - if (_bfd_vms_output_check (abfd, 64) < 0) - { - _bfd_vms_output_pop (abfd); - _bfd_vms_output_end (abfd); - _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); - _bfd_vms_output_long (abfd, 0); - _bfd_vms_output_push (abfd); /* prepare output for subrecords */ - } - - /* Create dummy sections to keep consecutive indices */ - - while (section->index - last_index > 1) - { -#if VMS_DEBUG - vms_debug (3, "index %d, last %d\n", section->index, last_index); -#endif - _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1); - _bfd_vms_output_short (abfd, 0); - _bfd_vms_output_short (abfd, 0); - _bfd_vms_output_long (abfd, 0); - sprintf (dummy_name, ".DUMMY%02d", last_index); - _bfd_vms_output_counted (abfd, dummy_name); - _bfd_vms_output_flush (abfd); - last_index++; - } - - /* Don't know if this is neccesary for the linker but for now it keeps - vms_slurp_gsd happy */ - - sname = (char *)section->name; - if (*sname == '.') - { - sname++; - if ((*sname == 't') && (strcmp (sname, "text") == 0)) - sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME; - else if ((*sname == 'd') && (strcmp (sname, "data") == 0)) - sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME; - else if ((*sname == 'b') && (strcmp (sname, "bss") == 0)) - sname = EVAX_BSS_NAME; - else if ((*sname == 'l') && (strcmp (sname, "link") == 0)) - sname = EVAX_LINK_NAME; - else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0)) - sname = EVAX_READONLY_NAME; - else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) - sname = EVAX_LITERAL_NAME; - else if ((*sname == 'c') && (strcmp (sname, "comm") == 0)) - sname = EVAX_COMMON_NAME; - else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) - sname = EVAX_LOCAL_NAME; - } - else - sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ); - - _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1); - _bfd_vms_output_short (abfd, section->alignment_power & 0xff); - if (bfd_is_com_section (section)) - { - new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM); - } - else - { - new_flags = vms_esecflag_by_name (evax_section_flags, sname, section->_raw_size); - } - _bfd_vms_output_short (abfd, new_flags); - _bfd_vms_output_long (abfd, section->_raw_size); - _bfd_vms_output_counted (abfd, sname); - _bfd_vms_output_flush (abfd); - - last_index = section->index; - section = section->next; - } - - /* output symbols */ - -#if VMS_DEBUG - vms_debug (3, "%d symbols found\n", abfd->symcount); -#endif - - bfd_set_start_address (abfd, (bfd_vma)-1); - - for (symnum = 0; symnum < abfd->symcount; symnum++) - { - - symbol = abfd->outsymbols[symnum]; - if (*(symbol->name) == '_') - { - if (strcmp (symbol->name, "__main") == 0) - bfd_set_start_address (abfd, (bfd_vma)symbol->value); - } - old_flags = symbol->flags; - - if (old_flags & BSF_FILE) - continue; - - if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */ - && (!bfd_is_und_section (symbol->section))) /* and not xref */ - continue; /* dont output */ - - /* 13 bytes egsd, max 64 chars name -> should be 77 bytes */ - - if (_bfd_vms_output_check (abfd, 80) < 0) - { - _bfd_vms_output_pop (abfd); - _bfd_vms_output_end (abfd); - _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1); - _bfd_vms_output_long (abfd, 0); - _bfd_vms_output_push (abfd); /* prepare output for subrecords */ - } - - _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1); - - _bfd_vms_output_short (abfd, 0); /* data type, alignment */ - - new_flags = 0; - - if (old_flags & BSF_WEAK) - new_flags |= EGSY_S_V_WEAK; - if (bfd_is_com_section (symbol->section)) /* .comm */ - new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM); - - if (old_flags & BSF_FUNCTION) - { - new_flags |= EGSY_S_V_NORM; - new_flags |= EGSY_S_V_REL; - } - if (old_flags & (BSF_GLOBAL|BSF_WEAK)) - { - new_flags |= EGSY_S_V_DEF; - if (!bfd_is_abs_section (symbol->section)) - new_flags |= EGSY_S_V_REL; - } - _bfd_vms_output_short (abfd, new_flags); - - if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */ - { - if (old_flags & BSF_FUNCTION) - { - _bfd_vms_output_quad (abfd, symbol->value); - _bfd_vms_output_quad (abfd, - ((asymbol *)(symbol->udata.p))->value); - _bfd_vms_output_long (abfd, - (((asymbol *)(symbol->udata.p)) - ->section->index)); - _bfd_vms_output_long (abfd, symbol->section->index); - } - else - { - _bfd_vms_output_quad (abfd, symbol->value); /* L_VALUE */ - _bfd_vms_output_quad (abfd, 0); /* L_CODE_ADDRESS */ - _bfd_vms_output_long (abfd, 0); /* L_CA_PSINDX */ - _bfd_vms_output_long (abfd, symbol->section->index);/* L_PSINDX */ - } - } - _bfd_vms_output_counted (abfd, _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ)); - - _bfd_vms_output_flush (abfd); - - } - - _bfd_vms_output_alignment (abfd, 8); - _bfd_vms_output_pop (abfd); - _bfd_vms_output_end (abfd); - - return 0; -} |