diff options
author | Alan Modra <amodra@gmail.com> | 2005-06-29 14:05:21 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2005-06-29 14:05:21 +0000 |
commit | 39c2f51bd9f82438706973c4b92597a945d9c4df (patch) | |
tree | 44152730391ea82957bcbc22e60bce18565e60f4 /bfd/elflink.c | |
parent | e8aaee2ad47c086c1c64639df152489eb283b342 (diff) | |
download | gdb-39c2f51bd9f82438706973c4b92597a945d9c4df.zip gdb-39c2f51bd9f82438706973c4b92597a945d9c4df.tar.gz gdb-39c2f51bd9f82438706973c4b92597a945d9c4df.tar.bz2 |
* elflink.c (_bfd_elf_gc_mark): Mark sections referenced by
.eh_frame specially..
(bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
Don't recheck sections we have already marked.
(elf_gc_sweep): Keep non-code sections referenced from .eh_frame.
* section.c (struct bfd_section): Add gc_mark_from_eh.
(STD_SECTION): Adjust.
* ecoff.c (bfd_debug_section): Adjust.
* bfd-in2.h: Regenerate.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index b561b1f..8870857 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -8733,6 +8733,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info, gc_mark_hook_fn gc_mark_hook) { bfd_boolean ret; + bfd_boolean is_eh; asection *group_sec; sec->gc_mark = 1; @@ -8745,6 +8746,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info, /* Look through the section relocs. */ ret = TRUE; + is_eh = strcmp (sec->name, ".eh_frame") == 0; if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0) { Elf_Internal_Rela *relstart, *rel, *relend; @@ -8821,6 +8823,8 @@ _bfd_elf_gc_mark (struct bfd_link_info *info, { if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) rsec->gc_mark = 1; + else if (is_eh) + rsec->gc_mark_from_eh = 1; else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook)) { ret = FALSE; @@ -8891,6 +8895,41 @@ elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook) if (o->gc_mark) continue; + /* Keep .gcc_except_table.* if the associated .text.* is + marked. This isn't very nice, but the proper solution, + splitting .eh_frame up and using comdat doesn't pan out + easily due to needing special relocs to handle the + difference of two symbols in separate sections. + Don't keep code sections referenced by .eh_frame. */ + if (o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0) + { + if (strncmp (o->name, ".gcc_except_table.", 18) == 0) + { + unsigned long len; + char *fn_name; + asection *fn_text; + + len = strlen (o->name + 18) + 1; + fn_name = bfd_malloc (len + 6); + if (fn_name == NULL) + return FALSE; + memcpy (fn_name, ".text.", 6); + memcpy (fn_name + 6, o->name + 18, len); + fn_text = bfd_get_section_by_name (sub, fn_name); + free (fn_name); + if (fn_text != NULL && fn_text->gc_mark) + o->gc_mark = 1; + } + + /* If not using specially named exception table section, + then keep whatever we are using. */ + else + o->gc_mark = 1; + + if (o->gc_mark) + continue; + } + /* Skip sweeping sections already excluded. */ if (o->flags & SEC_EXCLUDE) continue; @@ -9125,18 +9164,9 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) continue; for (o = sub->sections; o != NULL; o = o->next) - { - if (o->flags & SEC_KEEP) - { - /* _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 (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) - return FALSE; - } - } + if ((o->flags & SEC_KEEP) != 0 && !o->gc_mark) + if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) + return FALSE; } /* ... and mark SEC_EXCLUDE for those that go. */ |