IFUNCs used by libc.so.6 internally on x86-64
Stefan Liebler
stli@linux.vnet.ibm.com
Wed May 31 14:55:00 GMT 2017
On 02/06/2017 01:53 PM, Florian Weimer wrote:
> I put a debug printf into IRELATIVE processing and resolved the
> addresses using GDB. This way, I identified the following IFUNC-based
> relocations within libc.so.6:
>
> gettimeofday
> memmove
> strcasecmp
> strcspn
> strncasecmp
> strpbrk
> strspn
> time
>
> time and gettimeofday appear to be side effects of the use of vsyscalls.
> clock_gettime is not in this list because there is no direct call to
> the function in libc.so, I think. timespec_get could use it, but it
> currently has INTERNAL_VSYSCALL instead.
>
> The selection of string functions is rather curious. Were these choices
> deliberate? Why memmove and not memcpy, for example?
>
> Should we revisit our previous approach not to use IFUNCs within
> libc.so? Not using IFUNCs means that we increase the icache footprint
> because libc.so and and other code in the process use different
> implementations. And if we want to optimize the callers of functions
> which normally call those IFUNCs, we'd need to turn them into IFUNCs as
> well. (IFUNCs are contagious in this way.)
>
> Thanks,
> Florian
>
A colleague of mine reported "Invalid read"-valgrind messages with a
sample program on s390x:
int main()
{
strtok(strdup("xxxx"), "ab");
return 0;
}
The reads happen in strcspn which is called by strtok.
On s390x, the default strcspn ifunc-variant (which is string/strcspn.c)
is called directly without PLT.
On x86_64/ppc, strcspn is called via PLT and valgrind replaces strcspn
with it's own implementation.
Unfortunatley strtok is not replaced by valgrind.
Is there or shall we have a policy to allow / forbid the usage of
internal IFUNCs?
Or is this a question which has to be answered for each function on
every architecture?
OndÅej's commit "Use strspn/strcspn/strpbrk ifunc in internal calls."
(https://sourceware.org/git/?p=glibc.git;a=commit;h=0f4840be2528b3e3f2ecea009ab08e753701e9be)
introduced some of the internal IFUNCs:
"
A comment:
/* It doesn't make sense to send libc-internal strcspn calls through a PLT.
The speedup we get from using SSE4.2 instruction is likely eaten away
by the indirect call in the PLT. */
Does not make sense at all because nobody bothered to check it. Gap
between these implementations is quite big, when haystack is empty a
sse2 is around 40 cycles slower because it needs to populate a lookup
table and difference only increases with size. That is much bigger than
plt slowdown which is few cycles.
"
At least for s390x, using internal IFUNCs leads to a segfault while
linking libc.so if older binutils (before 2.26) are used.
Are internal IFUNCs supported on all architectures?
Bye
Stefan
More information about the Libc-alpha
mailing list