diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 26 |
2 files changed, 30 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 426561a..dd6ccab 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2018-03-28 Eric Botcazou <ebotcazou@adacore.com> + + PR ld/22972 + * elfxx-sparc.c (struct _bfd_sparc_elf_link_hash_entry): Add new flag + has_old_style_got_reloc. + (_bfd_sparc_elf_check_relocs) <GOT relocations>: Set it for old-style + relocations. Fix a couple of long lines. + (_bfd_sparc_elf_relocate_section) <R_SPARC_GOTDATA_OP>: Do not generate + a R_SPARC_NONE for the GOT slot if the symbol is also subject to old-style + GOT relocations. + 2018-03-25 H.J. Lu <hongjiu.lu@intel.com> PR ld/23000 diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 849182f..81812af 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -701,9 +701,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; @@ -1569,11 +1572,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) @@ -1603,7 +1607,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: @@ -3138,12 +3148,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)) { |