This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[glibc/release/2.26/master] aarch64: handle STO_AARCH64_VARIANT_PCS


https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f2f501ff397953d711ce249bc705fb6139ab1f7b

commit f2f501ff397953d711ce249bc705fb6139ab1f7b
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Thu Apr 25 15:35:35 2019 +0100

    aarch64: handle STO_AARCH64_VARIANT_PCS
    
    Backport of commit 82bc69c012838a381c4167c156a06f4598f34227
    and commit 30ba0375464f34e4bf8129f3d3dc14d0c09add17
    without using DT_AARCH64_VARIANT_PCS for optimizing the symbol table check.
    This is needed so the internal abi between ld.so and libc.so is unchanged.
    
    Avoid lazy binding of symbols that may follow a variant PCS with different
    register usage convention from the base PCS.
    
    Currently the lazy binding entry code does not preserve all the registers
    required for AdvSIMD and SVE vector calls.  Saving and restoring all
    registers unconditionally may break existing binaries, even if they never
    use vector calls, because of the larger stack requirement for lazy
    resolution, which can be significant on an SVE system.
    
    The solution is to mark all symbols in the symbol table that may follow
    a variant PCS so the dynamic linker can handle them specially.  In this
    patch such symbols are always resolved at load time, not lazily.
    
    So currently LD_AUDIT for variant PCS symbols are not supported, for that
    the _dl_runtime_profile entry needs to be changed e.g. to unconditionally
    save/restore all registers (but pass down arg and retval registers to
    pltentry/exit callbacks according to the base PCS).
    
    This patch also removes a __builtin_expect from the modified code because
    the branch prediction hint did not seem useful.
    
    	* sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Check
    	STO_AARCH64_VARIANT_PCS and bind such symbols at load time.

Diff:
---
 ChangeLog                    |  5 +++++
 sysdeps/aarch64/dl-machine.h | 35 +++++++++++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 55dde7d..8a2fad8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2019-07-12  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+	* sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Check
+	STO_AARCH64_VARIANT_PCS and bind such symbols at load time.
+
 2019-06-13  Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
 	* elf/elf.h (STO_AARCH64_VARIANT_PCS): Define.
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 3fb00e6..9ffc2e4 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -391,10 +391,37 @@ 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 (__builtin_expect (map->l_mach.plt, 0) == 0)
-	*reloc_addr += l_addr;
-      else
-	*reloc_addr = map->l_mach.plt;
+      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.  */
+	  const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
+	  const ElfW (Sym) *symtab =
+	    (const void *)D_PTR (map, l_info[DT_SYMTAB]);
+	  const ElfW (Sym) *sym = &symtab[symndx];
+	  if (__glibc_unlikely (sym->st_other & STO_AARCH64_VARIANT_PCS))
+	    {
+	      /* Avoid lazy resolution of variant PCS symbols.  */
+	      const struct r_found_version *version = NULL;
+	      if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+		{
+		  const ElfW (Half) *vernum =
+		    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
+		  version = &map->l_versions[vernum[symndx] & 0x7fff];
+		}
+	      elf_machine_rela (map, reloc, sym, version, reloc_addr,
+				skip_ifunc);
+	      return;
+	    }
+	}
+
+      *reloc_addr = map->l_mach.plt;
     }
   else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1))
     {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]