What is an indirect function (IFUNC)?

The GNU indirect function support (IFUNC) is a feature of the GNU toolchain that allows a developer to create multiple implementations of a given function and to select amongst them at runtime using a resolver function which is also written by the developer. The resolver function is called by the dynamic loader during early startup to resolve which of the implementations will be used by the application. Once an implementation choice is made it is fixed and may not be changed for the lifetime of the process.

How do indirect functions work?

In a traditional binary you have compile time and runtime choices regarding which functions are called by a source-level function call. While your source code may make a call to memcpy, such a call might be handled by a compiler builtin (results in no library call) or a library call (results in a call to an implementation of memcpy in a library). Further at runtime ELF symbol interposition means that any preloaded library might define memcpy and thus become the function that is bound to the program and used by all callers in the program that call such a named library function (ignoring dlmopen isolated namespaces where the choice can be made again). While ELF allows symbol interposition, such interposition is made based on library load order and symbol resolution. Where IFUNC takes this a step further it allows the selected symbol to further differentiate the implementation chosen. Symbols of type STT_GNU_IFUNC (GNU-specific extension) are treated differently from normal symbols. Such IFUNC symbols point to the resolver function, and all calls to such functions are delayed until runtime. References to the function are handled indirectly via R_*_IRELATIVE relocations which return the result of having run the resolver i.e. they return a function pointer to the chosen implementation. Thus when you call the function in question the dynamic loader runs the resolver to determine the best implementation to use, that choice is made and remembered (PLT is updated), and then the function is called.

Design goals

The following is a statement of intent in the design, and does not reflect what is currently implemented. This entire document is up for discussion.

How do I use indirect functions in my own code?

The GNU Compiler Collection documentation describes how IFUNC should be used here: ifunc attribute. That is all there is to it.

Unfortunately there are actually a lot of restrictions placed on IFUNC usage which aren't entirely clear and the documentation needs to be updated.

Fistly, as you can see there are already a few restrictions on the usage of IFUNC:

The restrictions are actually more strict than this because the resolution of an IFUNC can happen very early on in the dynamic loader startup process, particularly if -Wl,z,now is used to compile the application (requires all symbols be resolved before application startup).

If your applications uses IFUNCs and has problems, please reach out to libc-alpha@sourceware.org to discuss your use cases and how we can extend the existing framework to better support your uses. As noted above, some of these limitations can be lifted with more careful ordering of relocations for IFUNC across all architectures.

Work that needs to be done

The IFUNC implementation in glibc needs the following things to become sufficiently robust for real users to use:

Resources

None: GNU_IFUNC (last edited 2017-01-30 20:47:53 by CarlosODonell)