From 0fb7012e88683b8bd67a4fb8f782359fa0e11724 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 19 Oct 2017 05:18:07 -0700 Subject: [PATCH] sparc: Check bfd_link_executable for TLS check Copied from x86, check bfd_link_executable, instead of bfd_link_pic, for TLS transition check. Not sure if it works correctly. All usages of bfd_link_pic should be audited. PR ld/22263 * elfxx-sparc.c (sparc_elf_tls_transition): Replace bfd_link_pic with !bfd_link_executable, !bfd_link_pic with bfd_link_executable for TLS check. (_bfd_sparc_elf_check_relocs): Likewise. (allocate_dynrelocs): Likewise. (_bfd_sparc_elf_relocate_section): Likewise. --- bfd/ChangeLog | 10 ++++++++++ bfd/elfxx-sparc.c | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a300d1c427..303159b049 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-10-18 H.J. Lu + + PR ld/22263 + * elfxx-sparc.c (sparc_elf_tls_transition): Replace + bfd_link_pic with !bfd_link_executable, !bfd_link_pic with + bfd_link_executable for TLS check. + (_bfd_sparc_elf_check_relocs): Likewise. + (allocate_dynrelocs): Likewise. + (_bfd_sparc_elf_relocate_section): Likewise. + 2017-10-18 H.J. Lu * elf32-tilepro.c (tilepro_elf_gc_mark_hook): Call diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 54dea7b450..873062d23d 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -1353,7 +1353,7 @@ sparc_elf_tls_transition (struct bfd_link_info *info, bfd *abfd, && ! _bfd_sparc_elf_tdata (abfd)->has_tlsgd) r_type = R_SPARC_REV32; - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) return r_type; switch (r_type) @@ -1529,13 +1529,13 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_LOX10: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) goto r_sparc_plt32; break; case R_SPARC_TLS_IE_HI22: case R_SPARC_TLS_IE_LO10: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) info->flags |= DF_STATIC_TLS; /* Fall through */ @@ -1649,7 +1649,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_SPARC_TLS_GD_CALL: case R_SPARC_TLS_LDM_CALL: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) { /* These are basically R_SPARC_TLS_WPLT30 relocs against __tls_get_addr. */ @@ -2249,7 +2249,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) /* If R_SPARC_TLS_IE_{HI22,LO10} symbol is now local to the binary, make it a R_SPARC_TLS_LE_{HI22,LO10} requiring no TLS entry. */ if (h->got.refcount > 0 - && !bfd_link_pic (info) + && bfd_link_executable (info) && h->dynindx == -1 && _bfd_sparc_elf_hash_entry(h)->tls_type == GOT_TLS_IE) h->got.offset = (bfd_vma) -1; @@ -3591,7 +3591,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, else if (h != NULL) { tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type; - if (!bfd_link_pic (info) + if (bfd_link_executable (info) && h->dynindx == -1 && tls_type == GOT_TLS_IE) switch (SPARC_ELF_R_TYPE (rel->r_info)) @@ -3738,7 +3738,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_LOX10: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) { Elf_Internal_Rela outrel; bfd_boolean skip; @@ -3770,7 +3770,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, break; case R_SPARC_TLS_LDM_CALL: - if (! bfd_link_pic (info)) + if (bfd_link_executable (info)) { /* mov %g0, %o0 */ bfd_put_32 (output_bfd, 0x90100000, contents + rel->r_offset); @@ -3784,7 +3784,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx]; else if (h != NULL) tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type; - if (! bfd_link_pic (info) + if (bfd_link_executable (info) || (r_type == R_SPARC_TLS_GD_CALL && tls_type == GOT_TLS_IE)) { Elf_Internal_Rela *rel2; @@ -3893,7 +3893,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, case R_SPARC_TLS_IE_LD: case R_SPARC_TLS_IE_LDX: - if (! bfd_link_pic (info) && (h == NULL || h->dynindx == -1)) + if (bfd_link_executable (info) && (h == NULL || h->dynindx == -1)) { bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset); int rs2 = insn & 0x1f; -- 2.34.1