X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=bfd%2Fvms-alpha.c;h=4a9881be552f064cade5776176fd2f647d72b973;hb=c661778cb6b406d5b55fbf22ff88fbc85ee3f4c2;hp=be4d61ee2fde627128dea72960982dffebc82f30;hpb=0fca53b78d1ed76f2f23eef4ac7d5072e1bcd8b4;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index be4d61ee2f..4a9881be55 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -1,6 +1,5 @@ /* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1996-2017 Free Software Foundation, Inc. Initial version written by Klaus Kaempf (kkaempf@rmi.de) Major rewrite by Adacore. @@ -21,15 +20,16 @@ MA 02110-1301, USA. */ /* TODO: - o DMT + o overlayed sections o PIC o Generation of shared image - o Generation of GST in image o Relocation optimizations o EISD for the stack o Vectors isect o 64 bits sections o Entry point + o LIB$INITIALIZE + o protected sections (for messages) ... */ @@ -167,11 +167,11 @@ struct vms_symbol_entry unsigned short flags; /* Section and offset/value of the symbol. */ - unsigned int section; unsigned int value; + asection *section; /* Section and offset/value for the entry point (only for subprg). */ - unsigned int code_section; + asection *code_section; unsigned int code_value; /* Symbol vector offset. */ @@ -271,8 +271,14 @@ struct vms_private_data_struct struct hdr_struct hdr_data; /* data from HDR/EMH record */ struct eom_struct eom_data; /* data from EOM/EEOM record */ - unsigned int section_count; /* # of sections in following array */ - asection **sections; /* array of GSD/EGSD sections */ + + /* Transfer addresses (entry points). */ + bfd_vma transfer_address[4]; + + /* Array of GSD sections to get the correspond BFD one. */ + unsigned int section_max; /* Size of the sections array. */ + unsigned int section_count; /* Number of GSD sections. */ + asection **sections; /* Array of raw symbols. */ struct vms_symbol_entry **syms; @@ -297,7 +303,7 @@ struct vms_private_data_struct struct module *modules; /* list of all compilation units */ - struct dst_info *dst_info; + /* The DST section. */ asection *dst_section; unsigned int dst_ptr_offsets_count; /* # of offsets in following array */ @@ -323,11 +329,7 @@ struct vms_private_data_struct struct vms_internal_eisd_map *gbl_eisd_tail; /* linkage index counter used by conditional store commands */ - 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 */ + unsigned int vms_linkage_index; }; #define PRIV2(abfd, name) \ @@ -362,18 +364,18 @@ struct vms_section_data_struct ((struct vms_section_data_struct *)sec->used_by_bfd) /* To be called from the debugger. */ -struct vms_private_data_struct *bfd_vms_get_data (bfd *abfd); +struct vms_private_data_struct *bfd_vms_get_data (bfd *); -static int vms_get_remaining_object_record (bfd *abfd, int read_so_far); +static int vms_get_remaining_object_record (bfd *, unsigned int); static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd); static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *); static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *); static void alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *, bfd_vma); -static void alpha_vms_add_lw_reloc (struct bfd_link_info *info); -static void alpha_vms_add_qw_reloc (struct bfd_link_info *info); -static void alpha_vms_add_lw_fixup (struct bfd_link_info *, unsigned int, +static void alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int, bfd_vma); +static void alpha_vms_add_lw_reloc (struct bfd_link_info *); +static void alpha_vms_add_qw_reloc (struct bfd_link_info *); struct vector_type { @@ -433,7 +435,7 @@ struct alpha_vms_link_hash_table { struct bfd_link_hash_table root; - /* Vector of shared libaries. */ + /* Vector of shared libraries. */ struct vector_type shrlibs; /* Fixup section. */ @@ -519,9 +521,11 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) asection *section; flagword bfd_flags; + /* PR 17512: file: 3d9e9fe9. */ + if (offset >= PRIV (recrd.rec_size)) + return FALSE; eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset); rec_size = bfd_getl32 (eisd->eisdsize); - if (rec_size == 0) break; @@ -547,12 +551,14 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) what's in each section without examining the data. This is especially true of DWARF debug sections. */ bfd_flags = SEC_ALLOC; + if (vbn != 0) + bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD; if (flags & EISD__M_EXE) - bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD; + bfd_flags |= SEC_CODE; if (flags & EISD__M_NONSHRADR) - bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD; + bfd_flags |= SEC_DATA; if (!(flags & EISD__M_WRT)) bfd_flags |= SEC_READONLY; @@ -561,10 +567,10 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) bfd_flags |= SEC_DATA; if (flags & EISD__M_FIXUPVEC) - bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD; + bfd_flags |= SEC_DATA; if (flags & EISD__M_CRF) - bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD; + bfd_flags |= SEC_DATA; if (flags & EISD__M_GBL) { @@ -665,12 +671,6 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) if (gstvbn) { - flagword bfd_flags = SEC_HAS_CONTENTS; - - section = bfd_make_section (abfd, "$GST$"); - if (!section) - return FALSE; - if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET)) { bfd_set_error (bfd_error_file_truncated); @@ -680,12 +680,6 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) if (_bfd_vms_slurp_object_records (abfd) != TRUE) return FALSE; - section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1); - section->size = bfd_tell (abfd) - section->filepos; - - if (!bfd_set_section_flags (abfd, section, bfd_flags)) - return FALSE; - abfd->flags |= HAS_SYMS; } @@ -796,7 +790,7 @@ _bfd_vms_get_object_record (bfd *abfd) Return the size of the record or 0 on failure. */ static int -vms_get_remaining_object_record (bfd *abfd, int read_so_far) +vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far) { unsigned int to_read; @@ -805,7 +799,7 @@ vms_get_remaining_object_record (bfd *abfd, int read_so_far) /* Extract record size. */ PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2); - if (PRIV (recrd.rec_size) <= 0) + if (PRIV (recrd.rec_size) == 0) { bfd_set_error (bfd_error_file_truncated); return 0; @@ -832,6 +826,9 @@ vms_get_remaining_object_record (bfd *abfd, int read_so_far) return 0; PRIV (recrd.buf_size) = to_read; } + /* PR 17512: file: 025-1974-0.004. */ + else if (to_read <= read_so_far) + return 0; /* Read the remaining record. */ to_read -= read_so_far; @@ -862,9 +859,12 @@ _bfd_vms_slurp_ehdr (bfd *abfd) { unsigned char *ptr; unsigned char *vms_rec; + unsigned char *end; int subtype; vms_rec = PRIV (recrd.rec); + /* PR 17512: file: 62736583. */ + end = PRIV (recrd.buf) + PRIV (recrd.buf_size); vms_debug2 ((2, "HDR/EMH\n")); @@ -876,28 +876,42 @@ _bfd_vms_slurp_ehdr (bfd *abfd) { case EMH__C_MHD: /* Module header. */ + if (vms_rec + 21 >= end) + goto fail; 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); + if ((vms_rec + 20 + vms_rec[20] + 1) >= end) + goto fail; PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20); ptr = vms_rec + 20 + vms_rec[20] + 1; + if ((ptr + *ptr + 1) >= end) + goto fail; PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr); ptr += *ptr + 1; + if (ptr + 17 >= end) + goto fail; PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17); break; case EMH__C_LNM: + if (vms_rec + PRIV (recrd.rec_size - 6) > end) + goto fail; PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); break; case EMH__C_SRC: + if (vms_rec + PRIV (recrd.rec_size - 6) > end) + goto fail; PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); break; case EMH__C_TTL: + if (vms_rec + PRIV (recrd.rec_size - 6) > end) + goto fail; PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); break; @@ -908,6 +922,7 @@ _bfd_vms_slurp_ehdr (bfd *abfd) break; default: + fail: bfd_set_error (bfd_error_wrong_format); return FALSE; } @@ -940,71 +955,70 @@ struct sec_flags_struct /* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible. */ -static struct sec_flags_struct evax_section_flags[] = +static const struct sec_flags_struct evax_section_flags[] = { { EVAX_ABS_NAME, - (EGPS__V_SHR), - (SEC_DATA), - (EGPS__V_SHR), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, + EGPS__V_SHR, + 0, + EGPS__V_SHR, + 0 }, { EVAX_CODE_NAME, - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE), - (SEC_CODE), - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE), - (SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE, + SEC_CODE | SEC_READONLY, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE, + SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_LITERAL_NAME, - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD), - (SEC_DATA | SEC_READONLY), - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD, + SEC_DATA | SEC_READONLY, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD, + SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_LINK_NAME, - (EGPS__V_REL | EGPS__V_RD), - (SEC_DATA | SEC_READONLY), - (EGPS__V_REL | EGPS__V_RD), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, + EGPS__V_REL | EGPS__V_RD, + SEC_DATA | SEC_READONLY, + EGPS__V_REL | EGPS__V_RD, + SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_DATA_NAME, - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD), - (SEC_DATA), - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD, + SEC_DATA, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, + SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_BSS_NAME, - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD), - (SEC_NO_FLAGS), - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD), - (SEC_ALLOC) }, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD, + SEC_NO_FLAGS, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD, + SEC_ALLOC }, { EVAX_READONLYADDR_NAME, - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD), - (SEC_DATA | SEC_READONLY), - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD, + SEC_DATA | SEC_READONLY, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD, + SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_READONLY_NAME, - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD), - (SEC_DATA | SEC_READONLY), - (EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD, + SEC_DATA | SEC_READONLY, + EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD, + SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_LOCAL_NAME, - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT), - (SEC_DATA), - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, + SEC_DATA, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, + SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { EVAX_LITERALS_NAME, - (EGPS__V_PIC | EGPS__V_OVR), - (SEC_DATA | SEC_READONLY), - (EGPS__V_PIC | EGPS__V_OVR), - (SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) }, + EGPS__V_PIC | EGPS__V_OVR, + SEC_DATA | SEC_READONLY, + EGPS__V_PIC | EGPS__V_OVR, + SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }, { NULL, - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT), - (SEC_DATA), - (EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT), - (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) } + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, + SEC_DATA, + EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT, + SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD } }; -/* Retrieve bfd section flags by name and size. */ +/* Retrieve BFD section flags by name and size. */ static flagword -vms_secflag_by_name (bfd *abfd ATTRIBUTE_UNUSED, - struct sec_flags_struct *section_flags, - char *name, +vms_secflag_by_name (const struct sec_flags_struct *section_flags, + const char *name, int hassize) { int i = 0; @@ -1025,12 +1039,12 @@ vms_secflag_by_name (bfd *abfd ATTRIBUTE_UNUSED, return section_flags[i].flags_always; } -/* Retrieve vms section flags by name and size. */ +/* Retrieve VMS section flags by name and size. */ static flagword -vms_esecflag_by_name (struct sec_flags_struct *section_flags, - char *name, - int hassize) +vms_esecflag_by_name (const struct sec_flags_struct *section_flags, + const char *name, + int hassize) { int i = 0; @@ -1050,23 +1064,12 @@ vms_esecflag_by_name (struct sec_flags_struct *section_flags, return section_flags[i].vflags_always; } -/* Input routines. */ +/* Add SYM to the symbol table of ABFD. + Return FALSE in case of error. */ -static struct vms_symbol_entry * -add_symbol (bfd *abfd, const unsigned char *ascic) +static bfd_boolean +add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym) { - struct vms_symbol_entry *entry; - int len; - - len = *ascic++; - entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len); - if (entry == NULL) - return NULL; - entry->namelen = len; - memcpy (entry->name, ascic, len); - entry->name[len] = 0; - entry->owner = abfd; - if (PRIV (gsd_sym_count) >= PRIV (max_sym_count)) { if (PRIV (max_sym_count) == 0) @@ -1083,25 +1086,44 @@ add_symbol (bfd *abfd, const unsigned char *ascic) (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *))); } if (PRIV (syms) == NULL) - return NULL; + return FALSE; } - PRIV (syms)[PRIV (gsd_sym_count)++] = entry; + PRIV (syms)[PRIV (gsd_sym_count)++] = sym; + return TRUE; +} + +/* Create a symbol whose name is ASCIC and add it to ABFD. + Return NULL in case of error. */ + +static struct vms_symbol_entry * +add_symbol (bfd *abfd, const unsigned char *ascic) +{ + struct vms_symbol_entry *entry; + int len; + + len = *ascic++; + entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len); + if (entry == NULL) + return NULL; + entry->namelen = len; + memcpy (entry->name, ascic, len); + entry->name[len] = 0; + entry->owner = abfd; + + if (!add_symbol_entry (abfd, entry)) + return NULL; return entry; } /* Read and process EGSD. Return FALSE on failure. */ static bfd_boolean -_bfd_vms_slurp_egsd (bfd * abfd) +_bfd_vms_slurp_egsd (bfd *abfd) { int gsd_type, gsd_size; - asection *section; unsigned char *vms_rec; - flagword new_flags, old_flags; - char *name; unsigned long base_addr; - unsigned long align_addr; vms_debug2 ((2, "EGSD\n")); @@ -1123,41 +1145,82 @@ _bfd_vms_slurp_egsd (bfd * abfd) switch (gsd_type) { case EGSD__C_PSC: + /* Program section definition. */ { - /* Program section definition. */ struct vms_egps *egps = (struct vms_egps *)vms_rec; - name = _bfd_vms_save_counted_string (&egps->namlng); - section = bfd_make_section (abfd, name); - if (!section) - return FALSE; - old_flags = bfd_getl16 (egps->flags); - vms_section_data (section)->flags = old_flags; - vms_section_data (section)->no_flags = 0; - section->size = bfd_getl32 (egps->alloc); - new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, - section->size > 0); - if (!(old_flags & EGPS__V_NOMOD)) + flagword new_flags, vms_flags; + asection *section; + + vms_flags = bfd_getl16 (egps->flags); + + if ((vms_flags & EGPS__V_REL) == 0) { - new_flags |= SEC_HAS_CONTENTS; - if (old_flags & EGPS__V_REL) - new_flags |= SEC_RELOC; + /* Use the global absolute section for all + absolute sections. */ + section = bfd_abs_section_ptr; } - if (!bfd_set_section_flags (abfd, section, new_flags)) - return FALSE; - section->alignment_power = egps->align; - 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->size; - section->filepos = (unsigned int)-1; -#if VMS_DEBUG - vms_debug (4, "EGSD P-section %d (%s, flags %04x) ", - section->index, name, old_flags); - vms_debug (4, "%lu bytes at 0x%08lx (mem %p)\n", - (unsigned long)section->size, - (unsigned long)section->vma, section->contents); -#endif + else + { + char *name; + unsigned long align_addr; + + name = _bfd_vms_save_counted_string (&egps->namlng); + + section = bfd_make_section (abfd, name); + if (!section) + return FALSE; + + section->filepos = 0; + section->size = bfd_getl32 (egps->alloc); + section->alignment_power = egps->align; + + vms_section_data (section)->flags = vms_flags; + vms_section_data (section)->no_flags = 0; + + new_flags = vms_secflag_by_name (evax_section_flags, name, + section->size > 0); + if (section->size > 0) + new_flags |= SEC_LOAD; + if (!(vms_flags & EGPS__V_NOMOD) && section->size > 0) + { + /* Set RELOC and HAS_CONTENTS if the section is not + demand-zero and not empty. */ + new_flags |= SEC_HAS_CONTENTS; + if (vms_flags & EGPS__V_REL) + new_flags |= SEC_RELOC; + } + if (vms_flags & EGPS__V_EXE) + { + /* Set CODE if section is executable. */ + new_flags |= SEC_CODE; + new_flags &= ~SEC_DATA; + } + if (!bfd_set_section_flags (abfd, section, new_flags)) + return FALSE; + + /* Give a non-overlapping vma to non absolute sections. */ + 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->size; + } + + /* Append it to the section array. */ + if (PRIV (section_count) >= PRIV (section_max)) + { + if (PRIV (section_max) == 0) + PRIV (section_max) = 16; + else + PRIV (section_max) *= 2; + PRIV (sections) = bfd_realloc_or_free + (PRIV (sections), PRIV (section_max) * sizeof (asection *)); + if (PRIV (sections) == NULL) + return FALSE; + } + + PRIV (sections)[PRIV (section_count)] = section; + PRIV (section_count)++; } break; @@ -1166,6 +1229,7 @@ _bfd_vms_slurp_egsd (bfd * abfd) int nameoff; struct vms_symbol_entry *entry; struct vms_egsy *egsy = (struct vms_egsy *) vms_rec; + flagword old_flags; old_flags = bfd_getl16 (egsy->flags); if (old_flags & EGSY__V_DEF) @@ -1193,14 +1257,15 @@ _bfd_vms_slurp_egsd (bfd * abfd) struct vms_esdf *esdf = (struct vms_esdf *)vms_rec; entry->value = bfd_getl64 (esdf->value); - entry->section = bfd_getl32 (esdf->psindx); + entry->section = PRIV (sections)[bfd_getl32 (esdf->psindx)]; if (old_flags & EGSY__V_NORM) { PRIV (norm_sym_count)++; entry->code_value = bfd_getl64 (esdf->code_address); - entry->code_section = bfd_getl32 (esdf->ca_psindx); + entry->code_section = + PRIV (sections)[bfd_getl32 (esdf->ca_psindx)]; } } } @@ -1208,15 +1273,11 @@ _bfd_vms_slurp_egsd (bfd * abfd) case EGSD__C_SYMG: { - int nameoff; struct vms_symbol_entry *entry; struct vms_egst *egst = (struct vms_egst *)vms_rec; + flagword old_flags; old_flags = bfd_getl16 (egst->header.flags); - if (old_flags & EGSY__V_DEF) - nameoff = ESDF__B_NAMLNG; - else - nameoff = ESRF__B_NAMLNG; entry = add_symbol (abfd, &egst->namlng); @@ -1229,7 +1290,11 @@ _bfd_vms_slurp_egsd (bfd * abfd) entry->symbol_vector = bfd_getl32 (egst->value); - entry->section = bfd_getl32 (egst->psindx); + if (old_flags & EGSY__V_REL) + entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)]; + else + entry->section = bfd_abs_section_ptr; + entry->value = bfd_getl64 (egst->lp_2); if (old_flags & EGSY__V_NORM) @@ -1237,7 +1302,7 @@ _bfd_vms_slurp_egsd (bfd * abfd) PRIV (norm_sym_count)++; entry->code_value = bfd_getl64 (egst->lp_1); - entry->code_section = 0; + entry->code_section = bfd_abs_section_ptr; } } break; @@ -1249,7 +1314,7 @@ _bfd_vms_slurp_egsd (bfd * abfd) case EGSD__C_SYMM: case EGSD__C_SYMV: default: - (*_bfd_error_handler) (_("Unknown EGSD subtype %d"), gsd_type); + _bfd_error_handler (_("Unknown EGSD subtype %d"), gsd_type); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1280,7 +1345,7 @@ _bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc) if (PRIV (stackptr) >= STACKSIZE) { bfd_set_error (bfd_error_bad_value); - (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr)); + _bfd_error_handler (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr)); exit (1); } } @@ -1293,7 +1358,7 @@ _bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel) if (PRIV (stackptr) == 0) { bfd_set_error (bfd_error_bad_value); - (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop")); + _bfd_error_handler (_("Stack underflow in _bfd_vms_pop")); exit (1); } PRIV (stackptr)--; @@ -1530,7 +1595,7 @@ _bfd_vms_etir_name (int cmd) default: /* These names have not yet been added to this switch statement. */ - (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd); + _bfd_error_handler (_("unknown ETIR command %d"), cmd); } return NULL; @@ -1576,9 +1641,8 @@ _bfd_vms_get_value (bfd *abfd, const unsigned char *ascic, *vma = 0; else { - if (!(*info->callbacks->undefined_symbol) - (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE)) - abort (); + (*info->callbacks->undefined_symbol) + (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE); *vma = 0; } } @@ -1602,7 +1666,8 @@ alpha_vms_sym_to_ctxt (struct alpha_vms_link_hash_entry *h) return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index); else { - /* Can this happen ? I'd like to see an example. */ + /* Can this happen (non-relocatable symg) ? I'd like to see + an example. */ abort (); } } @@ -1617,16 +1682,9 @@ alpha_vms_sym_to_ctxt (struct alpha_vms_link_hash_entry *h) } static bfd_vma -alpha_vms_get_sym_value (unsigned int sect, bfd_vma addr, - struct alpha_vms_link_hash_entry *h) +alpha_vms_get_sym_value (asection *sect, bfd_vma addr) { - asection *s; - - BFD_ASSERT (h && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)); - - s = PRIV2 (h->root.u.def.section->owner, sections)[sect]; - return s->output_section->vma + s->output_offset + addr; + return sect->output_section->vma + sect->output_offset + addr; } static bfd_vma @@ -1680,7 +1738,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) #if VMS_DEBUG _bfd_vms_debug (4, "etir: %s(%d)\n", _bfd_vms_etir_name (cmd), cmd); - _bfd_hexdump (8, ptr, cmd_length - 4, (long) ptr); + _bfd_hexdump (8, ptr, cmd_length - 4, 0); #endif switch (cmd) @@ -1723,8 +1781,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) psect = bfd_getl32 (ptr); if ((unsigned int) psect >= PRIV (section_count)) { - (*_bfd_error_handler) (_("bad section index in %s"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("bad section index in %s"), + _bfd_vms_etir_name (cmd)); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1736,8 +1794,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_STA_LI: case ETIR__C_STA_MOD: case ETIR__C_STA_CKARG: - (*_bfd_error_handler) (_("unsupported STA cmd %s"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("unsupported STA cmd %s"), + _bfd_vms_etir_name (cmd)); return FALSE; break; @@ -1770,7 +1828,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) } else if (rel1 & RELC_SHR_BASE) { - alpha_vms_add_lw_fixup (info, rel1 & RELC_MASK, op1); + alpha_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1); rel1 = RELC_NONE; } if (rel1 != RELC_NONE) @@ -1833,7 +1891,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) else { op1 = alpha_vms_get_sym_value (h->sym->section, - h->sym->value, h); + h->sym->value); alpha_vms_add_qw_reloc (info); } } @@ -1857,7 +1915,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) else { op1 = alpha_vms_get_sym_value (h->sym->code_section, - h->sym->code_value, h); + h->sym->code_value); alpha_vms_add_qw_reloc (info); } } @@ -1912,14 +1970,14 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_STO_RB: case ETIR__C_STO_AB: case ETIR__C_STO_LP_PSB: - (*_bfd_error_handler) (_("%s: not supported"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("%s: not supported"), + _bfd_vms_etir_name (cmd)); return FALSE; break; case ETIR__C_STO_HINT_GBL: case ETIR__C_STO_HINT_PS: - (*_bfd_error_handler) (_("%s: not implemented"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("%s: not implemented"), + _bfd_vms_etir_name (cmd)); return FALSE; break; @@ -1943,8 +2001,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) lw psect index qw offset. */ case ETIR__C_STC_PS: - (*_bfd_error_handler) (_("%s: not supported"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("%s: not supported"), + _bfd_vms_etir_name (cmd)); return FALSE; break; @@ -1967,9 +2025,9 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) else { op1 = alpha_vms_get_sym_value (h->sym->code_section, - h->sym->code_value, h); + h->sym->code_value); op2 = alpha_vms_get_sym_value (h->sym->section, - h->sym->value, h); + h->sym->value); } } else @@ -2034,8 +2092,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) /* 214 Store-conditional NOP, BSR or HINT at psect + offset arg: none. */ case ETIR__C_STC_NBH_PS: - (*_bfd_error_handler) ("%s: not supported", - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("%s: not supported"), + _bfd_vms_etir_name (cmd)); return FALSE; break; @@ -2174,8 +2232,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) if (rel1 != RELC_NONE || rel2 != RELC_NONE) { bad_context: - (*_bfd_error_handler) (_("invalid use of %s with contexts"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("invalid use of %s with contexts"), + _bfd_vms_etir_name (cmd)); return FALSE; } if ((int)op2 < 0) /* Shift right. */ @@ -2190,8 +2248,8 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_OPR_ROT: /* Rotate. */ case ETIR__C_OPR_REDEF: /* Redefine symbol to current location. */ case ETIR__C_OPR_DFLIT: /* Define a literal. */ - (*_bfd_error_handler) (_("%s: not supported"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("%s: not supported"), + _bfd_vms_etir_name (cmd)); return FALSE; break; @@ -2208,7 +2266,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) break; default: - (*_bfd_error_handler) (_("reserved cmd %d"), cmd); + _bfd_error_handler (_("reserved cmd %d"), cmd); return FALSE; break; } @@ -2293,7 +2351,7 @@ _bfd_vms_slurp_eeom (bfd *abfd) PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod); if (PRIV (eom_data).eom_w_comcod > 1) { - (*_bfd_error_handler) (_("Object module NOT error-free !\n")); + _bfd_error_handler (_("Object module NOT error-free !\n")); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -2396,7 +2454,7 @@ vms_initialize (bfd * abfd) static const struct bfd_target * alpha_vms_object_p (bfd *abfd) { - PTR tdata_save = abfd->tdata.any; + void *tdata_save = abfd->tdata.any; unsigned int test_len; unsigned char *buf; @@ -2438,10 +2496,7 @@ alpha_vms_object_p (bfd *abfd) PRIV (recrd.rec) = buf; if (bfd_bread (buf, test_len, abfd) != test_len) - { - bfd_set_error (bfd_error_file_truncated); - goto error_ret; - } + goto err_wrong_format; /* Is it an image? */ if ((bfd_getl32 (buf) == EIHD__K_MAJORID) @@ -2466,7 +2521,6 @@ alpha_vms_object_p (bfd *abfd) if (buf == NULL) { PRIV (recrd.buf) = NULL; - bfd_set_error (bfd_error_no_memory); goto error_ret; } PRIV (recrd.buf) = buf; @@ -2481,10 +2535,7 @@ alpha_vms_object_p (bfd *abfd) while (remaining > 0) { if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read) - { - bfd_set_error (bfd_error_file_truncated); - goto err_wrong_format; - } + goto err_wrong_format; read_so_far += to_read; remaining -= to_read; @@ -2495,6 +2546,9 @@ alpha_vms_object_p (bfd *abfd) /* Reset the record pointer. */ PRIV (recrd.rec) = buf; + /* PR 17512: file: 7d7c57c2. */ + if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd)) + goto error_ret; vms_debug2 ((2, "file type is image\n")); if (_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset) != TRUE) @@ -2555,6 +2609,96 @@ alpha_vms_object_p (bfd *abfd) /* Image write. */ +/* Write an EMH/MHD record. */ + +static void +_bfd_vms_write_emh (bfd *abfd) +{ + struct vms_rec_wr *recwr = &PRIV (recwr); + + _bfd_vms_output_alignment (recwr, 2); + + /* EMH. */ + _bfd_vms_output_begin (recwr, EOBJ__C_EMH); + _bfd_vms_output_short (recwr, EMH__C_MHD); + _bfd_vms_output_short (recwr, EOBJ__C_STRLVL); + _bfd_vms_output_long (recwr, 0); + _bfd_vms_output_long (recwr, 0); + _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE); + + /* Create module name from filename. */ + if (bfd_get_filename (abfd) != 0) + { + char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE); + _bfd_vms_output_counted (recwr, module); + free (module); + } + else + _bfd_vms_output_counted (recwr, "NONAME"); + + _bfd_vms_output_counted (recwr, BFD_VERSION_STRING); + _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH); + _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH); + _bfd_vms_output_end (abfd, recwr); +} + +/* Write an EMH/LMN record. */ + +static void +_bfd_vms_write_lmn (bfd *abfd, const char *name) +{ + char version [64]; + struct vms_rec_wr *recwr = &PRIV (recwr); + unsigned int ver = BFD_VERSION / 10000; + + /* LMN. */ + _bfd_vms_output_begin (recwr, EOBJ__C_EMH); + _bfd_vms_output_short (recwr, EMH__C_LNM); + snprintf (version, sizeof (version), "%s %d.%d.%d", name, + ver / 10000, (ver / 100) % 100, ver % 100); + _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version)); + _bfd_vms_output_end (abfd, recwr); +} + + +/* Write eom record for bfd abfd. Return FALSE on error. */ + +static bfd_boolean +_bfd_vms_write_eeom (bfd *abfd) +{ + struct vms_rec_wr *recwr = &PRIV (recwr); + + vms_debug2 ((2, "vms_write_eeom\n")); + + _bfd_vms_output_alignment (recwr, 2); + + _bfd_vms_output_begin (recwr, EOBJ__C_EEOM); + _bfd_vms_output_long (recwr, PRIV (vms_linkage_index + 1) >> 1); + _bfd_vms_output_byte (recwr, 0); /* Completion code. */ + _bfd_vms_output_byte (recwr, 0); /* Fill byte. */ + + if ((abfd->flags & EXEC_P) == 0 + && 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 FALSE; + } + _bfd_vms_output_short (recwr, 0); + _bfd_vms_output_long (recwr, (unsigned long) section->target_index); + _bfd_vms_output_long (recwr, + (unsigned long) bfd_get_start_address (abfd)); + _bfd_vms_output_long (recwr, 0); + } + + _bfd_vms_output_end (abfd, recwr); + return TRUE; +} + static void vector_grow1 (struct vector_type *vec, size_t elsz) { @@ -2703,7 +2847,11 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec) if (!(sec->flags & SEC_READONLY)) eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF; - if (!(sec->flags & SEC_LOAD)) + /* If relocations or fixup will be applied, make this isect writeable. */ + if (sec->flags & SEC_RELOC) + eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF; + + if (!(sec->flags & SEC_HAS_CONTENTS)) { eisd->u.eisd.flags |= EISD__M_DZRO; eisd->u.eisd.flags &= ~EISD__M_CRF; @@ -2740,6 +2888,8 @@ alpha_vms_write_exec (bfd *abfd) struct vms_internal_eisd_map *eisd; asection *dst; asection *dmt; + file_ptr gst_filepos = 0; + unsigned int lnkflags = 0; /* Build the EIHD. */ PRIV (file_pos) = EIHD__C_LENGTH; @@ -2768,7 +2918,6 @@ alpha_vms_write_exec (bfd *abfd) bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE, eihd.hdrblkcnt); - bfd_putl32 (0, eihd.lnkflags); bfd_putl32 (0, eihd.ident); bfd_putl32 (0, eihd.sysver); @@ -2786,11 +2935,10 @@ alpha_vms_write_exec (bfd *abfd) bfd_putl32 (sizeof (struct vms_eiha), eiha->size); bfd_putl32 (0, eiha->spare); - bfd_putl32 (0x00000340, eiha->tfradr1); /* SYS$IMGACT */ - bfd_putl32 (0xffffffff, eiha->tfradr1_h); - bfd_putl64 (bfd_get_start_address (abfd), eiha->tfradr2); - bfd_putl64 (0, eiha->tfradr3); - bfd_putl64 (0, eiha->tfradr4); + bfd_putl64 (PRIV (transfer_address[0]), eiha->tfradr1); + bfd_putl64 (PRIV (transfer_address[1]), eiha->tfradr2); + bfd_putl64 (PRIV (transfer_address[2]), eiha->tfradr3); + bfd_putl64 (PRIV (transfer_address[3]), eiha->tfradr4); bfd_putl64 (0, eiha->inishr); /* Alloc EIHI. */ @@ -2804,6 +2952,7 @@ alpha_vms_write_exec (bfd *abfd) char *module; unsigned int len; + /* Set module name. */ module = vms_get_module_name (bfd_get_filename (abfd), TRUE); len = strlen (module); if (len > sizeof (eihi->imgnam) - 1) @@ -2812,8 +2961,15 @@ alpha_vms_write_exec (bfd *abfd) memcpy (eihi->imgnam + 1, module, len); free (module); } - bfd_putl32 (0, eihi->linktime + 0); - bfd_putl32 (0, eihi->linktime + 4); + { + unsigned int lo; + unsigned int hi; + + /* Set time. */ + vms_get_time (&hi, &lo); + bfd_putl32 (lo, eihi->linktime + 0); + bfd_putl32 (hi, eihi->linktime + 4); + } eihi->imgid[0] = 0; eihi->linkid[0] = 0; eihi->imgbid[0] = 0; @@ -2913,6 +3069,7 @@ alpha_vms_write_exec (bfd *abfd) PRIV (file_pos) += sec->size; } + /* Update EIHS. */ if (eihs != NULL && dst != NULL) { bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn); @@ -2920,9 +3077,17 @@ alpha_vms_write_exec (bfd *abfd) if (dmt != NULL) { + lnkflags |= EIHD__M_DBGDMT; bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn); bfd_putl32 (dmt->size, eihs->dmtsize); } + if (PRIV (gsd_sym_count) != 0) + { + alpha_vms_file_position_block (abfd); + gst_filepos = PRIV (file_pos); + bfd_putl32 ((gst_filepos / VMS_BLOCK_SIZE) + 1, eihs->gstvbn); + bfd_putl32 ((PRIV (gsd_sym_count) + 4) / 5 + 4, eihs->gstsize); + } } /* Write EISD in hdr. */ @@ -2932,6 +3097,7 @@ alpha_vms_write_exec (bfd *abfd) (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos)); /* Write first block. */ + bfd_putl32 (lnkflags, eihd.lnkflags); if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd)) return FALSE; @@ -2983,92 +3149,70 @@ alpha_vms_write_exec (bfd *abfd) } } - return TRUE; -} - -/* Object write. */ - -/* This hash routine borrowed from GNU-EMACS, and strengthened - slightly. ERY. */ - -static int -hash_string (const char *ptr) -{ - const unsigned char *p = (unsigned char *) ptr; - const unsigned char *end = p + strlen (ptr); - unsigned char c; - int hash = 0; - - while (p != end) + /* Write GST. */ + if (gst_filepos != 0) { - c = *p++; - hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c); - } - return hash; -} - -/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */ + struct vms_rec_wr *recwr = &PRIV (recwr); + unsigned int i; -static char * -_bfd_vms_length_hash_symbol (bfd *abfd, const char *in, int maxlen) -{ - unsigned long result; - int in_len; - char *new_name; - const char *old_name; - int i; - static char outbuf[EOBJ__C_SYMSIZ + 1]; - char *out = outbuf; + _bfd_vms_write_emh (abfd); + _bfd_vms_write_lmn (abfd, "GNU LD"); -#if VMS_DEBUG - vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in); -#endif - - if (maxlen > EOBJ__C_SYMSIZ) - maxlen = EOBJ__C_SYMSIZ; - - /* Save this for later. */ - new_name = out; + /* PSC for the absolute section. */ + _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); + _bfd_vms_output_long (recwr, 0); + _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); + _bfd_vms_output_short (recwr, 0); + _bfd_vms_output_short (recwr, EGPS__V_PIC | EGPS__V_LIB | EGPS__V_RD); + _bfd_vms_output_long (recwr, 0); + _bfd_vms_output_counted (recwr, ".$$ABS$$."); + _bfd_vms_output_end_subrec (recwr); + _bfd_vms_output_end (abfd, recwr); - /* We may need to truncate the symbol, save the hash for later. */ - in_len = strlen (in); + for (i = 0; i < PRIV (gsd_sym_count); i++) + { + struct vms_symbol_entry *sym = PRIV (syms)[i]; + bfd_vma val; + bfd_vma ep; - result = (in_len > maxlen) ? hash_string (in) : 0; + if ((i % 5) == 0) + { + _bfd_vms_output_alignment (recwr, 8); + _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); + _bfd_vms_output_long (recwr, 0); + } + _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYMG); + _bfd_vms_output_short (recwr, 0); /* Data type, alignment. */ + _bfd_vms_output_short (recwr, sym->flags); - old_name = in; + if (sym->code_section) + ep = alpha_vms_get_sym_value (sym->code_section, sym->code_value); + else + { + BFD_ASSERT (sym->code_value == 0); + ep = 0; + } + val = alpha_vms_get_sym_value (sym->section, sym->value); + _bfd_vms_output_quad + (recwr, sym->typ == EGSD__C_SYMG ? sym->symbol_vector : val); + _bfd_vms_output_quad (recwr, ep); + _bfd_vms_output_quad (recwr, val); + _bfd_vms_output_long (recwr, 0); + _bfd_vms_output_counted (recwr, sym->name); + _bfd_vms_output_end_subrec (recwr); + if ((i % 5) == 4) + _bfd_vms_output_end (abfd, recwr); + } + if ((i % 5) != 0) + _bfd_vms_output_end (abfd, recwr); - /* Do the length checking. */ - if (in_len <= maxlen) - i = in_len; - else - { - if (PRIV (flag_hash_long_names)) - i = maxlen - 9; - else - i = maxlen; + if (!_bfd_vms_write_eeom (abfd)) + return FALSE; } - - strncpy (out, in, (size_t) i); - in += i; - out += i; - - if ((in_len > maxlen) - && PRIV (flag_hash_long_names)) - sprintf (out, "_%08lx", result); - else - *out = 0; - -#if VMS_DEBUG - vms_debug (4, "--> [%d]\"%s\"\n", (int)strlen (outbuf), outbuf); -#endif - - if (in_len > maxlen - && PRIV (flag_hash_long_names) - && PRIV (flag_show_after_trunc)) - printf (_("Symbol %s replaced by %s\n"), old_name, new_name); - - return outbuf; + return TRUE; } + +/* Object write. */ /* Write section and symbol directory of bfd abfd. Return FALSE on error. */ @@ -3078,18 +3222,13 @@ _bfd_vms_write_egsd (bfd *abfd) asection *section; asymbol *symbol; unsigned int symnum; - int last_index = -1; - char dummy_name[10]; - char *sname; + const char *sname; flagword new_flags, old_flags; - int abs_section_index = 0; + int abs_section_index = -1; + unsigned int target_index = 0; struct vms_rec_wr *recwr = &PRIV (recwr); - vms_debug2 ((2, "vms_write_gsd\n")); - - /* Output sections. */ - section = abfd->sections; - vms_debug2 ((3, "%d sections found\n", abfd->section_count)); + vms_debug2 ((2, "vms_write_egsd\n")); /* Egsd is quadword aligned. */ _bfd_vms_output_alignment (recwr, 8); @@ -3097,15 +3236,28 @@ _bfd_vms_write_egsd (bfd *abfd) _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); _bfd_vms_output_long (recwr, 0); - while (section != 0) + /* Number sections. */ + for (section = abfd->sections; section != NULL; section = section->next) + { + if (section->flags & SEC_DEBUGGING) + continue; + if (!strcmp (section->name, ".vmsdebug")) + { + section->flags |= SEC_DEBUGGING; + continue; + } + section->target_index = target_index++; + } + + for (section = abfd->sections; section != NULL; section = section->next) { vms_debug2 ((3, "Section #%d %s, %d bytes\n", - section->index, section->name, (int)section->size)); + section->target_index, section->name, (int)section->size)); /* Don't write out the VMS debug info section since it is in the ETBT and EDBG sections in etir. */ - if (!strcmp (section->name, ".vmsdebug")) - goto done; + if (section->flags & SEC_DEBUGGING) + continue; /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */ if (_bfd_vms_output_check (recwr, 64) < 0) @@ -3115,25 +3267,12 @@ _bfd_vms_write_egsd (bfd *abfd) _bfd_vms_output_long (recwr, 0); } - /* Create dummy sections to keep consecutive indices. */ - while (section->index - last_index > 1) - { - vms_debug2 ((3, "index %d, last %d\n", section->index, last_index)); - _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); - _bfd_vms_output_short (recwr, 0); - _bfd_vms_output_short (recwr, 0); - _bfd_vms_output_long (recwr, 0); - sprintf (dummy_name, ".DUMMY%02d", last_index); - _bfd_vms_output_counted (recwr, dummy_name); - _bfd_vms_output_end_subrec (recwr); - last_index++; - } - /* Don't know if this is necessary for the linker but for now it keeps - vms_slurp_gsd happy */ - sname = (char *)section->name; + vms_slurp_gsd happy. */ + sname = section->name; if (*sname == '.') { + /* Remove leading dot. */ sname++; if ((*sname == 't') && (strcmp (sname, "text") == 0)) sname = EVAX_CODE_NAME; @@ -3148,20 +3287,12 @@ _bfd_vms_write_egsd (bfd *abfd) else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) sname = EVAX_LITERAL_NAME; else if ((*sname == 'l') && (strcmp (sname, "literals") == 0)) - { - sname = EVAX_LITERALS_NAME; - abs_section_index = section->index; - } + sname = EVAX_LITERALS_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__C_SECSIZ); - - _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); - _bfd_vms_output_short (recwr, section->alignment_power & 0xff); if (bfd_is_com_section (section)) new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD @@ -3181,14 +3312,17 @@ _bfd_vms_write_egsd (bfd *abfd) vms_debug2 ((3, "new_flags %x, _raw_size %lu\n", new_flags, (unsigned long)section->size)); + _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); + _bfd_vms_output_short (recwr, section->alignment_power & 0xff); _bfd_vms_output_short (recwr, new_flags); _bfd_vms_output_long (recwr, (unsigned long) section->size); _bfd_vms_output_counted (recwr, sname); _bfd_vms_output_end_subrec (recwr); - last_index = section->index; -done: - section = section->next; + /* If the section is an obsolute one, remind its index as it will be + used later for absolute symbols. */ + if ((new_flags & EGPS__V_REL) == 0 && abs_section_index < 0) + abs_section_index = section->target_index; } /* Output symbols. */ @@ -3198,33 +3332,54 @@ done: for (symnum = 0; symnum < abfd->symcount; symnum++) { - char *hash; - 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; + /* Work-around a missing feature: consider __main as the main entry + point. */ + if (symbol->name[0] == '_' && strcmp (symbol->name, "__main") == 0) + bfd_set_start_address (abfd, (bfd_vma)symbol->value); + + /* Only put in the GSD the global and the undefined symbols. */ if (old_flags & BSF_FILE) continue; - if ((old_flags & BSF_GLOBAL) == 0 /* Not xdef... */ - && !bfd_is_und_section (symbol->section) /* and not xref... */ - && !((old_flags & BSF_SECTION_SYM) != 0 /* and not LIB$INITIALIZE. */ - && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0)) - continue; + if ((old_flags & BSF_GLOBAL) == 0 && !bfd_is_und_section (symbol->section)) + { + /* If the LIB$INITIIALIZE section is present, add a reference to + LIB$INITIALIZE symbol. FIXME: this should be done explicitely + in the assembly file. */ + if (!((old_flags & BSF_SECTION_SYM) != 0 + && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0)) + continue; + } - /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. */ - if (_bfd_vms_output_check (recwr, 80) < 0) + /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. Add 16 more + bytes for a possible ABS section. */ + if (_bfd_vms_output_check (recwr, 80 + 16) < 0) { _bfd_vms_output_end (abfd, recwr); _bfd_vms_output_begin (recwr, EOBJ__C_EGSD); _bfd_vms_output_long (recwr, 0); } + if ((old_flags & BSF_GLOBAL) != 0 + && bfd_is_abs_section (symbol->section) + && abs_section_index <= 0) + { + /* Create an absolute section if none was defined. It is highly + unlikely that the name $ABS$ clashes with a user defined + non-absolute section name. */ + _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC); + _bfd_vms_output_short (recwr, 4); + _bfd_vms_output_short (recwr, EGPS__V_SHR); + _bfd_vms_output_long (recwr, 0); + _bfd_vms_output_counted (recwr, "$ABS$"); + _bfd_vms_output_end_subrec (recwr); + + abs_section_index = target_index++; + } + _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYM); /* Data type, alignment. */ @@ -3261,25 +3416,24 @@ done: { asymbol *sym; - sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym; + sym = + ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym; code_address = sym->value; - ca_psindx = sym->section->index; + ca_psindx = sym->section->target_index; } if (bfd_is_abs_section (symbol->section)) psindx = abs_section_index; else - psindx = symbol->section->index; + psindx = symbol->section->target_index; _bfd_vms_output_quad (recwr, symbol->value); _bfd_vms_output_quad (recwr, code_address); _bfd_vms_output_long (recwr, ca_psindx); _bfd_vms_output_long (recwr, psindx); } - hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ__C_SYMSIZ); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, symbol->name); _bfd_vms_output_end_subrec (recwr); - } _bfd_vms_output_alignment (recwr, 8); @@ -3295,44 +3449,14 @@ _bfd_vms_write_ehdr (bfd *abfd) { asymbol *symbol; unsigned int symnum; - int had_case = 0; - int had_file = 0; - char version [256]; struct vms_rec_wr *recwr = &PRIV (recwr); vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd)); _bfd_vms_output_alignment (recwr, 2); - /* EMH. */ - _bfd_vms_output_begin (recwr, EOBJ__C_EMH); - _bfd_vms_output_short (recwr, EMH__C_MHD); - _bfd_vms_output_short (recwr, EOBJ__C_STRLVL); - _bfd_vms_output_long (recwr, 0); - _bfd_vms_output_long (recwr, 0); - _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE); - - /* Create module name from filename. */ - if (bfd_get_filename (abfd) != 0) - { - char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE); - _bfd_vms_output_counted (recwr, module); - free (module); - } - else - _bfd_vms_output_counted (recwr, "NONAME"); - - _bfd_vms_output_counted (recwr, BFD_VERSION_STRING); - _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH); - _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH); - _bfd_vms_output_end (abfd, recwr); - - /* LMN. */ - _bfd_vms_output_begin (recwr, EOBJ__C_EMH); - _bfd_vms_output_short (recwr, EMH__C_LNM); - snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING); - _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version)); - _bfd_vms_output_end (abfd, recwr); + _bfd_vms_write_emh (abfd); + _bfd_vms_write_lmn (abfd, "GNU AS"); /* SRC. */ _bfd_vms_output_begin (recwr, EOBJ__C_EMH); @@ -3344,22 +3468,9 @@ _bfd_vms_write_ehdr (bfd *abfd) if (symbol->flags & BSF_FILE) { - if (CONST_STRNEQ ((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 (recwr, (unsigned char *) symbol->name, (int) strlen (symbol->name)); - if (had_case) - break; - had_file = 1; + break; } } @@ -3407,8 +3518,7 @@ start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset) { struct vms_rec_wr *recwr = &PRIV (recwr); - if (section->name[0] == '.' && section->name[1] == 'v' - && !strcmp (section->name, ".vmsdebug")) + if (section->flags & SEC_DEBUGGING) { _bfd_vms_output_begin (recwr, EOBJ__C_ETBT); @@ -3432,7 +3542,7 @@ start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset) { /* Push start offset. */ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ); - _bfd_vms_output_long (recwr, (unsigned long) section->index); + _bfd_vms_output_long (recwr, (unsigned long) section->target_index); _bfd_vms_output_quad (recwr, offset); _bfd_vms_output_end_subrec (recwr); @@ -3532,12 +3642,12 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) _bfd_vms_output_alignment (recwr, 4); - PRIV (vms_linkage_index) = 1; + PRIV (vms_linkage_index) = 0; for (section = abfd->sections; section; section = section->next) { vms_debug2 ((4, "writing %d. section '%s' (%d bytes)\n", - section->index, section->name, (int) (section->size))); + section->target_index, section->name, (int) (section->size))); if (!(section->flags & SEC_HAS_CONTENTS) || bfd_is_com_section (section)) @@ -3560,9 +3670,9 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) int pass2_in_progress = 0; unsigned int irel; - if (section->reloc_count <= 0) - (*_bfd_error_handler) - (_("SEC_RELOC with no relocs in section %s"), section->name); + if (section->reloc_count == 0) + _bfd_error_handler + (_("SEC_RELOC with no relocs in section %A"), section); #if VMS_DEBUG else @@ -3596,7 +3706,6 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) asection *sec = sym->section; bfd_boolean defer = defer_reloc_p (rptr); unsigned int slen; - char *hash; if (pass2_in_progress) { @@ -3615,8 +3724,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) /* Regular relocs are intertwined with binary data. */ if (curr_addr > addr) - (*_bfd_error_handler) (_("Size error in section %s"), - section->name); + _bfd_error_handler (_("Size error in section %A"), + section); size = addr - curr_addr; sto_imm (abfd, section, size, curr_data, curr_addr); curr_data += size; @@ -3635,13 +3744,11 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { bfd_vma addend = rptr->addend; slen = strlen ((char *) sym->name); - hash = _bfd_vms_length_hash_symbol - (abfd, sym->name, EOBJ__C_SYMSIZ); etir_output_check (abfd, section, curr_addr, slen); if (addend) { _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_end_subrec (recwr); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW); _bfd_vms_output_long (recwr, (unsigned long) addend); @@ -3655,7 +3762,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL_LW); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_end_subrec (recwr); } } @@ -3672,7 +3779,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { etir_output_check (abfd, section, curr_addr, 32); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ); - _bfd_vms_output_long (recwr, (unsigned long) sec->index); + _bfd_vms_output_long (recwr, + (unsigned long) sec->target_index); _bfd_vms_output_quad (recwr, rptr->addend + sym->value); _bfd_vms_output_end_subrec (recwr); /* ??? Table B-8 of the OpenVMS Linker Utilily Manual @@ -3689,13 +3797,11 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { bfd_vma addend = rptr->addend; slen = strlen ((char *) sym->name); - hash = _bfd_vms_length_hash_symbol - (abfd, sym->name, EOBJ__C_SYMSIZ); etir_output_check (abfd, section, curr_addr, slen); if (addend) { _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_end_subrec (recwr); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW); _bfd_vms_output_quad (recwr, addend); @@ -3708,7 +3814,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) else { _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_end_subrec (recwr); } } @@ -3725,7 +3831,8 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { etir_output_check (abfd, section, curr_addr, 32); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ); - _bfd_vms_output_long (recwr, (unsigned long) sec->index); + _bfd_vms_output_long (recwr, + (unsigned long) sec->target_index); _bfd_vms_output_quad (recwr, rptr->addend + sym->value); _bfd_vms_output_end_subrec (recwr); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_OFF); @@ -3741,22 +3848,19 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) etir_output_check (abfd, section, curr_addr, 64); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB); _bfd_vms_output_long - (recwr, (unsigned long) PRIV (vms_linkage_index)); - PRIV (vms_linkage_index) += 2; - hash = _bfd_vms_length_hash_symbol - (abfd, sym->name, EOBJ__C_SYMSIZ); - _bfd_vms_output_counted (recwr, hash); + (recwr, (unsigned long) rptr->addend); + if (rptr->addend > PRIV (vms_linkage_index)) + PRIV (vms_linkage_index) = rptr->addend; + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_byte (recwr, 0); _bfd_vms_output_end_subrec (recwr); break; case ALPHA_R_CODEADDR: slen = strlen ((char *) sym->name); - hash = _bfd_vms_length_hash_symbol - (abfd, sym->name, EOBJ__C_SYMSIZ); etir_output_check (abfd, section, curr_addr, slen); _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_end_subrec (recwr); break; @@ -3768,20 +3872,18 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL); _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex); _bfd_vms_output_long - (recwr, (unsigned long) udata->enbsym->section->index); + (recwr, (unsigned long) section->target_index); _bfd_vms_output_quad (recwr, rptr->address); _bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f); _bfd_vms_output_long - (recwr, (unsigned long) udata->enbsym->section->index); + (recwr, (unsigned long) section->target_index); _bfd_vms_output_quad (recwr, rptr->addend); - _bfd_vms_output_counted - (recwr, _bfd_vms_length_hash_symbol - (abfd, udata->origname, EOBJ__C_SYMSIZ)); + _bfd_vms_output_counted (recwr, udata->origname); _bfd_vms_output_end_subrec (recwr); break; case ALPHA_R_BSR: - (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc")); + _bfd_error_handler (_("Spurious ALPHA_R_BSR reloc")); break; case ALPHA_R_LDA: @@ -3793,15 +3895,13 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex + 1); _bfd_vms_output_long - (recwr, (unsigned long) udata->enbsym->section->index); + (recwr, (unsigned long) section->target_index); _bfd_vms_output_quad (recwr, rptr->address); _bfd_vms_output_long (recwr, (unsigned long) 0x237B0000); _bfd_vms_output_long - (recwr, (unsigned long) udata->bsym->section->index); + (recwr, (unsigned long) udata->bsym->section->target_index); _bfd_vms_output_quad (recwr, rptr->addend); - _bfd_vms_output_counted - (recwr, _bfd_vms_length_hash_symbol - (abfd, udata->origname, EOBJ__C_SYMSIZ)); + _bfd_vms_output_counted (recwr, udata->origname); _bfd_vms_output_end_subrec (recwr); break; @@ -3813,21 +3913,19 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL); _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex); _bfd_vms_output_long - (recwr, (unsigned long) udata->enbsym->section->index); + (recwr, (unsigned long) section->target_index); _bfd_vms_output_quad (recwr, rptr->address); _bfd_vms_output_long (recwr, (unsigned long) 0xD3400000); _bfd_vms_output_long - (recwr, (unsigned long) udata->enbsym->section->index); + (recwr, (unsigned long) section->target_index); _bfd_vms_output_quad (recwr, rptr->addend); - _bfd_vms_output_counted - (recwr, _bfd_vms_length_hash_symbol - (abfd, udata->origname, EOBJ__C_SYMSIZ)); + _bfd_vms_output_counted (recwr, udata->origname); _bfd_vms_output_end_subrec (recwr); break; default: - (*_bfd_error_handler) (_("Unhandled relocation %s"), - rptr->howto->name); + _bfd_error_handler (_("Unhandled relocation %s"), + rptr->howto->name); break; } @@ -3839,8 +3937,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { /* Output rest of section. */ if (curr_addr > section->size) - (*_bfd_error_handler) (_("Size error in section %s"), - section->name); + _bfd_error_handler (_("Size error in section %A"), section); size = section->size - curr_addr; sto_imm (abfd, section, size, curr_data, curr_addr); curr_data += size; @@ -3864,41 +3961,6 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) return TRUE; } -/* Write eom record for bfd abfd. Return FALSE on error. */ - -static bfd_boolean -_bfd_vms_write_eeom (bfd *abfd) -{ - struct vms_rec_wr *recwr = &PRIV (recwr); - - vms_debug2 ((2, "vms_write_eeom\n")); - - _bfd_vms_output_begin (recwr, EOBJ__C_EEOM); - _bfd_vms_output_long (recwr, (unsigned long) (PRIV (vms_linkage_index) >> 1)); - _bfd_vms_output_byte (recwr, 0); /* Completion code. */ - _bfd_vms_output_byte (recwr, 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 FALSE; - } - _bfd_vms_output_short (recwr, 0); - _bfd_vms_output_long (recwr, (unsigned long) (section->index)); - _bfd_vms_output_long (recwr, - (unsigned long) bfd_get_start_address (abfd)); - _bfd_vms_output_long (recwr, 0); - } - - _bfd_vms_output_end (abfd, recwr); - return TRUE; -} - /* Write cached information into a file being written, at bfd_close. */ static bfd_boolean @@ -4151,8 +4213,8 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, break; default: - (*_bfd_error_handler) (_("unknown source command %d"), - cmd); + _bfd_error_handler (_("unknown source command %d"), + cmd); cmd_length = 2; break; } @@ -4211,31 +4273,31 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, break; case DST__K_SET_LINUM_INCR: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_SET_LINUM_INCR not implemented")); cmd_length = 2; break; case DST__K_SET_LINUM_INCR_W: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_SET_LINUM_INCR_W not implemented")); cmd_length = 3; break; case DST__K_RESET_LINUM_INCR: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_RESET_LINUM_INCR not implemented")); cmd_length = 1; break; case DST__K_BEG_STMT_MODE: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_BEG_STMT_MODE not implemented")); cmd_length = 1; break; case DST__K_END_STMT_MODE: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_END_STMT_MODE not implemented")); cmd_length = 1; break; @@ -4262,25 +4324,25 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, break; case DST__K_SET_PC: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_SET_PC not implemented")); cmd_length = 2; break; case DST__K_SET_PC_W: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_SET_PC_W not implemented")); cmd_length = 3; break; case DST__K_SET_PC_L: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_SET_PC_L not implemented")); cmd_length = 5; break; case DST__K_SET_STMTNUM: - (*_bfd_error_handler) + _bfd_error_handler (_("DST__K_SET_STMTNUM not implemented")); cmd_length = 2; break; @@ -4324,8 +4386,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, } else { - (*_bfd_error_handler) (_("unknown line command %d"), - cmd); + _bfd_error_handler (_("unknown line command %d"), cmd); cmd_length = 2; } break; @@ -4453,6 +4514,11 @@ build_module_list (bfd *abfd) /* We don't have a DMT section so this must be an object. Parse the module right now in order to compute its start address and end address. */ + void *dst = PRIV (dst_section)->contents; + + if (dst == NULL) + return NULL; + module = new_module (abfd); parse_module (abfd, module, PRIV (dst_section)->contents, -1); list = module; @@ -4532,10 +4598,14 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, location. */ static bfd_boolean -_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section, - asymbol **symbols ATTRIBUTE_UNUSED, - bfd_vma offset, const char **file, - const char **func, unsigned int *line) +_bfd_vms_find_nearest_line (bfd *abfd, + asymbol **symbols ATTRIBUTE_UNUSED, + asection *section, + bfd_vma offset, + const char **file, + const char **func, + unsigned int *line, + unsigned int *discriminator) { struct module *module; @@ -4545,10 +4615,14 @@ _bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section, *file = NULL; *func = NULL; *line = 0; + if (discriminator) + *discriminator = 0; - if (PRIV (dst_section) == NULL || !(abfd->flags & (EXEC_P | DYNAMIC))) + /* We can't do anything if there is no DST (debug symbol table). */ + if (PRIV (dst_section) == NULL) return FALSE; + /* Create the module list - if not already done. */ if (PRIV (modules) == NULL) { PRIV (modules) = build_module_list (abfd); @@ -4592,7 +4666,7 @@ alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym) if (e->flags & EGSY__V_NORM) flags |= BSF_FUNCTION; value = e->value; - sec = PRIV (sections)[e->section]; + sec = e->section; } else { @@ -4618,35 +4692,9 @@ alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym) if (e->flags & EGSY__V_NORM) flags |= BSF_FUNCTION; - value = e->symbol_vector; - - /* Adding this offset is necessary in order for GDB to - read the DWARF-2 debug info from shared libraries. */ - if ((abfd->flags & DYNAMIC) && strstr (name, "$DWARF2.DEBUG") != 0) - value += PRIV (symvva); - + value = e->value; + /* sec = e->section; */ sec = bfd_abs_section_ptr; -#if 0 - /* Find containing section. */ - { - bfd_vma sbase = 0; - asection *s; - - for (s = abfd->sections; s; s = s->next) - { - if (value >= s->vma - && s->vma > sbase - && !(s->flags & SEC_COFF_SHARED_LIBRARY) - && (s->size > 0 || !(e->flags & EGSY__V_REL))) - { - sbase = s->vma; - sec = s; - } - } - value -= sbase; - } -#endif - break; default: @@ -4796,7 +4844,8 @@ alpha_vms_slurp_relocs (bfd *abfd) case ETIR__C_CTL_SETRB: if (prev_cmd != ETIR__C_STA_PQ) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), _bfd_vms_etir_name (cmd)); return FALSE; @@ -4813,7 +4862,8 @@ alpha_vms_slurp_relocs (bfd *abfd) { if (prev_cmd != ETIR__C_STA_GBL) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd), _bfd_vms_etir_name (ETIR__C_STA_LW)); return FALSE; @@ -4827,7 +4877,8 @@ alpha_vms_slurp_relocs (bfd *abfd) /* ALPHA_R_REFQUAD und_section, step 2 */ if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd), _bfd_vms_etir_name (ETIR__C_STA_QW)); return FALSE; @@ -4843,9 +4894,10 @@ alpha_vms_slurp_relocs (bfd *abfd) && prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_PQ) { - (*_bfd_error_handler) (_("Unknown reloc %s + %s"), - _bfd_vms_etir_name (prev_cmd), - _bfd_vms_etir_name (ETIR__C_STO_LW)); + /* xgettext:c-format */ + _bfd_error_handler (_("Unknown reloc %s + %s"), + _bfd_vms_etir_name (prev_cmd), + _bfd_vms_etir_name (ETIR__C_STO_LW)); return FALSE; } reloc_code = BFD_RELOC_32; @@ -4855,9 +4907,10 @@ alpha_vms_slurp_relocs (bfd *abfd) /* ALPHA_R_REFQUAD abs_section, step 2 */ if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW) { - (*_bfd_error_handler) (_("Unknown reloc %s + %s"), - _bfd_vms_etir_name (prev_cmd), - _bfd_vms_etir_name (ETIR__C_STO_QW)); + /* xgettext:c-format */ + _bfd_error_handler (_("Unknown reloc %s + %s"), + _bfd_vms_etir_name (prev_cmd), + _bfd_vms_etir_name (ETIR__C_STO_QW)); return FALSE; } reloc_code = BFD_RELOC_64; @@ -4866,9 +4919,10 @@ alpha_vms_slurp_relocs (bfd *abfd) case ETIR__C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */ if (prev_cmd != ETIR__C_STA_PQ) { - (*_bfd_error_handler) (_("Unknown reloc %s + %s"), - _bfd_vms_etir_name (prev_cmd), - _bfd_vms_etir_name (ETIR__C_STO_OFF)); + /* xgettext:c-format */ + _bfd_error_handler (_("Unknown reloc %s + %s"), + _bfd_vms_etir_name (prev_cmd), + _bfd_vms_etir_name (ETIR__C_STO_OFF)); return FALSE; } reloc_code = BFD_RELOC_64; @@ -4878,9 +4932,10 @@ alpha_vms_slurp_relocs (bfd *abfd) /* ALPHA_R_REFQUAD und_section, step 3 */ if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW) { - (*_bfd_error_handler) (_("Unknown reloc %s + %s"), - _bfd_vms_etir_name (prev_cmd), - _bfd_vms_etir_name (ETIR__C_OPR_ADD)); + /* xgettext:c-format */ + _bfd_error_handler (_("Unknown reloc %s + %s"), + _bfd_vms_etir_name (prev_cmd), + _bfd_vms_etir_name (ETIR__C_OPR_ADD)); return FALSE; } prev_cmd = ETIR__C_OPR_ADD; @@ -4933,8 +4988,8 @@ alpha_vms_slurp_relocs (bfd *abfd) continue; default: - (*_bfd_error_handler) (_("Unknown reloc %s"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("Unknown reloc %s"), + _bfd_vms_etir_name (cmd)); return FALSE; } @@ -4946,10 +5001,17 @@ alpha_vms_slurp_relocs (bfd *abfd) /* Get section to which the relocation applies. */ if (cur_psect < 0 || cur_psect > (int)PRIV (section_count)) { - (*_bfd_error_handler) (_("Invalid section index in ETIR")); + _bfd_error_handler (_("Invalid section index in ETIR")); return FALSE; } + sec = PRIV (sections)[cur_psect]; + if (sec == bfd_abs_section_ptr) + { + _bfd_error_handler (_("Relocation for non-REL psect")); + return FALSE; + } + vms_sec = vms_section_data (sec); /* Allocate a reloc entry. */ @@ -4960,7 +5022,7 @@ alpha_vms_slurp_relocs (bfd *abfd) vms_sec->reloc_max = 64; sec->relocation = bfd_zmalloc (vms_sec->reloc_max * sizeof (arelent)); - } + } else { vms_sec->reloc_max *= 2; @@ -4993,8 +5055,8 @@ alpha_vms_slurp_relocs (bfd *abfd) } if (sym == NULL) { - (*_bfd_error_handler) (_("Unknown symbol in command %s"), - _bfd_vms_etir_name (cmd)); + _bfd_error_handler (_("Unknown symbol in command %s"), + _bfd_vms_etir_name (cmd)); reloc->sym_ptr_ptr = NULL; } else @@ -5394,7 +5456,7 @@ alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, case BFD_RELOC_ALPHA_LDA: alpha_type = ALPHA_R_LDA; break; case BFD_RELOC_ALPHA_BOH: alpha_type = ALPHA_R_BOH; break; default: - (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code); + _bfd_error_handler (_("reloc (%d) is *UNKNOWN*"), code); return NULL; } vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name)); @@ -5453,43 +5515,18 @@ alpha_vms_get_synthetic_symtab (bfd *abfd, switch (e->typ) { case EGSD__C_SYM: - if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM)) - { - value = e->code_value; - sec = PRIV (sections)[e->code_section]; - } - else - continue; - break; - case EGSD__C_SYMG: if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM)) { - bfd_vma sbase = 0; - asection *s; - value = e->code_value; - - /* Find containing section. */ - for (s = abfd->sections; s; s = s->next) - { - if (value >= s->vma - && s->vma > sbase - && !(s->flags & SEC_COFF_SHARED_LIBRARY) - && (s->size > 0 || !(e->flags & EGSY__V_REL))) - { - sbase = s->vma; - sec = s; - } - } - value -= sbase; + sec = e->code_section; } else continue; break; default: - abort (); + continue; } l = strlen (name); @@ -5533,6 +5570,7 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len) subtype = (unsigned)bfd_getl16 (emh->subtyp); + /* xgettext:c-format */ fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len); switch (subtype) @@ -5682,6 +5720,7 @@ evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len) type = (unsigned)bfd_getl16 (e->gsdtyp); len = (unsigned)bfd_getl16 (e->gsdsiz); + /* xgettext:c-format */ fprintf (file, _(" EGSD entry %2u (type: %u, len: %u): "), n, type, len); n++; @@ -5884,18 +5923,22 @@ evax_bfd_print_hex (FILE *file, const char *pfx, static void evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps) { + /* xgettext:c-format */ fprintf (file, _(" linkage index: %u, replacement insn: 0x%08x\n"), (unsigned)bfd_getl32 (buf), (unsigned)bfd_getl32 (buf + 16)); + /* xgettext:c-format */ fprintf (file, _(" psect idx 1: %u, offset 1: 0x%08x %08x\n"), (unsigned)bfd_getl32 (buf + 4), (unsigned)bfd_getl32 (buf + 12), (unsigned)bfd_getl32 (buf + 8)); + /* xgettext:c-format */ fprintf (file, _(" psect idx 2: %u, offset 2: 0x%08x %08x\n"), (unsigned)bfd_getl32 (buf + 20), (unsigned)bfd_getl32 (buf + 28), (unsigned)bfd_getl32 (buf + 24)); if (is_ps) + /* xgettext:c-format */ fprintf (file, _(" psect idx 3: %u, offset 3: 0x%08x %08x\n"), (unsigned)bfd_getl32 (buf + 32), (unsigned)bfd_getl32 (buf + 40), @@ -5909,8 +5952,9 @@ evax_bfd_print_etir (FILE *file, const char *name, unsigned char *rec, unsigned int rec_len) { unsigned int off = sizeof (struct vms_egsd); - unsigned int sec_len; + unsigned int sec_len = 0; + /* xgettext:c-format */ fprintf (file, _(" %s (len=%u+%u):\n"), name, (unsigned)(rec_len - sizeof (struct vms_eobjrec)), (unsigned)sizeof (struct vms_eobjrec)); @@ -5926,6 +5970,7 @@ evax_bfd_print_etir (FILE *file, const char *name, size = bfd_getl16 (etir->size); buf = rec + off + sizeof (struct vms_etir); + /* xgettext:c-format */ fprintf (file, _(" (type: %3u, size: 4+%3u): "), type, size - 4); switch (type) { @@ -5944,6 +5989,7 @@ evax_bfd_print_etir (FILE *file, const char *name, break; case ETIR__C_STA_PQ: fprintf (file, _("STA_PQ (stack psect base + offset)\n")); + /* xgettext:c-format */ fprintf (file, _(" psect: %u, offset: 0x%08x %08x\n"), (unsigned)bfd_getl32 (buf + 0), (unsigned)bfd_getl32 (buf + 8), @@ -6008,6 +6054,10 @@ evax_bfd_print_etir (FILE *file, const char *name, sec_len += len; } break; + case ETIR__C_STO_GBL_LW: + fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"), + buf[0], buf + 1); + break; case ETIR__C_STO_LP_PSB: fprintf (file, _("STO_OFF (store LP with procedure signature)\n")); break; @@ -6076,6 +6126,7 @@ evax_bfd_print_etir (FILE *file, const char *name, case ETIR__C_STC_LP_PSB: fprintf (file, _("STC_LP_PSB (store cond linkage pair + signature)\n")); + /* xgettext:c-format */ fprintf (file, _(" linkage index: %u, procedure: %.*s\n"), (unsigned)bfd_getl32 (buf), buf[4], buf + 5); buf += 4 + 1 + buf[4]; @@ -6083,17 +6134,20 @@ evax_bfd_print_etir (FILE *file, const char *name, break; case ETIR__C_STC_GBL: fprintf (file, _("STC_GBL (store cond global)\n")); + /* xgettext:c-format */ fprintf (file, _(" linkage index: %u, global: %.*s\n"), (unsigned)bfd_getl32 (buf), buf[4], buf + 5); break; case ETIR__C_STC_GCA: fprintf (file, _("STC_GCA (store cond code address)\n")); + /* xgettext:c-format */ fprintf (file, _(" linkage index: %u, procedure name: %.*s\n"), (unsigned)bfd_getl32 (buf), buf[4], buf + 5); break; case ETIR__C_STC_PS: fprintf (file, _("STC_PS (store cond psect + offset)\n")); fprintf (file, + /* xgettext:c-format */ _(" linkage index: %u, psect: %u, offset: 0x%08x %08x\n"), (unsigned)bfd_getl32 (buf), (unsigned)bfd_getl32 (buf + 4), @@ -6311,6 +6365,7 @@ evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel, break; base = bfd_getl32 (rel + 4); + /* xgettext:c-format */ fprintf (file, _(" bitcount: %u, base addr: 0x%08x\n"), count, base); @@ -6324,6 +6379,7 @@ evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel, val = bfd_getl32 (rel); rel += 4; + /* xgettext:c-format */ fprintf (file, _(" bitmap: 0x%08x (count: %u):\n"), val, count); for (k = 0; k < 32; k++) @@ -6356,11 +6412,13 @@ evax_bfd_print_address_fixups (FILE *file, const unsigned char *rel) count = bfd_getl32 (rel + 0); if (count == 0) return; + /* xgettext:c-format */ fprintf (file, _(" image %u (%u entries)\n"), (unsigned)bfd_getl32 (rel + 4), count); rel += 8; for (j = 0; j < count; j++) { + /* xgettext:c-format */ fprintf (file, _(" offset: 0x%08x, val: 0x%08x\n"), (unsigned)bfd_getl32 (rel + 0), (unsigned)bfd_getl32 (rel + 4)); @@ -6382,6 +6440,7 @@ evax_bfd_print_reference_fixups (FILE *file, const unsigned char *rel) count = bfd_getl32 (rel + 0); if (count == 0) break; + /* xgettext:c-format */ fprintf (file, _(" image %u (%u entries), offsets:\n"), (unsigned)bfd_getl32 (rel + 4), count); rel += 8; @@ -6515,6 +6574,7 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) } else { + /* xgettext:c-format */ fprintf (file, _("class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"), bclass, dtype, len, pointer); switch (bclass) @@ -6530,10 +6590,12 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) evax_bfd_get_dsc_name (dsc->dtype)); evax_bfd_print_indent (indent + 1, file); fprintf (file, + /* xgettext:c-format */ _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"), dsc->dimct, dsc->aflags, dsc->digits, dsc->scale); evax_bfd_print_indent (indent + 1, file); fprintf (file, + /* xgettext:c-format */ _("arsize: %u, a0: 0x%08x\n"), (unsigned)bfd_getl32 (dsc->arsize), (unsigned)bfd_getl32 (dsc->a0)); @@ -6543,7 +6605,7 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) for (i = 0; i < dsc->dimct; i++) { evax_bfd_print_indent (indent + 2, file); - fprintf (file, _("[%u]: %u\n"), i + 1, + fprintf (file, "[%u]: %u\n", i + 1, (unsigned)bfd_getl32 (b)); b += 4; } @@ -6553,6 +6615,7 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) for (i = 0; i < dsc->dimct; i++) { evax_bfd_print_indent (indent + 2, file); + /* xgettext:c-format */ fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1, (unsigned)bfd_getl32 (b + 0), (unsigned)bfd_getl32 (b + 4)); @@ -6569,6 +6632,7 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) evax_bfd_get_dsc_name (ubs->dtype)); evax_bfd_print_indent (indent + 1, file); fprintf (file, + /* xgettext:c-format */ _("base: %u, pos: %u\n"), (unsigned)bfd_getl32 (ubs->base), (unsigned)bfd_getl32 (ubs->pos)); @@ -6589,6 +6653,7 @@ evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file) unsigned int len = 5; evax_bfd_print_indent (indent, file); + /* xgettext:c-format */ fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value); buf += 5; @@ -6617,6 +6682,7 @@ evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file) fprintf (file, _("(at bit offset %u)\n"), value); break; default: + /* xgettext:c-format */ fprintf (file, _("(reg: %u, disp: %u, indir: %u, kind: "), (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT, vflags & DST__K_DISP ? 1 : 0, @@ -6649,24 +6715,26 @@ evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file) unsigned int len = (unsigned)bfd_getl16 (buf); evax_bfd_print_indent (indent, file); - fprintf (file, ("len: %2u, kind: %2u "), len, kind); + /* xgettext:c-format */ + fprintf (file, _("len: %2u, kind: %2u "), len, kind); buf += 3; switch (kind) { case DST__K_TS_ATOM: - fprintf (file, ("atomic, type=0x%02x %s\n"), + /* xgettext:c-format */ + fprintf (file, _("atomic, type=0x%02x %s\n"), buf[0], evax_bfd_get_dsc_name (buf[0])); break; case DST__K_TS_IND: - fprintf (file, ("indirect, defined at 0x%08x\n"), + fprintf (file, _("indirect, defined at 0x%08x\n"), (unsigned)bfd_getl32 (buf)); break; case DST__K_TS_TPTR: - fprintf (file, ("typed pointer\n")); + fprintf (file, _("typed pointer\n")); evax_bfd_print_typspec (buf, indent + 1, file); break; case DST__K_TS_PTR: - fprintf (file, ("pointer\n")); + fprintf (file, _("pointer\n")); break; case DST__K_TS_ARRAY: { @@ -6674,30 +6742,30 @@ evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file) unsigned int vec_len; unsigned int i; - fprintf (file, ("array, dim: %u, bitmap: "), buf[0]); + fprintf (file, _("array, dim: %u, bitmap: "), buf[0]); vec_len = (buf[0] + 1 + 7) / 8; for (i = 0; i < vec_len; i++) fprintf (file, " %02x", buf[i + 1]); fputc ('\n', file); vs = buf + 1 + vec_len; evax_bfd_print_indent (indent, file); - fprintf (file, ("array descriptor:\n")); + fprintf (file, _("array descriptor:\n")); vs += evax_bfd_print_valspec (vs, indent + 1, file); for (i = 0; i < buf[0] + 1U; i++) if (buf[1 + i / 8] & (1 << (i % 8))) { evax_bfd_print_indent (indent, file); if (i == 0) - fprintf (file, ("type spec for element:\n")); + fprintf (file, _("type spec for element:\n")); else - fprintf (file, ("type spec for subscript %u:\n"), i); + fprintf (file, _("type spec for subscript %u:\n"), i); evax_bfd_print_typspec (vs, indent + 1, file); vs += bfd_getl16 (vs); } } break; default: - fprintf (file, ("*unhandled*\n")); + fprintf (file, _("*unhandled*\n")); } } @@ -6724,6 +6792,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) } len = bfd_getl16 (dsth.length); type = bfd_getl16 (dsth.type); + /* xgettext:c-format */ fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "), type, len, off); if (len == 0) @@ -6792,6 +6861,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) const char *name = (const char *)buf + sizeof (*dst); fprintf (file, _("modbeg\n")); + /* xgettext:c-format */ fprintf (file, _(" flags: %d, language: %u, " "major: %u, minor: %u\n"), dst->flags, @@ -6814,6 +6884,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) const char *name = (const char *)buf + sizeof (*dst); fputs (_("rtnbeg\n"), file); + /* xgettext:c-format */ fprintf (file, _(" flags: %u, address: 0x%08x, " "pd-address: 0x%08x\n"), dst->flags, @@ -6843,6 +6914,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) { struct vms_dst_epilog *dst = (void *)buf; + /* xgettext:c-format */ fprintf (file, _("epilog: flags: %u, count: %u\n"), dst->flags, (unsigned)bfd_getl32 (dst->count)); } @@ -6852,6 +6924,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) struct vms_dst_blkbeg *dst = (void *)buf; const char *name = (const char *)buf + sizeof (*dst); + /* xgettext:c-format */ fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"), (unsigned)bfd_getl32 (dst->address), name[0], name + 1); @@ -6885,7 +6958,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1); evax_bfd_print_valspec (buf, 4, file); - fprintf (file, (" len: %u bits\n"), + fprintf (file, _(" len: %u bits\n"), (unsigned)bfd_getl32 (name + 1 + name[0])); } break; @@ -6893,6 +6966,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) fprintf (file, _("recend\n")); break; case DST__K_ENUMBEG: + /* xgettext:c-format */ fprintf (file, _("enumbeg, len: %u, name: %.*s\n"), buf[0], buf[1], buf + 2); break; @@ -6906,9 +6980,9 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) case DST__K_LABEL: { struct vms_dst_label *lab = (void *)buf; - fprintf (file, ("label, name: %.*s\n"), + fprintf (file, _("label, name: %.*s\n"), lab->name[0], lab->name + 1); - fprintf (file, (" address: 0x%08x\n"), + fprintf (file, _(" address: 0x%08x\n"), (unsigned)bfd_getl32 (lab->value)); } break; @@ -6920,6 +6994,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt); for (i = 0; i < cnt; i++, rng += 8) + /* xgettext:c-format */ fprintf (file, _(" address: 0x%08x, size: %u\n"), (unsigned)bfd_getl32 (rng), (unsigned)bfd_getl32 (rng + 4)); @@ -7014,6 +7089,7 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) fprintf (file, _("delta pc +%-4d"), -cmd); line++; /* FIXME: curr increment. */ pc += -cmd; + /* xgettext:c-format */ fprintf (file, _(" pc: 0x%08x line: %5u\n"), pc, line); cmdlen = 1; @@ -7048,10 +7124,12 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) struct vms_dst_src_decl_src *src = (void *)(buf + 1); const char *name; + /* xgettext:c-format */ fprintf (file, _(" declfile: len: %u, flags: %u, " "fileid: %u\n"), src->length, src->flags, (unsigned)bfd_getl16 (src->fileid)); + /* xgettext:c-format */ fprintf (file, _(" rms: cdt: 0x%08x %08x, " "ebk: 0x%08x, ffb: 0x%04x, " "rfo: %u\n"), @@ -7155,9 +7233,11 @@ evax_bfd_print_image (bfd *abfd, FILE *file) fprintf (file, _("cannot read EIHD\n")); return; } + /* xgettext:c-format */ fprintf (file, _("EIHD: (size: %u, nbr blocks: %u)\n"), (unsigned)bfd_getl32 (eihd.size), (unsigned)bfd_getl32 (eihd.hdrblkcnt)); + /* xgettext:c-format */ fprintf (file, _(" majorid: %u, minorid: %u\n"), (unsigned)bfd_getl32 (eihd.majorid), (unsigned)bfd_getl32 (eihd.minorid)); @@ -7175,6 +7255,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) name = _("unknown"); break; } + /* xgettext:c-format */ fprintf (file, _(" image type: %u (%s)"), val, name); val = (unsigned)bfd_getl32 (eihd.subtype); @@ -7190,12 +7271,14 @@ evax_bfd_print_image (bfd *abfd, FILE *file) name = _("unknown"); break; } + /* xgettext:c-format */ fprintf (file, _(", subtype: %u (%s)\n"), val, name); eisd_off = bfd_getl32 (eihd.isdoff); eiha_off = bfd_getl32 (eihd.activoff); eihi_off = bfd_getl32 (eihd.imgidoff); eihs_off = bfd_getl32 (eihd.symdbgoff); + /* xgettext:c-format */ fprintf (file, _(" offsets: isd: %u, activ: %u, symdbg: %u, " "imgid: %u, patch: %u\n"), eisd_off, eiha_off, eihs_off, eihi_off, @@ -7209,6 +7292,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) " version array off: %u\n"), eihvn_off); fprintf (file, + /* xgettext:c-format */ _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"), (unsigned)bfd_getl32 (eihd.imgiocnt), (unsigned)bfd_getl32 (eihd.iochancnt), @@ -7245,6 +7329,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) if (val & EIHD__M_EXT_BIND_SECT) fprintf (file, " EXT_BIND_SECT"); fprintf (file, "\n"); + /* xgettext:c-format */ fprintf (file, _(" ident: 0x%08x, sysver: 0x%08x, " "match ctrl: %u, symvect_size: %u\n"), (unsigned)bfd_getl32 (eihd.ident), @@ -7257,6 +7342,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) { eihef_off = bfd_getl32 (eihd.ext_fixup_off); eihnp_off = bfd_getl32 (eihd.noopt_psect_off); + /* xgettext:c-format */ fprintf (file, _(", ext fixup offset: %u, no_opt psect off: %u"), eihef_off, eihnp_off); } @@ -7352,7 +7438,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) fputs (_("*unknown* "), file); break; } - fprintf (file, _(": %u.%u\n"), + fprintf (file, ": %u.%u\n", (unsigned)bfd_getl16 (ver.major), (unsigned)bfd_getl16 (ver.minor)); } @@ -7370,18 +7456,23 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } fprintf (file, _("Image activation: (size=%u)\n"), (unsigned)bfd_getl32 (eiha.size)); + /* xgettext:c-format */ fprintf (file, _(" First address : 0x%08x 0x%08x\n"), (unsigned)bfd_getl32 (eiha.tfradr1_h), (unsigned)bfd_getl32 (eiha.tfradr1)); + /* xgettext:c-format */ fprintf (file, _(" Second address: 0x%08x 0x%08x\n"), (unsigned)bfd_getl32 (eiha.tfradr2_h), (unsigned)bfd_getl32 (eiha.tfradr2)); + /* xgettext:c-format */ fprintf (file, _(" Third address : 0x%08x 0x%08x\n"), (unsigned)bfd_getl32 (eiha.tfradr3_h), (unsigned)bfd_getl32 (eiha.tfradr3)); + /* xgettext:c-format */ fprintf (file, _(" Fourth address: 0x%08x 0x%08x\n"), (unsigned)bfd_getl32 (eiha.tfradr4_h), (unsigned)bfd_getl32 (eiha.tfradr4)); + /* xgettext:c-format */ fprintf (file, _(" Shared image : 0x%08x 0x%08x\n"), (unsigned)bfd_getl32 (eiha.inishr_h), (unsigned)bfd_getl32 (eiha.inishr)); @@ -7396,6 +7487,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) fprintf (file, _("cannot read EIHI\n")); return; } + /* xgettext:c-format */ fprintf (file, _("Image identification: (major: %u, minor: %u)\n"), (unsigned)bfd_getl32 (eihi.majorid), (unsigned)bfd_getl32 (eihi.minorid)); @@ -7420,19 +7512,23 @@ evax_bfd_print_image (bfd *abfd, FILE *file) fprintf (file, _("cannot read EIHS\n")); return; } + /* xgettext:c-format */ fprintf (file, _("Image symbol & debug table: (major: %u, minor: %u)\n"), (unsigned)bfd_getl32 (eihs.majorid), (unsigned)bfd_getl32 (eihs.minorid)); dst_vbn = bfd_getl32 (eihs.dstvbn); dst_size = bfd_getl32 (eihs.dstsize); + /* xgettext:c-format */ fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"), dst_vbn, dst_size, dst_size); gst_vbn = bfd_getl32 (eihs.gstvbn); gst_size = bfd_getl32 (eihs.gstsize); + /* xgettext:c-format */ fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"), gst_vbn, gst_size); dmt_vbn = bfd_getl32 (eihs.dmtvbn); dmt_size = bfd_getl32 (eihs.dmtsize); + /* xgettext:c-format */ fprintf (file, _(" debug module table : vbn: %u, size: %u\n"), dmt_vbn, dmt_size); } @@ -7456,6 +7552,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) /* Next block. */ eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1); } + /* xgettext:c-format */ fprintf (file, _("Image section descriptor: (major: %u, minor: %u, " "size: %u, offset: %u)\n"), (unsigned)bfd_getl32 (eisd.majorid), @@ -7463,6 +7560,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) len, eisd_off); if (len == 0) break; + /* xgettext:c-format */ fprintf (file, _(" section: base: 0x%08x%08x size: 0x%08x\n"), (unsigned)bfd_getl32 (eisd.virt_addr + 4), (unsigned)bfd_getl32 (eisd.virt_addr + 0), @@ -7505,6 +7603,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) eiaf_vbn = bfd_getl32 (eisd.vbn); eiaf_size = bfd_getl32 (eisd.secsize); } + /* xgettext:c-format */ fprintf (file, _(" vbn: %u, pfc: %u, matchctl: %u type: %u ("), (unsigned)bfd_getl32 (eisd.vbn), eisd.pfc, eisd.matchctl, eisd.type); @@ -7534,6 +7633,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } fputs (_(")\n"), file); if (val & EISD__M_GBL) + /* xgettext:c-format */ fprintf (file, _(" ident: 0x%08x, name: %.*s\n"), (unsigned)bfd_getl32 (eisd.ident), eisd.gblnam[0], eisd.gblnam + 1); @@ -7562,6 +7662,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } count = bfd_getl16 (dmth.psect_count); fprintf (file, + /* xgettext:c-format */ _(" module offset: 0x%08x, size: 0x%08x, (%u psects)\n"), (unsigned)bfd_getl32 (dmth.modbeg), (unsigned)bfd_getl32 (dmth.size), count); @@ -7575,6 +7676,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) fprintf (file, _("cannot read DMT psect\n")); return; } + /* xgettext:c-format */ fprintf (file, _(" psect start: 0x%08x, length: %u\n"), (unsigned)bfd_getl32 (dmtp.start), (unsigned)bfd_getl32 (dmtp.length)); @@ -7630,12 +7732,15 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } eiaf = (struct vms_eiaf *)buf; fprintf (file, + /* xgettext:c-format */ _("Image activator fixup: (major: %u, minor: %u)\n"), (unsigned)bfd_getl32 (eiaf->majorid), (unsigned)bfd_getl32 (eiaf->minorid)); + /* xgettext:c-format */ fprintf (file, _(" iaflink : 0x%08x %08x\n"), (unsigned)bfd_getl32 (eiaf->iaflink + 0), (unsigned)bfd_getl32 (eiaf->iaflink + 4)); + /* xgettext:c-format */ fprintf (file, _(" fixuplnk: 0x%08x %08x\n"), (unsigned)bfd_getl32 (eiaf->fixuplnk + 0), (unsigned)bfd_getl32 (eiaf->fixuplnk + 4)); @@ -7645,22 +7750,27 @@ evax_bfd_print_image (bfd *abfd, FILE *file) (unsigned)bfd_getl32 (eiaf->flags)); qrelfixoff = bfd_getl32 (eiaf->qrelfixoff); lrelfixoff = bfd_getl32 (eiaf->lrelfixoff); + /* xgettext:c-format */ fprintf (file, _(" qrelfixoff: %5u, lrelfixoff: %5u\n"), qrelfixoff, lrelfixoff); qdotadroff = bfd_getl32 (eiaf->qdotadroff); ldotadroff = bfd_getl32 (eiaf->ldotadroff); + /* xgettext:c-format */ fprintf (file, _(" qdotadroff: %5u, ldotadroff: %5u\n"), qdotadroff, ldotadroff); codeadroff = bfd_getl32 (eiaf->codeadroff); lpfixoff = bfd_getl32 (eiaf->lpfixoff); + /* xgettext:c-format */ fprintf (file, _(" codeadroff: %5u, lpfixoff : %5u\n"), codeadroff, lpfixoff); chgprtoff = bfd_getl32 (eiaf->chgprtoff); fprintf (file, _(" chgprtoff : %5u\n"), chgprtoff); shrimgcnt = bfd_getl32 (eiaf->shrimgcnt); shlstoff = bfd_getl32 (eiaf->shlstoff); + /* xgettext:c-format */ fprintf (file, _(" shlstoff : %5u, shrimgcnt : %5u\n"), shlstoff, shrimgcnt); + /* xgettext:c-format */ fprintf (file, _(" shlextra : %5u, permctx : %5u\n"), (unsigned)bfd_getl32 (eiaf->shlextra), (unsigned)bfd_getl32 (eiaf->permctx)); @@ -7678,6 +7788,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) for (j = 0; j < shrimgcnt; j++, shl++) { fprintf (file, + /* xgettext:c-format */ _(" %u: size: %u, flags: 0x%02x, name: %.*s\n"), j, shl->size, shl->flags, shl->imgnam[0], shl->imgnam + 1); @@ -7710,7 +7821,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } if (lpfixoff != 0) { - fprintf (file, _(" Linkage Pairs Referece Fixups:\n")); + fprintf (file, _(" Linkage Pairs Reference Fixups:\n")); evax_bfd_print_reference_fixups (file, buf + lpfixoff); } if (chgprtoff) @@ -7724,6 +7835,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) { unsigned int prot = bfd_getl32 (eicp->newprt); fprintf (file, + /* xgettext:c-format */ _(" base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "), (unsigned)bfd_getl32 (eicp->baseva + 4), (unsigned)bfd_getl32 (eicp->baseva + 0), @@ -7904,8 +8016,11 @@ alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib) sl->has_fixups = TRUE; VEC_APPEND_EL (sl->lp, bfd_vma, sect->output_section->vma + sect->output_offset + offset); + sect->output_section->flags |= SEC_RELOC; } +/* Add a code address fixup at address SECT + OFFSET to SHLIB. */ + static void alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib) { @@ -7918,8 +8033,11 @@ alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib) sl->has_fixups = TRUE; VEC_APPEND_EL (sl->ca, bfd_vma, sect->output_section->vma + sect->output_offset + offset); + sect->output_section->flags |= SEC_RELOC; } +/* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */ + static void alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src, bfd *shlib, bfd_vma vec) @@ -7935,25 +8053,19 @@ alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src, r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref); r->vma = sect->output_section->vma + sect->output_offset + offset; r->ref = vec; + sect->output_section->flags |= SEC_RELOC; } static void -alpha_vms_add_lw_fixup (struct bfd_link_info *info ATTRIBUTE_UNUSED, +alpha_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED, unsigned int shr ATTRIBUTE_UNUSED, bfd_vma vec ATTRIBUTE_UNUSED) { + /* Not yet supported. */ abort (); } -#if 0 -static void -alpha_vms_add_qw_fixup (struct bfd_link_info *info ATTRIBUTE_UNUSED, - unsigned int shr ATTRIBUTE_UNUSED, - bfd_vma vec ATTRIBUTE_UNUSED) -{ - abort (); -} -#endif +/* Add relocation. FIXME: Not yet emitted. */ static void alpha_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED) @@ -8138,7 +8250,10 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) return FALSE; if (element->archive_pass == -1 || element->archive_pass == pass) - continue; + { + /* Next symbol if this archive is wrong or already handled. */ + continue; + } if (! bfd_check_format (element, bfd_object)) { @@ -8160,10 +8275,10 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) /* Unlike the generic linker, we know that this element provides a definition for an undefined symbol and we know that we want to include it. We don't need to check anything. */ - if (! (*info->callbacks->add_archive_element) (info, element, - h->root.string)) - return FALSE; - if (! alpha_vms_link_add_object_symbols (element, info)) + if (!(*info->callbacks + ->add_archive_element) (info, element, h->root.string, &element)) + continue; + if (!alpha_vms_link_add_object_symbols (element, info)) return FALSE; orig_element->archive_pass = pass; @@ -8204,6 +8319,8 @@ alpha_vms_build_fixups (struct bfd_link_info *info) unsigned int ca_sz = 0; unsigned int qr_sz = 0; unsigned int shrimg_cnt = 0; + unsigned int chgprt_num = 0; + unsigned int chgprt_sz = 0; struct vms_eiaf *eiaf; unsigned int off; asection *sec; @@ -8251,9 +8368,20 @@ alpha_vms_build_fixups (struct bfd_link_info *info) if (ca_sz + lp_sz + qr_sz == 0) return TRUE; + /* Add an eicp entry for the fixup itself. */ + chgprt_num = 1; + for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next) + { + /* This isect could be made RO or EXE after relocations are applied. */ + if ((sec->flags & SEC_RELOC) != 0 + && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) + chgprt_num++; + } + chgprt_sz = 4 + chgprt_num * sizeof (struct vms_eicp); + /* Allocate section content (round-up size) */ sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl) - + ca_sz + lp_sz + qr_sz; + + ca_sz + lp_sz + qr_sz + chgprt_sz; sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1); content = bfd_zalloc (info->output_bfd, sz); if (content == NULL) @@ -8416,9 +8544,118 @@ alpha_vms_build_fixups (struct bfd_link_info *info) bfd_putl32 (0, content + off + 4); off += 8; } + } - /* CA fixups. */ + /* Write the change protection table. */ + bfd_putl32 (off, eiaf->chgprtoff); + bfd_putl32 (chgprt_num, content + off); + off += 4; + + for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next) + { + struct vms_eicp *eicp; + unsigned int prot; + + if ((sec->flags & SEC_LINKER_CREATED) != 0 && + strcmp (sec->name, "$FIXUP$") == 0) + prot = PRT__C_UREW; + else if ((sec->flags & SEC_RELOC) != 0 + && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) + prot = PRT__C_UR; + else + continue; + + eicp = (struct vms_eicp *)(content + off); + bfd_putl64 (sec->vma - t->base_addr, eicp->baseva); + bfd_putl32 ((sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1), + eicp->size); + bfd_putl32 (prot, eicp->newprt); + off += sizeof (struct vms_eicp); + } + + return TRUE; +} + +/* Called by bfd_hash_traverse to fill the symbol table. + Return FALSE in case of failure. */ + +static bfd_boolean +alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov) +{ + struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh; + struct bfd_link_info *info = (struct bfd_link_info *)infov; + struct alpha_vms_link_hash_entry *h; + struct vms_symbol_entry *sym; + + if (hc->type == bfd_link_hash_warning) + { + hc = hc->u.i.link; + if (hc->type == bfd_link_hash_new) + return TRUE; + } + h = (struct alpha_vms_link_hash_entry *) hc; + + switch (h->root.type) + { + case bfd_link_hash_undefined: + return TRUE; + case bfd_link_hash_new: + case bfd_link_hash_warning: + abort (); + case bfd_link_hash_undefweak: + return TRUE; + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + { + asection *sec = h->root.u.def.section; + + /* FIXME: this is certainly a symbol from a dynamic library. */ + if (bfd_is_abs_section (sec)) + return TRUE; + + if (sec->owner->flags & DYNAMIC) + return TRUE; + } + break; + case bfd_link_hash_common: + break; + case bfd_link_hash_indirect: + return TRUE; + } + + /* Do not write not kept symbols. */ + if (info->strip == strip_some + && bfd_hash_lookup (info->keep_hash, h->root.root.string, + FALSE, FALSE) != NULL) + return TRUE; + + if (h->sym == NULL) + { + /* This symbol doesn't come from a VMS object. So we suppose it is + a data. */ + int len = strlen (h->root.root.string); + + sym = (struct vms_symbol_entry *)bfd_zalloc (info->output_bfd, + sizeof (*sym) + len); + if (sym == NULL) + abort (); + sym->namelen = len; + memcpy (sym->name, h->root.root.string, len); + sym->name[len] = 0; + sym->owner = info->output_bfd; + + sym->typ = EGSD__C_SYMG; + sym->data_type = 0; + sym->flags = EGSY__V_DEF | EGSY__V_REL; + sym->symbol_vector = h->root.u.def.value; + sym->section = h->root.u.def.section; + sym->value = h->root.u.def.value; } + else + sym = h->sym; + + if (!add_symbol_entry (info->output_bfd, sym)) + return FALSE; return TRUE; } @@ -8435,6 +8672,14 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) asection *dst; asection *dmt; + if (bfd_link_relocatable (info)) + { + /* FIXME: we do not yet support relocatable link. It is not obvious + how to do it for debug infos. */ + (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n")); + return FALSE; + } + bfd_get_outsymbols (abfd) = NULL; bfd_get_symcount (abfd) = 0; @@ -8477,12 +8722,17 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) } #endif + /* Generate the symbol table. */ + BFD_ASSERT (PRIV (syms) == NULL); + if (info->strip != strip_all) + bfd_hash_traverse (&info->hash->table, alpha_vms_link_output_symbol, info); + /* Find the entry point. */ if (bfd_get_start_address (abfd) == 0) { bfd *startbfd = NULL; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { /* Consider only VMS object files. */ if (sub->xvec != abfd->xvec) @@ -8496,6 +8746,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR)) { (*info->callbacks->einfo) + /* xgettext:c-format */ (_("%P: multiple entry points: in modules %B and %B\n"), startbfd, sub); continue; @@ -8516,7 +8767,24 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) } } - /* Allocate contents. */ + /* Set transfer addresses. */ + { + int i; + struct bfd_link_hash_entry *h; + + i = 0; + PRIV (transfer_address[i++]) = 0xffffffff00000340ULL; /* SYS$IMGACT */ + h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", FALSE, FALSE, TRUE); + if (h != NULL && h->type == bfd_link_hash_defined) + PRIV (transfer_address[i++]) = + alpha_vms_get_sym_value (h->u.def.section, h->u.def.value); + PRIV (transfer_address[i++]) = bfd_get_start_address (abfd); + while (i < 4) + PRIV (transfer_address[i++]) = 0; + } + + /* Allocate contents. + Also compute the virtual base address. */ base_addr = (bfd_vma)-1; last_addr = 0; for (o = abfd->sections; o != NULL; o = o->next) @@ -8534,6 +8802,9 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) if (o->vma + o->size > last_addr) last_addr = o->vma + o->size; } + /* Clear the RELOC flags. Currently we don't support incremental + linking. We use the RELOC flag for computing the eicp entries. */ + o->flags &= ~SEC_RELOC; } /* Create the fixup section. */ @@ -8549,11 +8820,13 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) alpha_vms_link_hash (info)->base_addr = base_addr; /* Create the DMT section, if necessary. */ - dst = PRIV (dst_section); + BFD_ASSERT (PRIV (dst_section) == NULL); + dst = bfd_get_section_by_name (abfd, "$DST$"); if (dst != NULL && dst->size == 0) dst = NULL; if (dst != NULL) { + PRIV (dst_section) = dst; dmt = bfd_make_section_anyway_with_flags (info->output_bfd, "$DMT$", SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED); @@ -8564,7 +8837,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) dmt = NULL; /* Read all sections from the inputs. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { if (sub->flags & DYNAMIC) { @@ -8615,7 +8888,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) unsigned int off = 0; /* For each object file (ie for each module). */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) { asection *sub_dst; struct vms_dmt_header *dmth = NULL; @@ -8705,9 +8978,17 @@ alpha_vms_get_section_contents (bfd *abfd, asection *section, return FALSE; } - /* Alloc in memory and read ETIRs. */ - BFD_ASSERT (section->contents == NULL); + /* If the section is already in memory, just copy it. */ + if (section->flags & SEC_IN_MEMORY) + { + BFD_ASSERT (section->contents != NULL); + memcpy (buf, section->contents + offset, count); + return TRUE; + } + if (section->size == 0) + return TRUE; + /* Alloc in memory and read ETIRs. */ for (sec = abfd->sections; sec; sec = sec->next) { BFD_ASSERT (sec->contents == NULL); @@ -8722,8 +9003,8 @@ alpha_vms_get_section_contents (bfd *abfd, asection *section, if (!alpha_vms_read_sections_content (abfd, NULL)) return FALSE; for (sec = abfd->sections; sec; sec = sec->next) - if (section->contents) - section->flags |= SEC_IN_MEMORY; + if (sec->contents) + sec->flags |= SEC_IN_MEMORY; memcpy (buf, section->contents + offset, count); return TRUE; } @@ -8793,7 +9074,7 @@ vms_close_and_cleanup (bfd * abfd) format. */ if (bfd_cache_close (abfd) != TRUE) return FALSE; - if (vms_convert_to_var_unix_filename (abfd->filename) != TRUE) + if (_bfd_vms_convert_to_var_unix_filename (abfd->filename) != TRUE) return FALSE; } #endif @@ -8808,38 +9089,19 @@ vms_new_section_hook (bfd * abfd, asection *section) { bfd_size_type amt; - /* Count hasn't been incremented yet. */ - unsigned int section_count = abfd->section_count + 1; - - vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s), count %d\n", - abfd, section->index, section->name, section_count)); - - bfd_set_section_alignment (abfd, section, 0); - - if (section_count > PRIV (section_count)) - { - amt = section_count; - amt *= sizeof (asection *); - PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt); - if (PRIV (sections) == NULL) - return FALSE; - PRIV (section_count) = section_count; - } - - vms_debug2 ((6, "section_count: %d\n", PRIV (section_count))); + vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n", + abfd, section->index, section->name)); - PRIV (sections)[section->index] = section; + if (! bfd_set_section_alignment (abfd, section, 0)) + return FALSE; - vms_debug2 ((7, "%d: %s\n", section->index, section->name)); + vms_debug2 ((7, "%u: %s\n", section->index, section->name)); amt = sizeof (struct vms_section_data_struct); - section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); + section->used_by_bfd = bfd_zalloc (abfd, amt); if (section->used_by_bfd == NULL) return FALSE; - if (strcmp (bfd_get_section_name (abfd, section), "$DST$") == 0) - PRIV (dst_section) = section; - /* Create the section symbol. */ return _bfd_generic_new_section_hook (abfd, section); } @@ -8907,7 +9169,7 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED, if (ret == NULL) return; - if (sec == 0) + if (sec == NULL) ret->type = 'U'; else if (bfd_is_com_section (sec)) ret->type = 'C'; @@ -8917,14 +9179,15 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED, ret->type = 'U'; else if (bfd_is_ind_section (sec)) ret->type = 'I'; - else if (bfd_get_section_flags (abfd, sec) & SEC_CODE) + else if ((symbol->flags & BSF_FUNCTION) + || (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 = '-'; + ret->type = '?'; if (ret->type != 'U') ret->value = symbol->value + symbol->section->vma; @@ -8940,7 +9203,6 @@ static bfd_boolean vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, const char *name) { - vms_debug2 ((1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name)); return name[0] == '$'; } @@ -9028,12 +9290,16 @@ bfd_vms_get_data (bfd *abfd) ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) #define alpha_vms_print_symbol vms_print_symbol #define alpha_vms_get_symbol_info vms_get_symbol_info +#define alpha_vms_get_symbol_version_string \ + _bfd_nosymbols_get_symbol_version_string + #define alpha_vms_read_minisymbols _bfd_generic_read_minisymbols #define alpha_vms_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define alpha_vms_get_lineno _bfd_nosymbols_get_lineno #define alpha_vms_find_inliner_info _bfd_nosymbols_find_inliner_info #define alpha_vms_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define alpha_vms_find_nearest_line _bfd_vms_find_nearest_dst_line +#define alpha_vms_find_nearest_line _bfd_vms_find_nearest_line +#define alpha_vms_find_line _bfd_nosymbols_find_line #define alpha_vms_bfd_is_local_label_name vms_bfd_is_local_label_name /* Generic table. */ @@ -9048,6 +9314,7 @@ bfd_vms_get_data (bfd *abfd) #define alpha_vms_bfd_relax_section bfd_generic_relax_section #define alpha_vms_bfd_gc_sections bfd_generic_gc_sections +#define alpha_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags #define alpha_vms_bfd_merge_sections bfd_generic_merge_sections #define alpha_vms_bfd_is_group_section bfd_generic_is_group_section #define alpha_vms_bfd_discard_group bfd_generic_discard_group @@ -9055,7 +9322,6 @@ bfd_vms_get_data (bfd *abfd) _bfd_generic_section_already_linked #define alpha_vms_bfd_define_common_symbol bfd_generic_define_common_symbol -#define alpha_vms_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define alpha_vms_bfd_link_just_syms _bfd_generic_link_just_syms #define alpha_vms_bfd_copy_link_hash_symbol_type \ _bfd_generic_copy_link_hash_symbol_type @@ -9070,8 +9336,9 @@ bfd_vms_get_data (bfd *abfd) _bfd_nodynamic_get_dynamic_reloc_upper_bound #define alpha_vms_canonicalize_dynamic_reloc \ _bfd_nodynamic_canonicalize_dynamic_reloc +#define alpha_vms_bfd_link_check_relocs _bfd_generic_link_check_relocs -const bfd_target vms_alpha_vec = +const bfd_target alpha_vms_vec = { "vms-alpha", /* Name. */ bfd_target_evax_flavour, @@ -9086,6 +9353,7 @@ const bfd_target vms_alpha_vec = 0, /* symbol_leading_char. */ ' ', /* ar_pad_char. */ 15, /* ar_max_namelen. */ + 0, /* match priority. */ bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, @@ -9096,7 +9364,7 @@ const bfd_target vms_alpha_vec = {_bfd_dummy_target, alpha_vms_object_p, /* bfd_check_format. */ _bfd_vms_lib_alpha_archive_p, _bfd_dummy_target}, {bfd_false, alpha_vms_mkobject, /* bfd_set_format. */ - _bfd_vms_lib_mkarchive, bfd_false}, + _bfd_vms_lib_alpha_mkarchive, bfd_false}, {bfd_false, alpha_vms_write_object_contents, /* bfd_write_contents. */ _bfd_vms_lib_write_archive_contents, bfd_false}, @@ -9112,5 +9380,5 @@ const bfd_target vms_alpha_vec = NULL, - (PTR) 0 + NULL };