This is the mail archive of the libc-alpha@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]

Re: [SPARC] Segfault when resolving STT_GNU_IFUNC functions


On Fri, Jun 10, 2011 at 03:58:42PM -0700, David Miller wrote:
> From: Aurelien Jarno <aurelien@aurel32.net>
> Date: Sat, 11 Jun 2011 00:27:12 +0200
> 
> > The problems happens because the IFUNC resolvers are sometimes also
> > called from generic code, in this case from elf/dl-runtime.c. The patch
> > below fixes the problem on sparc following the same principle, but is
> > just there to show the issue, it's not acceptable for mainline.
> 
> Thanks for debugging this.
> 
> If doing this generically isn't an option, we can abstract this call
> out into an arch header file such as dl-irel.h
> 
> Although, frankly I don't see why doing it generically would be a bad
> idea.

Just due to the fact that it will add some more instructions to pass the
values on all architectures, while only one is actually using it.

That said if it is acceptable, I have prepared a patch to fix all these
calls. I have verified that it fixes all the regressions for both
sparc32 and sparc64 on an Ultrasparc III machine. The testsuite results
is now identical with --enable-multi-arch and with --disable-multi-arch.

2011-06-11  Aurelien Jarno  <aurelien@aurel32.net>

	* elf/dl-runtime.c(_dl_fixup,_dl_profile_fixup): Pass dl_hwcap to
	ifuncs.
	* elf/dl-sym.c(do_sym): Likewise.

diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index b27cfbf..f48702b 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -146,7 +146,8 @@ _dl_fixup (
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
-    value = ((DL_FIXUP_VALUE_TYPE (*) (void)) DL_FIXUP_VALUE_ADDR (value)) ();
+    value = ((DL_FIXUP_VALUE_TYPE (*) (int))
+	     DL_FIXUP_VALUE_ADDR (value)) (GLRO(dl_hwcap));
 
   /* Finally, fix up the plt itself.  */
   if (__builtin_expect (GLRO(dl_bind_not), 0))
@@ -235,8 +236,8 @@ _dl_profile_fixup (
 	  if (defsym != NULL
 	      && __builtin_expect (ELFW(ST_TYPE) (defsym->st_info)
 				   == STT_GNU_IFUNC, 0))
-	    value = ((DL_FIXUP_VALUE_TYPE (*) (void))
-		     DL_FIXUP_VALUE_ADDR (value)) ();
+	    value = ((DL_FIXUP_VALUE_TYPE (*) (int))
+		     DL_FIXUP_VALUE_ADDR (value)) (GLRO(dl_hwcap));
 	}
       else
 	{
@@ -246,8 +247,8 @@ _dl_profile_fixup (
 
 	  if (__builtin_expect (ELFW(ST_TYPE) (refsym->st_info)
 				== STT_GNU_IFUNC, 0))
-	    value = ((DL_FIXUP_VALUE_TYPE (*) (void))
-		     DL_FIXUP_VALUE_ADDR (value)) ();
+	    value = ((DL_FIXUP_VALUE_TYPE (*) (int))
+		     DL_FIXUP_VALUE_ADDR (value)) (GLRO(dl_hwcap));
 
 	  result = l;
 	}
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 4faf05c..de6d34a 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -197,7 +197,8 @@ RTLD_NEXT used in code not dynamically loaded"));
 	  DL_FIXUP_VALUE_TYPE fixup
 	    = DL_FIXUP_MAKE_VALUE (result, (ElfW(Addr)) value);
 	  fixup =
-	    ((DL_FIXUP_VALUE_TYPE (*) (void)) DL_FIXUP_VALUE_ADDR (fixup)) ();
+	    ((DL_FIXUP_VALUE_TYPE (*) (int))
+	     DL_FIXUP_VALUE_ADDR (fixup)) (GLRO(dl_hwcap));
 	  value = (void *) DL_FIXUP_VALUE_CODE_ADDR (fixup);
 	}
 


-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net


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