/* SPARC-specific support for ELF
- Copyright (C) 2005-2018 Free Software Foundation, Inc.
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
break;
}
/* xgettext:c-format */
- _bfd_error_handler (_("%pB: invalid BFD relocation type %d"), abfd, (int) code);
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
bfd_set_error (bfd_error_bad_value);
return NULL;
}
if ((cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, r_type)) == NULL)
{
- _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
- abfd, r_type);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
#define GOT_TLS_IE 3
unsigned char tls_type;
- /* Symbol has GOT or PLT relocations. */
+ /* Symbol has GOT or PLT relocations. */
unsigned int has_got_reloc : 1;
+ /* Symbol has old-style, non-relaxable GOT relocations. */
+ unsigned int has_old_style_got_reloc : 1;
+
/* Symbol has non-GOT/non-PLT relocations in text sections. */
unsigned int has_non_got_reloc : 1;
&& r_type != R_SPARC_GOTDATA_OP_LOX10)
local_got_refcounts[r_symndx] += 1;
- old_tls_type = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
+ old_tls_type
+ = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
}
- /* If a TLS symbol is accessed using IE at least once, there is no point
- in using the dynamic model for it. */
+ /* If a TLS symbol is accessed using IE at least once, there is no
+ point in using the dynamic model for it. */
if (old_tls_type != tls_type)
{
if (old_tls_type == GOT_UNKNOWN)
return FALSE;
if (eh != NULL)
- eh->has_got_reloc = 1;
+ {
+ eh->has_got_reloc = 1;
+ if (r_type == R_SPARC_GOT10
+ || r_type == R_SPARC_GOT13
+ || r_type == R_SPARC_GOT22)
+ eh->has_old_style_got_reloc = 1;
+ }
break;
case R_SPARC_TLS_GD_CALL:
break;
case R_SPARC_GNU_VTENTRY:
- BFD_ASSERT (h != NULL);
- if (h != NULL
- && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
if ((input_section->flags & SEC_ALLOC) == 0
|| h->plt.offset == (bfd_vma) -1)
- abort ();
+ {
+ /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+ STT_GNU_IFUNC symbol as STT_FUNC. */
+ if (elf_section_type (input_section) == SHT_NOTE)
+ goto skip_ifunc;
+ abort ();
+ }
plt_sec = htab->elf.splt;
if (! plt_sec)
}
}
+ skip_ifunc:
eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
resolved_to_zero = eh && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
/* If the symbol is global but not dynamic, an .rela.* slot has
- been allocated for it in the GOT so output R_SPARC_NONE here.
- See also the handling of other GOT relocations just below. */
+ been allocated for it in the GOT so output R_SPARC_NONE here,
+ if it isn't also subject to another, old-style GOT relocation.
+ See also the handling of these GOT relocations just below. */
if (h != NULL
&& h->dynindx == -1
&& !h->forced_local
&& h->root.type != bfd_link_hash_undefweak
+ && !eh->has_old_style_got_reloc
&& (h->got.offset & 1) == 0
&& bfd_link_pic (info))
{
BFD_ASSERT (htab != NULL);
dynobj = htab->elf.dynobj;
+ /* We arranged in size_dynamic_sections to put the STT_REGISTER
+ entries at the end of the dynlocal list, so they came at the end
+ of the local symbols in the symtab. Except that they aren't
+ STB_LOCAL, so we need to back up symtab->sh_info. */
+ if (ABI_64_P (output_bfd)
+ && elf_hash_table (info)->dynlocal)
+ {
+ asection *dynsymsec = bfd_get_linker_section (dynobj, ".dynsym");
+ struct elf_link_local_dynamic_entry *e;
+
+ for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
+ if (e->input_indx == -1)
+ break;
+ if (e)
+ elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
+ = e->dynindx;
+ }
+
sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)