2009-06-14  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/10270
	* elf32-i386.c (elf_i386_allocate_dynrelocs): Disallow
	dynamic IFUNC pointer in non-shared object.  Use .got.plt
	for IFUNC definition in PIE.
	(elf_i386_allocate_dynrelocs): Resolve IFUNC definition in
	PIE locally.

	* elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Disallow
	dynamic IFUNC pointer in non-shared object.  Use .got.plt
	for IFUNC definition in PIE.
	(elf64_x86_64_relocate_section): Resolve IFUNC definition in
	PIE locally.

ld/testsuite/

2009-06-14  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/10270
	* ld-ifunc/ifunc-9-x86.d: New.
	* ld-ifunc/ifunc-9-x86.s: Likewise.
This commit is contained in:
H.J. Lu 2009-06-14 22:13:30 +00:00
parent f6475b4872
commit 44c4ea11d3
6 changed files with 110 additions and 20 deletions

View File

@ -1,3 +1,18 @@
2009-06-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/10270
* elf32-i386.c (elf_i386_allocate_dynrelocs): Disallow
dynamic IFUNC pointer in non-shared object. Use .got.plt
for IFUNC definition in PIE.
(elf_i386_allocate_dynrelocs): Resolve IFUNC definition in
PIE locally.
* elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Disallow
dynamic IFUNC pointer in non-shared object. Use .got.plt
for IFUNC definition in PIE.
(elf64_x86_64_relocate_section): Resolve IFUNC definition in
PIE locally.
2009-06-13 H.J. Lu <hongjiu.lu@intel.com>
* elf32-i386.c (elf_i386_check_relocs): Properly report

View File

@ -2143,6 +2143,27 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
asection *plt, *gotplt, *relplt;
/* When a shared library references a STT_GNU_IFUNC symbol
defined in executable. the .got.plt slot in the shared library
will contain address of the .plt slot in the binary and only
its .got.plt will contain the resolved function that should be
called. Pointer equality won't work correctly. PIE should
be used if pointer equality is required here. */
if (!info->shared
&& (h->dynindx != -1
|| info->export_dynamic)
&& h->pointer_equality_needed)
{
info->callbacks->einfo
(_("%F%P: dynamic STT_GNU_IFUNC symbool `%s' with pointer "
"equality in `%B' can not be used when making an "
"executable; recompile with -fPIE and relink with -pie\n"),
h->root.root.string,
h->root.u.def.section->owner);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
/* Return and discard space for dynamic relocations against it if
it is never referenced in a non-shared object. */
if (!h->ref_regular)
@ -2210,8 +2231,9 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
not dynamic.
2. Use .got.plt in a non-shared object if pointer equality
isn't needed.
3. Use .got.plt if .got isn't used.
4. Otherwise use .got so that it can be shared among different
3. Use .got.plt in PIE.
4. Use .got.plt if .got isn't used.
5. Otherwise use .got so that it can be shared among different
objects at run-time.
We only need to relocate .got entry in shared object. */
if ((info->shared
@ -2219,6 +2241,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|| h->forced_local))
|| (!info->shared
&& !h->pointer_equality_needed)
|| (info->executable && info->shared)
|| htab->sgot == NULL)
{
/* Use .got.plt. */
@ -3194,7 +3217,8 @@ elf_i386_relocate_section (bfd *output_bfd,
+ offset);
if (h->dynindx == -1
|| h->forced_local)
|| h->forced_local
|| info->executable)
{
/* This symbol is resolved locally. */
outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);

View File

@ -1982,6 +1982,27 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{
asection *plt, *gotplt, *relplt;
/* When a shared library references a STT_GNU_IFUNC symbol
defined in executable. the .got.plt slot in the shared library
will contain address of the .plt slot in the binary and only
its .got.plt will contain the resolved function that should be
called. Pointer equality won't work correctly. PIE should
be used if pointer equality is required here. */
if (!info->shared
&& (h->dynindx != -1
|| info->export_dynamic)
&& h->pointer_equality_needed)
{
info->callbacks->einfo
(_("%F%P: dynamic STT_GNU_IFUNC symbool `%s' with pointer "
"equality in `%B' can not be used when making an "
"executable; recompile with -fPIE and relink with -pie\n"),
h->root.root.string,
h->root.u.def.section->owner);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
/* Return and discard space for dynamic relocations against it if
it is never referenced in a non-shared object. */
if (!h->ref_regular)
@ -2049,8 +2070,9 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
not dynamic.
2. Use .got.plt in a non-shared object if pointer equality
isn't needed.
3. Use .got.plt if .got isn't used.
4. Otherwise use .got so that it can be shared among different
3. Use .got.plt in PIE.
4. Use .got.plt if .got isn't used.
5. Otherwise use .got so that it can be shared among different
objects at run-time.
We only need to relocate .got entry in shared object. */
if ((info->shared
@ -2058,6 +2080,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|| h->forced_local))
|| (!info->shared
&& !h->pointer_equality_needed)
|| (info->executable && info->shared)
|| htab->sgot == NULL)
{
/* Use .got.plt. */
@ -2914,7 +2937,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+ input_section->output_offset);
if (h->dynindx == -1
|| h->forced_local)
|| h->forced_local
|| info->executable)
{
/* This symbol is resolved locally. */
outrel.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);

View File

@ -1,20 +1,26 @@
2009-06-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/10270
* ld-ifunc/ifunc-9-x86.d: New.
* ld-ifunc/ifunc-9-x86.s: Likewise.
2009-06-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/10269
*: ld-ifunc/ifunc-1-local-x86.d: New.
*: ld-ifunc/ifunc-1-local-x86.s: Likewise.
*: ld-ifunc/ifunc-2-local-i386.d: Likewise.
*: ld-ifunc/ifunc-2-local-i386.s: Likewise.
*: ld-ifunc/ifunc-2-local-x86-64.d: Likewise.
*: ld-ifunc/ifunc-2-local-x86-64.s: Likewise.
*: ld-ifunc/ifunc-4-local-x86.d: Likewise.
*: ld-ifunc/ifunc-4-local-x86.s: Likewise.
*: ld-ifunc/ifunc-5-local-i386.s: Likewise.
*: ld-ifunc/ifunc-5-local-x86-64.s: Likewise.
*: ld-ifunc/ifunc-5a-local-i386.d: Likewise.
*: ld-ifunc/ifunc-5a-local-x86-64.d: Likewise.
*: ld-ifunc/ifunc-5b-local-i386.d: Likewise.
*: ld-ifunc/ifunc-5b-local-x86-64.d: Likewise.
* ld-ifunc/ifunc-1-local-x86.d: New.
* ld-ifunc/ifunc-1-local-x86.s: Likewise.
* ld-ifunc/ifunc-2-local-i386.d: Likewise.
* ld-ifunc/ifunc-2-local-i386.s: Likewise.
* ld-ifunc/ifunc-2-local-x86-64.d: Likewise.
* ld-ifunc/ifunc-2-local-x86-64.s: Likewise.
* ld-ifunc/ifunc-4-local-x86.d: Likewise.
* ld-ifunc/ifunc-4-local-x86.s: Likewise.
* ld-ifunc/ifunc-5-local-i386.s: Likewise.
* ld-ifunc/ifunc-5-local-x86-64.s: Likewise.
* ld-ifunc/ifunc-5a-local-i386.d: Likewise.
* ld-ifunc/ifunc-5a-local-x86-64.d: Likewise.
* ld-ifunc/ifunc-5b-local-i386.d: Likewise.
* ld-ifunc/ifunc-5b-local-x86-64.d: Likewise.
2009-06-03 H.J. Lu <hongjiu.lu@intel.com>

View File

@ -0,0 +1,3 @@
#ld: --export-dynamic
#error: .*dynamic STT_GNU_IFUNC symbool `foo' with pointer equality in `.*.o' can not be used when making an executable; recompile with -fPIE and relink with -pie
#target: x86_64-*-* i?86-*-*

View File

@ -0,0 +1,18 @@
.text
.type foo, %gnu_indirect_function
.globl foo
.type foo, @function
foo:
ret
.size foo, .-foo
.type start,"function"
.global start
start:
.type _start,"function"
.global _start
_start:
.type __start,"function"
.global __start
__start:
.type __start,"function"
movl foo, %eax