summaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2022-04-26 09:08:54 -0700
committerH.J. Lu <hjl.tools@gmail.com>2022-04-28 09:20:30 -0700
commit68c4956b1401de70173848a6bdf620cb42fa9358 (patch)
tree4e78b4d2d33a9b17371e61aade9b168d0bb377fa /bfd/elf64-x86-64.c
parent9dd9f9ce1e231ef594845f11c05a724653241b58 (diff)
downloadbinutils-gdb-68c4956b1401de70173848a6bdf620cb42fa9358.tar.gz
x86: Properly handle function pointer reference
Update commit ebb191adac4ab45498dec0bfaac62f0a33537ba4 Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed Feb 9 15:51:22 2022 -0800 x86: Disallow invalid relocation against protected symbol to allow function pointer reference and make sure that PLT entry isn't used for function reference due to function pointer reference. bfd/ PR ld/29087 * elf32-i386.c (elf_i386_scan_relocs): Don't set pointer_equality_needed nor check non-canonical reference for function pointer reference. * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise. ld/ PR ld/29087 * testsuite/ld-x86-64/x86-64.exp: Run PR ld/29087 tests. * testsuite/ld-x86-64/protected-func-3.c: New file.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 6cebc7ca2b3..6d69d6141ee 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2211,33 +2211,18 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
else if (r_type != R_X86_64_PC32_BND
&& r_type != R_X86_64_PC64)
{
- h->pointer_equality_needed = 1;
/* At run-time, R_X86_64_64 can be resolved for both
x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
- can only be resolved for x32. */
+ can only be resolved for x32. Function pointer
+ reference doesn't need PLT for pointer equality. */
if ((sec->flags & SEC_READONLY) == 0
&& (r_type == R_X86_64_64
|| (!ABI_64_P (abfd)
&& (r_type == R_X86_64_32
|| r_type == R_X86_64_32S))))
func_pointer_ref = true;
- }
-
- if (h->pointer_equality_needed
- && h->type == STT_FUNC
- && eh->def_protected
- && elf_has_indirect_extern_access (h->root.u.def.section->owner))
- {
- /* Disallow non-canonical reference to canonical
- protected function. */
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pB: non-canonical reference to canonical "
- "protected function `%s' in %pB"),
- abfd, h->root.root.string,
- h->root.u.def.section->owner);
- bfd_set_error (bfd_error_bad_value);
- goto error_return;
+ else
+ h->pointer_equality_needed = 1;
}
if (!func_pointer_ref)
@@ -2259,6 +2244,23 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
if (!h->def_regular
|| (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
h->plt.refcount = 1;
+
+ if (h->pointer_equality_needed
+ && h->type == STT_FUNC
+ && eh->def_protected
+ && elf_has_indirect_extern_access (h->root.u.def.section->owner))
+ {
+ /* Disallow non-canonical reference to canonical
+ protected function. */
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: non-canonical reference to canonical "
+ "protected function `%s' in %pB"),
+ abfd, h->root.root.string,
+ h->root.u.def.section->owner);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
}
}