e354a5
commit 558251bd8785760ad40fcbfeaaee5d27fa5b0fe4
e354a5
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
e354a5
Date:   Thu Oct 22 17:55:01 2020 +0100
e354a5
e354a5
    aarch64: Fix DT_AARCH64_VARIANT_PCS handling [BZ #26798]
e354a5
    
e354a5
    The variant PCS support was ineffective because in the common case
e354a5
    linkmap->l_mach.plt == 0 but then the symbol table flags were ignored
e354a5
    and normal lazy binding was used instead of resolving the relocs early.
e354a5
    (This was a misunderstanding about how GOT[1] is setup by the linker.)
e354a5
    
e354a5
    In practice this mainly affects SVE calls when the vector length is
e354a5
    more than 128 bits, then the top bits of the argument registers get
e354a5
    clobbered during lazy binding.
e354a5
    
e354a5
    Fixes bug 26798.
e354a5
e354a5
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
e354a5
index b39eae4acf4086ee..3fd3c8a265d012b1 100644
e354a5
--- a/sysdeps/aarch64/dl-machine.h
e354a5
+++ b/sysdeps/aarch64/dl-machine.h
e354a5
@@ -391,13 +391,6 @@ elf_machine_lazy_rel (struct link_map *map,
e354a5
   /* Check for unexpected PLT reloc type.  */
e354a5
   if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1))
e354a5
     {
e354a5
-      if (map->l_mach.plt == 0)
e354a5
-	{
e354a5
-	  /* Prelinking.  */
e354a5
-	  *reloc_addr += l_addr;
e354a5
-	  return;
e354a5
-	}
e354a5
-
e354a5
       if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL))
e354a5
 	{
e354a5
 	  /* Check the symbol table for variant PCS symbols.  */
e354a5
@@ -421,7 +414,10 @@ elf_machine_lazy_rel (struct link_map *map,
e354a5
 	    }
e354a5
 	}
e354a5
 
e354a5
-      *reloc_addr = map->l_mach.plt;
e354a5
+      if (map->l_mach.plt == 0)
e354a5
+	*reloc_addr += l_addr;
e354a5
+      else
e354a5
+	*reloc_addr = map->l_mach.plt;
e354a5
     }
e354a5
   else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1))
e354a5
     {