This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: SPU overlay update
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Tue, 11 Mar 2008 20:02:20 +1030
- Subject: Re: SPU overlay update
- References: <20080128055644.GA9974@bubble.grove.modra.org>
My 2008-01-28 changes to elf32-spu.c introduced a bug that could cause
a ld segfault in spu_elf_relocate_section when elf_local_got_ents was
accessed. Simply testing for a NULL would be sufficient to cure the
bug, but I think it's better to protect the access by using the same
logic as that used when setting up elf_local_got_ents. Doing so also
cures another bug that could be tickled by data that happened to look
like a branch.
* elf32-spu.c (spu_elf_relocate_section): Test identical conditions
to those in process_stubs for overlay symbols.
Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.31
diff -c -p -r1.31 elf32-spu.c
*** bfd/elf32-spu.c 3 Mar 2008 10:03:40 -0000 1.31
--- bfd/elf32-spu.c 11 Mar 2008 09:29:20 -0000
*************** spu_elf_relocate_section (bfd *output_bf
*** 2708,2714 ****
bfd_reloc_status_type r;
bfd_boolean unresolved_reloc;
bfd_boolean warned;
- bfd_boolean branch;
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
--- 2708,2713 ----
*************** spu_elf_relocate_section (bfd *output_bf
*** 2769,2801 ****
/* If this symbol is in an overlay area, we may need to relocate
to the overlay stub. */
addend = rel->r_addend;
- branch = (is_branch (contents + rel->r_offset)
- || is_hint (contents + rel->r_offset));
if (htab->stub_sec != NULL
! && needs_ovl_stub (sym_name, sec, input_section, htab, branch)
&& (h == NULL
|| (h != htab->ovly_load && h != htab->ovly_return)))
{
! unsigned int ovl = 0;
! struct got_entry *g, **head;
! if (branch)
! ovl = (spu_elf_section_data (input_section->output_section)
! ->u.o.ovl_index);
if (h != NULL)
! head = &h->got.glist;
else
! head = elf_local_got_ents (input_bfd) + r_symndx;
! for (g = *head; g != NULL; g = g->next)
! if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
! break;
! if (g == NULL)
! abort ();
! relocation = g->stub_addr;
! addend = 0;
}
r = _bfd_final_link_relocate (howto,
--- 2768,2818 ----
/* If this symbol is in an overlay area, we may need to relocate
to the overlay stub. */
addend = rel->r_addend;
if (htab->stub_sec != NULL
! && sec != NULL
! && sec->output_section != NULL
! && sec->output_section->owner == output_bfd
&& (h == NULL
|| (h != htab->ovly_load && h != htab->ovly_return)))
{
! bfd_boolean branch;
! unsigned int sym_type;
! branch = FALSE;
! if (r_type == R_SPU_REL16
! || r_type == R_SPU_ADDR16)
! branch = (is_branch (contents + rel->r_offset)
! || is_hint (contents + rel->r_offset));
if (h != NULL)
! sym_type = h->type;
else
! sym_type = ELF_ST_TYPE (sym->st_info);
! if ((sym_type == STT_FUNC || branch)
! && needs_ovl_stub (sym_name, sec, input_section, htab, branch))
! {
! unsigned int ovl = 0;
! struct got_entry *g, **head;
! if (branch)
! ovl = (spu_elf_section_data (input_section->output_section)
! ->u.o.ovl_index);
!
! if (h != NULL)
! head = &h->got.glist;
! else
! head = elf_local_got_ents (input_bfd) + r_symndx;
!
! for (g = *head; g != NULL; g = g->next)
! if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
! break;
! if (g == NULL)
! abort ();
!
! relocation = g->stub_addr;
! addend = 0;
! }
}
r = _bfd_final_link_relocate (howto,
--
Alan Modra
Australia Development Lab, IBM