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.14-319-g3a62d00


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  3a62d00d408e9ec19479b6c7d39e89021061f9cd (commit)
      from  68577918437e2ccfd6bd2836892f59ef42994963 (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://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3a62d00d408e9ec19479b6c7d39e89021061f9cd

commit 3a62d00d408e9ec19479b6c7d39e89021061f9cd
Author: Andreas Schwab <schwab@redhat.com>
Date:   Tue Oct 4 16:10:16 2011 +0200

    Don't call ifunc functions in trace mode

diff --git a/ChangeLog b/ChangeLog
index a8ccdac..2fdde34 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+2011-10-04  Andreas Schwab  <schwab@redhat.com>
+
+	* include/dlfcn.h (__RTLD_NOIFUNC): Define.
+	* elf/do-rel.h (elf_dynamic_do_rel): Add parameter skip_ifunc and
+	pass it down.
+	* elf/dynamic-link.h: Adjust prototypes of elf_machine_rel,
+	elf_machine_rela, elf_machine_lazy_rel.
+	(_ELF_DYNAMIC_DO_RELOC): Add parameter skip_ifunc and pass it down.
+	(ELF_DYNAMIC_DO_REL): Likewise.
+	(ELF_DYNAMIC_DO_RELA): Likewise.
+	(ELF_DYNAMIC_RELOCATE): Likewise.
+	* elf/dl-reloc.c (_dl_relocate_object): Pass __RTLD_NOIFUNC down
+	to ELF_DYNAMIC_DO_REL.
+	* elf/rtld.c (_dl_start): Adjust use of ELF_DYNAMIC_RELOCATE.
+	(dl_main): In trace mode always set __RTLD_NOIFUNC.
+	* elf/dl-conflict.c (_dl_resolve_conflicts): Adjust call to
+	elf_machine_rela.
+	* sysdeps/i386/dl-machine.h (elf_machine_rel): Add parameter
+	skip_ifunc, don't call ifunc function if non-zero.
+	(elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	(elf_machine_lazy_rela): Likewise.
+	* sysdeps/ia64/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela):
+	Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela):
+	Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+	* sysdeps/x86_64/dl-machine.h (elf_machine_rela): Likewise.
+	(elf_machine_lazy_rel): Likewise.
+
 2011-09-28  Ulrich Drepper  <drepper@gmail.com>
 
 	* nss/nss_files/files-init.c (_nss_files_init): Use static
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
index b730105..653e446 100644
--- a/elf/dl-conflict.c
+++ b/elf/dl-conflict.c
@@ -1,5 +1,5 @@
 /* Resolve conflicts against already prelinked libraries.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
 
@@ -69,7 +69,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
     GL(dl_num_cache_relocations) += conflictend - conflict;
 
     for (; conflict < conflictend; ++conflict)
-      elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset);
+      elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
+			0);
   }
 #endif
 }
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 7294112..c57b0f0 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -162,6 +162,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
   /* Initialize it to make the compiler happy.  */
   const char *errstring = NULL;
   int lazy = reloc_mode & RTLD_LAZY;
+  int skip_ifunc = reloc_mode & __RTLD_NOIFUNC;
 
 #ifdef SHARED
   /* If we are auditing, install the same handlers we need for profiling.  */
@@ -261,7 +262,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
 #include "dynamic-link.h"
 
-    ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
+    ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
 
 #ifndef PROF
     if (__builtin_expect (consider_profiling, 0))
diff --git a/elf/do-rel.h b/elf/do-rel.h
index 990b961..6187b9e 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -1,5 +1,5 @@
 /* Do relocations for ELF dynamic linking.
-   Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2003, 2004, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -52,7 +52,7 @@
 auto inline void __attribute__ ((always_inline))
 elf_dynamic_do_rel (struct link_map *map,
 		    ElfW(Addr) reladdr, ElfW(Addr) relsize,
-		    int lazy)
+		    int lazy, int skip_ifunc)
 {
   const ElfW(Rel) *r = (const void *) reladdr;
   const ElfW(Rel) *end = (const void *) (reladdr + relsize);
@@ -66,7 +66,7 @@ elf_dynamic_do_rel (struct link_map *map,
     {
       /* Doing lazy PLT relocations; they need very little info.  */
       for (; r < end; ++r)
-	elf_machine_lazy_rel (map, l_addr, r);
+	elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
     }
   else
 #endif
@@ -119,14 +119,14 @@ elf_dynamic_do_rel (struct link_map *map,
 	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
 	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
 			       &map->l_versions[ndx],
-			       (void *) (l_addr + r->r_offset));
+			       (void *) (l_addr + r->r_offset), skip_ifunc);
 	    }
 	}
 #ifndef RTLD_BOOTSTRAP
       else
 	for (; r < end; ++r)
 	  elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
-			   (void *) (l_addr + r->r_offset));
+			   (void *) (l_addr + r->r_offset), skip_ifunc);
 #endif
     }
 }
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 9c16da4..2bdab45 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -60,7 +60,7 @@ int internal_function _dl_try_allocate_static_tls (struct link_map *map);
 auto inline void __attribute__((always_inline))
 elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
 		 const ElfW(Sym) *sym, const struct r_found_version *version,
-		 void *const reloc_addr);
+		 void *const reloc_addr, int skip_ifunc);
 auto inline void __attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 			  void *const reloc_addr);
@@ -69,7 +69,7 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 auto inline void __attribute__((always_inline))
 elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 		  const ElfW(Sym) *sym, const struct r_found_version *version,
-		  void *const reloc_addr);
+		  void *const reloc_addr, int skip_ifunc);
 auto inline void __attribute__((always_inline))
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 			   void *const reloc_addr);
@@ -77,11 +77,13 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
 auto inline void __attribute__((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc);
+		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
+		      int skip_ifunc);
 # else
 auto inline void __attribute__((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc);
+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+		      int skip_ifunc);
 # endif
 #endif
 
@@ -254,7 +256,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
    not happen we do something more optimal.  */
 
 # ifdef ELF_MACHINE_PLTREL_OVERLAP
-#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
+#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
   do {									      \
     struct { ElfW(Addr) start, size; int lazy; } ranges[3];		      \
     int ranges_index;							      \
@@ -284,10 +286,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
       elf_dynamic_do_##reloc ((map),					      \
 			      ranges[ranges_index].start,		      \
 			      ranges[ranges_index].size,		      \
-			      ranges[ranges_index].lazy);		      \
+			      ranges[ranges_index].lazy,		      \
+			      skip_ifunc);				      \
   } while (0)
 # else
-#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
+#  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
   do {									      \
     struct { ElfW(Addr) start, size; int lazy; } ranges[2];		      \
     ranges[0].lazy = 0;							      \
@@ -324,7 +327,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
       }									      \
 									      \
     if (ELF_DURING_STARTUP)						      \
-      elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0);     \
+      elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0,      \
+			      skip_ifunc);				      \
     else								      \
       {									      \
 	int ranges_index;						      \
@@ -332,7 +336,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
 	  elf_dynamic_do_##reloc ((map),				      \
 				  ranges[ranges_index].start,		      \
 				  ranges[ranges_index].size,		      \
-				  ranges[ranges_index].lazy);		      \
+				  ranges[ranges_index].lazy,		      \
+				  skip_ifunc);				      \
       }									      \
   } while (0)
 # endif
@@ -345,29 +350,29 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
 
 # if ! ELF_MACHINE_NO_REL
 #  include "do-rel.h"
-#  define ELF_DYNAMIC_DO_REL(map, lazy) \
-  _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL)
+#  define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
+  _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
 # else
-#  define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do.  */
+#  define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do.  */
 # endif
 
 # if ! ELF_MACHINE_NO_RELA
 #  define DO_RELA
 #  include "do-rel.h"
-#  define ELF_DYNAMIC_DO_RELA(map, lazy) \
-  _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL)
+#  define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
+  _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
 # else
-#  define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do.  */
+#  define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do.  */
 # endif
 
 /* This can't just be an inline function because GCC is too dumb
    to inline functions containing inlines themselves.  */
-# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \
+# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \
   do {									      \
     int edr_lazy = elf_machine_runtime_setup ((map), (lazy),		      \
 					      (consider_profile));	      \
-    ELF_DYNAMIC_DO_REL ((map), edr_lazy);				      \
-    ELF_DYNAMIC_DO_RELA ((map), edr_lazy);				      \
+    ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc);			      \
+    ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc);			      \
   } while (0)
 
 #endif
diff --git a/elf/rtld.c b/elf/rtld.c
index 324d979..e4e413f 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -544,7 +544,7 @@ _dl_start (void *arg)
       /* Relocate ourselves so we can do normal function calls and
 	 data access using the global offset table.  */
 
-      ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
+      ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
     }
   bootstrap_map.l_relocated = 1;
 
@@ -1951,8 +1951,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 
 	  /* Relocate the main executable.  */
 	  struct relocate_args args = { .l = l,
-					.reloc_mode = (GLRO(dl_lazy)
-						       ? RTLD_LAZY : 0) };
+					.reloc_mode = ((GLRO(dl_lazy)
+						       ? RTLD_LAZY : 0)
+						       | __RTLD_NOIFUNC) };
 	  _dl_receive_error (print_unresolved, relocate_doit, &args);
 
 	  /* This loop depends on the dependencies of the executable to
@@ -2029,7 +2030,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 	      struct relocate_args args;
 	      unsigned int i;
 
-	      args.reloc_mode = GLRO(dl_lazy) ? RTLD_LAZY : 0;
+	      args.reloc_mode = ((GLRO(dl_lazy) ? RTLD_LAZY : 0)
+				 | __RTLD_NOIFUNC);
 
 	      i = main_map->l_searchlist.r_nlist;
 	      while (i-- > 0)
@@ -2049,7 +2051,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 		  /* Mark the link map as not yet relocated again.  */
 		  GL(dl_rtld_map).l_relocated = 0;
 		  _dl_relocate_object (&GL(dl_rtld_map),
-				       main_map->l_scope, 0, 0);
+				       main_map->l_scope, __RTLD_NOIFUNC, 0);
 		}
 	    }
 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
diff --git a/include/dlfcn.h b/include/dlfcn.h
index af92483..9e76d35 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -10,6 +10,7 @@
 #define __RTLD_CALLMAP	0x10000000
 #define __RTLD_AUDIT	0x08000000
 #define __RTLD_SECURE	0x04000000 /* Apply additional security checks.  */
+#define __RTLD_NOIFUNC	0x02000000 /* Suppress calling ifunc functions.  */
 
 #define __LM_ID_CALLER	-2
 
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index d1a83ee..9469a2b 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -305,7 +305,7 @@ auto inline void
 __attribute ((always_inline))
 elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
 		 const Elf32_Sym *sym, const struct r_found_version *version,
-		 void *const reloc_addr_arg)
+		 void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -341,7 +341,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
       if (sym != NULL
 	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
 			       0)
-	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+	  && __builtin_expect (!skip_ifunc, 1))
 	value = ((Elf32_Addr (*) (void)) value) ();
 
       switch (r_type)
@@ -482,7 +483,7 @@ auto inline void
 __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -499,8 +500,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 
       if (sym != NULL
 	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
-	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
-			       0))
+	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
+	  && __builtin_expect (!skip_ifunc, 1))
 	value = ((Elf32_Addr (*) (void)) value) ();
 
       switch (ELF32_R_TYPE (reloc->r_info))
@@ -647,7 +648,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf32_Addr l_addr, const Elf32_Rel *reloc)
+		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
+		      int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -698,19 +700,20 @@ elf_machine_lazy_rel (struct link_map *map,
 	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
 	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
 			       &map->l_versions[ndx],
-			       (void *) (l_addr + r->r_offset));
+			       (void *) (l_addr + r->r_offset), skip_ifunc);
 	    }
 # ifndef RTLD_BOOTSTRAP
 	  else
 	    elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
-			     (void *) (l_addr + r->r_offset));
+			     (void *) (l_addr + r->r_offset), skip_ifunc);
 # endif
 	}
     }
   else if (__builtin_expect (r_type == R_386_IRELATIVE, 0))
     {
       Elf32_Addr value = map->l_addr + *reloc_addr;
-      value = ((Elf32_Addr (*) (void)) value) ();
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = ((Elf32_Addr (*) (void)) value) ();
       *reloc_addr = value;
     }
   else
@@ -722,7 +725,8 @@ elf_machine_lazy_rel (struct link_map *map,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rela (struct link_map *map,
-		       Elf32_Addr l_addr, const Elf32_Rela *reloc)
+		       Elf32_Addr l_addr, const Elf32_Rela *reloc,
+		       int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -739,7 +743,8 @@ elf_machine_lazy_rela (struct link_map *map,
   else if (__builtin_expect (r_type == R_386_IRELATIVE, 0))
     {
       Elf32_Addr value = map->l_addr + reloc->r_addend;
-      value = ((Elf32_Addr (*) (void)) value) ();
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = ((Elf32_Addr (*) (void)) value) ();
       *reloc_addr = value;
     }
   else
diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
index 6f88005..6053b3b 100644
--- a/sysdeps/ia64/dl-machine.h
+++ b/sysdeps/ia64/dl-machine.h
@@ -372,7 +372,8 @@ elf_machine_rela (struct link_map *map,
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg,
+		  int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -486,7 +487,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 auto inline void
 __attribute ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf64_Addr l_addr, const Elf64_Rela *reloc)
+		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index e7052b6..b24fee0 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -272,7 +272,7 @@ extern void _dl_reloc_overflow (struct link_map *map,
 auto inline void __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const Elf32_Sym *const refsym = sym;
@@ -307,7 +307,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
-      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+      && __builtin_expect (!skip_ifunc, 1))
     value = ((Elf32_Addr (*) (void)) value) ();
 
   /* A small amount of code is duplicated here for speed.  In libc,
@@ -382,7 +383,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 
 auto inline void __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf32_Addr l_addr, const Elf32_Rela *reloc)
+		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
+		      int skip_ifunc)
 {
   /* elf_machine_runtime_setup handles this. */
 }
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index ab90d1e..f4265bb 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -556,7 +556,8 @@ elf_machine_rela (struct link_map *map,
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg,
+		  int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -579,7 +580,8 @@ elf_machine_rela (struct link_map *map,
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
-      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+      && __builtin_expect (!skip_ifunc, 1))
     value = resolve_ifunc (value, map, sym_map);
 
   /* For relocs that don't edit code, return.
@@ -592,12 +594,14 @@ elf_machine_rela (struct link_map *map,
       return;
 
     case R_PPC64_IRELATIVE:
-      value = resolve_ifunc (value, map, sym_map);
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = resolve_ifunc (value, map, sym_map);
       *reloc_addr = value;
       return;
 
     case R_PPC64_JMP_IREL:
-      value = resolve_ifunc (value, map, sym_map);
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = resolve_ifunc (value, map, sym_map);
       /* Fall thru */
     case R_PPC64_JMP_SLOT:
 #ifdef RESOLVE_CONFLICT_FIND_MAP
@@ -846,7 +850,8 @@ elf_machine_rela (struct link_map *map,
 
 auto inline void __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf64_Addr l_addr, const Elf64_Rela *reloc)
+		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
+		      int skip_ifunc)
 {
   /* elf_machine_runtime_setup handles this.  */
 }
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index b1f6f41..ea7c6a6 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -275,7 +275,7 @@ auto inline void
 __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -433,7 +433,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf32_Addr l_addr, const Elf32_Rela *reloc)
+		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index 913ea08..68015a7 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -247,7 +247,7 @@ auto inline void
 __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -412,7 +412,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf64_Addr l_addr, const Elf64_Rela *reloc)
+		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index 4e09ea4..e02f47c 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -262,7 +262,7 @@ auto inline void
 __attribute ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -446,7 +446,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf32_Addr l_addr, const Elf32_Rela *reloc)
+		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   /* Check for unexpected PLT reloc type.  */
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 8f54f7e..0ef5d28 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -342,7 +342,7 @@ auto inline void
 __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const Elf32_Sym *const refsym = sym;
@@ -392,7 +392,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
-      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+      && __builtin_expect (!skip_ifunc, 1))
     {
       value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap));
     }
@@ -546,7 +547,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf32_Addr l_addr, const Elf32_Rela *reloc)
+		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -556,7 +558,8 @@ elf_machine_lazy_rel (struct link_map *map,
   else if (r_type == R_SPARC_JMP_IREL)
     {
       Elf32_Addr value = map->l_addr + reloc->r_addend;
-      value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap));
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap));
       sparc_fixup_plt (reloc, reloc_addr, value, 1, 1);
     }
   else if (r_type == R_SPARC_NONE)
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 47579cd..501092e 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -368,7 +368,7 @@ auto inline void
 __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
 #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
@@ -422,7 +422,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
-      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+      && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+      && __builtin_expect (!skip_ifunc, 1))
     value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap));
 
   switch (r_type)
@@ -639,7 +640,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 auto inline void
 __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf64_Addr l_addr, const Elf64_Rela *reloc)
+		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -650,7 +652,8 @@ elf_machine_lazy_rel (struct link_map *map,
 	   || r_type == R_SPARC_IRELATIVE)
     {
       Elf64_Addr value = map->l_addr + reloc->r_addend;
-      value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap));
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap));
       if (r_type == R_SPARC_JMP_IREL)
 	{
 	  /* 'high' is always zero, for large PLT entries the linker
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 4c31ac5..6d66ff6 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -255,7 +255,7 @@ auto inline void
 __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg)
+		  void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -293,7 +293,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
       if (sym != NULL
 	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
 			       0)
-	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1))
+	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+	  && __builtin_expect (!skip_ifunc, 1))
 	value = ((Elf64_Addr (*) (void)) value) ();
 
       switch (r_type)
@@ -459,7 +460,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 auto inline void
 __attribute ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf64_Addr l_addr, const Elf64_Rela *reloc)
+		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
+		      int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -486,7 +488,8 @@ elf_machine_lazy_rel (struct link_map *map,
   else if (__builtin_expect (r_type == R_X86_64_IRELATIVE, 0))
     {
       Elf64_Addr value = map->l_addr + reloc->r_addend;
-      value = ((Elf64_Addr (*) (void)) value) ();
+      if (__builtin_expect (!skip_ifunc, 1))
+	value = ((Elf64_Addr (*) (void)) value) ();
       *reloc_addr = value;
     }
   else

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

Summary of changes:
 ChangeLog                              |   43 ++++++++++++++++++++++++++++++++
 elf/dl-conflict.c                      |    5 ++-
 elf/dl-reloc.c                         |    3 +-
 elf/do-rel.h                           |   10 +++---
 elf/dynamic-link.h                     |   41 +++++++++++++++++-------------
 elf/rtld.c                             |   12 +++++---
 include/dlfcn.h                        |    1 +
 sysdeps/i386/dl-machine.h              |   27 ++++++++++++--------
 sysdeps/ia64/dl-machine.h              |    6 +++-
 sysdeps/powerpc/powerpc32/dl-machine.h |    8 +++--
 sysdeps/powerpc/powerpc64/dl-machine.h |   15 +++++++---
 sysdeps/s390/s390-32/dl-machine.h      |    5 ++-
 sysdeps/s390/s390-64/dl-machine.h      |    5 ++-
 sysdeps/sh/dl-machine.h                |    5 ++-
 sysdeps/sparc/sparc32/dl-machine.h     |   11 +++++---
 sysdeps/sparc/sparc64/dl-machine.h     |   11 +++++---
 sysdeps/x86_64/dl-machine.h            |   11 +++++---
 17 files changed, 149 insertions(+), 70 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]