Provided by: freebsd-manpages_12.2-2_all bug

NAME

       DEFINE_IFUNC — define a kernel function with an implementation selected at run-time

SYNOPSIS

       #include <machine/ifunc.h>

       DEFINE_IFUNC(qual, ret_type, name, args);

DESCRIPTION

       ifuncs  are  a  linker  feature  which  allows the programmer to define functions whose implementation is
       selected at boot-time or module load-time.  The DEFINE_IFUNC macro can be used to define an  ifunc.   The
       selection  is  performed by a resolver function, which returns a pointer to the selected function.  ifunc
       resolvers are invoked very early during the machine-dependent initialization routine, or at load time for
       dynamically loaded modules.  Resolution must occur before the first call to an ifunc.   ifunc  resolution
       is  performed  after  CPU features are enumerated and after the kernel's environment is initialized.  The
       typical use-case for an ifunc is a routine whose behavior depends on optional CPU features.  For example,
       newer generations of a given CPU architecture may provide an instruction to optimize a common  operation.
       To  avoid  the overhead of testing for the CPU feature each time the operation is performed, an ifunc can
       be used to provide two implementations  for  the  operation:  one  targeting  platforms  with  the  extra
       instruction, and one for older platforms.

       Because  DEFINE_IFUNC  is  a  macro  that  defines a dynamically typed function, its usage looks somewhat
       unusual.  The qual parameter is a list of zero or more C function qualifiers to be applied to the  ifunc.
       This  parameter  is  typically  empty or the static qualifier.  ret_type is the return type of the ifunc.
       name is the name of the ifunc.  args is a parenthesized, comma-separated list of the parameter  types  of
       the function, as they would appear in a C function declaration.

       The  DEFINE_IFUNC  usage  must  be  followed  by  the resolver function body.  The resolver must return a
       function with return type ret_type and parameter types args.  The resolver function is defined  with  the
       ‘resolver’  gcc-style  function attribute, causing the corresponding elf(5) function symbol to be of type
       STT_GNU_IFUNC instead of STT_FUNC.  The  kernel  linker  invokes  the  resolver  to  process  relocations
       targeting ifunc calls and PLT entries referencing such symbols.

EXAMPLES

       ifunc  resolvers  are  executed early during boot, before most kernel facilities are available.  They are
       effectively limited to checking CPU feature flags and tunables.

       static size_t
       fast_strlen(const char *s __unused)
       {
               size_t len;

               /* Fast, but may not be correct in all cases. */
               __asm("movq $42,%0\n" : "=r" (len));
               return (len);
       }

       static size_t
       slow_strlen(const char *s)
       {
               const char *t;

               for (t = s; *t != '\0'; t++);
               return (t - s);
       }

       DEFINE_IFUNC(, size_t, strlen, (const char *))
       {
               int enabled;

               enabled = 1;
               TUNABLE_INT_FETCH("debug.use_fast_strlen", &enabled);
               if (enabled && (cpu_features & CPUID_FAST_STRLEN) != 0)
                       return (fast_strlen);
               else
                       return (slow_strlen);
       }

       This defines a strlen() function with an optimized implementation for CPUs that advertise support.

SEE ALSO

       elf(5)

NOTES

       ifuncs are not supported on all architectures.  They require both toolchain  support,  to  emit  function
       symbols  of type STT_GNU_IFUNC, and kernel linker support to invoke ifunc resolvers during boot or during
       module load.

Debian                                            May 18, 2019                                   DEFINE_IFUNC(9)