93 lines
3.1 KiB
Diff
93 lines
3.1 KiB
Diff
diff -rup binutils.orig/bfd/elf32-i386.c binutils-2.38/bfd/elf32-i386.c
|
|
--- binutils.orig/bfd/elf32-i386.c 2022-05-24 12:01:20.307998318 +0100
|
|
+++ binutils-2.38/bfd/elf32-i386.c 2022-05-24 12:04:48.789688224 +0100
|
|
@@ -1772,11 +1772,14 @@ elf_i386_scan_relocs (bfd *abfd,
|
|
}
|
|
else
|
|
{
|
|
- h->pointer_equality_needed = 1;
|
|
- /* R_386_32 can be resolved at run-time. */
|
|
+ /* R_386_32 can be resolved at run-time. Function
|
|
+ pointer reference doesn't need PLT for pointer
|
|
+ equality. */
|
|
if (r_type == R_386_32
|
|
&& (sec->flags & SEC_READONLY) == 0)
|
|
func_pointer_ref = true;
|
|
+ else
|
|
+ h->pointer_equality_needed = 1;
|
|
}
|
|
|
|
if (!func_pointer_ref)
|
|
@@ -1798,6 +1801,23 @@ elf_i386_scan_relocs (bfd *abfd,
|
|
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;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff -rup binutils.orig/bfd/elf64-x86-64.c binutils-2.38/bfd/elf64-x86-64.c
|
|
--- binutils.orig/bfd/elf64-x86-64.c 2022-05-24 12:01:20.296998387 +0100
|
|
+++ binutils-2.38/bfd/elf64-x86-64.c 2022-05-24 12:06:07.720192208 +0100
|
|
@@ -2211,16 +2211,18 @@ elf_x86_64_scan_relocs (bfd *abfd, struc
|
|
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;
|
|
+ else
|
|
+ h->pointer_equality_needed = 1;
|
|
}
|
|
|
|
if (!func_pointer_ref)
|
|
@@ -2242,6 +2244,23 @@ elf_x86_64_scan_relocs (bfd *abfd, struc
|
|
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;
|
|
+ }
|
|
}
|
|
}
|
|
|