Question about the highly optimized aspects of libc implementation
Florian Weimer
fweimer@redhat.com
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.
Thanks,
Florian
More information about the Libc-help
mailing list