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