diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2022-04-26 09:08:54 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2022-04-28 09:20:30 -0700 |
commit | 68c4956b1401de70173848a6bdf620cb42fa9358 (patch) | |
tree | 4e78b4d2d33a9b17371e61aade9b168d0bb377fa /bfd/elf64-x86-64.c | |
parent | 9dd9f9ce1e231ef594845f11c05a724653241b58 (diff) | |
download | gdb-68c4956b1401de70173848a6bdf620cb42fa9358.zip gdb-68c4956b1401de70173848a6bdf620cb42fa9358.tar.gz gdb-68c4956b1401de70173848a6bdf620cb42fa9358.tar.bz2 |
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.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 6cebc7c..6d69d61 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; + } } } |