alpha relaxation fixes
Richard Henderson
rth@twiddle.net
Wed May 25 20:15:00 GMT 2005
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
More information about the Binutils
mailing list