aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elfxx-sparc.c67
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. */