summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2013-01-31 07:32:44 +0000
committerAlan Modra <amodra@bigpond.net.au>2013-01-31 07:32:44 +0000
commitec8b361c688b220ed5392aa14c50cca04da28fe0 (patch)
tree4fe5f10ff43a44fac2839de970c42ca2dff4f64d
parentd08f6e9e44366b755fc0ce32d96f18225e1891fd (diff)
downloadgdb-ec8b361c688b220ed5392aa14c50cca04da28fe0.tar.gz
PR ld/15056
* elfxx-sparc.c (_bfd_sparc_elf_gc_mark_hook): Handle implicit references to __tls_get_addr. * elf32-tilpro.c (tilepro_elf_gc_mark_hook): Likewise. Correct vtinherit and vtentry reloc handling too. * elfxx-tilegx.c (tilegx_elf_gc_mark_hook): As for tilepro.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elf32-tilepro.c32
-rw-r--r--bfd/elfxx-sparc.c23
-rw-r--r--bfd/elfxx-tilegx.c32
4 files changed, 87 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9598b6a50c4..c53af4ba489 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,4 +1,14 @@
2013-01-31 Alan Modra <amodra@gmail.com>
+ David S. Miller <davem@davemloft.net>
+
+ PR ld/15056
+ * elfxx-sparc.c (_bfd_sparc_elf_gc_mark_hook): Handle implicit
+ references to __tls_get_addr.
+ * elf32-tilpro.c (tilepro_elf_gc_mark_hook): Likewise. Correct
+ vtinherit and vtentry reloc handling too.
+ * elfxx-tilegx.c (tilegx_elf_gc_mark_hook): As for tilepro.
+
+2013-01-31 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc_stub_name): Trim off trailing "+0".
diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c
index fc49e2b816d..db37403b7f8 100644
--- a/bfd/elf32-tilepro.c
+++ b/bfd/elf32-tilepro.c
@@ -1868,11 +1868,33 @@ tilepro_elf_gc_mark_hook (asection *sec,
if (h != NULL)
{
switch (ELF32_R_TYPE (rel->r_info))
- {
- case R_TILEPRO_GNU_VTINHERIT:
- case R_TILEPRO_GNU_VTENTRY:
- break;
- }
+ {
+ case R_TILEPRO_GNU_VTINHERIT:
+ case R_TILEPRO_GNU_VTENTRY:
+ return NULL;
+ }
+ }
+
+ /* FIXME: The test here, in check_relocs and in relocate_section
+ dealing with TLS optimization, ought to be !info->executable. */
+ if (info->shared)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_TILEPRO_TLS_GD_CALL:
+ /* This reloc implicitly references __tls_get_addr. We know
+ another reloc will reference the same symbol as the one
+ on this reloc, so the real symbol and section will be
+ gc marked when processing the other reloc. That lets
+ us handle __tls_get_addr here. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ h->mark = 1;
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ sym = NULL;
+ }
}
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 196d566aa99..9684ffd7a4d 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1873,6 +1873,29 @@ _bfd_sparc_elf_gc_mark_hook (asection *sec,
return NULL;
}
+ /* FIXME: The test here, in check_relocs and in relocate_section
+ dealing with TLS optimization, ought to be !info->executable. */
+ if (info->shared)
+ {
+ switch (SPARC_ELF_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_TLS_GD_CALL:
+ case R_SPARC_TLS_LDM_CALL:
+ /* This reloc implicitly references __tls_get_addr. We know
+ another reloc will reference the same symbol as the one
+ on this reloc, so the real symbol and section will be
+ gc marked when processing the other reloc. That lets
+ us handle __tls_get_addr here. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ h->mark = 1;
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ sym = NULL;
+ }
+ }
+
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c
index b28d1a875a5..cd92bf9a875 100644
--- a/bfd/elfxx-tilegx.c
+++ b/bfd/elfxx-tilegx.c
@@ -2107,11 +2107,33 @@ tilegx_elf_gc_mark_hook (asection *sec,
if (h != NULL)
{
switch (TILEGX_ELF_R_TYPE (rel->r_info))
- {
- case R_TILEGX_GNU_VTINHERIT:
- case R_TILEGX_GNU_VTENTRY:
- break;
- }
+ {
+ case R_TILEGX_GNU_VTINHERIT:
+ case R_TILEGX_GNU_VTENTRY:
+ return NULL;
+ }
+ }
+
+ /* FIXME: The test here, in check_relocs and in relocate_section
+ dealing with TLS optimization, ought to be !info->executable. */
+ if (info->shared)
+ {
+ switch (TILEGX_ELF_R_TYPE (rel->r_info))
+ {
+ case R_TILEGX_TLS_GD_CALL:
+ /* This reloc implicitly references __tls_get_addr. We know
+ another reloc will reference the same symbol as the one
+ on this reloc, so the real symbol and section will be
+ gc marked when processing the other reloc. That lets
+ us handle __tls_get_addr here. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ h->mark = 1;
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ sym = NULL;
+ }
}
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);