diff options
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 67 |
2 files changed, 57 insertions, 20 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5045c81..7195221 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-06-29 Egeyar Bagcioglu <egeyar.bagcioglu@oracle.com> + + * elfxx-sparc.c (allocate_dynrelocs): Don't make a symbol dynamic + unless it is undefined weak. + * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Set the flag + relative_reloc to direct non-dynamic symbols to R_SPARC_RELATIVE + relocation. + * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_symbol): If symbol + is not dynamic in PIC, abort. + 2017-06-29 Jiong Wang <jiong.wang@arm.com> PR ld/21402 diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index a9362a3..1fd2141 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2310,7 +2310,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 && !h->forced_local - && !resolved_to_zero) + && !resolved_to_zero + && h->root.type == bfd_link_hash_undefweak) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -2422,7 +2423,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 && !h->forced_local - && !resolved_to_zero) + && !resolved_to_zero + && h->root.type == bfd_link_hash_undefweak) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -2564,7 +2566,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 && !h->forced_local - && !resolved_to_zero) + && !resolved_to_zero + && h->root.type == bfd_link_hash_undefweak) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -3125,6 +3128,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, bfd_boolean is_plt = FALSE; bfd_boolean unresolved_reloc; bfd_boolean resolved_to_zero; + bfd_boolean relative_reloc; r_type = SPARC_ELF_R_TYPE (rel->r_info); if (r_type == R_SPARC_GNU_VTINHERIT @@ -3349,6 +3353,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, if (htab->elf.sgot == NULL) abort (); + relative_reloc = FALSE; if (h != NULL) { bfd_boolean dyn; @@ -3382,6 +3387,16 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, SPARC_ELF_PUT_WORD (htab, output_bfd, relocation, htab->elf.sgot->contents + off); h->got.offset |= 1; + + if (h->dynindx == -1 + && !h->forced_local + && h->root.type != bfd_link_hash_undefweak + && bfd_link_pic (info)) + { + /* If this symbol isn't dynamic in PIC + generate R_SPARC_RELATIVE here. */ + relative_reloc = TRUE; + } } } else @@ -3401,25 +3416,9 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, off &= ~1; else { - if (bfd_link_pic (info)) { - asection *s; - Elf_Internal_Rela outrel; - - /* We need to generate a R_SPARC_RELATIVE reloc - for the dynamic linker. */ - s = htab->elf.srelgot; - BFD_ASSERT (s != NULL); - - outrel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset - + off); - outrel.r_info = SPARC_ELF_R_INFO (htab, NULL, - 0, R_SPARC_RELATIVE); - outrel.r_addend = relocation; - relocation = 0; - sparc_elf_append_rela (output_bfd, s, &outrel); + relative_reloc = TRUE; } SPARC_ELF_PUT_WORD (htab, output_bfd, relocation, @@ -3427,6 +3426,27 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, local_got_offsets[r_symndx] |= 1; } } + + if (relative_reloc) + { + asection *s; + Elf_Internal_Rela outrel; + + /* We need to generate a R_SPARC_RELATIVE reloc + for the dynamic linker. */ + s = htab->elf.srelgot; + BFD_ASSERT (s != NULL); + + outrel.r_offset = (htab->elf.sgot->output_section->vma + + htab->elf.sgot->output_offset + + off); + outrel.r_info = SPARC_ELF_R_INFO (htab, NULL, + 0, R_SPARC_RELATIVE); + outrel.r_addend = relocation; + relocation = 0; + sparc_elf_append_rela (output_bfd, s, &outrel); + } + relocation = htab->elf.sgot->output_offset + off - got_base; break; @@ -4482,6 +4502,13 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd, eh = (struct _bfd_sparc_elf_link_hash_entry *) h; + /* Abort if the symbol is not dynamic in PIC */ + if (h->dynindx == -1 + && !h->forced_local + && h->root.type != bfd_link_hash_undefweak + && bfd_link_pic (info)) + abort(); + /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for resolved undefined weak symbols in executable so that their references have value 0 at run-time. */ |