Question about the highly optimized aspects of libc implementation

Florian Weimer
Mon Dec 4 12:15:00 GMT 2017

On 12/04/2017 02:15 AM, Will Hawkins wrote:

>> The fcntl implementation calls va_arg on a variadic argument which might not
>> actually exist.  The syscall function does something similar (but it is
>> actually implemented in machine code, so it's less of a problem).
> Are you referring to
> ...
> int
> __libc_fcntl (int fd, int cmd, ...)
> {
>    va_list ap;
>    void *arg;
>    va_start (ap, cmd);
>    arg = va_arg (ap, void *);
>    va_end (ap);
> ...
> from sysdeps/unix/sysv/linux/fcntl.c?

Right, this is what I had in mind.

>> The NSS internals in general and getaddrinfo in particular call functions
>> through a mis-matching function pointer (with an additional argument added,
>> or with a void * argument where the function is defined with a concrete
>> function pointer).
> Are you referring to, for example,
>        if (fct != NULL)
>          {
>            if (req->ai_family == AF_INET6
>          || req->ai_family == AF_UNSPEC)
>        {
>          gethosts (AF_INET6, struct in6_addr);
>          no_inet6_data = no_data;
>          inet6_status = status;
>        }

Yes, per the comment above:

	  if (fct == NULL)
	    /* We are cheating here.  The gethostbyname2_r
	       function does not have the same interface as
	       gethostbyname3_r but the extra arguments the
	       latter takes are added at the end.  So the
	       gethostbyname2_r code will just ignore them.  */
	    fct = __nss_lookup_function (nip, "gethostbyname2_r");

> from sysdeps/posix/getaddrinfo.c where gethosts uses DL_CALL_FCT to
> invoke fct as if it were a function that returned void* and with an
> additional void* parameter as a result of the call through
> _dl_mcount_wrapper_check?

I haven't considered this.  I meant the pointer assignment I quoted above.

> What you've given me is great! However, if there are other interesting
> ones, I'd love to hear them! I love seeing the /expert/ uses of the C
> language for learning. You are all amazing craftpersons -- it's great
> to watch you work.

Oh, I expected you were doing research on deliberate use of non-standard 
constructs.  We get such queries from time to time.

The examples I quoted can hardly be considered “expert uses”.  They are 
just the historically chosen approach.  I doubt we would add such code 
today, maybe with the exception of the fcntl case.

In any case, these a truly bad examples, and we only get away with this 
because the C library is essentially part of the C implementation.  For 
general-purpose programming, these practices are harmful, and we are 
gradually removing problematic code from glibc, too.

> Are there any places where, I know this sounds crazy, but functions
> are invoked with push/jump (or straight jumps) because, for instance
> they are tail calls or somehow the return address is known statically?

In general, the compiler does this automatically if feasible.  If we 
need this optimization (say for clone/vfork), I think we implement the 
functions involved in assembler.


More information about the Libc-help mailing list