[glibc/release/2.27/master] aarch64: Fix DT_AARCH64_VARIANT_PCS handling [BZ #26798]
Szabolcs Nagy
nsz@sourceware.org
Wed Nov 4 12:44:40 GMT 2020
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=dc7f51bda99fa8eceb7f9049c0a9827064ff7e85
commit dc7f51bda99fa8eceb7f9049c0a9827064ff7e85
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Thu Oct 22 17:55:01 2020 +0100
aarch64: Fix DT_AARCH64_VARIANT_PCS handling [BZ #26798]
The variant PCS support was ineffective because in the common case
linkmap->l_mach.plt == 0 but then the symbol table flags were ignored
and normal lazy binding was used instead of resolving the relocs early.
(This was a misunderstanding about how GOT[1] is setup by the linker.)
In practice this mainly affects SVE calls when the vector length is
more than 128 bits, then the top bits of the argument registers get
clobbered during lazy binding.
Fixes bug 26798.
(cherry picked from commit 558251bd8785760ad40fcbfeaaee5d27fa5b0fe4)
Diff:
---
sysdeps/aarch64/dl-machine.h | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 0c1f8d66b3..8989398186 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -388,13 +388,6 @@ elf_machine_lazy_rel (struct link_map *map,
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1))
{
- if (map->l_mach.plt == 0)
- {
- /* Prelinking. */
- *reloc_addr += l_addr;
- return;
- }
-
if (1) /* DT_AARCH64_VARIANT_PCS is not available, so always check. */
{
/* Check the symbol table for variant PCS symbols. */
@@ -418,7 +411,10 @@ elf_machine_lazy_rel (struct link_map *map,
}
}
- *reloc_addr = map->l_mach.plt;
+ if (map->l_mach.plt == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr = map->l_mach.plt;
}
else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1))
{
More information about the Glibc-cvs
mailing list