This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: PR ld/14105: Always create PLT eh_frame
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Sun, 13 May 2012 14:36:51 -0700
- Subject: PATCH: PR ld/14105: Always create PLT eh_frame
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
This patch changes i386/x86-64 backend to always create PLT eh_frame
section with SEC_LINKER_CREATED. It also updates bfd_elf_discard_info
to handle PLT eh_frame created by linker. OK to install?
Thanks.
H.J.
----
bfd/
2012-05-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14105
* elf32-i386.c (elf_i386_create_dynamic_sections): Always
create PLT eh_frame section with SEC_LINKER_CREATED.
* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Likewise.
* elflink.c (not_this_section): New.
(bfd_elf_discard_info): Also handle PLT eh_frame created by
linker.
ld/testsuite/
2012-05-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14105
* ld-elf/eh4.d: Add PLT eh_frame.
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 270a7c7..31b3c57 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1015,13 +1015,15 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
return FALSE;
if (!info->no_ld_generated_unwind_info
- && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL
+ && htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
{
flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
htab->plt_eh_frame
- = bfd_make_section_with_flags (dynobj, ".eh_frame",
- flags | SEC_READONLY);
+ = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame",
+ (flags
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
return FALSE;
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 1111d77..aafe60d 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -979,15 +979,17 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
abort ();
if (!info->no_ld_generated_unwind_info
- && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL
+ && htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
{
const struct elf_x86_64_backend_data *const abed
= get_elf_x86_64_backend_data (dynobj);
flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
htab->plt_eh_frame
- = bfd_make_section_with_flags (dynobj, ".eh_frame",
- flags | SEC_READONLY);
+ = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame",
+ (flags
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3))
return FALSE;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 65d3a2c..03f07a9 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12438,6 +12438,14 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
return FALSE;
}
+/* Return TRUE if SEC isn't DATA. */
+
+static bfd_boolean
+not_this_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *data)
+{
+ return (void *) sec != data;
+}
+
/* Discard unneeded references to discarded sections.
Returns TRUE if any section's size was changed. */
/* This function assumes that the relocations are in sorted order,
@@ -12513,6 +12521,23 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
&cookie))
ret = TRUE;
fini_reloc_cookie_rels (&cookie, eh);
+
+ if ((eh->flags & SEC_LINKER_CREATED) == 0)
+ {
+ /* Also handle PLT eh_frame created by linker. */
+ eh = bfd_get_section_by_name_if (abfd, ".eh_frame",
+ not_this_section, eh);
+ if (eh != NULL
+ && init_reloc_cookie_rels (&cookie, info, abfd, eh))
+ {
+ _bfd_elf_parse_eh_frame (abfd, info, eh, &cookie);
+ if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
+ bfd_elf_reloc_symbol_deleted_p,
+ &cookie))
+ ret = TRUE;
+ fini_reloc_cookie_rels (&cookie, eh);
+ }
+ }
}
if (bed->elf_backend_discard_info != NULL
diff --git a/ld/testsuite/ld-elf/eh4.d b/ld/testsuite/ld-elf/eh4.d
index b482d03..34ce70e 100644
--- a/ld/testsuite/ld-elf/eh4.d
+++ b/ld/testsuite/ld-elf/eh4.d
@@ -29,6 +29,17 @@ Contents of the .eh_frame section:
DW_CFA_set_loc: 00000417
DW_CFA_def_cfa_offset: 80
-00000048 ZERO terminator
+00000048 00000024 0000004c FDE cie=00000000 pc=00000240..00000260
+ DW_CFA_def_cfa_offset: 16
+ DW_CFA_advance_loc: 6 to 00000246
+ DW_CFA_def_cfa_offset: 24
+ DW_CFA_advance_loc: 10 to 00000250
+ DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus\)
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+
+00000070 ZERO terminator
#pass