/* 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.
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;
s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ || !bfd_set_section_alignment (s, bed->plt_alignment))
return FALSE;
htab->iplt = s;
s = bfd_make_section_with_flags (abfd, ".rela.iplt",
flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s,
- bed->s->log_file_align))
+ || !bfd_set_section_alignment (s, bed->s->log_file_align))
return FALSE;
htab->irelplt = s;
&& 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))
{
|| r_type == R_SPARC_UA32
|| r_type == R_SPARC_DISP32)
&& (((input_section->flags & SEC_DEBUGGING) != 0
- && strcmp (bfd_section_name (input_bfd,
- input_section),
+ && strcmp (bfd_section_name (input_section),
".stab") == 0)
|| _bfd_elf_section_offset (output_bfd, info,
input_section,
if (name == NULL)
return FALSE;
if (*name == '\0')
- name = bfd_section_name (input_bfd, sec);
+ name = bfd_section_name (sec);
}
(*info->callbacks->reloc_overflow)
(info, (h ? &h->root : NULL), name, howto->name,
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)