x86-64: Use .plt.bnd for IFUNC function address
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 10 May 2017 16:28:00 +0000 (09:28 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 10 May 2017 16:28:28 +0000 (09:28 -0700)
When -z bndplt is used, we must use the .plt.bnd entry for IFUNC function
address.

bfd/

PR ld/21481
* elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Use .plt.bnd
for IFUNC function address.

ld/

PR ld/21481
* testsuite/ld-x86-64/pr21481a.c: New file.
* testsuite/ld-x86-64/pr21481b.S: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/21481 tests.

bfd/ChangeLog
bfd/elf64-x86-64.c
ld/ChangeLog
ld/testsuite/ld-x86-64/pr21481a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr21481b.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index c12ff16..b307ecb 100644 (file)
@@ -1,3 +1,9 @@
+2017-05-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21481
+       * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Use .plt.bnd
+       for IFUNC function address.
+
 2017-05-10  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * elf32-arc.c (FEATURE_LIST_NAME): Define.
index 1fbba1b..fb9336d 100644 (file)
@@ -5974,6 +5974,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
          else
            {
              asection *plt;
+             bfd_vma plt_offset;
 
              if (!h->pointer_equality_needed)
                abort ();
@@ -5981,10 +5982,19 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
              /* For non-shared object, we can't use .got.plt, which
                 contains the real function addres if we need pointer
                 equality.  We load the GOT entry with the PLT entry.  */
-             plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+             if (htab->plt_bnd != NULL)
+               {
+                 plt = htab->plt_bnd;
+                 plt_offset = eh->plt_bnd.offset;
+               }
+             else
+               {
+                 plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+                 plt_offset =  h->plt.offset;
+               }
              bfd_put_64 (output_bfd, (plt->output_section->vma
                                       + plt->output_offset
-                                      + h->plt.offset),
+                                      + plt_offset),
                          htab->elf.sgot->contents + h->got.offset);
              return TRUE;
            }
index b04c3e0..2dfb06e 100644 (file)
@@ -1,3 +1,10 @@
+2017-05-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21481
+       * testsuite/ld-x86-64/pr21481a.c: New file.
+       * testsuite/ld-x86-64/pr21481b.S: Likewise.
+       * testsuite/ld-x86-64/x86-64.exp: Run PR ld/21481 tests.
+
 2017-05-10  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * testsuite/ld-arc/attr-merge-0.d: New file.
diff --git a/ld/testsuite/ld-x86-64/pr21481a.c b/ld/testsuite/ld-x86-64/pr21481a.c
new file mode 100644 (file)
index 0000000..370275a
--- /dev/null
@@ -0,0 +1,8 @@
+extern void check (void);
+
+int
+main ()
+{
+  check ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-x86-64/pr21481b.S b/ld/testsuite/ld-x86-64/pr21481b.S
new file mode 100644 (file)
index 0000000..744d86a
--- /dev/null
@@ -0,0 +1,56 @@
+       .section        .rodata.str1.1,"aMS",@progbits,1
+.LC0:
+       .string "PASS"
+       .text
+       .globl  check
+       .type   check, @function
+check:
+       subq    $8, %rsp
+       call    *get_func1@GOTPCREL(%rip)
+       cmpl    $func1, %eax
+       jne     .L3
+       movq    func1_p@GOTPCREL(%rip), %rdx
+       cmpq    %rax, (%rdx)
+       jne     .L3
+       call    *func1@GOTPCREL(%rip)
+       cmpl    $1, %eax
+       jne     .L3
+       call    *call_func1@GOTPCREL(%rip)
+       cmpl    $1, %eax
+       jne     .L3
+       leaq    .LC0(%rip), %rdi
+       addq    $8, %rsp
+       jmp     *puts@GOTPCREL(%rip)
+.L3:
+       call    *abort@GOTPCREL(%rip)
+       .size   check, .-check
+       .globl  get_func1
+       .type   get_func1, @function
+get_func1:
+       movq    func1@GOTPCREL(%rip), %rax
+       ret
+       .size   get_func1, .-get_func1
+       .globl  call_func1
+       .type   call_func1, @function
+call_func1:
+       jmp     *func1@GOTPCREL(%rip)
+       .size   call_func1, .-call_func1
+       .globl  func1_p
+       .section        .rodata,"a",@progbits
+       .align 8
+       .size   func1_p, 8
+       .type   func1_p, @object
+func1_p:
+       .dc.a   func1
+       .text
+implementation1:
+       movl    $1, %eax
+       ret
+       .size   implementation1, .-implementation1
+       .globl  func1
+       .type   func1, @gnu_indirect_function
+func1:
+       leaq    implementation1(%rip), %rax
+       ret
+       .size   func1, .-func1
+       .section        .note.GNU-stack,"",@progbits
index 84cc7d7..61032aa 100644 (file)
@@ -1316,6 +1316,24 @@ if { [isnative] && [which $CC] != 0 } {
                "pr20800" \
                "pass.out" \
            ] \
+           [list \
+               "Run pr21481a" \
+               "$NOPIE_LDFLAGS -Wl,-z,bndplt" \
+               "" \
+               { pr21481a.c pr21481b.S } \
+               "pr21481a" \
+               "pass.out" \
+               "$NOPIE_CFLAGS" \
+           ] \
+           [list \
+               "Run pr21481b" \
+               "$NOPIE_LDFLAGS -Wl,-z,bndplt,-z,now" \
+               "" \
+               { pr21481a.c pr21481b.S } \
+               "pr21481b" \
+               "pass.out" \
+               "$NOPIE_CFLAGS" \
+           ] \
        ]
     }