This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
alpha relaxation fixes
- From: Richard Henderson <rth at twiddle dot net>
- To: binutils at gcc dot gnu dot org
- Date: Wed, 25 May 2005 13:06:00 -0700
- Subject: alpha relaxation fixes
I have a patch to turn on relaxation with ld -O, which is default
with gcc -O. It turned up some failures bootstrapping gcc.
This was caused by gotent's getting lost, and still being attached
to got subsections that have been merged and discarded. Every time
through the relaxation loop, these discarded subsections would
double in size. Sort of the inverse of relaxation. Oops.
r~
* elf64-alpha.c (elf64_alpha_merge_gots): Fix gotent iteration
in the presence of deleting elements.
(elf64_alpha_size_got_sections): Zero dead got section size.
Index: elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.135
diff -u -p -d -r1.135 elf64-alpha.c
--- elf64-alpha.c 23 May 2005 01:26:58 -0000 1.135
+++ elf64-alpha.c 25 May 2005 19:57:52 -0000
@@ -3523,16 +3523,17 @@ elf64_alpha_merge_gots (a, b)
|| h->root.root.type == bfd_link_hash_warning)
h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
- start = &h->got_entries;
- for (pbe = start, be = *start; be ; pbe = &be->next, be = be->next)
+ pbe = start = &h->got_entries;
+ while ((be = *pbe) != NULL)
{
if (be->use_count == 0)
{
*pbe = be->next;
- continue;
+ memset (be, 0xa5, sizeof (*be));
+ goto kill;
}
if (be->gotobj != b)
- continue;
+ goto next;
for (ae = *start; ae ; ae = ae->next)
if (ae->gotobj == a
@@ -3542,12 +3543,15 @@ elf64_alpha_merge_gots (a, b)
ae->flags |= be->flags;
ae->use_count += be->use_count;
*pbe = be->next;
- goto global_found;
+ memset (be, 0xa5, sizeof (*be));
+ goto kill;
}
be->gotobj = a;
total += alpha_got_entry_size (be->reloc_type);
- global_found:;
+ next:;
+ pbe = &be->next;
+ kill:;
}
}
@@ -3703,8 +3707,11 @@ elf64_alpha_size_got_sections (info)
if (elf64_alpha_can_merge_gots (cur_got_obj, i))
{
elf64_alpha_merge_gots (cur_got_obj, i);
+
+ alpha_elf_tdata(i)->got->size = 0;
i = alpha_elf_tdata(i)->got_link_next;
alpha_elf_tdata(cur_got_obj)->got_link_next = i;
+
something_changed = 1;
}
else