This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: gc sections and .eh_frame
> Great, thanks. I guess looping over the input BFDs would be better.
Right, I think it's the best approach. Not very pretty but it works for me.
* elflink.c (bfd_elf_gc_sections): Mark again the sections rooted
at .eh_frame if the EH tables are not in .gcc_except_table.* sections.
--
Eric Botcazou
Index: elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.136.2.3
diff -u -p -r1.136.2.3 elflink.c
--- elflink.c 27 Apr 2005 16:47:24 -0000 1.136.2.3
+++ elflink.c 10 Jun 2005 11:43:48 -0000
@@ -9031,6 +9031,8 @@ bfd_elf_gc_sections (bfd *abfd, struct b
asection * (*gc_mark_hook)
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+ bfd_boolean has_gcc_except_table = FALSE;
+ asection *eh_frame = NULL;
if (!get_elf_backend_data (abfd)->can_gc_sections
|| info->relocatable
@@ -9081,13 +9083,31 @@ bfd_elf_gc_sections (bfd *abfd, struct b
orphaned FDEs so don't mark sections referenced by the
EH frame section. */
if (strcmp (o->name, ".eh_frame") == 0)
- o->gc_mark = 1;
+ {
+ o->gc_mark = 1;
+ eh_frame = o;
+ }
else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
return FALSE;
}
+
+ /* Detect .gcc_except_table.* sections in the input files. */
+ if (!has_gcc_except_table
+ && strncmp (o->name, ".gcc_except_table", 17) == 0)
+ has_gcc_except_table = TRUE;
}
}
+ /* If we have not detected .gcc_except_table.* sections in the input files,
+ that probably means the target uses a specific section for the EH tables.
+ Play safe and let .eh_frame mark the sections it really needs, since we
+ will not be able to do it explicitly. */
+ if (eh_frame && !has_gcc_except_table)
+ {
+ if (!_bfd_elf_gc_mark (info, eh_frame, gc_mark_hook))
+ return FALSE;
+ }
+
/* ... and mark SEC_EXCLUDE for those that go. */
if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook))
return FALSE;