X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fvms-alpha.c;h=b00ab2a54df11305c068dcb950dfcf5e3f1b1424;hb=0955507f6e7144c9c5e420bbcf617593b13de38b;hp=c0ba3c46d81be436767a292c2dfec7eb5c0f7cf0;hpb=a283ff9345ad55bdb2c65fd8eb2add63ffa60dac;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index c0ba3c46d8..b00ab2a54d 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-2016 Free Software Foundation, Inc. Initial version written by Klaus Kaempf (kkaempf@rmi.de) Major rewrite by Adacore. @@ -304,6 +303,7 @@ struct vms_private_data_struct struct module *modules; /* list of all compilation units */ + /* The DST section. */ asection *dst_section; unsigned int dst_ptr_offsets_count; /* # of offsets in following array */ @@ -329,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) \ @@ -368,9 +364,9 @@ 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 *); @@ -378,8 +374,8 @@ static void alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *, bfd_vma); 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 *info); -static void alpha_vms_add_qw_reloc (struct bfd_link_info *info); +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 { @@ -439,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. */ @@ -525,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; @@ -792,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; @@ -801,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; @@ -828,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; @@ -858,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")); @@ -872,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; @@ -904,6 +922,7 @@ _bfd_vms_slurp_ehdr (bfd *abfd) break; default: + fail: bfd_set_error (bfd_error_wrong_format); return FALSE; } @@ -992,7 +1011,7 @@ static const struct sec_flags_struct evax_section_flags[] = 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 } + SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD } }; /* Retrieve BFD section flags by name and size. */ @@ -1129,14 +1148,15 @@ _bfd_vms_slurp_egsd (bfd *abfd) /* Program section definition. */ { struct vms_egps *egps = (struct vms_egps *)vms_rec; - flagword new_flags, old_flags; + flagword new_flags, vms_flags; asection *section; - old_flags = bfd_getl16 (egps->flags); + vms_flags = bfd_getl16 (egps->flags); - if ((old_flags & EGPS__V_REL) == 0) + if ((vms_flags & EGPS__V_REL) == 0) { - /* Use the global absolute section for all absolute sections. */ + /* Use the global absolute section for all + absolute sections. */ section = bfd_abs_section_ptr; } else @@ -1154,17 +1174,27 @@ _bfd_vms_slurp_egsd (bfd *abfd) section->size = bfd_getl32 (egps->alloc); section->alignment_power = egps->align; - vms_section_data (section)->flags = old_flags; + 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 (!(old_flags & EGPS__V_NOMOD) && 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 (old_flags & EGPS__V_REL) + 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; @@ -1611,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; } } @@ -1709,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, (intptr_t) ptr); + _bfd_hexdump (8, ptr, cmd_length - 4, 0); #endif switch (cmd) @@ -2425,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; @@ -2467,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) @@ -2495,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; @@ -2510,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; @@ -2524,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) @@ -2648,7 +2673,7 @@ _bfd_vms_write_eeom (bfd *abfd) _bfd_vms_output_alignment (recwr, 2); _bfd_vms_output_begin (recwr, EOBJ__C_EEOM); - _bfd_vms_output_long (recwr, (unsigned long) (PRIV (vms_linkage_index) >> 1)); + _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. */ @@ -2674,88 +2699,6 @@ _bfd_vms_write_eeom (bfd *abfd) return TRUE; } -/* 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) - { - c = *p++; - hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c); - } - return hash; -} - -/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */ - -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; - -#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; - - /* We may need to truncate the symbol, save the hash for later. */ - in_len = strlen (in); - - result = (in_len > maxlen) ? hash_string (in) : 0; - - old_name = in; - - /* Do the length checking. */ - if (in_len <= maxlen) - i = in_len; - else - { - if (PRIV (flag_hash_long_names)) - i = maxlen - 9; - else - i = maxlen; - } - - strncpy (out, in, (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; -} - static void vector_grow1 (struct vector_type *vec, size_t elsz) { @@ -2908,7 +2851,7 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec) if (sec->flags & SEC_RELOC) eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF; - if (!(sec->flags & SEC_LOAD)) + if (!(sec->flags & SEC_HAS_CONTENTS)) { eisd->u.eisd.flags |= EISD__M_DZRO; eisd->u.eisd.flags &= ~EISD__M_CRF; @@ -3229,7 +3172,6 @@ alpha_vms_write_exec (bfd *abfd) for (i = 0; i < PRIV (gsd_sym_count); i++) { struct vms_symbol_entry *sym = PRIV (syms)[i]; - char *hash; bfd_vma val; bfd_vma ep; @@ -3256,8 +3198,7 @@ alpha_vms_write_exec (bfd *abfd) _bfd_vms_output_quad (recwr, ep); _bfd_vms_output_quad (recwr, val); _bfd_vms_output_long (recwr, 0); - hash = _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ__C_SYMSIZ); - _bfd_vms_output_counted (recwr, hash); + _bfd_vms_output_counted (recwr, sym->name); _bfd_vms_output_end_subrec (recwr); if ((i % 5) == 4) _bfd_vms_output_end (abfd, recwr); @@ -3352,8 +3293,6 @@ _bfd_vms_write_egsd (bfd *abfd) else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0)) sname = EVAX_LOCAL_NAME; } - else - sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ__C_SECSIZ); if (bfd_is_com_section (section)) new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD @@ -3393,18 +3332,13 @@ _bfd_vms_write_egsd (bfd *abfd) for (symnum = 0; symnum < abfd->symcount; symnum++) { - char *hash; - symbol = abfd->outsymbols[symnum]; old_flags = symbol->flags; /* Work-around a missing feature: consider __main as the main entry point. */ - if (*(symbol->name) == '_') - { - if (strcmp (symbol->name, "__main") == 0) - bfd_set_start_address (abfd, (bfd_vma)symbol->value); - } + 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) @@ -3497,8 +3431,7 @@ _bfd_vms_write_egsd (bfd *abfd) _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); } @@ -3516,8 +3449,6 @@ _bfd_vms_write_ehdr (bfd *abfd) { asymbol *symbol; unsigned int symnum; - int had_case = 0; - int had_file = 0; struct vms_rec_wr *recwr = &PRIV (recwr); vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd)); @@ -3537,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; } } @@ -3724,7 +3642,7 @@ _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) { @@ -3752,7 +3670,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) int pass2_in_progress = 0; unsigned int irel; - if (section->reloc_count <= 0) + if (section->reloc_count == 0) (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"), section->name); @@ -3788,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) { @@ -3827,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); @@ -3847,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); } } @@ -3882,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); @@ -3901,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); } } @@ -3935,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; @@ -3962,17 +3872,13 @@ _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->target_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->target_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; @@ -3989,16 +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->target_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->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; @@ -4010,17 +3913,13 @@ _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->target_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->target_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; @@ -4617,6 +4516,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; @@ -4696,10 +4600,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; @@ -4709,10 +4617,14 @@ _bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section, *file = NULL; *func = NULL; *line = 0; + if (discriminator) + *discriminator = 0; + /* 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); @@ -5087,7 +4999,14 @@ alpha_vms_slurp_relocs (bfd *abfd) (*_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. */ @@ -5098,7 +5017,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; @@ -6022,7 +5941,7 @@ 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; fprintf (file, _(" %s (len=%u+%u):\n"), name, (unsigned)(rec_len - sizeof (struct vms_eobjrec)), @@ -7827,7 +7746,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) @@ -8282,7 +8201,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) to include it. We don't need to check anything. */ if (!(*info->callbacks ->add_archive_element) (info, element, h->root.string, &element)) - return FALSE; + continue; if (!alpha_vms_link_add_object_symbols (element, info)) return FALSE; @@ -8581,20 +8500,31 @@ alpha_vms_build_fixups (struct bfd_link_info *info) return TRUE; } -/* Called by bfd_link_hash_traverse to fill the symbol table. +/* 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_link_hash_entry *hc, void *infov) +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 alpha_vms_link_hash_entry *)hc; + 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_new: 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; @@ -8614,7 +8544,6 @@ alpha_vms_link_output_symbol (struct bfd_link_hash_entry *hc, void *infov) case bfd_link_hash_common: break; case bfd_link_hash_indirect: - case bfd_link_hash_warning: return TRUE; } @@ -8667,7 +8596,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) asection *dst; asection *dmt; - if (info->relocatable) + if (bfd_link_relocatable (info)) { /* FIXME: we do not yet support relocatable link. It is not obvious how to do it for debug infos. */ @@ -8720,14 +8649,14 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) /* Generate the symbol table. */ BFD_ASSERT (PRIV (syms) == NULL); if (info->strip != strip_all) - bfd_link_hash_traverse (info->hash, alpha_vms_link_output_symbol, info); + 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) @@ -8831,7 +8760,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) { @@ -8882,7 +8811,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; @@ -8972,9 +8901,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); @@ -8989,8 +8926,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; } @@ -9075,15 +9012,16 @@ vms_new_section_hook (bfd * abfd, asection *section) { bfd_size_type amt; - vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s)\n", + vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n", abfd, section->index, section->name)); - bfd_set_section_alignment (abfd, section, 0); + 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; @@ -9188,7 +9126,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] == '$'; } @@ -9276,12 +9213,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. */ @@ -9296,6 +9237,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 @@ -9303,7 +9245,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 @@ -9318,8 +9259,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, @@ -9334,6 +9276,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, @@ -9360,5 +9303,5 @@ const bfd_target vms_alpha_vec = NULL, - (PTR) 0 + NULL };