From: Alan Modra Date: Thu, 29 Jan 2015 09:08:28 +0000 (+1030) Subject: Don't segfault or assert on NULL tls_sec X-Git-Tag: binutils-2_25_1~222 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=41b7d3b8459ab326fe1703ae14203c06de97205a;p=thirdparty%2Fbinutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 45f9c699d68..79f333af9ee 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,12 @@ 2015-02-11 Alan Modra Apply from master. + 2015-02-09 Alan Modra + * 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-01-29 Alan Modra * elf64-ppc.c (ppc64_elf_relocate_section): Correct GOT_TLSLD optimization. Tidy mask for GOT_TLSGD optimization. diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 57d634951ab..83f8452d2a1 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -8215,7 +8215,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++ @@ -8233,9 +8238,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)) { @@ -8321,7 +8331,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 @@ -8345,18 +8356,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 2cff63e70dd..3b64f9a16db 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -14110,7 +14110,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++ @@ -14127,9 +14132,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)) { @@ -14262,7 +14272,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 @@ -14282,7 +14293,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: @@ -14297,11 +14309,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 d1d36db68d3..9f4ee0eb02e 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); - } } } }