X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felfxx-sparc.c;h=735e83f3de5cc9866d4ed34240aec001626c5136;hb=13bff72615e5a93a6e5f28e83a594125e66ccced;hp=89d3a37626faa94e9a518e7d2c49508d9a3f7583;hpb=2dcf00ce6c001c42c89e6f6baace708b706994f2;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 89d3a37626..735e83f3de 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -1,5 +1,5 @@ /* 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. @@ -311,7 +311,7 @@ static reloc_howto_type sparc_rev32_howto = HOWTO(R_SPARC_REV32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_REV32", FALSE,0,0xffffffff,TRUE); reloc_howto_type * -_bfd_sparc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, +_bfd_sparc_elf_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) { /* We explicitly handle each relocation type in the switch @@ -585,8 +585,10 @@ _bfd_sparc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, default: break; } - bfd_set_error (bfd_error_bad_value); - return NULL; + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code); + bfd_set_error (bfd_error_bad_value); + return NULL; } reloc_howto_type * @@ -595,10 +597,7 @@ _bfd_sparc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int i; - for (i = 0; - i < (sizeof (_bfd_sparc_elf_howto_table) - / sizeof (_bfd_sparc_elf_howto_table[0])); - i++) + for (i = 0; i < ARRAY_SIZE (_bfd_sparc_elf_howto_table); i++) if (_bfd_sparc_elf_howto_table[i].name != NULL && strcasecmp (_bfd_sparc_elf_howto_table[i].name, r_name) == 0) return &_bfd_sparc_elf_howto_table[i]; @@ -614,7 +613,8 @@ _bfd_sparc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, } reloc_howto_type * -_bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type) +_bfd_sparc_elf_info_to_howto_ptr (bfd *abfd ATTRIBUTE_UNUSED, + unsigned int r_type) { switch (r_type) { @@ -636,8 +636,10 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type) default: if (r_type >= (unsigned int) R_SPARC_max_std) { - _bfd_error_handler (_("invalid relocation type %d"), (int) r_type); - r_type = R_SPARC_NONE; + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + bfd_set_error (bfd_error_bad_value); + return NULL; } return &_bfd_sparc_elf_howto_table[r_type]; } @@ -648,13 +650,18 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type) #define SPARC_ELF_R_TYPE(r_info) \ ((r_info) & 0xff) -void -_bfd_sparc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, +bfd_boolean +_bfd_sparc_elf_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { unsigned int r_type = SPARC_ELF_R_TYPE (dst->r_info); - cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type); + if ((cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, r_type)) == NULL) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + return TRUE; } @@ -692,9 +699,12 @@ struct _bfd_sparc_elf_link_hash_entry #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; @@ -1253,15 +1263,14 @@ create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) 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; @@ -1560,11 +1569,12 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, && 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) @@ -1594,7 +1604,13 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, 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: @@ -1820,9 +1836,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, 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; @@ -2992,7 +3006,13 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, 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) @@ -3096,6 +3116,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, } } + skip_ifunc: eh = (struct _bfd_sparc_elf_link_hash_entry *) h; resolved_to_zero = eh && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh); @@ -3122,12 +3143,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, 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)) { @@ -4140,8 +4163,7 @@ do_relocation: || 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, @@ -4170,7 +4192,7 @@ do_relocation: 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, @@ -4767,6 +4789,24 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i 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)