diff options
author | Alan Modra <amodra@gmail.com> | 2012-05-25 01:12:20 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-05-25 01:12:20 +0000 |
commit | 9a2a56cc5a38cdf74d9a34557274ad055f8a8a62 (patch) | |
tree | fdc3a5feb7549b64f97919c64741a49e0905f92d /bfd/elf-eh-frame.c | |
parent | 3161ca4f50fe4f8bae8b6a3024b65961b02703c6 (diff) | |
download | gdb-9a2a56cc5a38cdf74d9a34557274ad055f8a8a62.zip gdb-9a2a56cc5a38cdf74d9a34557274ad055f8a8a62.tar.gz gdb-9a2a56cc5a38cdf74d9a34557274ad055f8a8a62.tar.bz2 |
PR ld/13909
* elf-eh-frame.c (_bfd_elf_eh_frame_present): New function.
(_bfd_elf_maybe_strip_eh_frame_hdr): Use it here.
* elf-bfd.h (_bfd_elf_eh_frame_present): Declare.
* elflink.c (bfd_elf_size_dynamic_sections): Let the backend
size dynamic sections before stripping eh_frame_hdr.
(bfd_elf_gc_sections): Handle multiple .eh_frame sections.
* elf32-ppc.c (ppc_elf_size_dynamic_sections): Drop glink_eh_frame
if no other .eh_frame sections exist.
* elf64-ppc.c (ppc64_elf_size_stubs): Likewise.
* elf32-i386.c (elf_i386_create_dynamic_sections): Don't size
or alloc plt_eh_frame here..
(elf_i386_size_dynamic_sections): ..do it here instead. Don't
specially keep sgotplt, iplt, tgotplt, sdynbss for symbols.
(elf_i386_finish_dynamic_sections): Check plt_eh_frame->contents
before writing plt offset.
* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Don't size
or alloc plt_eh_frame here..
(elf_x86_64_size_dynamic_sections): ..do it here instead.
(elf_x86_64_finish_dynamic_sections): Check plt_eh_frame->contents
before writing plt offset.
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r-- | bfd/elf-eh-frame.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 685540c..a75d806 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -1247,6 +1247,26 @@ _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) return TRUE; } +/* Return true if there is at least one non-empty .eh_frame section in + input files. Can only be called after ld has mapped input to + output sections, and before sections are stripped. */ +bfd_boolean +_bfd_elf_eh_frame_present (struct bfd_link_info *info) +{ + asection *eh = bfd_get_section_by_name (info->output_bfd, ".eh_frame"); + + if (eh == NULL) + return FALSE; + + /* Count only sections which have at least a single CIE or FDE. + There cannot be any CIE or FDE <= 8 bytes. */ + for (eh = eh->map_head.s; eh != NULL; eh = eh->map_head.s) + if (eh->size > 8) + return TRUE; + + return FALSE; +} + /* This function is called from size_dynamic_sections. It needs to decide whether .eh_frame_hdr should be output or not, because when the dynamic symbol table has been sized it is too late @@ -1255,8 +1275,6 @@ _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) { - asection *o; - bfd *abfd; struct elf_link_hash_table *htab; struct eh_frame_hdr_info *hdr_info; @@ -1265,28 +1283,9 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) if (hdr_info->hdr_sec == NULL) return TRUE; - if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)) - { - hdr_info->hdr_sec = NULL; - return TRUE; - } - - abfd = NULL; - if (info->eh_frame_hdr) - for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) - { - /* Count only sections which have at least a single CIE or FDE. - There cannot be any CIE or FDE <= 8 bytes. */ - o = bfd_get_section_by_name (abfd, ".eh_frame"); - while (o != NULL - && (o->size <= 8 - || bfd_is_abs_section (o->output_section))) - o = bfd_get_next_section_by_name (o); - if (o != NULL) - break; - } - - if (abfd == NULL) + if (bfd_is_abs_section (hdr_info->hdr_sec->output_section) + || !info->eh_frame_hdr + || !_bfd_elf_eh_frame_present (info)) { hdr_info->hdr_sec->flags |= SEC_EXCLUDE; hdr_info->hdr_sec = NULL; |