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