| Index: bfd/elf32-vax.c
|
| diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
|
| index 84ec972563f328974ba7fdc3c1cc62173cb7ac62..d6ae14e132caa81c5b3e6f93e634ea794668902d 100644
|
| --- a/bfd/elf32-vax.c
|
| +++ b/bfd/elf32-vax.c
|
| @@ -465,7 +465,7 @@ elf_vax_link_hash_table_create (bfd *abfd)
|
| struct elf_link_hash_table *ret;
|
| bfd_size_type amt = sizeof (struct elf_link_hash_table);
|
|
|
| - ret = bfd_malloc (amt);
|
| + ret = bfd_zmalloc (amt);
|
| if (ret == NULL)
|
| return NULL;
|
|
|
| @@ -585,20 +585,22 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
|
| while (h->root.type == bfd_link_hash_indirect
|
| || h->root.type == bfd_link_hash_warning)
|
| h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
| +
|
| + /* PR15323, ref flags aren't set for references in the same
|
| + object. */
|
| + h->root.non_ir_ref = 1;
|
| }
|
|
|
| switch (ELF32_R_TYPE (rel->r_info))
|
| {
|
| case R_VAX_GOT32:
|
| BFD_ASSERT (h != NULL);
|
| - if (h->forced_local
|
| - || h == elf_hash_table (info)->hgot
|
| - || h == elf_hash_table (info)->hplt)
|
| - break;
|
|
|
| /* If this is a local symbol, we resolve it directly without
|
| creating a global offset table entry. */
|
| - if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
|
| + if (h->forced_local
|
| + || h == elf_hash_table (info)->hgot
|
| + || h == elf_hash_table (info)->hplt)
|
| break;
|
|
|
| /* This symbol requires a global offset table entry. */
|
| @@ -668,11 +670,11 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
|
| never referenced by a dynamic object, in which case we
|
| don't need to generate a procedure linkage table entry
|
| after all. */
|
| + BFD_ASSERT (h != NULL);
|
|
|
| /* If this is a local symbol, we resolve it directly without
|
| creating a procedure linkage table entry. */
|
| - BFD_ASSERT (h != NULL);
|
| - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || h->forced_local)
|
| + if (h->forced_local)
|
| break;
|
|
|
| h->needs_plt = 1;
|
| @@ -910,9 +912,8 @@ elf_vax_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec,
|
| understand. */
|
|
|
| static bfd_boolean
|
| -elf_vax_adjust_dynamic_symbol (info, h)
|
| - struct bfd_link_info *info;
|
| - struct elf_link_hash_entry *h;
|
| +elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
|
| + struct elf_link_hash_entry *h)
|
| {
|
| bfd *dynobj;
|
| asection *s;
|
| @@ -933,39 +934,21 @@ elf_vax_adjust_dynamic_symbol (info, h)
|
| if (h->type == STT_FUNC
|
| || h->needs_plt)
|
| {
|
| - if (! info->shared
|
| - && !h->def_dynamic
|
| - && !h->ref_dynamic
|
| - /* We must always create the plt entry if it was referenced
|
| - by a PLTxxO relocation. In this case we already recorded
|
| - it as a dynamic symbol. */
|
| - && h->dynindx == -1)
|
| + if (h->plt.refcount <= 0
|
| + || SYMBOL_CALLS_LOCAL (info, h)
|
| + || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
| + && h->root.type == bfd_link_hash_undefweak))
|
| {
|
| /* This case can occur if we saw a PLTxx reloc in an input
|
| file, but the symbol was never referred to by a dynamic
|
| - object. In such a case, we don't actually need to build
|
| - a procedure linkage table, and we can just do a PCxx
|
| - reloc instead. */
|
| - BFD_ASSERT (h->needs_plt);
|
| + object, or if all references were garbage collected. In
|
| + such a case, we don't actually need to build a procedure
|
| + linkage table, and we can just do a PCxx reloc instead. */
|
| h->plt.offset = (bfd_vma) -1;
|
| - return TRUE;
|
| - }
|
| -
|
| - /* GC may have rendered this entry unused. */
|
| - if (h->plt.refcount <= 0)
|
| - {
|
| h->needs_plt = 0;
|
| - h->plt.offset = (bfd_vma) -1;
|
| return TRUE;
|
| }
|
|
|
| - /* Make sure this symbol is output as a dynamic symbol. */
|
| - if (h->dynindx == -1)
|
| - {
|
| - if (! bfd_elf_link_record_dynamic_symbol (info, h))
|
| - return FALSE;
|
| - }
|
| -
|
| s = bfd_get_linker_section (dynobj, ".plt");
|
| BFD_ASSERT (s != NULL);
|
|
|
| @@ -1065,6 +1048,59 @@ elf_vax_adjust_dynamic_symbol (info, h)
|
| return _bfd_elf_adjust_dynamic_copy (h, s);
|
| }
|
|
|
| +/* This function is called via elf_link_hash_traverse. It resets GOT
|
| + and PLT (.GOT) reference counts back to -1 so normal PC32 relocation
|
| + will be done. */
|
| +
|
| +static bfd_boolean
|
| +elf_vax_discard_got_entries (struct elf_link_hash_entry *h,
|
| + void *infoptr ATTRIBUTE_UNUSED)
|
| +{
|
| + h->got.refcount = -1;
|
| + h->plt.refcount = -1;
|
| +
|
| + return TRUE;
|
| +}
|
| +
|
| +/* Discard unused dynamic data if this is a static link. */
|
| +
|
| +static bfd_boolean
|
| +elf_vax_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
| + struct bfd_link_info *info)
|
| +{
|
| + bfd *dynobj;
|
| + asection *s;
|
| +
|
| + dynobj = elf_hash_table (info)->dynobj;
|
| +
|
| + if (dynobj && !elf_hash_table (info)->dynamic_sections_created)
|
| + {
|
| + /* We may have created entries in the .rela.got and .got sections.
|
| + However, if we are not creating the dynamic sections, we will
|
| + not actually use these entries. Reset the size of .rela.got
|
| + and .got, which will cause them to get stripped from the output
|
| + file below. */
|
| + s = bfd_get_linker_section (dynobj, ".rela.got");
|
| + if (s != NULL)
|
| + s->size = 0;
|
| + s = bfd_get_linker_section (dynobj, ".got.plt");
|
| + if (s != NULL)
|
| + s->size = 0;
|
| + s = bfd_get_linker_section (dynobj, ".got");
|
| + if (s != NULL)
|
| + s->size = 0;
|
| + }
|
| +
|
| + /* If this is a static link, we need to discard all the got entries we've
|
| + recorded. */
|
| + if (!dynobj || !elf_hash_table (info)->dynamic_sections_created)
|
| + elf_link_hash_traverse (elf_hash_table (info),
|
| + elf_vax_discard_got_entries,
|
| + info);
|
| +
|
| + return TRUE;
|
| +}
|
| +
|
| /* Set the sizes of the dynamic sections. */
|
|
|
| static bfd_boolean
|
| @@ -1090,23 +1126,6 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
|
| }
|
| }
|
| - else
|
| - {
|
| - /* We may have created entries in the .rela.got and .got sections.
|
| - However, if we are not creating the dynamic sections, we will
|
| - not actually use these entries. Reset the size of .rela.got
|
| - and .got, which will cause it to get stripped from the output
|
| - file below. */
|
| - s = bfd_get_linker_section (dynobj, ".rela.got");
|
| - if (s != NULL)
|
| - s->size = 0;
|
| - s = bfd_get_linker_section (dynobj, ".got.plt");
|
| - if (s != NULL)
|
| - s->size = 0;
|
| - s = bfd_get_linker_section (dynobj, ".got");
|
| - if (s != NULL)
|
| - s->size = 0;
|
| - }
|
|
|
| /* If this is a -Bsymbolic shared link, then we need to discard all PC
|
| relative relocs against symbols defined in a regular object. We
|
| @@ -1117,9 +1136,9 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| elf_vax_discard_copies,
|
| NULL);
|
|
|
| - /* If this is a -Bsymbolic shared link or a static link, we need to
|
| - discard all the got entries we've recorded. Otherwise, we need to
|
| - instantiate (allocate space for them). */
|
| + /* If this is a -Bsymbolic shared link, we need to discard all the got
|
| + entries we've recorded. Otherwise, we need to instantiate (allocate
|
| + space for them). */
|
| elf_link_hash_traverse (elf_hash_table (info),
|
| elf_vax_instantiate_got_entries,
|
| info);
|
| @@ -1275,12 +1294,12 @@ elf_vax_discard_copies (struct elf_vax_link_hash_entry *h,
|
| return TRUE;
|
| }
|
|
|
| -/* This function is called via elf_link_hash_traverse. It looks for entries
|
| - that have GOT or PLT (.GOT) references. If creating a static object or a
|
| - shared object with -Bsymbolic, it resets the reference count back to 0
|
| - and sets the offset to -1 so normal PC32 relocation will be done. If
|
| - creating a shared object or executable, space in the .got and .rela.got
|
| - will be reserved for the symbol. */
|
| +/* This function is called via elf_link_hash_traverse. It looks for
|
| + entries that have GOT or PLT (.GOT) references. If creating a shared
|
| + object with -Bsymbolic, or the symbol has been forced local, then it
|
| + resets the reference count back to -1 so normal PC32 relocation will
|
| + be done. Otherwise space in the .got and .rela.got will be reserved
|
| + for the symbol. */
|
|
|
| static bfd_boolean
|
| elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
|
| @@ -1295,25 +1314,18 @@ elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
|
| return TRUE;
|
|
|
| dynobj = elf_hash_table (info)->dynobj;
|
| - if (dynobj == NULL)
|
| - return TRUE;
|
| + BFD_ASSERT (dynobj != NULL);
|
|
|
| sgot = bfd_get_linker_section (dynobj, ".got");
|
| srelgot = bfd_get_linker_section (dynobj, ".rela.got");
|
|
|
| - if (!elf_hash_table (info)->dynamic_sections_created
|
| - || (info->shared && info->symbolic)
|
| - || h->forced_local)
|
| + if (SYMBOL_REFERENCES_LOCAL (info, h))
|
| {
|
| - h->got.refcount = 0;
|
| - h->got.offset = (bfd_vma) -1;
|
| - h->plt.refcount = 0;
|
| - h->plt.offset = (bfd_vma) -1;
|
| + h->got.refcount = -1;
|
| + h->plt.refcount = -1;
|
| }
|
| else if (h->got.refcount > 0)
|
| {
|
| - bfd_boolean dyn;
|
| -
|
| /* Make sure this symbol is output as a dynamic symbol. */
|
| if (h->dynindx == -1)
|
| {
|
| @@ -1321,15 +1333,9 @@ elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
|
| return FALSE;
|
| }
|
|
|
| - dyn = elf_hash_table (info)->dynamic_sections_created;
|
| /* Allocate space in the .got and .rela.got sections. */
|
| - if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
| - && (info->shared
|
| - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
|
| - {
|
| - sgot->size += 4;
|
| - srelgot->size += sizeof (Elf32_External_Rela);
|
| - }
|
| + sgot->size += 4;
|
| + srelgot->size += sizeof (Elf32_External_Rela);
|
| }
|
|
|
| return TRUE;
|
| @@ -1402,12 +1408,12 @@ elf_vax_relocate_section (bfd *output_bfd,
|
| else
|
| {
|
| bfd_boolean unresolved_reloc;
|
| - bfd_boolean warned;
|
| + bfd_boolean warned, ignored;
|
|
|
| RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
|
| r_symndx, symtab_hdr, sym_hashes,
|
| h, sec, relocation,
|
| - unresolved_reloc, warned);
|
| + unresolved_reloc, warned, ignored);
|
|
|
| if ((h->root.type == bfd_link_hash_defined
|
| || h->root.type == bfd_link_hash_defweak)
|
| @@ -1454,17 +1460,14 @@ elf_vax_relocate_section (bfd *output_bfd,
|
| case R_VAX_GOT32:
|
| /* Relocation is to the address of the entry for this symbol
|
| in the global offset table. */
|
| +
|
| + /* Resolve a GOTxx reloc against a local symbol directly,
|
| + without using the global offset table. */
|
| if (h == NULL
|
| - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
| - || h->got.offset == (bfd_vma) -1
|
| - || h->forced_local)
|
| + || h->got.offset == (bfd_vma) -1)
|
| break;
|
|
|
| - /* Relocation is the offset of the entry for this symbol in
|
| - the global offset table. */
|
| -
|
| {
|
| - bfd_boolean dyn;
|
| bfd_vma off;
|
|
|
| if (sgot == NULL)
|
| @@ -1473,37 +1476,10 @@ elf_vax_relocate_section (bfd *output_bfd,
|
| BFD_ASSERT (sgot != NULL);
|
| }
|
|
|
| - BFD_ASSERT (h != NULL);
|
| off = h->got.offset;
|
| - BFD_ASSERT (off != (bfd_vma) -1);
|
| BFD_ASSERT (off < sgot->size);
|
|
|
| - dyn = elf_hash_table (info)->dynamic_sections_created;
|
| - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
|
| - || (info->shared
|
| - && SYMBOL_REFERENCES_LOCAL (info, h)))
|
| - {
|
| - /* The symbol was forced to be local
|
| - because of a version file.. We must initialize
|
| - this entry in the global offset table. Since
|
| - the offset must always be a multiple of 4, we
|
| - use the least significant bit to record whether
|
| - we have initialized it already.
|
| -
|
| - When doing a dynamic link, we create a .rela.got
|
| - relocation entry to initialize the value. This
|
| - is done in the finish_dynamic_symbol routine. */
|
| - if ((off & 1) != 0)
|
| - off &= ~1;
|
| - else
|
| - {
|
| - bfd_put_32 (output_bfd, relocation + rel->r_addend,
|
| - sgot->contents + off);
|
| - h->got.offset |= 1;
|
| - }
|
| - } else {
|
| - bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
|
| - }
|
| + bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
|
|
|
| relocation = sgot->output_offset + off;
|
| /* The GOT relocation uses the addend. */
|
| @@ -1530,19 +1506,9 @@ elf_vax_relocate_section (bfd *output_bfd,
|
| /* Resolve a PLTxx reloc against a local symbol directly,
|
| without using the procedure linkage table. */
|
| if (h == NULL
|
| - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
| - || h->forced_local)
|
| + || h->plt.offset == (bfd_vma) -1)
|
| break;
|
|
|
| - if (h->plt.offset == (bfd_vma) -1
|
| - || !elf_hash_table (info)->dynamic_sections_created)
|
| - {
|
| - /* We didn't make a PLT entry for this symbol. This
|
| - happens when statically linking PIC code, or when
|
| - using -Bsymbolic. */
|
| - break;
|
| - }
|
| -
|
| if (splt == NULL)
|
| {
|
| splt = bfd_get_linker_section (dynobj, ".plt");
|
| @@ -1877,25 +1843,10 @@ elf_vax_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
|
|
| rela.r_offset = (sgot->output_section->vma
|
| + sgot->output_offset
|
| - + (h->got.offset &~ 1));
|
| -
|
| - /* If the symbol was forced to be local because of a version file
|
| - locally we just want to emit a RELATIVE reloc. The entry in
|
| - the global offset table will already have been initialized in
|
| - the relocate_section function. */
|
| - if (info->shared
|
| - && h->dynindx == -1
|
| - && h->def_regular)
|
| - {
|
| - rela.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
|
| - }
|
| - else
|
| - {
|
| - rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
|
| - }
|
| + + h->got.offset);
|
| + rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
|
| rela.r_addend = bfd_get_signed_32 (output_bfd,
|
| - (sgot->contents
|
| - + (h->got.offset & ~1)));
|
| + sgot->contents + h->got.offset);
|
|
|
| loc = srela->contents;
|
| loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
|
| @@ -1926,7 +1877,7 @@ elf_vax_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
|
| }
|
|
|
| /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
|
| - if (strcmp (h->root.root.string, "_DYNAMIC") == 0
|
| + if (h == elf_hash_table (info)->hdynamic
|
| || h == elf_hash_table (info)->hgot)
|
| sym->st_shndx = SHN_ABS;
|
|
|
| @@ -2038,13 +1989,16 @@ elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
|
| }
|
|
|
| - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
| + if (elf_section_data (sgot->output_section) != NULL)
|
| + elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
|
|
| return TRUE;
|
| }
|
|
|
| static enum elf_reloc_type_class
|
| -elf_vax_reloc_type_class (const Elf_Internal_Rela *rela)
|
| +elf_vax_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
|
| + const asection *rel_sec ATTRIBUTE_UNUSED,
|
| + const Elf_Internal_Rela *rela)
|
| {
|
| switch ((int) ELF32_R_TYPE (rela->r_info))
|
| {
|
| @@ -2080,6 +2034,8 @@ elf_vax_plt_sym_val (bfd_vma i, const asection *plt,
|
| #define elf_backend_check_relocs elf_vax_check_relocs
|
| #define elf_backend_adjust_dynamic_symbol \
|
| elf_vax_adjust_dynamic_symbol
|
| +#define elf_backend_always_size_sections \
|
| + elf_vax_always_size_sections
|
| #define elf_backend_size_dynamic_sections \
|
| elf_vax_size_dynamic_sections
|
| #define elf_backend_init_index_section _bfd_elf_init_1_index_section
|
|
|