x86-64: Also generate unwind info for .plt.bnd
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Jan 2017 18:30:56 +0000 (10:30 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Jan 2017 18:32:17 +0000 (10:32 -0800)
Also generate unwind info for the .plt.bnd section.  Sine it is the same
as unwind info for the .plt.got section, we use unwind info for the
.plt.got section to cover the the .plt.bnd section.

bfd/

PR ld/21038
* elf64-x86-64.c (elf_x86_64_link_hash_table): Add
plt_bnd_eh_frame.
(elf_x86_64_check_relocs): Create .eh_frame section for the
.plt.bnd section.
(elf_x86_64_size_dynamic_sections): Allocate and initialize
.eh_frame section for the .plt.bnd section.
(elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section
for the .plt.bnd section.

ld/

PR ld/21038
* testsuite/ld-x86-64/pr21038b.d: Updated.
* testsuite/ld-x86-64/pr21038c.d: New file.
* testsuite/ld-x86-64/pr21038c.s: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run pr21038c.

bfd/ChangeLog
bfd/elf64-x86-64.c
ld/ChangeLog
ld/testsuite/ld-x86-64/pr21038b.d
ld/testsuite/ld-x86-64/pr21038c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr21038c.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 6705ae4f3a7c96cc11304eff0af3ffaae27b973b..ef7d68c2c4ae369d89edf64d0a083364b9953988 100644 (file)
@@ -1,3 +1,15 @@
+2017-01-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21038
+       * elf64-x86-64.c (elf_x86_64_link_hash_table): Add
+       plt_bnd_eh_frame.
+       (elf_x86_64_check_relocs): Create .eh_frame section for the
+       .plt.bnd section.
+       (elf_x86_64_size_dynamic_sections): Allocate and initialize
+       .eh_frame section for the .plt.bnd section.
+       (elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section
+       for the .plt.bnd section.
+
 2017-01-12  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/20876
index 1fb865c618363f4e8cab14f0b2fe62c2e9e7bba3..a058eca3abf03cc2f79601d170b2d6b9f9c459e5 100644 (file)
@@ -934,6 +934,7 @@ struct elf_x86_64_link_hash_table
   asection *interp;
   asection *plt_eh_frame;
   asection *plt_bnd;
+  asection *plt_bnd_eh_frame;
   asection *plt_got;
   asection *plt_got_eh_frame;
 
@@ -2343,23 +2344,21 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              /* MPX PLT is supported only if elf_x86_64_arch_bed
                 is used in 64-bit mode.  */
              if (ABI_64_P (abfd)
-                     && info->bndplt
-                     && (get_elf_x86_64_backend_data (abfd)
-                         == &elf_x86_64_arch_bed))
+                 && info->bndplt
+                 && (get_elf_x86_64_backend_data (abfd)
+                     == &elf_x86_64_arch_bed))
                {
                  elf_x86_64_hash_entry (h)->has_bnd_reloc = 1;
 
                  /* Create the second PLT for Intel MPX support.  */
                  if (htab->plt_bnd == NULL)
                    {
-                     unsigned int plt_bnd_align;
                      const struct elf_backend_data *bed;
 
                      bed = get_elf_backend_data (info->output_bfd);
                      BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry) == 8
                                  && (sizeof (elf_x86_64_bnd_plt2_entry)
                                      == sizeof (elf_x86_64_legacy_plt2_entry)));
-                     plt_bnd_align = 3;
 
                      if (htab->elf.dynobj == NULL)
                        htab->elf.dynobj = abfd;
@@ -2374,7 +2373,24 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                      if (htab->plt_bnd == NULL
                          || !bfd_set_section_alignment (htab->elf.dynobj,
                                                         htab->plt_bnd,
-                                                        plt_bnd_align))
+                                                        3))
+                       goto error_return;
+                   }
+
+                 if (!info->no_ld_generated_unwind_info
+                     && htab->plt_bnd_eh_frame == NULL)
+                   {
+                     flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+                                       | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+                                       | SEC_LINKER_CREATED);
+                     htab->plt_bnd_eh_frame
+                       = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
+                                                             ".eh_frame",
+                                                             flags);
+                     if (htab->plt_bnd_eh_frame == NULL
+                         || !bfd_set_section_alignment (htab->elf.dynobj,
+                                                        htab->plt_bnd_eh_frame,
+                                                        3))
                        goto error_return;
                    }
                }
@@ -3687,6 +3703,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
   bfd_boolean relocs;
   bfd *ibfd;
   const struct elf_backend_data *bed;
+  const struct elf_x86_64_backend_data *arch_data;
 
   htab = elf_x86_64_hash_table (info);
   if (htab == NULL)
@@ -3878,30 +3895,31 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
        htab->elf.sgotplt->size = 0;
     }
 
+  arch_data = (htab->plt_bnd != NULL
+              ? &elf_x86_64_bnd_arch_bed
+              : get_elf_x86_64_arch_data (bed));
+
   if (_bfd_elf_eh_frame_present (info))
     {
       if (htab->plt_eh_frame != NULL
          && htab->elf.splt != NULL
          && htab->elf.splt->size != 0
          && !bfd_is_abs_section (htab->elf.splt->output_section))
-       {
-         /* Unwind info for the BND PLT and the normal PLT have the
-            same time.  */
-         const struct elf_x86_64_backend_data *arch_data
-           = get_elf_x86_64_arch_data (bed);
-         htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
-       }
+       htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
 
       if (htab->plt_got_eh_frame != NULL
          && htab->plt_got != NULL
          && htab->plt_got->size != 0
          && !bfd_is_abs_section (htab->plt_got->output_section))
-       {
-         const struct elf_x86_64_backend_data *arch_data
-           = get_elf_x86_64_arch_data (bed);
-         htab->plt_got_eh_frame->size
-           = arch_data->eh_frame_plt_got_size;
-       }
+       htab->plt_got_eh_frame->size = arch_data->eh_frame_plt_got_size;
+
+      /* Unwind info for .plt.bnd and .plt.got sections are
+        identical.  */
+      if (htab->plt_bnd_eh_frame != NULL
+         && htab->plt_bnd != NULL
+         && htab->plt_bnd->size != 0
+         && !bfd_is_abs_section (htab->plt_bnd->output_section))
+       htab->plt_bnd_eh_frame->size = arch_data->eh_frame_plt_got_size;
     }
 
   /* We now have determined the sizes of the various dynamic sections.
@@ -3921,6 +3939,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          || s == htab->plt_got
          || s == htab->plt_eh_frame
          || s == htab->plt_got_eh_frame
+         || s == htab->plt_bnd_eh_frame
          || s == htab->elf.sdynbss
          || s == htab->elf.sdynrelro)
        {
@@ -3975,13 +3994,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
   if (htab->plt_eh_frame != NULL
       && htab->plt_eh_frame->contents != NULL)
     {
-      /* Unwind info for the BND PLT and the normal PLT have the same
-        size, but different contents.  */
-      const struct elf_x86_64_backend_data *arch_data
-       = (htab->plt_bnd != NULL
-          ? &elf_x86_64_bnd_arch_bed
-          : get_elf_x86_64_arch_data (bed));
-
       memcpy (htab->plt_eh_frame->contents,
              arch_data->eh_frame_plt, htab->plt_eh_frame->size);
       bfd_put_32 (dynobj, htab->elf.splt->size,
@@ -3991,10 +4003,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
   if (htab->plt_got_eh_frame != NULL
       && htab->plt_got_eh_frame->contents != NULL)
     {
-      /* Unwind info for .plt.bnd and .plt.got sections are identical.  */
-      const struct elf_x86_64_backend_data *arch_data
-       = get_elf_x86_64_arch_data (bed);
-
       memcpy (htab->plt_got_eh_frame->contents,
              arch_data->eh_frame_plt_got,
              htab->plt_got_eh_frame->size);
@@ -4003,6 +4011,17 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
                   + PLT_FDE_LEN_OFFSET));
     }
 
+  if (htab->plt_bnd_eh_frame != NULL
+      && htab->plt_bnd_eh_frame->contents != NULL)
+    {
+      memcpy (htab->plt_bnd_eh_frame->contents,
+             arch_data->eh_frame_plt_got,
+             htab->plt_bnd_eh_frame->size);
+      bfd_put_32 (dynobj, htab->plt_bnd->size,
+                 (htab->plt_bnd_eh_frame->contents
+                  + PLT_FDE_LEN_OFFSET));
+    }
+
   if (htab->elf.dynamic_sections_created)
     {
       /* Add some entries to the .dynamic section.  We fill in the
@@ -6495,6 +6514,33 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
        }
     }
 
+  /* Adjust .eh_frame for .plt.bnd section.  */
+  if (htab->plt_bnd_eh_frame != NULL
+      && htab->plt_bnd_eh_frame->contents != NULL)
+    {
+      if (htab->plt_bnd != NULL
+         && htab->plt_bnd->size != 0
+         && (htab->plt_bnd->flags & SEC_EXCLUDE) == 0
+         && htab->plt_bnd->output_section != NULL
+         && htab->plt_bnd_eh_frame->output_section != NULL)
+       {
+         bfd_vma plt_start = htab->plt_bnd->output_section->vma;
+         bfd_vma eh_frame_start = htab->plt_bnd_eh_frame->output_section->vma
+                                  + htab->plt_bnd_eh_frame->output_offset
+                                  + PLT_FDE_START_OFFSET;
+         bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+                            htab->plt_bnd_eh_frame->contents
+                            + PLT_FDE_START_OFFSET);
+       }
+      if (htab->plt_bnd_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+       {
+         if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+                                                htab->plt_bnd_eh_frame,
+                                                htab->plt_bnd_eh_frame->contents))
+           return FALSE;
+       }
+    }
+
   if (htab->elf.sgot && htab->elf.sgot->size > 0)
     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
       = GOT_ENTRY_SIZE;
index 79bcc5f77ea55d81a8eb6df7b70bc7ef6d5d8454..1579442b1ca433ae43cd9353c69e3ac6dc150f19 100644 (file)
@@ -1,3 +1,11 @@
+2017-01-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21038
+       * testsuite/ld-x86-64/pr21038b.d: Updated.
+       * testsuite/ld-x86-64/pr21038c.d: New file.
+       * testsuite/ld-x86-64/pr21038c.s: Likewise.
+       * testsuite/ld-x86-64/x86-64.exp: Run pr21038c.
+
 2017-01-11  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/21038
index 1690d1e3d8342c351de3af4144bebf07c17832a3..053d9086f8eed324b0852d07aee5699681f92e26 100644 (file)
@@ -40,6 +40,15 @@ Contents of the .eh_frame section:
   DW_CFA_nop
   DW_CFA_nop
 
+0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000240..0000000000000248
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
 
 Disassembly of section .plt:
 
diff --git a/ld/testsuite/ld-x86-64/pr21038c.d b/ld/testsuite/ld-x86-64/pr21038c.d
new file mode 100644 (file)
index 0000000..33ff4ed
--- /dev/null
@@ -0,0 +1,90 @@
+#name: PR ld/21038 (.plt.got and .plt.bnd)
+#as: --64
+#ld: -z bndplt -melf_x86_64 -shared -z relro --ld-generated-unwind-info
+#objdump: -dw -Wf
+
+.*: +file format .*
+
+Contents of the .eh_frame section:
+
+0+ 0000000000000014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     1b
+
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+18 0000000000000014 0000001c FDE cie=00000000 pc=0000000000000290..00000000000002a1
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+30 0000000000000024 00000034 FDE cie=00000000 pc=0000000000000260..0000000000000280
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 6 to 0000000000000266
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 10 to 0000000000000270
+  DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit5; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus\)
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000288..0000000000000290
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+70 0000000000000014 00000074 FDE cie=00000000 pc=0000000000000280..0000000000000288
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+
+Disassembly of section .plt:
+
+0+260 <.plt>:
+ +[a-f0-9]+:   ff 35 a2 0d 20 00       pushq  0x200da2\(%rip\)        # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+:   f2 ff 25 a3 0d 20 00    bnd jmpq \*0x200da3\(%rip\)        # 201010 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+:   0f 1f 00                nopl   \(%rax\)
+ +[a-f0-9]+:   68 00 00 00 00          pushq  \$0x0
+ +[a-f0-9]+:   f2 e9 e5 ff ff ff       bnd jmpq 260 <.plt>
+ +[a-f0-9]+:   0f 1f 44 00 00          nopl   0x0\(%rax,%rax,1\)
+
+Disassembly of section .plt.got:
+
+0+280 <.plt.got>:
+ +[a-f0-9]+:   f2 ff 25 71 0d 20 00    bnd jmpq \*0x200d71\(%rip\)        # 200ff8 <func1>
+ +[a-f0-9]+:   90                      nop
+
+Disassembly of section .plt.bnd:
+
+0+288 <func2@plt>:
+ +[a-f0-9]+:   f2 ff 25 89 0d 20 00    bnd jmpq \*0x200d89\(%rip\)        # 201018 <func2>
+ +[a-f0-9]+:   90                      nop
+
+Disassembly of section .text:
+
+0+290 <foo>:
+ +[a-f0-9]+:   e8 eb ff ff ff          callq  280 <.plt.got>
+ +[a-f0-9]+:   e8 ee ff ff ff          callq  288 <func2@plt>
+ +[a-f0-9]+:   48 8b 05 57 0d 20 00    mov    0x200d57\(%rip\),%rax        # 200ff8 <func1>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr21038c.s b/ld/testsuite/ld-x86-64/pr21038c.s
new file mode 100644 (file)
index 0000000..38fc10d
--- /dev/null
@@ -0,0 +1,9 @@
+       .text
+       .globl foo
+       .type foo, @function
+foo:
+       .cfi_startproc
+       call    func1@plt
+       call    func2@plt
+       movq    func1@GOTPCREL(%rip), %rax
+       .cfi_endproc
index ff782a093eca546de1c6584deaa989f193bee88a..8e4e4225dd8fccaf3c2bb676e6a2c3c4e0a619c0 100644 (file)
@@ -1023,3 +1023,4 @@ run_dump_test "pr20830a"
 run_dump_test "pr20830b"
 run_dump_test "pr21038a"
 run_dump_test "pr21038b"
+run_dump_test "pr21038c"