summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-01-29 19:38:28 +1030
committerAlan Modra <amodra@gmail.com>2015-02-09 14:06:27 +1030
commit989f98793c06132bb5cdc2f7807b7eee5108342f (patch)
tree55837e1e0a367fa4492dcde295e84c9ed2465cef
parentca4be51cd81b0bfff2ada60c98e7c67c936045b7 (diff)
downloadbinutils-gdb-989f98793c06132bb5cdc2f7807b7eee5108342f.tar.gz
Don't segfault or assert on NULL tls_sec
Real code won't hit these, but it's possible to contrive a testcase.. * elf32-ppc.c (ppc_elf_relocate_section): Don't segfault on NULL tls_sec. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elflink.c (elf_link_output_extsym): Don't assert on NULL tls_sec.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-ppc.c30
-rw-r--r--bfd/elf64-ppc.c30
-rw-r--r--bfd/elflink.c6
4 files changed, 51 insertions, 22 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 434a40378d9..21ce154ddc5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
2015-02-09 Alan Modra <amodra@gmail.com>
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't segfault on NULL
+ tls_sec.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elflink.c (elf_link_output_extsym): Don't assert on NULL tls_sec.
+
+2015-02-09 Alan Modra <amodra@gmail.com>
+
* elflink.c: Whitespace, formatting fixes.
(elf_link_input_bfd): Clarify comment.
(elf_link_output_extsym): Exclude symbols in linker created
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 640ced978cb..8d8167a4253 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -8221,7 +8221,12 @@ ppc_elf_relocate_section (bfd *output_bfd,
{
outrel.r_addend += relocation;
if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
- outrel.r_addend -= htab->elf.tls_sec->vma;
+ {
+ if (htab->elf.tls_sec == NULL)
+ outrel.r_addend = 0;
+ else
+ outrel.r_addend -= htab->elf.tls_sec->vma;
+ }
}
loc = rsec->contents;
loc += (rsec->reloc_count++
@@ -8239,9 +8244,14 @@ ppc_elf_relocate_section (bfd *output_bfd,
value = 1;
else if (tls_ty != 0)
{
- value -= htab->elf.tls_sec->vma + DTP_OFFSET;
- if (tls_ty == (TLS_TLS | TLS_TPREL))
- value += DTP_OFFSET - TP_OFFSET;
+ if (htab->elf.tls_sec == NULL)
+ value = 0;
+ else
+ {
+ value -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (tls_ty == (TLS_TLS | TLS_TPREL))
+ value += DTP_OFFSET - TP_OFFSET;
+ }
if (tls_ty == (TLS_TLS | TLS_GD))
{
@@ -8327,7 +8337,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
case R_PPC_DTPREL16_LO:
case R_PPC_DTPREL16_HI:
case R_PPC_DTPREL16_HA:
- addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
break;
/* Relocations that may need to be propagated if this is a shared
@@ -8351,18 +8362,21 @@ ppc_elf_relocate_section (bfd *output_bfd,
bfd_put_32 (output_bfd, insn, p);
break;
}
- addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
/* The TPREL16 relocs shouldn't really be used in shared
libs as they will result in DT_TEXTREL being set, but
support them anyway. */
goto dodyn;
case R_PPC_TPREL32:
- addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
goto dodyn;
case R_PPC_DTPREL32:
- addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
goto dodyn;
case R_PPC_DTPMOD32:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index d597fec59a3..f821231d64a 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -14121,7 +14121,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
{
outrel.r_addend += relocation;
if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL))
- outrel.r_addend -= htab->elf.tls_sec->vma;
+ {
+ if (htab->elf.tls_sec == NULL)
+ outrel.r_addend = 0;
+ else
+ outrel.r_addend -= htab->elf.tls_sec->vma;
+ }
}
loc = relgot->contents;
loc += (relgot->reloc_count++
@@ -14138,9 +14143,14 @@ ppc64_elf_relocate_section (bfd *output_bfd,
relocation = 1;
else if (tls_type != 0)
{
- relocation -= htab->elf.tls_sec->vma + DTP_OFFSET;
- if (tls_type == (TLS_TLS | TLS_TPREL))
- relocation += DTP_OFFSET - TP_OFFSET;
+ if (htab->elf.tls_sec == NULL)
+ relocation = 0;
+ else
+ {
+ relocation -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (tls_type == (TLS_TLS | TLS_TPREL))
+ relocation += DTP_OFFSET - TP_OFFSET;
+ }
if (tls_type == (TLS_TLS | TLS_GD))
{
@@ -14273,7 +14283,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
bfd_put_32 (output_bfd, insn, p);
break;
}
- addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
if (info->shared)
/* The TPREL16 relocs shouldn't really be used in shared
libs as they will result in DT_TEXTREL being set, but
@@ -14293,7 +14304,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_DTPREL16_HIGHERA:
case R_PPC64_DTPREL16_HIGHEST:
case R_PPC64_DTPREL16_HIGHESTA:
- addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
break;
case R_PPC64_ADDR64_LOCAL:
@@ -14308,11 +14320,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
goto dodyn;
case R_PPC64_TPREL64:
- addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
goto dodyn;
case R_PPC64_DTPREL64:
- addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (htab->elf.tls_sec != NULL)
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
/* Fall thru */
/* Relocations that may need to be propagated if this is a
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 409be0c6083..16d9f20a40f 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -9042,12 +9042,6 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
asection *tls_sec = elf_hash_table (flinfo->info)->tls_sec;
if (tls_sec != NULL)
sym.st_value -= tls_sec->vma;
- else
- {
- /* The TLS section may have been garbage collected. */
- BFD_ASSERT (flinfo->info->gc_sections
- && !input_sec->gc_mark);
- }
}
}
}