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.
This commit is contained in:
H.J. Lu 2017-05-10 09:28:00 -07:00
parent f78c0b9158
commit aab82f4c20
6 changed files with 107 additions and 2 deletions

View 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.

View 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;
}

View 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.

View File

@ -0,0 +1,8 @@
extern void check (void);
int
main ()
{
check ();
return 0;
}

View File

@ -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

View 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" \
] \
]
}