This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
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