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]

GNU C Library master sources branch master updated. glibc-2.18-450-g7520ff8


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  7520ff8c744a704ca39741c165a2360d63a4f47a (commit)
      from  6f476861be660541eee229acfbc9ef4098af70ab (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7520ff8c744a704ca39741c165a2360d63a4f47a

commit 7520ff8c744a704ca39741c165a2360d63a4f47a
Author: Will Newton <will.newton@linaro.org>
Date:   Mon Nov 25 14:56:28 2013 +0000

    aarch64: Enable ifunc support.
    
    Add support for handling the R_AARCH64_IRELATIVE relocation and
    STT_GNU_IFUNC symbols to the aarch64 port.
    
    ports/ChangeLog.aarch64:
    
    2013-11-26  Will Newton  <will.newton@linaro.org>
    
    	* sysdeps/aarch64/dl-irel.h: Include ldsodefs.h.
    	(ELF_MACHINE_IRELA): Define.  (elf_ifunc_invoke): Pass
    	hwcap to ifunc resolver function.  (elf_irela): New function.
    	* sysdeps/aarch64/dl-machine.h: Include dl-irel.h.
    	(elf_machine_rela) Handle STT_GNU_IFUNC symbols and
    	R_AARCH64_IRELATIVE relocations.  (elf_machine_lazy_rel):
    	Handle R_AARCH64_IRELATIVE relocations.

diff --git a/ports/ChangeLog.aarch64 b/ports/ChangeLog.aarch64
index 1fd96ee..c6331a4 100644
--- a/ports/ChangeLog.aarch64
+++ b/ports/ChangeLog.aarch64
@@ -1,3 +1,13 @@
+2013-11-26  Will Newton  <will.newton@linaro.org>
+
+	* sysdeps/aarch64/dl-irel.h: Include ldsodefs.h.
+	(ELF_MACHINE_IRELA): Define.  (elf_ifunc_invoke): Pass
+	hwcap to ifunc resolver function.  (elf_irela): New function.
+	* sysdeps/aarch64/dl-machine.h: Include dl-irel.h.
+	(elf_machine_rela) Handle STT_GNU_IFUNC symbols and
+	R_AARCH64_IRELATIVE relocations.  (elf_machine_lazy_rel):
+	Handle R_AARCH64_IRELATIVE relocations.
+
 2013-10-30  Mike Frysinger  <vapier@gentoo.org>
 
 	* sysdeps/unix/sysv/linux/aarch64/configure.in: Moved to ...
diff --git a/ports/sysdeps/aarch64/dl-irel.h b/ports/sysdeps/aarch64/dl-irel.h
index 1a3811e..f37ee39 100644
--- a/ports/sysdeps/aarch64/dl-irel.h
+++ b/ports/sysdeps/aarch64/dl-irel.h
@@ -22,15 +22,31 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <ldsodefs.h>
 
-/* AArch64 does not yet implement IFUNC support.  However since
-   2011-06-20 provision of a elf_ifunc_invoke has been mandatory.  */
+#define ELF_MACHINE_IRELA	1
 
 static inline ElfW(Addr)
 __attribute ((always_inline))
 elf_ifunc_invoke (ElfW(Addr) addr)
 {
-  return ((ElfW(Addr) (*) (void)) (addr)) ();
+  return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));
+}
+
+static inline void
+__attribute ((always_inline))
+elf_irela (const ElfW(Rela) *reloc)
+{
+  ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset;
+  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
+
+  if (__glibc_likely (r_type == R_AARCH64_IRELATIVE))
+    {
+      ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend);
+      *reloc_addr = value;
+    }
+  else
+    __libc_fatal ("unexpected reloc type in static binary");
 }
 
 #endif
diff --git a/ports/sysdeps/aarch64/dl-machine.h b/ports/sysdeps/aarch64/dl-machine.h
index 71dd6b3..01a214f 100644
--- a/ports/sysdeps/aarch64/dl-machine.h
+++ b/ports/sysdeps/aarch64/dl-machine.h
@@ -23,6 +23,7 @@
 
 #include <tls.h>
 #include <dl-tlsdesc.h>
+#include <dl-irel.h>
 
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute__ ((unused))
@@ -243,6 +244,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
       ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
 
+      if (sym != NULL
+	  && __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)
+	  && __glibc_likely (sym->st_shndx != SHN_UNDEF)
+	  && __glibc_likely (!skip_ifunc))
+	value = elf_ifunc_invoke (value);
+
       switch (r_type)
 	{
 	case R_AARCH64_COPY:
@@ -331,6 +338,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 	    }
 	  break;
 
+	case R_AARCH64_IRELATIVE:
+	  value = map->l_addr + reloc->r_addend;
+	  value = elf_ifunc_invoke (value);
+	  *reloc_addr = value;
+	  break;
+
 	default:
 	  _dl_reloc_bad_type (map, r_type, 0);
 	  break;
@@ -374,6 +387,13 @@ elf_machine_lazy_rel (struct link_map *map,
       td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
 			  + map->l_addr);
     }
+  else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
+    {
+      ElfW(Addr) value = map->l_addr + reloc->r_addend;
+      if (__glibc_likely (!skip_ifunc))
+	value = elf_ifunc_invoke (value);
+      *reloc_addr = value;
+    }
   else
     _dl_reloc_bad_type (map, r_type, 1);
 }

-----------------------------------------------------------------------

Summary of changes:
 ports/ChangeLog.aarch64            |   10 ++++++++++
 ports/sysdeps/aarch64/dl-irel.h    |   22 +++++++++++++++++++---
 ports/sysdeps/aarch64/dl-machine.h |   20 ++++++++++++++++++++
 3 files changed, 49 insertions(+), 3 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


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