| Index: bfd/elfxx-sparc.c
|
| diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
|
| index e14afaf970fa2b1ea58b3dceb04048c824caca30..8250f840a13558da074662f97757479e6e35c8f0 100644
|
| --- a/bfd/elfxx-sparc.c
|
| +++ b/bfd/elfxx-sparc.c
|
| @@ -1433,7 +1433,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
| TRUE);
|
| if (h == NULL)
|
| return FALSE;
|
| -
|
| +
|
| /* Fake a STT_GNU_IFUNC symbol. */
|
| h->type = STT_GNU_IFUNC;
|
| h->def_regular = 1;
|
| @@ -1450,6 +1450,10 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
| 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;
|
| }
|
|
|
| if (h && h->type == STT_GNU_IFUNC)
|
| @@ -1873,6 +1877,29 @@ _bfd_sparc_elf_gc_mark_hook (asection *sec,
|
| return NULL;
|
| }
|
|
|
| + /* FIXME: The test here, in check_relocs and in relocate_section
|
| + dealing with TLS optimization, ought to be !info->executable. */
|
| + if (info->shared)
|
| + {
|
| + switch (SPARC_ELF_R_TYPE (rel->r_info))
|
| + {
|
| + case R_SPARC_TLS_GD_CALL:
|
| + case R_SPARC_TLS_LDM_CALL:
|
| + /* This reloc implicitly references __tls_get_addr. We know
|
| + another reloc will reference the same symbol as the one
|
| + on this reloc, so the real symbol and section will be
|
| + gc marked when processing the other reloc. That lets
|
| + us handle __tls_get_addr here. */
|
| + h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
|
| + FALSE, FALSE, TRUE);
|
| + BFD_ASSERT (h != NULL);
|
| + h->mark = 1;
|
| + if (h->u.weakdef != NULL)
|
| + h->u.weakdef->mark = 1;
|
| + sym = NULL;
|
| + }
|
| + }
|
| +
|
| return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
|
| }
|
|
|
| @@ -2985,19 +3012,19 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
|
| if (h == NULL)
|
| abort ();
|
|
|
| - /* Set STT_GNU_IFUNC symbol value. */
|
| + /* Set STT_GNU_IFUNC symbol value. */
|
| h->root.u.def.value = sym->st_value;
|
| h->root.u.def.section = sec;
|
| }
|
| }
|
| else
|
| {
|
| - 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 (warned)
|
| {
|
| /* To avoid generating warning messages about truncated
|
| @@ -3278,7 +3305,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
|
| if (h == NULL)
|
| break;
|
| }
|
| - /* PR 7027: We need similar behaviour for 64-bit binaries. */
|
| + /* PR 7027: We need similar behaviour for 64-bit binaries. */
|
| else if (r_type == R_SPARC_WPLT30 && h == NULL)
|
| break;
|
| else
|
| @@ -4126,7 +4153,7 @@ do_relocation:
|
| {
|
| const char *name;
|
|
|
| - /* The Solaris native linker silently disregards overflows.
|
| + /* The Solaris native linker silently disregards overflows.
|
| We don't, but this breaks stabs debugging info, whose
|
| relocations are only 32-bits wide. Ignore overflows in
|
| this case and also for discarded entries. */
|
| @@ -4511,7 +4538,7 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
|
| _GLOBAL_OFFSET_TABLE_ is not absolute: it is relative to the
|
| ".got" section. Likewise _PROCEDURE_LINKAGE_TABLE_ and ".plt". */
|
| if (sym != NULL
|
| - && (strcmp (h->root.root.string, "_DYNAMIC") == 0
|
| + && (h == htab->elf.hdynamic
|
| || (!htab->is_vxworks
|
| && (h == htab->elf.hgot || h == htab->elf.hplt))))
|
| sym->st_shndx = SHN_ABS;
|
| @@ -4718,7 +4745,7 @@ finish_local_dynamic_symbol (void **slot, void *inf)
|
| struct elf_link_hash_entry *h
|
| = (struct elf_link_hash_entry *) *slot;
|
| struct bfd_link_info *info
|
| - = (struct bfd_link_info *) inf;
|
| + = (struct bfd_link_info *) inf;
|
|
|
| return _bfd_sparc_elf_finish_dynamic_symbol (info->output_bfd, info,
|
| h, NULL);
|
| @@ -4766,9 +4793,10 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i
|
| }
|
| }
|
|
|
| - elf_section_data (splt->output_section)->this_hdr.sh_entsize
|
| - = (htab->is_vxworks || !ABI_64_P (output_bfd))
|
| - ? 0 : htab->plt_entry_size;
|
| + if (elf_section_data (splt->output_section) != NULL)
|
| + elf_section_data (splt->output_section)->this_hdr.sh_entsize
|
| + = ((htab->is_vxworks || !ABI_64_P (output_bfd))
|
| + ? 0 : htab->plt_entry_size);
|
| }
|
|
|
| /* Set the first entry in the global offset table to the address of
|
| @@ -4882,6 +4910,7 @@ _bfd_sparc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
|
| out_attr = &out_attrs[Tag_GNU_Sparc_HWCAPS];
|
|
|
| out_attr->i |= in_attr->i;
|
| + out_attr->type = 1;
|
|
|
| /* Merge Tag_compatibility attributes and any common GNU ones. */
|
| _bfd_elf_merge_object_attributes (ibfd, obfd);
|
|
|