summaryrefslogtreecommitdiff
path: root/bfd/elf-eh-frame.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2012-05-25 01:12:18 +0000
committerAlan Modra <amodra@bigpond.net.au>2012-05-25 01:12:18 +0000
commit83e8d83b7e9dd9915154aa1b0df16aae11f3b075 (patch)
tree41ccd352b4a50108269a0693b108727e8e5179ee /bfd/elf-eh-frame.c
parentbc6ce2780cd8d2df46e239ec8aec56d312bb9c5d (diff)
downloadbinutils-redhat-83e8d83b7e9dd9915154aa1b0df16aae11f3b075.tar.gz
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.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 685540c910..a75d806165 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;