PATCH: PR ld/14105: Always create PLT eh_frame

H.J. Lu hjl.tools@gmail.com
Tue May 22 14:07:00 GMT 2012


On Tue, May 22, 2012 at 5:15 AM, Alan Modra <amodra@gmail.com> wrote:
> On Mon, May 21, 2012 at 08:18:41PM -0700, H.J. Lu wrote:
>>       * elflink.c (bfd_elf_discard_info): Also handle PLT eh_frame
>>       created by linker.
>
> I think we may have an ordering problem.  bfd_elf_discard_info runs
> before the PLT eh_frame is completely filled out (on powerpc, before
> any of it is written, so there is certainly a problem there).  On i386
> and x86_64, we write the PLT offset in finish_dynamic_sections.  How
> does this interact with elf-eh-frame optimisations?  Just looking at
> the code I think it probably is OK, but please do check exactly what
> happens with every word read out of your PLT eh_frame!
>
>> +       if (!plt_eh_frame_done)
>
> It probably isn't worth bothering with a flag here.  If you leave that
> out, then if we have multiple .eh_frame sections in the future for
> other reasons they will be handled too.  That also allows for some
> simplification.  Your bfd_get_next_section_by_name can be simplified
> too.  Committing the following.  I'll leave the x86 bits to you.
>

This is what I checked in.

Thanks.

-- 
H.J.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 270b83a..cfdcaa3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-22  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.
+
 2012-05-22  Alan Modra  <amodra@gmail.com>

 	* elflink.c (bfd_elf_discard_info): Handle multiple .eh_frame
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index dd49486..84299ce 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 3353560..1f490d4 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/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 1236650..e0d072f 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,20 @@
+2012-05-20  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/14105
+	* ld-elf/eh4.d: Add PLT eh_frame.
+
+	* ld-i386/i386.exp: Run pr12570a and pr12570b.
+	* ld-x86-64/x86-64.exp: Likewise.
+
+	* ld-i386/pr12570a.d: New file.
+	* ld-i386/pr12570a.s: Likewise.
+	* ld-i386/pr12570b.s: Likewise.
+	* ld-i386/pr12570b.s: Likewise.
+	* ld-x86-64/pr12570a.d: Likewise.
+	* ld-x86-64/pr12570a.s: Likewise.
+	* ld-x86-64/pr12570b.d: Likewise.
+	* ld-x86-64/pr12570b.s: Likewise.
+
 2012-05-19  Alan Modra  <amodra@gmail.com>

 	* ld-elf/elf.exp (note-3.so): xfail tic6x due to non-pic warnings.
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

diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index d1031c5..47f918f 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -231,6 +231,8 @@ run_dump_test "nogot2"
 run_dump_test "discarded1"
 run_dump_test "pr12718"
 run_dump_test "pr12921"
+run_dump_test "pr12570a"
+run_dump_test "pr12570b"

 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr12570a.d b/ld/testsuite/ld-i386/pr12570a.d
new file mode 100644
index 0000000..03aeb7b
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr12570a.d
@@ -0,0 +1,8 @@
+#name: PR ld/12570
+#as: --32
+#ld: -melf_i386 -shared
+#readelf: -wf --wide
+
+#...
+  DW_CFA_def_cfa_expression \(DW_OP_breg4 \(esp\): 4; DW_OP_breg8
\(eip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit2;
DW_OP_shl; DW_OP_plus\)
+#...
diff --git a/ld/testsuite/ld-i386/pr12570a.s b/ld/testsuite/ld-i386/pr12570a.s
new file mode 100644
index 0000000..38e0593
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr12570a.s
@@ -0,0 +1,8 @@
+	.text
+	.globl foo
+	.type foo, @function
+foo:
+	.cfi_startproc
+	jmp	 bar@PLT
+	.cfi_endproc
+	.size	foo, .-foo
diff --git a/ld/testsuite/ld-i386/pr12570b.d b/ld/testsuite/ld-i386/pr12570b.d
new file mode 100644
index 0000000..0532aac
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr12570b.d
@@ -0,0 +1,9 @@
+#name: PR ld/12570
+#as: --32
+#ld: -melf_i386 -shared
+#readelf: -wf --wide
+
+#failif
+#...
+  DW_CFA_def_cfa_expression \(DW_OP_breg4 \(esp\): 4; DW_OP_breg8
\(eip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit2;
DW_OP_shl; DW_OP_plus\)
+#...
diff --git a/ld/testsuite/ld-i386/pr12570b.s b/ld/testsuite/ld-i386/pr12570b.s
new file mode 100644
index 0000000..e76b9f1
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr12570b.s
@@ -0,0 +1,8 @@
+	.text
+	.globl foo
+	.type foo, @function
+foo:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+	.size	foo, .-foo
diff --git a/ld/testsuite/ld-x86-64/pr12570a.d
b/ld/testsuite/ld-x86-64/pr12570a.d
new file mode 100644
index 0000000..6105a74
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr12570a.d
@@ -0,0 +1,8 @@
+#name: PR ld/12570
+#as: --64
+#ld: -melf_x86_64 -shared
+#readelf: -wf --wide
+
+#...
+  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\)
+#...
diff --git a/ld/testsuite/ld-x86-64/pr12570a.s
b/ld/testsuite/ld-x86-64/pr12570a.s
new file mode 100644
index 0000000..38e0593
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr12570a.s
@@ -0,0 +1,8 @@
+	.text
+	.globl foo
+	.type foo, @function
+foo:
+	.cfi_startproc
+	jmp	 bar@PLT
+	.cfi_endproc
+	.size	foo, .-foo
diff --git a/ld/testsuite/ld-x86-64/pr12570b.d
b/ld/testsuite/ld-x86-64/pr12570b.d
new file mode 100644
index 0000000..d65f8da
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr12570b.d
@@ -0,0 +1,9 @@
+#name: PR ld/12570
+#as: --64
+#ld: -melf_x86_64 -shared
+#readelf: -wf --wide
+
+#failif
+#...
+  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\)
+#...
diff --git a/ld/testsuite/ld-x86-64/pr12570b.s
b/ld/testsuite/ld-x86-64/pr12570b.s
new file mode 100644
index 0000000..e76b9f1
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr12570b.s
@@ -0,0 +1,8 @@
+	.text
+	.globl foo
+	.type foo, @function
+foo:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+	.size	foo, .-foo
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp
b/ld/testsuite/ld-x86-64/x86-64.exp
index e8afbc2..7d2934f 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -206,6 +206,8 @@ run_dump_test "discarded1"
 run_dump_test "pr12718"
 run_dump_test "pr12921"
 run_dump_test "pr13947"
+run_dump_test "pr12570a"
+run_dump_test "pr12570b"

 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return



More information about the Binutils mailing list