i386: Issue an error on non-PIC call to IFUNC in PIC object

On i386, IFUNC function must be called via PLT.  Since PLT in PIC
object uses EBX register, R_386_PLT32 relocation must be used to
call IFUNC function even when IFUNC function is defined locally.
Linker should issue an error when R_386_PC32 relocation is used
to call IFUNC function.

Since PR ld/19784 tests doesn't use PLT relocation to local IFUNC
function, they are moved to the x86-64 test directory.

bfd/

	PR ld/14961
	PR ld/20515
	* elf32-i386.c (elf_i386_check_relocs): Issue an error when
	R_386_PC32 relocation is used to call IFUNC function in PIC
	object.

ld/

	PR ld/14961
	PR ld/20515
	* testsuite/ld-i386/i386.exp: Run pr20515.
	* testsuite/ld-i386/pr20515.d: New file.
	* testsuite/ld-i386/pr20515.s: Likewise.
	* testsuite/ld-ifunc/ifunc-14a.s: Use R_386_PLT32 to call IFUNC
	function.
	* testsuite/ld-ifunc/ifunc-14c.s: Likewise.
	* testsuite/ld-ifunc/ifunc-2-i386.s: Likewise.
	* testsuite/ld-ifunc/ifunc-2-local-i386.s: Likewise.
	* testsuite/ld-ifunc/ifunc.exp: Move PR ld/19784 tests to ...
	* testsuite/ld-x86-64/x86-64.exp: Here.
	* testsuite/ld-ifunc/pr19784a.c: Moved to ...
	* testsuite/ld-x86-64/pr19784a.c: Here.
	* testsuite/ld-ifunc/pr19784b.c: Moved to ...
	* testsuite/ld-x86-64/pr19784b.c: Here.
	* testsuite/ld-ifunc/pr19784c.c: Moved to ...
	* testsuite/ld-x86-64/pr19784c.c: Here.
This commit is contained in:
H.J. Lu 2016-08-29 08:12:59 -07:00
parent 7fac69100a
commit 74437ea28f
15 changed files with 101 additions and 44 deletions

View file

@ -1,3 +1,11 @@
2016-08-29 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14961
PR ld/20515
* elf32-i386.c (elf_i386_check_relocs): Issue an error when
R_386_PC32 relocation is used to call IFUNC function in PIC
object.
2016-08-27 Alan Modra <amodra@gmail.com>
PR 20520

View file

@ -2178,6 +2178,20 @@ do_relocation:
a function defined in a shared library. */
if ((sec->flags & SEC_CODE) == 0)
h->pointer_equality_needed = 1;
else if (h->type == STT_GNU_IFUNC
&& bfd_link_pic (info))
{
if (isym == NULL)
name = h->root.root.string;
else
name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
NULL);
(*_bfd_error_handler)
(_("%B: unsupported non-PIC call to IFUNC `%s'"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
}
else
{

View file

@ -1,3 +1,24 @@
2016-08-29 H.J. Lu <hongjiu.lu@intel.com>
PR ld/14961
PR ld/20515
* testsuite/ld-i386/i386.exp: Run pr20515.
* testsuite/ld-i386/pr20515.d: New file.
* testsuite/ld-i386/pr20515.s: Likewise.
* testsuite/ld-ifunc/ifunc-14a.s: Use R_386_PLT32 to call IFUNC
function.
* testsuite/ld-ifunc/ifunc-14c.s: Likewise.
* testsuite/ld-ifunc/ifunc-2-i386.s: Likewise.
* testsuite/ld-ifunc/ifunc-2-local-i386.s: Likewise.
* testsuite/ld-ifunc/ifunc.exp: Move PR ld/19784 tests to ...
* testsuite/ld-x86-64/x86-64.exp: Here.
* testsuite/ld-ifunc/pr19784a.c: Moved to ...
* testsuite/ld-x86-64/pr19784a.c: Here.
* testsuite/ld-ifunc/pr19784b.c: Moved to ...
* testsuite/ld-x86-64/pr19784b.c: Here.
* testsuite/ld-ifunc/pr19784c.c: Moved to ...
* testsuite/ld-x86-64/pr19784c.c: Here.
2016-08-26 Thomas Preud'homme <thomas.preudhomme@arm.com>
* emultempl/armelf.em (params): New static variable.

View file

@ -413,6 +413,7 @@ run_dump_test "pr20253-4a"
run_dump_test "pr20253-4b"
run_dump_test "pr20253-4c"
run_dump_test "pr20253-5"
run_dump_test "pr20515"
if { !([istarget "i?86-*-linux*"]
|| [istarget "i?86-*-gnu*"]

View file

@ -0,0 +1,3 @@
#as: --32
#ld: -m elf_i386 -shared
#error: unsupported non-PIC call to IFUNC `foo'

View file

@ -0,0 +1,12 @@
.text
.globl bar
.type bar, @function
bar:
jmp foo
.size bar, .-bar
.hidden foo
.type foo, %gnu_indirect_function
.globl foo
foo:
ret
.size foo, .-foo

View file

@ -2,6 +2,6 @@
.globl bar
.type bar, @function
bar:
jmp foo
jmp foo@PLT
.size bar, .-bar
.hidden foo

View file

@ -2,6 +2,6 @@
.globl xxx
.type xxx, @function
xxx:
jmp foo
jmp foo@PLT
.size xxx, .-xxx
.hidden foo

View file

@ -15,7 +15,7 @@ bar:
.L6:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
call __GI_foo
call __GI_foo@PLT
leal __GI_foo@GOTOFF(%ebx), %eax
ret
.size bar, .-bar

View file

@ -12,7 +12,7 @@ bar:
.L6:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
call __GI_foo
call __GI_foo@PLT
leal __GI_foo@GOTOFF(%ebx), %eax
ret
.size bar, .-bar

View file

@ -505,30 +505,6 @@ run_cc_link_tests [list \
{} \
"libpr18841c.so" \
] \
[list \
"Build libpr19784a.so" \
"-shared -Wl,-Bsymbolic-functions" \
"-fPIC -O2 -g" \
{ pr19784b.c pr19784c.c } \
{} \
"libpr19784a.so" \
] \
[list \
"Build libpr19784b.so" \
"-shared -Wl,-Bsymbolic-functions" \
"-fPIC -O2 -g" \
{ pr19784c.c pr19784b.c } \
{} \
"libpr19784b.so" \
] \
[list \
"Build pr19784a.o" \
"" \
"" \
{ pr19784a.c } \
"" \
"" \
] \
]
run_ld_link_exec_tests [list \
@ -556,20 +532,4 @@ run_ld_link_exec_tests [list \
"pr18841c" \
"pr18841.out" \
] \
[list \
"Run pr19784a" \
"tmpdir/pr19784a.o tmpdir/libpr19784a.so" \
"" \
{ dummy.c } \
"pr19784a" \
"pass.out" \
] \
[list \
"Run pr19784b" \
"--as-needed tmpdir/pr19784a.o tmpdir/libpr19784b.so" \
"" \
{ dummy.c } \
"pr19784b" \
"pass.out" \
] \
]

View file

@ -822,6 +822,28 @@ if { [isnative] && [which $CC] != 0 } {
{{objdump {-dw} pr19319.dd}} \
"pr19319" \
] \
[list \
"Build libpr19784a.so" \
"-shared -Wl,-Bsymbolic-functions" \
"-fPIC -O2 -g" \
{ pr19784b.c pr19784c.c } \
{} \
"libpr19784a.so" \
] \
[list \
"Build libpr19784b.so" \
"-shared -Wl,-Bsymbolic-functions" \
"-fPIC -O2 -g" \
{ pr19784c.c pr19784b.c } \
{} \
"libpr19784b.so" \
] \
[list \
"Build pr19784a.o" \
"" \
"" \
{ pr19784a.c } \
] \
]
run_ld_link_exec_tests [list \
@ -892,6 +914,22 @@ if { [isnative] && [which $CC] != 0 } {
"gotpcrel1" \
"gotpcrel1.out" \
] \
[list \
"Run pr19784a" \
"tmpdir/pr19784a.o tmpdir/libpr19784a.so" \
"" \
{ dummy.s } \
"pr19784a" \
"pass.out" \
] \
[list \
"Run pr19784b" \
"--as-needed tmpdir/pr19784a.o tmpdir/libpr19784b.so" \
"" \
{ dummy.s } \
"pr19784b" \
"pass.out" \
] \
]
if { [istarget "x86_64-*-linux*"] \