diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2004-04-21 07:14:15 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@libertysurf.fr> | 2004-04-21 07:14:15 +0000 |
commit | 715df9b8e05846e1e01e03ba01ff9877964331a3 (patch) | |
tree | a1f63aabbb602c04567e7ec7c83c3f51577b1301 /bfd | |
parent | 58434bc1b4c4db2fc376b7a705d1b6a89e8eadb8 (diff) | |
download | gdb-715df9b8e05846e1e01e03ba01ff9877964331a3.zip gdb-715df9b8e05846e1e01e03ba01ff9877964331a3.tar.gz 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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elflink.c | 42 |
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; + } } } |