This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PowerPC64 toc edit segfault
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Tue, 8 Feb 2011 13:31:51 +1030
- Subject: PowerPC64 toc edit segfault
This fixes an oversight in the PowerPC64 linker TOC editing code, that
can lead to a segfault. An input object file may have a non-empty
.toc section but no references to the .toc entries. Odd, but possible.
Most likely with user assembly, but might also occur due to compiler
bugs.
Applied mainline and branch.
* elf64-ppc.c (ppc64_elf_edit_toc): Don't segfault on NULL
local_syms when looking for local symbols in .toc.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.340
diff -u -p -r1.340 elf64-ppc.c
--- bfd/elf64-ppc.c 31 Jan 2011 22:38:26 -0000 1.340
+++ bfd/elf64-ppc.c 8 Feb 2011 01:33:46 -0000
@@ -8372,34 +8372,35 @@ ppc64_elf_edit_toc (struct bfd_link_info
/* We shouldn't have local or global symbols defined in the TOC,
but handle them anyway. */
- for (sym = local_syms;
- sym < local_syms + symtab_hdr->sh_info;
- ++sym)
- if (sym->st_value != 0
- && bfd_section_from_elf_index (ibfd, sym->st_shndx) == toc)
- {
- unsigned long i;
+ if (local_syms != NULL)
+ for (sym = local_syms;
+ sym < local_syms + symtab_hdr->sh_info;
+ ++sym)
+ if (sym->st_value != 0
+ && bfd_section_from_elf_index (ibfd, sym->st_shndx) == toc)
+ {
+ unsigned long i;
- if (sym->st_value > toc->rawsize)
- i = toc->rawsize >> 3;
- else
- i = sym->st_value >> 3;
+ if (sym->st_value > toc->rawsize)
+ i = toc->rawsize >> 3;
+ else
+ i = sym->st_value >> 3;
- if ((skip[i] & (ref_from_discarded | can_optimize)) != 0)
- {
- if (local_toc_syms)
- (*_bfd_error_handler)
- (_("%s defined on removed toc entry"),
- bfd_elf_sym_name (ibfd, symtab_hdr, sym, NULL));
- do
- ++i;
- while ((skip[i] & (ref_from_discarded | can_optimize)));
- sym->st_value = (bfd_vma) i << 3;
- }
+ if ((skip[i] & (ref_from_discarded | can_optimize)) != 0)
+ {
+ if (local_toc_syms)
+ (*_bfd_error_handler)
+ (_("%s defined on removed toc entry"),
+ bfd_elf_sym_name (ibfd, symtab_hdr, sym, NULL));
+ do
+ ++i;
+ while ((skip[i] & (ref_from_discarded | can_optimize)));
+ sym->st_value = (bfd_vma) i << 3;
+ }
- sym->st_value -= skip[i];
- symtab_hdr->contents = (unsigned char *) local_syms;
- }
+ sym->st_value -= skip[i];
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
/* Adjust any global syms defined in this toc input section. */
if (toc_inf.global_toc_syms)
--
Alan Modra
Australia Development Lab, IBM