aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2004-04-21 07:14:15 +0000
committerEric Botcazou <ebotcazou@libertysurf.fr>2004-04-21 07:14:15 +0000
commit715df9b8e05846e1e01e03ba01ff9877964331a3 (patch)
treea1f63aabbb602c04567e7ec7c83c3f51577b1301
parent58434bc1b4c4db2fc376b7a705d1b6a89e8eadb8 (diff)
downloadfsf-binutils-gdb-715df9b8e05846e1e01e03ba01ff9877964331a3.zip
fsf-binutils-gdb-715df9b8e05846e1e01e03ba01ff9877964331a3.tar.gz
fsf-binutils-gdb-715df9b8e05846e1e01e03ba01ff9877964331a3.tar.bz2
* elflink.c (elf_gc_mark_dynamic_ref_symbol): New function.
(bfd_elf_gc_sections): Fail if a shared object is being created. Do not fail if dynamic sections have been created. Instead call elf_gc_mark_dynamic_ref_symbol to mark sections that contain dynamically referenced symbols. Do not mark the whole graph rooted at .eh_frame, only the section proper.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elflink.c42
2 files changed, 46 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bff4274..10e322e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2004-04-21 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * elflink.c (elf_gc_mark_dynamic_ref_symbol): New function.
+ (bfd_elf_gc_sections): Fail if a shared object is being created.
+ Do not fail if dynamic sections have been created. Instead call
+ elf_gc_mark_dynamic_ref_symbol to mark sections that contain
+ dynamically referenced symbols. Do not mark the whole graph
+ rooted at .eh_frame, only the section proper.
+
2004-04-20 DJ Delorie <dj@redhat.com>
* reloc.c: Add BFD_RELOC_32_SECREL.
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6628db3..38a89fd 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8412,6 +8412,24 @@ elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
return TRUE;
}
+/* Mark sections containing dynamically referenced symbols. This is called
+ through elf_link_hash_traverse. */
+
+static bfd_boolean
+elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h,
+ void *okp ATTRIBUTE_UNUSED)
+{
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC))
+ h->root.u.def.section->flags |= SEC_KEEP;
+
+ return TRUE;
+}
+
/* Do mark and sweep of unused sections. */
bfd_boolean
@@ -8426,8 +8444,8 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
if (!get_elf_backend_data (abfd)->can_gc_sections
|| info->relocatable
|| info->emitrelocations
- || !is_elf_hash_table (info->hash)
- || elf_hash_table (info)->dynamic_sections_created)
+ || info->shared
+ || !is_elf_hash_table (info->hash))
{
(*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
return TRUE;
@@ -8447,8 +8465,15 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
if (!ok)
return FALSE;
- /* Grovel through relocs to find out who stays ... */
+ /* Mark dynamically referenced symbols. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_mark_dynamic_ref_symbol,
+ &ok);
+ if (!ok)
+ return FALSE;
+ /* Grovel through relocs to find out who stays ... */
gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
{
@@ -8460,8 +8485,15 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
for (o = sub->sections; o != NULL; o = o->next)
{
if (o->flags & SEC_KEEP)
- if (!elf_gc_mark (info, o, gc_mark_hook))
- return FALSE;
+ {
+ /* _bfd_elf_discard_section_eh_frame knows how to discard
+ orphaned FDEs so don't mark sections referenced by the
+ EH frame section. */
+ if (strcmp (o->name, ".eh_frame") == 0)
+ o->gc_mark = 1;
+ else if (!elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ }
}
}