x86-64: Correct unwind info for the BND PLT
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 11 Jan 2017 17:16:44 +0000 (09:16 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 11 Jan 2017 17:17:05 +0000 (09:17 -0800)
Since the BND PLT has

 230: 68 00 00 00 00        pushq  $0x0
 235: f2 e9 e5 ff ff ff     bnd jmpq 220 <.plt>
 23b: 0f 1f 44 00 00        nopl   0x0(%rax,%rax,1)

instead of

 230: ff 25 e2 0d 20 00     jmpq   *0x200de2(%rip)        # 201018
<func>
 236: 68 00 00 00 00        pushq  $0x0
 23b: e9 e0 ff ff ff        jmpq   220 <.plt>

its unwind info should be

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)

bfd/

PR ld/21038
* elf64-x86-64.c (elf_x86_64_eh_frame_bnd_plt): New.
(elf_x86_64_bnd_arch_bed): Use elf_x86_64_eh_frame_bnd_plt and
elf_x86_64_eh_frame_plt_got.
(elf_x86_64_size_dynamic_sections): Get unwind info from
elf_x86_64_bnd_arch_bed for the BND PLT.

ld/

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

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

index d4c973b9bc65c3a1f8592634f3692f47e67d9757..252e57baf5b78476586df6e6014e83c2b8dc91fa 100644 (file)
@@ -1,3 +1,12 @@
+2017-01-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21038
+       * elf64-x86-64.c (elf_x86_64_eh_frame_bnd_plt): New.
+       (elf_x86_64_bnd_arch_bed): Use elf_x86_64_eh_frame_bnd_plt and
+       elf_x86_64_eh_frame_plt_got.
+       (elf_x86_64_size_dynamic_sections): Get unwind info from
+       elf_x86_64_bnd_arch_bed for the BND PLT.
+
 2017-01-11  Jeremy Soller  <jackpot51@gmail.com>
 
        * config.bfd: Add entries for i686-redox and x86_64-redox.
index 1edab046a1166e04010fe83848a9b15d5ad7a64c..1fb865c618363f4e8cab14f0b2fe62c2e9e7bba3 100644 (file)
@@ -659,6 +659,41 @@ static const bfd_byte elf_x86_64_eh_frame_plt[] =
   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
 };
 
+/* .eh_frame covering the BND .plt section.  */
+
+static const bfd_byte elf_x86_64_eh_frame_bnd_plt[] =
+{
+  PLT_CIE_LENGTH, 0, 0, 0,     /* CIE length */
+  0, 0, 0, 0,                  /* CIE ID */
+  1,                           /* CIE version */
+  'z', 'R', 0,                 /* Augmentation string */
+  1,                           /* Code alignment factor */
+  0x78,                                /* Data alignment factor */
+  16,                          /* Return address column */
+  1,                           /* Augmentation size */
+  DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+  DW_CFA_def_cfa, 7, 8,                /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
+  DW_CFA_offset + 16, 1,       /* DW_CFA_offset: r16 (rip) at cfa-8 */
+  DW_CFA_nop, DW_CFA_nop,
+
+  PLT_FDE_LENGTH, 0, 0, 0,     /* FDE length */
+  PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+  0, 0, 0, 0,                  /* R_X86_64_PC32 .plt goes here */
+  0, 0, 0, 0,                  /* .plt size goes here */
+  0,                           /* Augmentation size */
+  DW_CFA_def_cfa_offset, 16,   /* DW_CFA_def_cfa_offset: 16 */
+  DW_CFA_advance_loc + 6,      /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+  DW_CFA_def_cfa_offset, 24,   /* DW_CFA_def_cfa_offset: 24 */
+  DW_CFA_advance_loc + 10,     /* DW_CFA_advance_loc: 10 to __PLT__+16 */
+  DW_CFA_def_cfa_expression,   /* DW_CFA_def_cfa_expression */
+  11,                          /* Block length */
+  DW_OP_breg7, 8,              /* DW_OP_breg7 (rsp): 8 */
+  DW_OP_breg16, 0,             /* 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
+};
+
 /* .eh_frame covering the .plt.got section.  */
 
 static const bfd_byte elf_x86_64_eh_frame_plt_got[] =
@@ -770,11 +805,10 @@ static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed =
     1+6,                                /* plt_got_insn_size */
     11,                                 /* plt_plt_insn_end */
     0,                                  /* plt_lazy_offset */
-    elf_x86_64_eh_frame_plt,            /* eh_frame_plt */
-    sizeof (elf_x86_64_eh_frame_plt),   /* eh_frame_plt_size */
-    /* FIXME: Needs .eh_frame coverage.  */
-    NULL,                               /* eh_frame_plt_got */
-    0,                                  /* eh_frame_plt_got_size */
+    elf_x86_64_eh_frame_bnd_plt,        /* eh_frame_plt */
+    sizeof (elf_x86_64_eh_frame_bnd_plt), /* eh_frame_plt_size */
+    elf_x86_64_eh_frame_plt_got,        /* eh_frame_plt_got */
+    sizeof (elf_x86_64_eh_frame_plt_got), /* eh_frame_plt_got_size */
   };
 
 #define        elf_backend_arch_data   &elf_x86_64_arch_bed
@@ -3851,6 +3885,8 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          && 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;
@@ -3939,8 +3975,12 @@ 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
-       = get_elf_x86_64_arch_data (bed);
+       = (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);
@@ -3951,6 +3991,7 @@ 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);
 
index 0a72581d70dbb27ad43d4254c98216e28997f7ba..79bcc5f77ea55d81a8eb6df7b70bc7ef6d5d8454 100644 (file)
@@ -1,3 +1,12 @@
+2017-01-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21038
+       * testsuite/ld-x86-64/pr21038a.d: New file.
+       * testsuite/ld-x86-64/pr21038a.s: Likewise.
+       * testsuite/ld-x86-64/pr21038b.d: Likewise.
+       * testsuite/ld-x86-64/pr21038b.s: Likewise.
+       * testsuite/ld-x86-64/x86-64.exp: Run pr21038a and pr21038b.
+
 2017-01-11  Jeremy Soller  <jackpot51@gmail.com>
 
        * configure.tgt: Add entries for x86-redox and x86_64-redox.
diff --git a/ld/testsuite/ld-x86-64/pr21038a.d b/ld/testsuite/ld-x86-64/pr21038a.d
new file mode 100644 (file)
index 0000000..f2f88eb
--- /dev/null
@@ -0,0 +1,71 @@
+#name: PR ld/21038 (.plt.got)
+#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=0000000000000238..0000000000000244
+  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=0000000000000220..0000000000000230
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 6 to 0000000000000226
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 10 to 0000000000000230
+  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=0000000000000230..0000000000000238
+  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+220 <.plt>:
+ +[a-f0-9]+:   ff 35 e2 0d 20 00       pushq  0x200de2\(%rip\)        # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+:   f2 ff 25 e3 0d 20 00    bnd jmpq \*0x200de3\(%rip\)        # 201010 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+:   0f 1f 00                nopl   \(%rax\)
+
+Disassembly of section .plt.got:
+
+0+230 <.plt.got>:
+ +[a-f0-9]+:   f2 ff 25 c1 0d 20 00    bnd jmpq \*0x200dc1\(%rip\)        # 200ff8 <func>
+ +[a-f0-9]+:   90                      nop
+
+Disassembly of section .text:
+
+0+238 <foo>:
+ +[a-f0-9]+:   e8 f3 ff ff ff          callq  230 <.plt.got>
+ +[a-f0-9]+:   48 8b 05 b4 0d 20 00    mov    0x200db4\(%rip\),%rax        # 200ff8 <func>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr21038a.s b/ld/testsuite/ld-x86-64/pr21038a.s
new file mode 100644 (file)
index 0000000..d9a1b4c
--- /dev/null
@@ -0,0 +1,8 @@
+       .text
+       .globl foo
+       .type foo, @function
+foo:
+       .cfi_startproc
+       call    func@plt
+       movq    func@GOTPCREL(%rip), %rax
+       .cfi_endproc
diff --git a/ld/testsuite/ld-x86-64/pr21038b.d b/ld/testsuite/ld-x86-64/pr21038b.d
new file mode 100644 (file)
index 0000000..1690d1e
--- /dev/null
@@ -0,0 +1,64 @@
+#name: PR ld/21038 (.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=0000000000000248..000000000000024d
+  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=0000000000000220..0000000000000240
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 6 to 0000000000000226
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 10 to 0000000000000230
+  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
+
+
+Disassembly of section .plt:
+
+0+220 <.plt>:
+ +[a-f0-9]+:   ff 35 e2 0d 20 00       pushq  0x200de2\(%rip\)        # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+:   f2 ff 25 e3 0d 20 00    bnd jmpq \*0x200de3\(%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 220 <.plt>
+ +[a-f0-9]+:   0f 1f 44 00 00          nopl   0x0\(%rax,%rax,1\)
+
+Disassembly of section .plt.bnd:
+
+0+240 <func@plt>:
+ +[a-f0-9]+:   f2 ff 25 d1 0d 20 00    bnd jmpq \*0x200dd1\(%rip\)        # 201018 <func>
+ +[a-f0-9]+:   90                      nop
+
+Disassembly of section .text:
+
+0+248 <foo>:
+ +[a-f0-9]+:   e8 f3 ff ff ff          callq  240 <func@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr21038b.s b/ld/testsuite/ld-x86-64/pr21038b.s
new file mode 100644 (file)
index 0000000..3a8fc47
--- /dev/null
@@ -0,0 +1,7 @@
+       .text
+       .globl foo
+       .type foo, @function
+foo:
+       .cfi_startproc
+       call    func@plt
+       .cfi_endproc
index f6b18bd7307f455e670b318482dd5eecb1ecebdd..ff782a093eca546de1c6584deaa989f193bee88a 100644 (file)
@@ -1021,3 +1021,5 @@ run_dump_test "pltgot-1"
 run_dump_test "pltgot-2"
 run_dump_test "pr20830a"
 run_dump_test "pr20830b"
+run_dump_test "pr21038a"
+run_dump_test "pr21038b"