1 .\" Copyright (c) 2019 The FreeBSD Foundation
3 .\" This documentation was written by Mark Johnston <markj@FreeBSD.org>
4 .\" under sponsorship from the FreeBSD Foundation.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\" notice, this list of conditions and the following disclaimer in the
13 .\" documentation and/or other materials provided with the distribution.
15 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 .Nd define a kernel function with an implementation selected at run-time
37 .Fn DEFINE_IFUNC qual ret_type name args
39 ifuncs are a linker feature which allows the programmer to define functions
40 whose implementation is selected at boot-time or module load-time.
43 macro can be used to define an ifunc.
44 The selection is performed by a resolver function, which returns a pointer
45 to the selected function.
46 ifunc resolvers are invoked very early during the machine-dependent
47 initialization routine, or at load time for dynamically loaded modules.
48 Resolution must occur before the first call to an ifunc.
49 ifunc resolution is performed after CPU features are enumerated and after the
50 kernel's environment is initialized.
51 The typical use-case for an ifunc is a routine whose behavior depends on
52 optional CPU features.
53 For example, newer generations of a given CPU architecture may provide an
54 instruction to optimize a common operation.
55 To avoid the overhead of testing for the CPU feature each time the operation
56 is performed, an ifunc can be used to provide two implementations for the
57 operation: one targeting platforms with the extra instruction, and one
62 is a macro that defines a dynamically typed function, its usage looks somewhat
66 parameter is a list of zero or more C function qualifiers to be applied to the
68 This parameter is typically empty or the
72 is the return type of the ifunc.
74 is the name of the ifunc.
76 is a parenthesized, comma-separated list of the parameter types of the function,
77 as they would appear in a C function declaration.
81 usage must be followed by the resolver function body.
82 The resolver must return a function with return type
86 The resolver function is defined with the
88 gcc-style function attribute, causing the corresponding
90 function symbol to be of type
94 The kernel linker invokes the resolver to process relocations targeting ifunc
95 calls and PLT entries referencing such symbols.
97 ifunc resolvers are executed early during boot, before most kernel facilities
99 They are effectively limited to checking CPU feature flags and tunables.
102 fast_strlen(const char *s __unused)
106 /* Fast, but may not be correct in all cases. */
107 __asm("movq $42,%0\\n" : "=r" (len));
112 slow_strlen(const char *s)
116 for (t = s; *t != '\\0'; t++);
120 DEFINE_IFUNC(, size_t, strlen, (const char *))
125 TUNABLE_INT_FETCH("debug.use_fast_strlen", &enabled);
126 if (enabled && (cpu_features & CPUID_FAST_STRLEN) != 0)
127 return (fast_strlen);
129 return (slow_strlen);
135 function with an optimized implementation for CPUs that advertise support.
139 ifuncs are not supported on all architectures.
140 They require both toolchain support, to emit function symbols of type
142 and kernel linker support to invoke ifunc resolvers during boot or