about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2020-10-22 17:55:01 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2020-11-04 12:30:42 +0000
commit268df5a91054fcb4284e8504afd086a769ec4c40 (patch)
tree1a5619dcee24cf9827b517a9a879aa53e2488590
parent2b802d55b70154d1864a4f0bac973af354408e83 (diff)
downloadglibc-release/2.26/master.tar.gz
glibc-release/2.26/master.tar.xz
glibc-release/2.26/master.zip
aarch64: Fix DT_AARCH64_VARIANT_PCS handling [BZ #26798] release/2.26/master
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)
-rw-r--r--sysdeps/aarch64/dl-machine.h12
1 files changed, 4 insertions, 8 deletions
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 9ffc2e4c9d..b5a0bdad95 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -391,13 +391,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.  */
@@ -421,7 +414,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))
     {