From 715df9b8e05846e1e01e03ba01ff9877964331a3 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 21 Apr 2004 07:14:15 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 9 +++++++++ bfd/elflink.c | 42 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bff42748257..10e322e48a7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2004-04-21 Eric Botcazou + + * 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 * reloc.c: Add BFD_RELOC_32_SECREL. diff --git a/bfd/elflink.c b/bfd/elflink.c index 6628db34cce..38a89fd6fe1 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; + } } } -- 2.30.2