From aab82f4c201a2612c0fb6d5b66d8e4ce2f036f1c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 10 May 2017 09:28:00 -0700 Subject: [PATCH] x86-64: Use .plt.bnd for IFUNC function address 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 | 6 +++++ bfd/elf64-x86-64.c | 14 ++++++++-- ld/ChangeLog | 7 +++++ ld/testsuite/ld-x86-64/pr21481a.c | 8 ++++++ ld/testsuite/ld-x86-64/pr21481b.S | 56 +++++++++++++++++++++++++++++++++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 18 +++++++++++++ 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 ld/testsuite/ld-x86-64/pr21481a.c create mode 100644 ld/testsuite/ld-x86-64/pr21481b.S diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c12ff16..b307ecb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2017-05-10 H.J. Lu + + 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 * elf32-arc.c (FEATURE_LIST_NAME): Define. diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 1fbba1b..fb9336d 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -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; } diff --git a/ld/ChangeLog b/ld/ChangeLog index b04c3e0..2dfb06e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2017-05-10 H.J. Lu + + 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 * 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 index 0000000..370275a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21481a.c @@ -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 index 0000000..744d86a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr21481b.S @@ -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 diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 84cc7d7..61032aa 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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" \ + ] \ ] } -- 2.7.4