This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] S/390: Fix two issues with the IFUNC optimized mem* routines
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: Andreas Jaeger <aj at suse dot com>
- Cc: libc-alpha at sourceware dot org
- Date: Wed, 29 Aug 2012 13:44:27 +0200
- Subject: Re: [PATCH] S/390: Fix two issues with the IFUNC optimized mem* routines
- References: <20120829104421.GA27985@bart> <2132160.qasrdnDSJk@byrd>
On 29/08/12 13:05, Andreas Jaeger wrote:
> On Wednesday, August 29, 2012 12:44:21 Andreas Krebbel wrote:
>> Hi,
>>
>> the attached patch fixes two problems with the S/390 IFUNC
>> optimization of the mem* functions:
>>
>> 1. In the current implementation the resolver functions reside in a
>> different file than the CPU optimized versions. This requires an
>> R_390_RELATIVE runtime relocation to be generated when the resolver
>> returns the function pointers. This caused a bug with GCJ. libgcj
>> calls memcpy via function pointer (R_390_GLOB_DAT). This relocation
>> is resolved at load time of libgcj. The dynamic linker in that case
>> called the memcpy resolver inside Glibc *before* glibc has been
>> relocated causing the resolver to return a bogus value.
>>
>> This perhaps could also be fixed in the dynamic linker by calling the
>> ifunc resolvers only in a second pass over all the relocations?!
>
> Could this also be an issue on other architectures like x86-64? I had a
> few strange bugreports with LD_BIND_NOW=1 in kde that were impossible to
> debug but seemed to involve multiarch functions,
Not for the Glibc functions I think. The resolver functions for x86_64 use lea to load the
address of the optimized functions. This works without generating runtime relocations.
Another reason is that, according to H.J.Lu, Glibc on x86_64 is always forced to be loaded
first so it wouldn't even be a problem if the resolvers would need runtime relocations.
However, I think this is a general problem which might very well occur with other shared
objects defining IFUNC optimized routines. Forcing IFUNC resolvers to never generate any
runtime relocations to me appears like a rather non-obvious limitation.
Please see the following example on x86-64. The example works fine after making a1 static:
a.c:
#include <stdio.h>
void a (int) __attribute__((ifunc ("resolve_a")));
void a1 (int i)
{
printf("%d\n", i + 1);
}
void (*resolve_a (void)) (int)
{
return &a1;
}
b.c:
extern void a (int);
void (*ap) (int) = a;
void
b (int i)
{
ap (i + 1);
}
main.c:
extern void b (int);
int
main ()
{
b (1);
}
gcc -shared -fpic a.c -o liba.so
gcc -shared -fpic b.c -o libb.so
gcc -o main main.c -L./ -lb -la
export LD_LIBRARY_PATH=./
$ ./main
3
gcc -o main main.c -L./ -la -lb
$ ./main
Segmentation fault