xref: /xnu-8020.121.3/bsd/libkern/libkern.h (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
1 /*
2  * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*-
29  * Copyright (c) 1992, 1993
30  *	The Regents of the University of California.  All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  * 1. Redistributions of source code must retain the above copyright
36  *    notice, this list of conditions and the following disclaimer.
37  * 2. Redistributions in binary form must reproduce the above copyright
38  *    notice, this list of conditions and the following disclaimer in the
39  *    documentation and/or other materials provided with the distribution.
40  * 3. All advertising materials mentioning features or use of this software
41  *    must display the following acknowledgement:
42  *	This product includes software developed by the University of
43  *	California, Berkeley and its contributors.
44  * 4. Neither the name of the University nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  *
60  *	@(#)libkern.h	8.1 (Berkeley) 6/10/93
61  */
62 /*
63  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
64  * support for mandatory and extensible security protections.  This notice
65  * is included in support of clause 2.2 (b) of the Apple Public License,
66  * Version 2.0.
67  */
68 
69 #ifndef _LIBKERN_LIBKERN_H_
70 #define _LIBKERN_LIBKERN_H_
71 
72 #include <sys/appleapiopts.h>
73 #include <stdint.h>
74 #include <stdarg.h>     /* for platform-specific va_list */
75 #include <string.h>
76 #include <machine/limits.h>
77 #include <sys/cdefs.h>
78 #include <sys/types.h>
79 #include <mach/vm_param.h>
80 #include <libkern/crc.h>
81 #include <libkern/copyio.h>
82 
83 #if defined(__arm__) || defined(__arm64__)
84 #include <arm/arch.h> /* for _ARM_ARCH_* */
85 #endif
86 
87 #ifdef __APPLE_API_OBSOLETE
88 /* BCD conversions. */
89 extern u_char const     bcd2bin_data[];
90 extern u_char const     bin2bcd_data[];
91 
92 #define bcd2bin(bcd)    (bcd2bin_data[bcd])
93 #define bin2bcd(bin)    (bin2bcd_data[bin])
94 #endif /* __APPLE_API_OBSOLETE */
95 
96 #ifdef __APPLE_API_PRIVATE
97 extern char const       hex2ascii_data[];
98 
99 #define hex2ascii(hex)  (hex2ascii_data[hex])
100 #endif /* __APPLE_API_PRIVATE */
101 
102 __BEGIN_DECLS
103 static inline int
imax(int a,int b)104 imax(int a, int b)
105 {
106 	return a > b ? a : b;
107 }
108 static inline int
imin(int a,int b)109 imin(int a, int b)
110 {
111 	return a < b ? a : b;
112 }
113 static inline long
lmax(long a,long b)114 lmax(long a, long b)
115 {
116 	return a > b ? a : b;
117 }
118 static inline long
lmin(long a,long b)119 lmin(long a, long b)
120 {
121 	return a < b ? a : b;
122 }
123 static inline u_int
max(u_int a,u_int b)124 max(u_int a, u_int b)
125 {
126 	return a > b ? a : b;
127 }
128 static inline u_int
min(u_int a,u_int b)129 min(u_int a, u_int b)
130 {
131 	return a < b ? a : b;
132 }
133 static inline u_int32_t
ulmax(u_int32_t a,u_int32_t b)134 ulmax(u_int32_t a, u_int32_t b)
135 {
136 	return a > b ? a : b;
137 }
138 static inline u_int32_t
ulmin(u_int32_t a,u_int32_t b)139 ulmin(u_int32_t a, u_int32_t b)
140 {
141 	return a < b ? a : b;
142 }
143 
144 
145 
146 /* Prototypes for non-quad routines. */
147 extern int      ffs(unsigned int);
148 extern int      ffsll(unsigned long long);
149 extern int      fls(unsigned int);
150 extern int      flsll(unsigned long long);
151 extern u_int32_t        random(void);
152 extern size_t   scanc(size_t, u_char *, const u_char *, u_char);
153 extern long     strtol(const char*, char **, int);
154 extern u_long   strtoul(const char *, char **, int);
155 extern quad_t   strtoq(const char *, char **, int);
156 extern u_quad_t strtouq(const char *, char **, int);
157 extern char     *strsep(char **, const char *);
158 extern void     *memchr(const void *, int, size_t);
159 extern void     url_decode(char *str);
160 
161 /*
162  * NOTE: snprintf() returns the full length of the formatted string even if it
163  * couldn't fit in the supplied buffer.
164  * Use scnprintf() if you need the actual number of bytes (minus the \0)
165  */
166 int     snprintf(char *, size_t, const char *, ...) __printflike(3, 4);
167 int     scnprintf(char *, size_t, const char *, ...) __printflike(3, 4);
168 
169 /* sprintf() is being deprecated. Please use snprintf() instead. */
170 int     sprintf(char *bufp, const char *, ...) __deprecated __printflike(2, 3);
171 int     sscanf(const char *, char const *, ...) __scanflike(2, 3);
172 int     printf(const char *, ...) __printflike(1, 2);
173 
174 #if KERNEL_PRIVATE
175 int     _consume_printf_args(int, ...);
176 #endif
177 
178 #if CONFIG_NO_PRINTF_STRINGS
179 #if KERNEL_PRIVATE
180 #define printf(x, ...)  _consume_printf_args( 0, ## __VA_ARGS__ )
181 #else
182 #define printf(x, ...)  do {} while (0)
183 #endif
184 #endif
185 
186 uint16_t        crc16(uint16_t crc, const void *bufp, size_t len);
187 uint32_t        crc32(uint32_t crc, const void *bufp, size_t len);
188 
189 #if XNU_KERNEL_PRIVATE
190 #if KASAN
191 uint16_t __nosan_crc16(uint16_t crc, const void *bufp, size_t len);
192 #else
193 static inline uint16_t
__nosan_crc16(uint16_t crc,const void * bufp,size_t len)194 __nosan_crc16(uint16_t crc, const void *bufp, size_t len)
195 {
196 	return crc16(crc, bufp, len);
197 }
198 #endif
199 #endif
200 
201 int     copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done);
202 int     copyinstr(const user_addr_t uaddr, void *kaddr, size_t len, size_t *done) OS_WARN_RESULT;
203 int     copyoutstr(const void *kaddr, user_addr_t udaddr, size_t len, size_t *done);
204 #if XNU_KERNEL_PRIVATE
205 int     copyin_atomic32(const user_addr_t user_addr, uint32_t *u32);
206 int     copyin_atomic32_wait_if_equals(const user_addr_t user_addr, uint32_t u32);
207 int     copyin_atomic64(const user_addr_t user_addr, uint64_t *u64);
208 int     copyout_atomic32(uint32_t u32, user_addr_t user_addr);
209 int     copyout_atomic64(uint64_t u64, user_addr_t user_addr);
210 int     copyoutstr_prevalidate(const void *kaddr, user_addr_t uaddr, size_t len);
211 #endif
212 
213 int vsscanf(const char *, char const *, va_list);
214 
215 extern int      vprintf(const char *, va_list) __printflike(1, 0);
216 extern int      vsnprintf(char *, size_t, const char *, va_list) __printflike(3, 0);
217 extern int      vscnprintf(char *, size_t, const char *, va_list) __printflike(3, 0);
218 
219 #if XNU_KERNEL_PRIVATE
220 extern bool     printf_log_locked(bool addcr, const char*, ...) __printflike(2, 3);
221 extern bool     vprintf_log_locked(const char *, va_list, bool driverkit) __printflike(1, 0);
222 extern void     osobject_retain(void * object);
223 extern void     osobject_release(void * object);
224 #endif
225 
226 /* vsprintf() is being deprecated. Please use vsnprintf() instead. */
227 extern int      vsprintf(char *bufp, const char *, va_list) __deprecated __printflike(2, 0);
228 
229 #ifdef KERNEL_PRIVATE
230 #ifdef __arm__
231 void flush_inner_dcaches(void);
232 void clean_inner_dcaches(void);
233 #endif
234 extern void invalidate_icache(vm_offset_t, unsigned, int);
235 extern void flush_dcache(vm_offset_t, unsigned, int);
236 #else
237 extern void invalidate_icache(vm_offset_t, unsigned, int);
238 extern void flush_dcache(vm_offset_t, unsigned, int);
239 #endif
240 extern void invalidate_icache64(addr64_t, unsigned, int);
241 extern void flush_dcache64(addr64_t, unsigned, int);
242 
243 
244 static inline int
clz(unsigned int num)245 clz(unsigned int num)
246 {
247 #if (__arm__ || __arm64__)
248 	// On ARM, clz(0) is defined to return number of bits in the input type
249 	return __builtin_clz(num);
250 #else
251 	// On Intel, clz(0) is undefined
252 	return num ? __builtin_clz(num) : sizeof(num) * CHAR_BIT;
253 #endif
254 }
255 
256 #if XNU_KERNEL_PRIVATE
257 
258 /*
259  * Define a function that for whatever reason needs to exist, but must never be
260  * called.
261  */
262 #define UNSUPPORTED_API(funcname, ...) \
263 	_Pragma("clang diagnostic push") \
264 	_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
265 	funcname(__VA_ARGS__) { panic("%s: unsupported API", __func__); } \
266 	_Pragma("clang diagnostic pop")
267 
268 #endif
269 
270 __END_DECLS
271 
272 #endif /* _LIBKERN_LIBKERN_H_ */
273