This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: ld --as-needed assertion fail, BFD internal error and crash
I made an elementary mistake, forgetting that warning symbols replace
their "real" symbol, so you don't find the real symbol on a hash
traversal. Not saving and restoring these symbols led to the
segfault.
* elflink.c (elf_link_add_object_symbols): Save and restore
warning sym's linked sym.
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.205
diff -u -p -r1.205 elflink.c
--- bfd/elflink.c 16 Mar 2006 12:20:14 -0000 1.205
+++ bfd/elflink.c 17 Mar 2006 02:57:00 -0000
@@ -3457,9 +3457,15 @@ elf_link_add_object_symbols (bfd *abfd,
for (entsize = 0, i = 0; i < htab->root.table.size; i++)
{
struct bfd_hash_entry *p;
+ struct elf_link_hash_entry *h;
for (p = htab->root.table.table[i]; p != NULL; p = p->next)
- entsize += htab->root.table.entsize;
+ {
+ h = (struct elf_link_hash_entry *) p;
+ entsize += htab->root.table.entsize;
+ if (h->root.type == bfd_link_hash_warning)
+ entsize += htab->root.table.entsize;
+ }
}
tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *);
@@ -3487,11 +3493,18 @@ elf_link_add_object_symbols (bfd *abfd,
for (i = 0; i < htab->root.table.size; i++)
{
struct bfd_hash_entry *p;
+ struct elf_link_hash_entry *h;
for (p = htab->root.table.table[i]; p != NULL; p = p->next)
{
memcpy (old_ent, p, htab->root.table.entsize);
old_ent = (char *) old_ent + htab->root.table.entsize;
+ h = (struct elf_link_hash_entry *) p;
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ memcpy (old_ent, h->root.u.i.link, htab->root.table.entsize);
+ old_ent = (char *) old_ent + htab->root.table.entsize;
+ }
}
}
}
@@ -4124,10 +4137,19 @@ elf_link_add_object_symbols (bfd *abfd,
for (p = htab->root.table.table[i]; p != NULL; p = p->next)
{
h = (struct elf_link_hash_entry *) p;
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
if (h->dynindx >= old_dynsymcount)
_bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index);
+
memcpy (p, old_ent, htab->root.table.entsize);
old_ent = (char *) old_ent + htab->root.table.entsize;
+ h = (struct elf_link_hash_entry *) p;
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize);
+ old_ent = (char *) old_ent + htab->root.table.entsize;
+ }
}
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre