]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/DEFINE_IFUNC.9
Add a man page for DEFINE_IFUNC.
[FreeBSD/FreeBSD.git] / share / man / man9 / DEFINE_IFUNC.9
1 .\" Copyright (c) 2019 The FreeBSD Foundation
2 .\"
3 .\" This documentation was written by Mark Johnston <markj@FreeBSD.org>
4 .\" under sponsorship from the FreeBSD Foundation.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
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.
14 .\"
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
25 .\" SUCH DAMAGE.
26 .\"
27 .\" $FreeBSD$
28 .\"
29 .Dd May 18, 2019
30 .Dt DEFINE_IFUNC 9
31 .Os
32 .Sh NAME
33 .Nm DEFINE_IFUNC
34 .Nd define a kernel function with an implementation selected at run-time
35 .Sh SYNOPSIS
36 .In machine/ifunc.h
37 .Fn DEFINE_IFUNC qual ret_type name args
38 .Sh DESCRIPTION
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.
41 The
42 .Nm
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
58 for older platforms.
59 .Pp
60 Because
61 .Nm
62 is a macro that defines a dynamically typed function, its usage looks somewhat
63 unusual.
64 The
65 .Ar qual
66 parameter is a list of zero or more C function qualifiers to be applied to the
67 ifunc.
68 This parameter is typically empty or the
69 .Dv static
70 qualifier.
71 .Ar ret_type
72 is the return type of the ifunc.
73 .Ar name
74 is the name of the ifunc.
75 .Ar args
76 is a parenthesized, comma-separated list of the parameter types of the function,
77 as they would appear in a C function declaration.
78 .Pp
79 The
80 .Nm
81 usage must be followed by the resolver function body.
82 The resolver must return a function with return type
83 .Ar ret_type
84 and parameter types
85 .Ar args .
86 The resolver function is defined with the
87 .Ql resolver
88 gcc-style function attribute, causing the corresponding
89 .Xr elf 5
90 function symbol to be of type
91 .Dv STT_GNU_IFUNC
92 instead of
93 .Dv STT_FUNC .
94 The kernel linker invokes the resolver to process relocations targeting ifunc
95 calls and PLT entries referencing such symbols.
96 .Sh EXAMPLES
97 ifunc resolvers are executed early during boot, before most kernel facilities
98 are available.
99 They are effectively limited to checking CPU feature flags and tunables.
100 .Bd -literal
101 static size_t
102 fast_strlen(const char *s __unused)
103 {
104         size_t len;
105
106         /* Fast, but may not be correct in all cases. */
107         __asm("movq $42,%0\\n" : "=r" (len));
108         return (len);
109 }
110
111 static size_t
112 slow_strlen(const char *s)
113 {
114         const char *t;
115
116         for (t = s; *t != '\\0'; t++);
117         return (t - s);
118 }
119
120 DEFINE_IFUNC(, size_t, strlen, (const char *))
121 {
122         int enabled;
123
124         enabled = 1;
125         TUNABLE_INT_FETCH("debug.use_fast_strlen", &enabled);
126         if (enabled && (cpu_features & CPUID_FAST_STRLEN) != 0)
127                 return (fast_strlen);
128         else
129                 return (slow_strlen);
130 }
131 .Ed
132 .Pp
133 This defines a
134 .Fn strlen
135 function with an optimized implementation for CPUs that advertise support.
136 .Sh SEE ALSO
137 .Xr elf 5
138 .Sh NOTES
139 ifuncs are not supported on all architectures.
140 They require both toolchain support, to emit function symbols of type
141 .Dv STT_GNU_IFUNC ,
142 and kernel linker support to invoke ifunc resolvers during boot or
143 during module load.