xref: /xnu-10063.121.3/osfmk/libsa/string.h (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1*2c2f96dcSApple OSS Distributions /*
2*2c2f96dcSApple OSS Distributions  * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3*2c2f96dcSApple OSS Distributions  *
4*2c2f96dcSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*2c2f96dcSApple OSS Distributions  *
6*2c2f96dcSApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*2c2f96dcSApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*2c2f96dcSApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*2c2f96dcSApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*2c2f96dcSApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*2c2f96dcSApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*2c2f96dcSApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*2c2f96dcSApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*2c2f96dcSApple OSS Distributions  *
15*2c2f96dcSApple OSS Distributions  * Please obtain a copy of the License at
16*2c2f96dcSApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*2c2f96dcSApple OSS Distributions  *
18*2c2f96dcSApple OSS Distributions  * The Original Code and all software distributed under the License are
19*2c2f96dcSApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*2c2f96dcSApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*2c2f96dcSApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*2c2f96dcSApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*2c2f96dcSApple OSS Distributions  * Please see the License for the specific language governing rights and
24*2c2f96dcSApple OSS Distributions  * limitations under the License.
25*2c2f96dcSApple OSS Distributions  *
26*2c2f96dcSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*2c2f96dcSApple OSS Distributions  */
28*2c2f96dcSApple OSS Distributions /*
29*2c2f96dcSApple OSS Distributions  * NOTICE: This file was modified by McAfee Research in 2004 to introduce
30*2c2f96dcSApple OSS Distributions  * support for mandatory and extensible security protections.  This notice
31*2c2f96dcSApple OSS Distributions  * is included in support of clause 2.2 (b) of the Apple Public License,
32*2c2f96dcSApple OSS Distributions  * Version 2.0.
33*2c2f96dcSApple OSS Distributions  */
34*2c2f96dcSApple OSS Distributions /*
35*2c2f96dcSApple OSS Distributions  * HISTORY
36*2c2f96dcSApple OSS Distributions  * @OSF_COPYRIGHT@
37*2c2f96dcSApple OSS Distributions  */
38*2c2f96dcSApple OSS Distributions 
39*2c2f96dcSApple OSS Distributions #if (defined(__has_include) && __has_include(<__xnu_libcxx_sentinel.h>) && !defined(XNU_LIBCXX_SDKROOT))
40*2c2f96dcSApple OSS Distributions 
41*2c2f96dcSApple OSS Distributions #if !__has_include_next(<string.h>)
42*2c2f96dcSApple OSS Distributions #error Do not build with -nostdinc (use GCC_USE_STANDARD_INCLUDE_SEARCHING=NO)
43*2c2f96dcSApple OSS Distributions #endif /* !__has_include_next(<string.h>) */
44*2c2f96dcSApple OSS Distributions 
45*2c2f96dcSApple OSS Distributions #include_next <string.h>
46*2c2f96dcSApple OSS Distributions 
47*2c2f96dcSApple OSS Distributions #else /* (defined(__has_include) && __has_include(<__xnu_libcxx_sentinel.h>) && !defined(XNU_LIBCXX_SDKROOT)) */
48*2c2f96dcSApple OSS Distributions 
49*2c2f96dcSApple OSS Distributions #ifndef _STRING_H_
50*2c2f96dcSApple OSS Distributions #define _STRING_H_      1
51*2c2f96dcSApple OSS Distributions 
52*2c2f96dcSApple OSS Distributions #include <sys/cdefs.h>
53*2c2f96dcSApple OSS Distributions #ifdef MACH_KERNEL_PRIVATE
54*2c2f96dcSApple OSS Distributions #include <types.h>
55*2c2f96dcSApple OSS Distributions #else /* MACH_KERNEL_PRIVATE */
56*2c2f96dcSApple OSS Distributions #include <sys/types.h>
57*2c2f96dcSApple OSS Distributions #endif /* MACH_KERNEL_PRIVATE */
58*2c2f96dcSApple OSS Distributions 
59*2c2f96dcSApple OSS Distributions #ifdef KERNEL
60*2c2f96dcSApple OSS Distributions #include <machine/trap.h>
61*2c2f96dcSApple OSS Distributions #endif /* KERNEL */
62*2c2f96dcSApple OSS Distributions 
63*2c2f96dcSApple OSS Distributions __BEGIN_DECLS
64*2c2f96dcSApple OSS Distributions 
65*2c2f96dcSApple OSS Distributions #ifndef NULL
66*2c2f96dcSApple OSS Distributions #if defined (__cplusplus)
67*2c2f96dcSApple OSS Distributions #if __cplusplus >= 201103L
68*2c2f96dcSApple OSS Distributions #define NULL nullptr
69*2c2f96dcSApple OSS Distributions #else
70*2c2f96dcSApple OSS Distributions #define NULL 0
71*2c2f96dcSApple OSS Distributions #endif
72*2c2f96dcSApple OSS Distributions #else
73*2c2f96dcSApple OSS Distributions #define NULL ((void *)0)
74*2c2f96dcSApple OSS Distributions #endif
75*2c2f96dcSApple OSS Distributions #endif
76*2c2f96dcSApple OSS Distributions 
77*2c2f96dcSApple OSS Distributions /*
78*2c2f96dcSApple OSS Distributions  * Memory functions
79*2c2f96dcSApple OSS Distributions  *
80*2c2f96dcSApple OSS Distributions  *   int bcmp(const void *s1, const void *s2, size_t n);
81*2c2f96dcSApple OSS Distributions  *   int memcmp(const void *s1, const void *s2, size_t n);
82*2c2f96dcSApple OSS Distributions  *   int timingsafe_bcmp(const void *b1, const void *b2, size_t n);
83*2c2f96dcSApple OSS Distributions  *
84*2c2f96dcSApple OSS Distributions  *   void bzero(void *dst, size_t n);
85*2c2f96dcSApple OSS Distributions  *   void *memset(void *s, int c, size_t n);
86*2c2f96dcSApple OSS Distributions  *   int memset_s(void *s, size_t smax, int c, size_t n);
87*2c2f96dcSApple OSS Distributions  *
88*2c2f96dcSApple OSS Distributions  *   void bcopy(const void *src, void *dst, size_t n);
89*2c2f96dcSApple OSS Distributions  *   void *memcpy(void *dst, const void *src, size_t n);
90*2c2f96dcSApple OSS Distributions  *   void *memove(void *dst, const void *src, size_t n);
91*2c2f96dcSApple OSS Distributions  *
92*2c2f96dcSApple OSS Distributions  *
93*2c2f96dcSApple OSS Distributions  * String functions
94*2c2f96dcSApple OSS Distributions  *
95*2c2f96dcSApple OSS Distributions  *   size_t strlen(const char *s);
96*2c2f96dcSApple OSS Distributions  *   size_t strnlen(const char *s, size_t n);
97*2c2f96dcSApple OSS Distributions  *
98*2c2f96dcSApple OSS Distributions  *   int strcmp(const char *s1, const char *s2);
99*2c2f96dcSApple OSS Distributions  *   int strncmp(const char *s1, const char *s2, size_t n);
100*2c2f96dcSApple OSS Distributions  *   int strlcmp(const char *s1, const char *s2, size_t n);
101*2c2f96dcSApple OSS Distributions  *   int strbufcmp(const char *s1, size_t n1, const char *s2, size_t n2);
102*2c2f96dcSApple OSS Distributions  *   int strprefix(const char *s1, const char *s2);
103*2c2f96dcSApple OSS Distributions  *   int strcasecmp(const char *s1, const char *s2);
104*2c2f96dcSApple OSS Distributions  *   int strncasecmp(const char *s1, const char *s2, size_t n);
105*2c2f96dcSApple OSS Distributions  *   int strlcasecmp(const char *s1, const char *s2, size_t n);
106*2c2f96dcSApple OSS Distributions  *   int strbufcasecmp(const char *s1, size_t n1, const char *s2, size_t n2);
107*2c2f96dcSApple OSS Distributions  *
108*2c2f96dcSApple OSS Distributions  *   char *strchr(const char *s, int c);
109*2c2f96dcSApple OSS Distributions  *   char *strrchr(const char *s, int c);
110*2c2f96dcSApple OSS Distributions  *   char *strnstr(const char *s, const char *find, size_t slen);
111*2c2f96dcSApple OSS Distributions  *
112*2c2f96dcSApple OSS Distributions  *   size_t strlcpy(char *dst, const char *src, size_t n);
113*2c2f96dcSApple OSS Distributions  *   const char *strbufcpy(char *dst, size_t dstlen, const char *src, size_t srclen);
114*2c2f96dcSApple OSS Distributions  *   size_t strlcat(char *dst, const char *src, size_t n);
115*2c2f96dcSApple OSS Distributions  *   const char *strbufcat(char *dst, size_t dstlen, const char *src, size_t srclen);
116*2c2f96dcSApple OSS Distributions  */
117*2c2f96dcSApple OSS Distributions 
118*2c2f96dcSApple OSS Distributions 
119*2c2f96dcSApple OSS Distributions #pragma mark _FORTIFY_SOURCE helpers
120*2c2f96dcSApple OSS Distributions 
121*2c2f96dcSApple OSS Distributions /*
122*2c2f96dcSApple OSS Distributions  * _FORTIFY_SOURCE > 0 will enable checked memory/string functions.
123*2c2f96dcSApple OSS Distributions  *
124*2c2f96dcSApple OSS Distributions  * _FORTIFY_SOURCE_STRICT will enable stricter checking (optional)
125*2c2f96dcSApple OSS Distributions  * for memcpy/memmove/bcopy and will check that copies do not go
126*2c2f96dcSApple OSS Distributions  * past the end of a struct member.
127*2c2f96dcSApple OSS Distributions  */
128*2c2f96dcSApple OSS Distributions #if KASAN
129*2c2f96dcSApple OSS Distributions #  define __XNU_FORTIFY_SOURCE          0 /* kasan is a superset */
130*2c2f96dcSApple OSS Distributions #elif defined (_FORTIFY_SOURCE) && _FORTIFY_SOURCE == 0
131*2c2f96dcSApple OSS Distributions #  define __XNU_FORTIFY_SOURCE          0 /* forcefully disabled */
132*2c2f96dcSApple OSS Distributions #elif XNU_KERNEL_PRIVATE || defined(_FORTIFY_SOURCE_STRICT)
133*2c2f96dcSApple OSS Distributions #  define __XNU_FORTIFY_SOURCE          2
134*2c2f96dcSApple OSS Distributions #else
135*2c2f96dcSApple OSS Distributions #  define __XNU_FORTIFY_SOURCE          1
136*2c2f96dcSApple OSS Distributions #endif
137*2c2f96dcSApple OSS Distributions 
138*2c2f96dcSApple OSS Distributions /*
139*2c2f96dcSApple OSS Distributions  * The overloadable attribute is load bearing in two major ways:
140*2c2f96dcSApple OSS Distributions  * - __builtin_${function} from ${function} would be infinite recursion and UB,
141*2c2f96dcSApple OSS Distributions  * - we need to still expose the regular prototype for people wanting to take
142*2c2f96dcSApple OSS Distributions  *   its address.
143*2c2f96dcSApple OSS Distributions  */
144*2c2f96dcSApple OSS Distributions #define __xnu_string_inline \
145*2c2f96dcSApple OSS Distributions 	static inline __attribute__((__always_inline__, __overloadable__))
146*2c2f96dcSApple OSS Distributions 
147*2c2f96dcSApple OSS Distributions /*
148*2c2f96dcSApple OSS Distributions  * We want to allow certain functions like strlen() to constant fold
149*2c2f96dcSApple OSS Distributions  * at compile time (such as strlen("foo")).
150*2c2f96dcSApple OSS Distributions  *
151*2c2f96dcSApple OSS Distributions  * In order to do so, we need an overload that has a similar looking
152*2c2f96dcSApple OSS Distributions  * signature but is different from the regular function so that it can
153*2c2f96dcSApple OSS Distributions  * call its matching builtin without causing UB due to inifinite recursion.
154*2c2f96dcSApple OSS Distributions  * We abuse that the pass_object_size class of attributes gives us
155*2c2f96dcSApple OSS Distributions  * precisely that semantics.
156*2c2f96dcSApple OSS Distributions  */
157*2c2f96dcSApple OSS Distributions #define __xnu_force_overload            __xnu_pass_object_size
158*2c2f96dcSApple OSS Distributions 
159*2c2f96dcSApple OSS Distributions /*
160*2c2f96dcSApple OSS Distributions  * The object_size extension defines two kinds of size: the "struct size" and
161*2c2f96dcSApple OSS Distributions  * the "member size". The "struct size" is the size of the buffer from the
162*2c2f96dcSApple OSS Distributions  * starting address to the end of the largest enclosing object. The "member
163*2c2f96dcSApple OSS Distributions  * size" is the size of the buffer from the starting address to the end of the
164*2c2f96dcSApple OSS Distributions  * immediately enclosing array. For instance, given this:
165*2c2f96dcSApple OSS Distributions  *
166*2c2f96dcSApple OSS Distributions  *  struct foo {
167*2c2f96dcSApple OSS Distributions  *      char a[20];
168*2c2f96dcSApple OSS Distributions  *      char b[20];
169*2c2f96dcSApple OSS Distributions  *  } my_foo;
170*2c2f96dcSApple OSS Distributions  *
171*2c2f96dcSApple OSS Distributions  * The "struct size" for &my_foo.a[10] is 30 (`sizeof(struct foo) -
172*2c2f96dcSApple OSS Distributions  * offsetof(struct foo, a[10])`), and the "member size" for it is 10
173*2c2f96dcSApple OSS Distributions  * (`sizeof(my_foo.a) - 10`).
174*2c2f96dcSApple OSS Distributions  *
175*2c2f96dcSApple OSS Distributions  * In general, you should use the member size for string operations (as it is
176*2c2f96dcSApple OSS Distributions  * always a mistake to go out of bounds of a char buffer with a string
177*2c2f96dcSApple OSS Distributions  * operation) and the struct size for bytewise operations (like bcopy, bzero,
178*2c2f96dcSApple OSS Distributions  * memset, etc). The object_size extension is intended to provide _some_ bounds
179*2c2f96dcSApple OSS Distributions  * safety at a low engineering cost, and various patterns intentionally
180*2c2f96dcSApple OSS Distributions  * overflowing from individual fields with bytewise operations have
181*2c2f96dcSApple OSS Distributions  * historically been tolerated both by engineers and the compiler (despite
182*2c2f96dcSApple OSS Distributions  * probably being undefined).
183*2c2f96dcSApple OSS Distributions  *
184*2c2f96dcSApple OSS Distributions  * As an important side note, -fbounds-safety does not allow naïvely
185*2c2f96dcSApple OSS Distributions  * overflowing from individual fields. -fbounds-safety bounds checks are always
186*2c2f96dcSApple OSS Distributions  * equivalent to checks against the member size.
187*2c2f96dcSApple OSS Distributions  */
188*2c2f96dcSApple OSS Distributions 
189*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_dynamic_object_size)
190*2c2f96dcSApple OSS Distributions #  define __xnu_pass_struct_size        __attribute__((__pass_dynamic_object_size__(0)))
191*2c2f96dcSApple OSS Distributions #  define __xnu_pass_member_size        __attribute__((__pass_dynamic_object_size__(1)))
192*2c2f96dcSApple OSS Distributions #  define __xnu_struct_size(ptr)        __builtin_dynamic_object_size(ptr, 0)
193*2c2f96dcSApple OSS Distributions #  define __xnu_member_size(ptr)        __builtin_dynamic_object_size(ptr, 1)
194*2c2f96dcSApple OSS Distributions #else
195*2c2f96dcSApple OSS Distributions #  define __xnu_pass_struct_size        __attribute__((__pass_object_size__(0)))
196*2c2f96dcSApple OSS Distributions #  define __xnu_pass_member_size        __attribute__((__pass_object_size__(1)))
197*2c2f96dcSApple OSS Distributions #  define __xnu_struct_size(ptr)        __builtin_object_size(ptr, 0)
198*2c2f96dcSApple OSS Distributions #  define __xnu_member_size(ptr)        __builtin_object_size(ptr, 1)
199*2c2f96dcSApple OSS Distributions #endif
200*2c2f96dcSApple OSS Distributions 
201*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE == 0 || !__has_attribute(diagnose_if)
202*2c2f96dcSApple OSS Distributions #  define __xnu_struct_size_precondition(ptr, size, message)
203*2c2f96dcSApple OSS Distributions #  define __xnu_member_size_precondition(ptr, size, message)
204*2c2f96dcSApple OSS Distributions #else
205*2c2f96dcSApple OSS Distributions #  define __xnu_struct_size_precondition(ptr, size, message) \
206*2c2f96dcSApple OSS Distributions 	__attribute__((__diagnose_if__(__xnu_struct_size(ptr) < (size), message, "error")))
207*2c2f96dcSApple OSS Distributions #  define __xnu_member_size_precondition(ptr, size, message) \
208*2c2f96dcSApple OSS Distributions 	__attribute__((__diagnose_if__(__xnu_member_size(ptr) < (size), message, "error")))
209*2c2f96dcSApple OSS Distributions #endif
210*2c2f96dcSApple OSS Distributions 
211*2c2f96dcSApple OSS Distributions 
212*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE > 1
213*2c2f96dcSApple OSS Distributions #  define __xnu_object_size_precondition(...) \
214*2c2f96dcSApple OSS Distributions 	__xnu_member_size_precondition(__VA_ARGS__)
215*2c2f96dcSApple OSS Distributions #  define __xnu_object_size_check(...) \
216*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(__VA_ARGS__)
217*2c2f96dcSApple OSS Distributions #  define __xnu_pass_object_size        __xnu_pass_member_size
218*2c2f96dcSApple OSS Distributions #else
219*2c2f96dcSApple OSS Distributions #  define __xnu_object_size_precondition(...) \
220*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_precondition(__VA_ARGS__)
221*2c2f96dcSApple OSS Distributions #  define __xnu_object_size_check(...) \
222*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(__VA_ARGS__)
223*2c2f96dcSApple OSS Distributions #  define __xnu_pass_object_size        __xnu_pass_struct_size
224*2c2f96dcSApple OSS Distributions #endif
225*2c2f96dcSApple OSS Distributions 
226*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE == 0 || __has_ptrcheck
227*2c2f96dcSApple OSS Distributions #define __xnu_struct_size_check(ptr, size)   ((void)0)
228*2c2f96dcSApple OSS Distributions #define __xnu_member_size_check(ptr, size)   ((void)0)
229*2c2f96dcSApple OSS Distributions #else
230*2c2f96dcSApple OSS Distributions __xnu_string_inline __cold __dead2 void
231*2c2f96dcSApple OSS Distributions __xnu_fortify_trap_write(void)
232*2c2f96dcSApple OSS Distributions {
233*2c2f96dcSApple OSS Distributions 	ml_fatal_trap(0xbffe); /* XNU_HARD_TRAP_STRING_CHK */
234*2c2f96dcSApple OSS Distributions }
235*2c2f96dcSApple OSS Distributions 
236*2c2f96dcSApple OSS Distributions __xnu_string_inline __cold void
237*2c2f96dcSApple OSS Distributions __xnu_fortify_trap_read(void)
238*2c2f96dcSApple OSS Distributions {
239*2c2f96dcSApple OSS Distributions 	/* for now do not emit read traps yet */
240*2c2f96dcSApple OSS Distributions #if 0
241*2c2f96dcSApple OSS Distributions 	ml_recoverable_trap(0xfffe); /* XNU_SOFT_TRAP_STRING_CHK */
242*2c2f96dcSApple OSS Distributions #endif
243*2c2f96dcSApple OSS Distributions }
244*2c2f96dcSApple OSS Distributions 
245*2c2f96dcSApple OSS Distributions #define __xnu_fortify_trap(ptr)  _Generic(ptr, \
246*2c2f96dcSApple OSS Distributions 	const char *: __xnu_fortify_trap_read(),                                \
247*2c2f96dcSApple OSS Distributions 	const void *: __xnu_fortify_trap_read(),                                \
248*2c2f96dcSApple OSS Distributions 	default:      __xnu_fortify_trap_write())
249*2c2f96dcSApple OSS Distributions 
250*2c2f96dcSApple OSS Distributions #define __xnu_struct_size_check(ptr, size)  ({ \
251*2c2f96dcSApple OSS Distributions 	if (__xnu_struct_size(ptr) < (size)) {                                  \
252*2c2f96dcSApple OSS Distributions 	        __xnu_fortify_trap(ptr);                                        \
253*2c2f96dcSApple OSS Distributions 	}                                                                       \
254*2c2f96dcSApple OSS Distributions })
255*2c2f96dcSApple OSS Distributions #define __xnu_member_size_check(ptr, size)  ({ \
256*2c2f96dcSApple OSS Distributions 	if (__xnu_member_size(ptr) < (size)) {                                  \
257*2c2f96dcSApple OSS Distributions 	        __xnu_fortify_trap(ptr);                                        \
258*2c2f96dcSApple OSS Distributions 	}                                                                       \
259*2c2f96dcSApple OSS Distributions })
260*2c2f96dcSApple OSS Distributions #endif
261*2c2f96dcSApple OSS Distributions 
262*2c2f96dcSApple OSS Distributions /*
263*2c2f96dcSApple OSS Distributions  * Verifies at compile-time that an expression is an array (of any type).
264*2c2f96dcSApple OSS Distributions  */
265*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_types_compatible_p)
266*2c2f96dcSApple OSS Distributions #define __xnu_is_array(A) __builtin_types_compatible_p(typeof((A)[0])[], typeof(A))
267*2c2f96dcSApple OSS Distributions #else
268*2c2f96dcSApple OSS Distributions #define __xnu_is_array(A) 1
269*2c2f96dcSApple OSS Distributions #endif
270*2c2f96dcSApple OSS Distributions #define __xnu_assert_is_array(A, MSG) _Static_assert(__xnu_is_array(A), MSG)
271*2c2f96dcSApple OSS Distributions 
272*2c2f96dcSApple OSS Distributions #define __xnu_count_args1(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, N, ...) N
273*2c2f96dcSApple OSS Distributions #define __xnu_count_args(...) \
274*2c2f96dcSApple OSS Distributions 	__xnu_count_args1(, ##__VA_ARGS__, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
275*2c2f96dcSApple OSS Distributions 
276*2c2f96dcSApple OSS Distributions #define __xnu_argc_overload1(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
277*2c2f96dcSApple OSS Distributions #define __xnu_argc_overload(base, ...) \
278*2c2f96dcSApple OSS Distributions 	__xnu_argc_overload1(base, __xnu_count_args(__VA_ARGS__), ##__VA_ARGS__)
279*2c2f96dcSApple OSS Distributions 
280*2c2f96dcSApple OSS Distributions #pragma mark memory functions
281*2c2f96dcSApple OSS Distributions 
282*2c2f96dcSApple OSS Distributions 
283*2c2f96dcSApple OSS Distributions extern int bcmp(const void *s1 __sized_by(n), const void *s2 __sized_by(n), size_t n) __stateful_pure;
284*2c2f96dcSApple OSS Distributions 
285*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
286*2c2f96dcSApple OSS Distributions int
bcmp(const void * const s1 __xnu_pass_struct_size __sized_by (n),const void * const s2 __xnu_pass_struct_size __sized_by (n),size_t n)287*2c2f96dcSApple OSS Distributions bcmp(
288*2c2f96dcSApple OSS Distributions 	const void *const       s1 __xnu_pass_struct_size __sized_by(n),
289*2c2f96dcSApple OSS Distributions 	const void *const       s2 __xnu_pass_struct_size __sized_by(n),
290*2c2f96dcSApple OSS Distributions 	size_t                  n)
291*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(s1, n, "read overflow (first argument)")
292*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(s2, n, "read overflow (second argument)")
293*2c2f96dcSApple OSS Distributions {
294*2c2f96dcSApple OSS Distributions 	extern int __xnu_bcmp(
295*2c2f96dcSApple OSS Distributions 		const void * __sized_by(n),
296*2c2f96dcSApple OSS Distributions 		const void * __sized_by(n),
297*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_bcmp");
298*2c2f96dcSApple OSS Distributions 
299*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(s1, n);
300*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(s2, n);
301*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_bcmp)
302*2c2f96dcSApple OSS Distributions 	return __builtin_bcmp(s1, s2, n);
303*2c2f96dcSApple OSS Distributions #else
304*2c2f96dcSApple OSS Distributions 	return __xnu_bcmp(s1, s2, n);
305*2c2f96dcSApple OSS Distributions #endif
306*2c2f96dcSApple OSS Distributions }
307*2c2f96dcSApple OSS Distributions 
308*2c2f96dcSApple OSS Distributions 
309*2c2f96dcSApple OSS Distributions extern int memcmp(const void *s1 __sized_by(n), const void *s2 __sized_by(n), size_t n) __stateful_pure;
310*2c2f96dcSApple OSS Distributions 
311*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
312*2c2f96dcSApple OSS Distributions int
memcmp(const void * const s1 __xnu_pass_struct_size __sized_by (n),const void * const s2 __xnu_pass_struct_size __sized_by (n),size_t n)313*2c2f96dcSApple OSS Distributions memcmp(
314*2c2f96dcSApple OSS Distributions 	const void *const       s1 __xnu_pass_struct_size __sized_by(n),
315*2c2f96dcSApple OSS Distributions 	const void *const       s2 __xnu_pass_struct_size __sized_by(n),
316*2c2f96dcSApple OSS Distributions 	size_t                  n)
317*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(s1, n, "read overflow (first argument)")
318*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(s2, n, "read overflow (second argument)")
319*2c2f96dcSApple OSS Distributions {
320*2c2f96dcSApple OSS Distributions 	extern int __xnu_memcmp(
321*2c2f96dcSApple OSS Distributions 		const void *__sized_by(n),
322*2c2f96dcSApple OSS Distributions 		const void *__sized_by(n),
323*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_memcmp");
324*2c2f96dcSApple OSS Distributions 
325*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(s1, n);
326*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(s2, n);
327*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_memcmp)
328*2c2f96dcSApple OSS Distributions 	return __builtin_memcmp(s1, s2, n);
329*2c2f96dcSApple OSS Distributions #else
330*2c2f96dcSApple OSS Distributions 	return __xnu_memcmp(s1, s2, n);
331*2c2f96dcSApple OSS Distributions #endif
332*2c2f96dcSApple OSS Distributions }
333*2c2f96dcSApple OSS Distributions 
334*2c2f96dcSApple OSS Distributions 
335*2c2f96dcSApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE
336*2c2f96dcSApple OSS Distributions /*
337*2c2f96dcSApple OSS Distributions  * memcmp_zero_ptr_aligned() checks string s of n bytes contains all zeros.
338*2c2f96dcSApple OSS Distributions  * Address and size of the string s must be pointer-aligned.
339*2c2f96dcSApple OSS Distributions  * Return 0 if true, 1 otherwise. Also return 0 if n is 0.
340*2c2f96dcSApple OSS Distributions  */
341*2c2f96dcSApple OSS Distributions extern unsigned long memcmp_zero_ptr_aligned(const void *s __sized_by(n), size_t n) __stateful_pure;
342*2c2f96dcSApple OSS Distributions #endif
343*2c2f96dcSApple OSS Distributions 
344*2c2f96dcSApple OSS Distributions 
345*2c2f96dcSApple OSS Distributions extern int timingsafe_bcmp(const void *b1 __sized_by(n), const void *b2 __sized_by(n), size_t n);
346*2c2f96dcSApple OSS Distributions 
347*2c2f96dcSApple OSS Distributions 
348*2c2f96dcSApple OSS Distributions extern void bzero(void *s __sized_by(n), size_t n);
349*2c2f96dcSApple OSS Distributions 
350*2c2f96dcSApple OSS Distributions __xnu_string_inline
351*2c2f96dcSApple OSS Distributions void
bzero(void * const s __xnu_pass_struct_size __sized_by (n),size_t n)352*2c2f96dcSApple OSS Distributions bzero(
353*2c2f96dcSApple OSS Distributions 	void *const             s __xnu_pass_struct_size __sized_by(n),
354*2c2f96dcSApple OSS Distributions 	size_t                  n)
355*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(s, n, "write overflow")
356*2c2f96dcSApple OSS Distributions {
357*2c2f96dcSApple OSS Distributions 	extern void __xnu_bzero(
358*2c2f96dcSApple OSS Distributions 		const void *__sized_by(n),
359*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_bzero");
360*2c2f96dcSApple OSS Distributions 
361*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(s, n);
362*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_bzero)
363*2c2f96dcSApple OSS Distributions 	__builtin_bzero(s, n);
364*2c2f96dcSApple OSS Distributions #else
365*2c2f96dcSApple OSS Distributions 	__xnu_bzero(s, n);
366*2c2f96dcSApple OSS Distributions #endif
367*2c2f96dcSApple OSS Distributions }
368*2c2f96dcSApple OSS Distributions 
369*2c2f96dcSApple OSS Distributions 
370*2c2f96dcSApple OSS Distributions extern void *memset(void *s __sized_by(n), int c, size_t n);
371*2c2f96dcSApple OSS Distributions 
372*2c2f96dcSApple OSS Distributions __xnu_string_inline
373*2c2f96dcSApple OSS Distributions void *
__sized_by(n)374*2c2f96dcSApple OSS Distributions __sized_by(n)
375*2c2f96dcSApple OSS Distributions memset(
376*2c2f96dcSApple OSS Distributions 	void *const             s __xnu_pass_object_size __sized_by(n),
377*2c2f96dcSApple OSS Distributions 	int                     c,
378*2c2f96dcSApple OSS Distributions 	size_t                  n)
379*2c2f96dcSApple OSS Distributions __xnu_object_size_precondition(s, n, "write overflow")
380*2c2f96dcSApple OSS Distributions {
381*2c2f96dcSApple OSS Distributions 	extern void __xnu_memset(
382*2c2f96dcSApple OSS Distributions 		void *__sized_by(n),
383*2c2f96dcSApple OSS Distributions 		int,
384*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_memset");
385*2c2f96dcSApple OSS Distributions 
386*2c2f96dcSApple OSS Distributions 	__xnu_object_size_check(s, n);
387*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_memset)
388*2c2f96dcSApple OSS Distributions 	return __builtin_memset(s, c, n);
389*2c2f96dcSApple OSS Distributions #else
390*2c2f96dcSApple OSS Distributions 	return __xnu_memset(s, c, n);
391*2c2f96dcSApple OSS Distributions #endif
392*2c2f96dcSApple OSS Distributions }
393*2c2f96dcSApple OSS Distributions 
394*2c2f96dcSApple OSS Distributions 
395*2c2f96dcSApple OSS Distributions extern int memset_s(void *s __sized_by(smax), size_t smax, int c, size_t n);
396*2c2f96dcSApple OSS Distributions 
397*2c2f96dcSApple OSS Distributions 
398*2c2f96dcSApple OSS Distributions extern void *memmove(void *dst __sized_by(n), const void *src __sized_by(n), size_t n);
399*2c2f96dcSApple OSS Distributions 
400*2c2f96dcSApple OSS Distributions __xnu_string_inline
401*2c2f96dcSApple OSS Distributions void *
__sized_by(n)402*2c2f96dcSApple OSS Distributions __sized_by(n)
403*2c2f96dcSApple OSS Distributions memmove(
404*2c2f96dcSApple OSS Distributions 	void *const             dst __xnu_pass_object_size __sized_by(n),
405*2c2f96dcSApple OSS Distributions 	const void *const       src __xnu_pass_object_size __sized_by(n),
406*2c2f96dcSApple OSS Distributions 	size_t                  n)
407*2c2f96dcSApple OSS Distributions __xnu_object_size_precondition(dst, n, "write overflow")
408*2c2f96dcSApple OSS Distributions __xnu_object_size_precondition(src, n, "read overflow")
409*2c2f96dcSApple OSS Distributions {
410*2c2f96dcSApple OSS Distributions 	extern void *__xnu_memmove(
411*2c2f96dcSApple OSS Distributions 		void *dst __sized_by(n),
412*2c2f96dcSApple OSS Distributions 		const void *src __sized_by(n),
413*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_memmove");
414*2c2f96dcSApple OSS Distributions 
415*2c2f96dcSApple OSS Distributions 	__xnu_object_size_check(dst, n);
416*2c2f96dcSApple OSS Distributions 	__xnu_object_size_check(src, n);
417*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_memmove)
418*2c2f96dcSApple OSS Distributions 	return __builtin_memmove(dst, src, n);
419*2c2f96dcSApple OSS Distributions #else
420*2c2f96dcSApple OSS Distributions 	return __xnu_memmove(dst, src, n);
421*2c2f96dcSApple OSS Distributions #endif
422*2c2f96dcSApple OSS Distributions }
423*2c2f96dcSApple OSS Distributions 
424*2c2f96dcSApple OSS Distributions __xnu_string_inline
425*2c2f96dcSApple OSS Distributions void *
__sized_by(n)426*2c2f96dcSApple OSS Distributions __sized_by(n)
427*2c2f96dcSApple OSS Distributions __nochk_memmove(
428*2c2f96dcSApple OSS Distributions 	void *const             dst __xnu_pass_struct_size __sized_by(n),
429*2c2f96dcSApple OSS Distributions 	const void *const       src __xnu_pass_struct_size __sized_by(n),
430*2c2f96dcSApple OSS Distributions 	size_t                  n)
431*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(dst, n, "write overflow")
432*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(src, n, "read overflow")
433*2c2f96dcSApple OSS Distributions {
434*2c2f96dcSApple OSS Distributions 	extern void *__xnu_memmove(
435*2c2f96dcSApple OSS Distributions 		void *dst __sized_by(n),
436*2c2f96dcSApple OSS Distributions 		const void *src __sized_by(n),
437*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_memmove");
438*2c2f96dcSApple OSS Distributions 
439*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(dst, n);
440*2c2f96dcSApple OSS Distributions 	__xnu_struct_size_check(src, n);
441*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_memmove)
442*2c2f96dcSApple OSS Distributions 	return __builtin_memmove(dst, src, n);
443*2c2f96dcSApple OSS Distributions #else
444*2c2f96dcSApple OSS Distributions 	return __xnu_memmove(dst, src, n);
445*2c2f96dcSApple OSS Distributions #endif
446*2c2f96dcSApple OSS Distributions }
447*2c2f96dcSApple OSS Distributions 
448*2c2f96dcSApple OSS Distributions 
449*2c2f96dcSApple OSS Distributions extern void bcopy(const void *src __sized_by(n), void *dst __sized_by(n), size_t n);
450*2c2f96dcSApple OSS Distributions 
451*2c2f96dcSApple OSS Distributions __xnu_string_inline
452*2c2f96dcSApple OSS Distributions void
bcopy(const void * const src __xnu_pass_object_size __sized_by (n),void * const dst __xnu_pass_object_size __sized_by (n),size_t n)453*2c2f96dcSApple OSS Distributions bcopy(
454*2c2f96dcSApple OSS Distributions 	const void *const       src __xnu_pass_object_size __sized_by(n),
455*2c2f96dcSApple OSS Distributions 	void *const             dst __xnu_pass_object_size __sized_by(n),
456*2c2f96dcSApple OSS Distributions 	size_t                  n)
457*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(dst, n, "write overflow")
458*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(src, n, "read overflow")
459*2c2f96dcSApple OSS Distributions {
460*2c2f96dcSApple OSS Distributions 	(void)memmove(dst, src, n);
461*2c2f96dcSApple OSS Distributions }
462*2c2f96dcSApple OSS Distributions 
463*2c2f96dcSApple OSS Distributions __xnu_string_inline
464*2c2f96dcSApple OSS Distributions void
__nochk_bcopy(const void * const src __xnu_pass_struct_size __sized_by (n),void * const dst __xnu_pass_struct_size __sized_by (n),size_t n)465*2c2f96dcSApple OSS Distributions __nochk_bcopy(
466*2c2f96dcSApple OSS Distributions 	const void *const       src __xnu_pass_struct_size __sized_by(n),
467*2c2f96dcSApple OSS Distributions 	void *const             dst __xnu_pass_struct_size __sized_by(n),
468*2c2f96dcSApple OSS Distributions 	size_t                  n)
469*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(dst, n, "write overflow")
470*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(src, n, "read overflow")
471*2c2f96dcSApple OSS Distributions {
472*2c2f96dcSApple OSS Distributions 	(void)__nochk_memmove(dst, src, n);
473*2c2f96dcSApple OSS Distributions }
474*2c2f96dcSApple OSS Distributions 
475*2c2f96dcSApple OSS Distributions 
476*2c2f96dcSApple OSS Distributions extern void *memcpy(void *dst __sized_by(n), const void *src __sized_by(n), size_t n);
477*2c2f96dcSApple OSS Distributions 
478*2c2f96dcSApple OSS Distributions __xnu_string_inline
479*2c2f96dcSApple OSS Distributions void *
__sized_by(n)480*2c2f96dcSApple OSS Distributions __sized_by(n)
481*2c2f96dcSApple OSS Distributions memcpy(
482*2c2f96dcSApple OSS Distributions 	void *const             dst __xnu_pass_object_size __sized_by(n),
483*2c2f96dcSApple OSS Distributions 	const void *const       src __xnu_pass_object_size __sized_by(n),
484*2c2f96dcSApple OSS Distributions 	size_t                  n)
485*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(dst, n, "write overflow")
486*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(src, n, "read overflow")
487*2c2f96dcSApple OSS Distributions {
488*2c2f96dcSApple OSS Distributions 	return memmove(dst, src, n);
489*2c2f96dcSApple OSS Distributions }
490*2c2f96dcSApple OSS Distributions 
491*2c2f96dcSApple OSS Distributions __xnu_string_inline
492*2c2f96dcSApple OSS Distributions void *
__sized_by(n)493*2c2f96dcSApple OSS Distributions __sized_by(n)
494*2c2f96dcSApple OSS Distributions __nochk_memcpy(
495*2c2f96dcSApple OSS Distributions 	void *const             dst __xnu_pass_struct_size __sized_by(n),
496*2c2f96dcSApple OSS Distributions 	const void *const       src __xnu_pass_struct_size __sized_by(n),
497*2c2f96dcSApple OSS Distributions 	size_t                  n)
498*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(dst, n, "write overflow")
499*2c2f96dcSApple OSS Distributions __xnu_struct_size_precondition(src, n, "read overflow")
500*2c2f96dcSApple OSS Distributions {
501*2c2f96dcSApple OSS Distributions 	return __nochk_memmove(dst, src, n);
502*2c2f96dcSApple OSS Distributions }
503*2c2f96dcSApple OSS Distributions 
504*2c2f96dcSApple OSS Distributions 
505*2c2f96dcSApple OSS Distributions #pragma mark string functions
506*2c2f96dcSApple OSS Distributions 
507*2c2f96dcSApple OSS Distributions extern size_t strlen(const char *__null_terminated s) __stateful_pure;
508*2c2f96dcSApple OSS Distributions 
509*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strlen)
510*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
511*2c2f96dcSApple OSS Distributions size_t
strlen(const char * const s __xnu_force_overload)512*2c2f96dcSApple OSS Distributions strlen(const char * /* __null_terminated */ const s __xnu_force_overload)
513*2c2f96dcSApple OSS Distributions {
514*2c2f96dcSApple OSS Distributions 	return __builtin_strlen(s);
515*2c2f96dcSApple OSS Distributions }
516*2c2f96dcSApple OSS Distributions #endif
517*2c2f96dcSApple OSS Distributions 
518*2c2f96dcSApple OSS Distributions 
519*2c2f96dcSApple OSS Distributions extern size_t strnlen(const char *__counted_by(n)s, size_t n) __stateful_pure;
520*2c2f96dcSApple OSS Distributions 
521*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strnlen)
522*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
523*2c2f96dcSApple OSS Distributions size_t
strnlen(const char * const __counted_by (n)s __xnu_force_overload,size_t n)524*2c2f96dcSApple OSS Distributions strnlen(const char *const __counted_by(n) s __xnu_force_overload, size_t n)
525*2c2f96dcSApple OSS Distributions {
526*2c2f96dcSApple OSS Distributions 	return __builtin_strnlen(s, n);
527*2c2f96dcSApple OSS Distributions }
528*2c2f96dcSApple OSS Distributions #endif
529*2c2f96dcSApple OSS Distributions 
530*2c2f96dcSApple OSS Distributions 
531*2c2f96dcSApple OSS Distributions /* strbuflen is the same as strnlen. */
532*2c2f96dcSApple OSS Distributions #define strbuflen_1(BUF) ({ \
533*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(BUF, "argument is not an array"); \
534*2c2f96dcSApple OSS Distributions 	strnlen((BUF), sizeof(BUF)); \
535*2c2f96dcSApple OSS Distributions })
536*2c2f96dcSApple OSS Distributions #define strbuflen_2(BUF, LEN) strnlen(BUF, LEN)
537*2c2f96dcSApple OSS Distributions #define strbuflen(...) __xnu_argc_overload(strbuflen, __VA_ARGS__)
538*2c2f96dcSApple OSS Distributions 
539*2c2f96dcSApple OSS Distributions 
540*2c2f96dcSApple OSS Distributions extern int strcmp(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure;
541*2c2f96dcSApple OSS Distributions 
542*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strcmp)
543*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
544*2c2f96dcSApple OSS Distributions int
strcmp(const char * const s1 __xnu_force_overload,const char * const __null_terminated s2)545*2c2f96dcSApple OSS Distributions strcmp(
546*2c2f96dcSApple OSS Distributions 	const char *const /* __null_terminated */ s1 __xnu_force_overload,
547*2c2f96dcSApple OSS Distributions 	const char *const __null_terminated s2)
548*2c2f96dcSApple OSS Distributions {
549*2c2f96dcSApple OSS Distributions 	return __builtin_strcmp(s1, s2);
550*2c2f96dcSApple OSS Distributions }
551*2c2f96dcSApple OSS Distributions #else
552*2c2f96dcSApple OSS Distributions #endif
553*2c2f96dcSApple OSS Distributions 
554*2c2f96dcSApple OSS Distributions 
555*2c2f96dcSApple OSS Distributions __ptrcheck_unavailable_r("strlcmp or strbufcmp")
556*2c2f96dcSApple OSS Distributions extern int strncmp(const char *__unsafe_indexable s1, const char *__unsafe_indexable s2, size_t n) __stateful_pure;
557*2c2f96dcSApple OSS Distributions 
558*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strncmp)
559*2c2f96dcSApple OSS Distributions __ptrcheck_unavailable_r("strlcmp or strbufcmp")
560*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
561*2c2f96dcSApple OSS Distributions int
strncmp(const char * const __unsafe_indexable s1 __xnu_force_overload,const char * const __unsafe_indexable s2,size_t n)562*2c2f96dcSApple OSS Distributions strncmp(
563*2c2f96dcSApple OSS Distributions 	const char *const __unsafe_indexable s1 __xnu_force_overload,
564*2c2f96dcSApple OSS Distributions 	const char *const __unsafe_indexable s2, size_t n)
565*2c2f96dcSApple OSS Distributions {
566*2c2f96dcSApple OSS Distributions 	return __builtin_strncmp(s1, s2, n);
567*2c2f96dcSApple OSS Distributions }
568*2c2f96dcSApple OSS Distributions #endif
569*2c2f96dcSApple OSS Distributions 
570*2c2f96dcSApple OSS Distributions /*
571*2c2f96dcSApple OSS Distributions  * Use strlcmp if you want to compare one string with a known length (with or
572*2c2f96dcSApple OSS Distributions  * without a NUL terminator) and one string with an unknown length (that always
573*2c2f96dcSApple OSS Distributions  * has a NUL terminator).
574*2c2f96dcSApple OSS Distributions  * See docs/primitives/string-handling.md for more information.
575*2c2f96dcSApple OSS Distributions  */
576*2c2f96dcSApple OSS Distributions extern int strlcmp(const char *__counted_by(n)s1, const char *s2, size_t n) __stateful_pure;
577*2c2f96dcSApple OSS Distributions 
578*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strncmp)
579*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
580*2c2f96dcSApple OSS Distributions int
strlcmp(const char * const __counted_by (s1len)s1 __xnu_force_overload,const char * const s2,size_t s1len)581*2c2f96dcSApple OSS Distributions strlcmp(
582*2c2f96dcSApple OSS Distributions 	const char *const __counted_by(s1len) s1 __xnu_force_overload,
583*2c2f96dcSApple OSS Distributions 	const char *const s2, size_t s1len)
584*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(s1, s1len, "read overflow")
585*2c2f96dcSApple OSS Distributions {
586*2c2f96dcSApple OSS Distributions 	extern int __xnu_strlcmp(
587*2c2f96dcSApple OSS Distributions 		const char * __counted_by(s1len) s1,
588*2c2f96dcSApple OSS Distributions 		const char *__null_terminated s2,
589*2c2f96dcSApple OSS Distributions 		size_t s1len) __asm("_strlcmp");
590*2c2f96dcSApple OSS Distributions 
591*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(s1, s1len);
592*2c2f96dcSApple OSS Distributions 	return __xnu_strlcmp(s1, s2, s1len);
593*2c2f96dcSApple OSS Distributions }
594*2c2f96dcSApple OSS Distributions #endif
595*2c2f96dcSApple OSS Distributions 
596*2c2f96dcSApple OSS Distributions 
597*2c2f96dcSApple OSS Distributions /*
598*2c2f96dcSApple OSS Distributions  * Use strbufcmp if you want to compare two strings and you know both of their
599*2c2f96dcSApple OSS Distributions  * lengths. See docs/primitives/string-handling.md for more information.
600*2c2f96dcSApple OSS Distributions  */
601*2c2f96dcSApple OSS Distributions extern int strbufcmp(const char *__counted_by(s1len)s1, size_t s1len, const char *__counted_by(s2len)s2, size_t s2len) __stateful_pure;
602*2c2f96dcSApple OSS Distributions 
603*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
604*2c2f96dcSApple OSS Distributions int
strbufcmp(const char * const __counted_by (s1len)s1 __xnu_pass_member_size,size_t s1len,const char * const __counted_by (s2len)s2 __xnu_pass_member_size,size_t s2len)605*2c2f96dcSApple OSS Distributions strbufcmp(
606*2c2f96dcSApple OSS Distributions 	const char *const __counted_by(s1len) s1 __xnu_pass_member_size, size_t s1len,
607*2c2f96dcSApple OSS Distributions 	const char *const __counted_by(s2len) s2 __xnu_pass_member_size, size_t s2len)
608*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(s1, s1len, "read overflow")
609*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(s2, s2len, "read overflow")
610*2c2f96dcSApple OSS Distributions {
611*2c2f96dcSApple OSS Distributions 	extern int __xnu_strbufcmp(
612*2c2f96dcSApple OSS Distributions 		const char * __counted_by(s1len) s1,
613*2c2f96dcSApple OSS Distributions 		size_t s1len,
614*2c2f96dcSApple OSS Distributions 		const char *__counted_by(s2len) s2,
615*2c2f96dcSApple OSS Distributions 		size_t s2len) __asm("_strbufcmp");
616*2c2f96dcSApple OSS Distributions 
617*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(s1, s1len);
618*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(s2, s2len);
619*2c2f96dcSApple OSS Distributions 	return __xnu_strbufcmp(s1, s1len, s2, s2len);
620*2c2f96dcSApple OSS Distributions }
621*2c2f96dcSApple OSS Distributions 
622*2c2f96dcSApple OSS Distributions #define strbufcmp_2(A, B) ({ \
623*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(A, "first argument is not an array"); \
624*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(B, "second argument is not an array"); \
625*2c2f96dcSApple OSS Distributions 	(strbufcmp)((A), sizeof(A), (B), sizeof(B)); \
626*2c2f96dcSApple OSS Distributions })
627*2c2f96dcSApple OSS Distributions #define strbufcmp_4 (strbufcmp)
628*2c2f96dcSApple OSS Distributions #define strbufcmp(...) __xnu_argc_overload(strbufcmp, __VA_ARGS__)
629*2c2f96dcSApple OSS Distributions 
630*2c2f96dcSApple OSS Distributions 
631*2c2f96dcSApple OSS Distributions extern int strprefix(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure;
632*2c2f96dcSApple OSS Distributions 
633*2c2f96dcSApple OSS Distributions 
634*2c2f96dcSApple OSS Distributions extern int strcasecmp(const char *__null_terminated s1, const char *__null_terminated s2) __stateful_pure;
635*2c2f96dcSApple OSS Distributions 
636*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strcasecmp)
637*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
638*2c2f96dcSApple OSS Distributions int
strcasecmp(const char * const s1 __xnu_force_overload,const char * const __null_terminated s2)639*2c2f96dcSApple OSS Distributions strcasecmp(
640*2c2f96dcSApple OSS Distributions 	const char *const /* __null_terminated */ s1 __xnu_force_overload,
641*2c2f96dcSApple OSS Distributions 	const char *const __null_terminated s2)
642*2c2f96dcSApple OSS Distributions {
643*2c2f96dcSApple OSS Distributions 	return __builtin_strcasecmp(s1, s2);
644*2c2f96dcSApple OSS Distributions }
645*2c2f96dcSApple OSS Distributions #endif
646*2c2f96dcSApple OSS Distributions 
647*2c2f96dcSApple OSS Distributions 
648*2c2f96dcSApple OSS Distributions __ptrcheck_unavailable_r("strlcasecmp or strbufcasecmp")
649*2c2f96dcSApple OSS Distributions extern int strncasecmp(const char *__unsafe_indexable s1, const char *__unsafe_indexable s2, size_t n) __stateful_pure;
650*2c2f96dcSApple OSS Distributions 
651*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strncasecmp)
652*2c2f96dcSApple OSS Distributions __ptrcheck_unavailable_r("strlcasecmp or strbufcasecmp")
653*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
654*2c2f96dcSApple OSS Distributions int
strncasecmp(const char * const __unsafe_indexable s1 __xnu_force_overload,const char * const __unsafe_indexable s2,size_t n)655*2c2f96dcSApple OSS Distributions strncasecmp(
656*2c2f96dcSApple OSS Distributions 	const char *const __unsafe_indexable s1 __xnu_force_overload,
657*2c2f96dcSApple OSS Distributions 	const char *const __unsafe_indexable s2, size_t n)
658*2c2f96dcSApple OSS Distributions {
659*2c2f96dcSApple OSS Distributions 	return __builtin_strncasecmp(s1, s2, n);
660*2c2f96dcSApple OSS Distributions }
661*2c2f96dcSApple OSS Distributions #endif
662*2c2f96dcSApple OSS Distributions 
663*2c2f96dcSApple OSS Distributions /*
664*2c2f96dcSApple OSS Distributions  * Use strlcasecmp if you want to compare one string with a known length (with
665*2c2f96dcSApple OSS Distributions  * or without a NUL terminator) and one string with an unknown length (that
666*2c2f96dcSApple OSS Distributions  * always has a NUL terminator).
667*2c2f96dcSApple OSS Distributions  * See docs/primitives/string-handling.md for more information.
668*2c2f96dcSApple OSS Distributions  */
669*2c2f96dcSApple OSS Distributions extern int strlcasecmp(const char *__counted_by(n)s1, const char *s2, size_t n) __stateful_pure;
670*2c2f96dcSApple OSS Distributions 
671*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
672*2c2f96dcSApple OSS Distributions int
strlcasecmp(const char * const __counted_by (s1len)s1 __xnu_force_overload,const char * __null_terminated const s2,size_t s1len)673*2c2f96dcSApple OSS Distributions strlcasecmp(
674*2c2f96dcSApple OSS Distributions 	const char *const __counted_by(s1len) s1 __xnu_force_overload,
675*2c2f96dcSApple OSS Distributions 	const char *__null_terminated const s2, size_t s1len)
676*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(s1, s1len, "read overflow")
677*2c2f96dcSApple OSS Distributions {
678*2c2f96dcSApple OSS Distributions 	extern int __xnu_strlcasecmp(
679*2c2f96dcSApple OSS Distributions 		const char * __counted_by(s1len) s1,
680*2c2f96dcSApple OSS Distributions 		const char *__null_terminated s2,
681*2c2f96dcSApple OSS Distributions 		size_t s1len) __asm("_strlcasecmp");
682*2c2f96dcSApple OSS Distributions 
683*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(s1, s1len);
684*2c2f96dcSApple OSS Distributions 	return __xnu_strlcasecmp(s1, s2, s1len);
685*2c2f96dcSApple OSS Distributions }
686*2c2f96dcSApple OSS Distributions 
687*2c2f96dcSApple OSS Distributions 
688*2c2f96dcSApple OSS Distributions /*
689*2c2f96dcSApple OSS Distributions  * Use strbufcmp if you want to compare two strings and you know both of their
690*2c2f96dcSApple OSS Distributions  * lengths. See docs/primitives/string-handling.md for more information.
691*2c2f96dcSApple OSS Distributions  */
692*2c2f96dcSApple OSS Distributions extern int strbufcasecmp(const char *__counted_by(s1len)s1, size_t s1len, const char *__counted_by(s2len)s2, size_t s2len) __stateful_pure;
693*2c2f96dcSApple OSS Distributions 
694*2c2f96dcSApple OSS Distributions __xnu_string_inline __stateful_pure
695*2c2f96dcSApple OSS Distributions int
strbufcasecmp(const char * const __counted_by (s1len)s1 __xnu_pass_member_size,size_t s1len,const char * const __counted_by (s2len)s2 __xnu_pass_member_size,size_t s2len)696*2c2f96dcSApple OSS Distributions strbufcasecmp(
697*2c2f96dcSApple OSS Distributions 	const char *const __counted_by(s1len) s1 __xnu_pass_member_size, size_t s1len,
698*2c2f96dcSApple OSS Distributions 	const char *const __counted_by(s2len) s2 __xnu_pass_member_size, size_t s2len)
699*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(s1, s1len, "read overflow")
700*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(s2, s2len, "read overflow")
701*2c2f96dcSApple OSS Distributions {
702*2c2f96dcSApple OSS Distributions 	extern int __xnu_strbufcasecmp(
703*2c2f96dcSApple OSS Distributions 		const char * __counted_by(s1len) s1,
704*2c2f96dcSApple OSS Distributions 		size_t s1len,
705*2c2f96dcSApple OSS Distributions 		const char *__counted_by(s2len) s2,
706*2c2f96dcSApple OSS Distributions 		size_t s2len) __asm("_strbufcasecmp");
707*2c2f96dcSApple OSS Distributions 
708*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(s1, s1len);
709*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(s2, s2len);
710*2c2f96dcSApple OSS Distributions 	return __xnu_strbufcasecmp(s1, s1len, s2, s2len);
711*2c2f96dcSApple OSS Distributions }
712*2c2f96dcSApple OSS Distributions 
713*2c2f96dcSApple OSS Distributions #define strbufcasecmp_2(A, B) ({ \
714*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(A, "first argument is not an array"); \
715*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(B, "second argument is not an array"); \
716*2c2f96dcSApple OSS Distributions 	(strbufcasecmp)((A), sizeof(A), (B), sizeof(B)); \
717*2c2f96dcSApple OSS Distributions })
718*2c2f96dcSApple OSS Distributions #define strbufcasecmp_4 (strbufcasecmp)
719*2c2f96dcSApple OSS Distributions #define strbufcasecmp(...) __xnu_argc_overload(strbufcasecmp, __VA_ARGS__)
720*2c2f96dcSApple OSS Distributions 
721*2c2f96dcSApple OSS Distributions 
722*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strchr)
723*2c2f96dcSApple OSS Distributions __xnu_string_inline
724*2c2f96dcSApple OSS Distributions char *__null_terminated
strchr(const char * const s __xnu_force_overload,int c)725*2c2f96dcSApple OSS Distributions strchr(const char *const /* __null_terminated */ s __xnu_force_overload, int c)
726*2c2f96dcSApple OSS Distributions {
727*2c2f96dcSApple OSS Distributions 	return __unsafe_forge_null_terminated(char *, __builtin_strchr(s, c));
728*2c2f96dcSApple OSS Distributions }
729*2c2f96dcSApple OSS Distributions #endif
730*2c2f96dcSApple OSS Distributions 
731*2c2f96dcSApple OSS Distributions 
732*2c2f96dcSApple OSS Distributions #if XNU_KERNEL_PRIVATE /* rdar://103276672 */
733*2c2f96dcSApple OSS Distributions extern char *__null_terminated strrchr(const char *__null_terminated s, int c) __stateful_pure;
734*2c2f96dcSApple OSS Distributions 
735*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strrchr) && !__has_ptrcheck /* rdar://103265304 */
736*2c2f96dcSApple OSS Distributions __xnu_string_inline
737*2c2f96dcSApple OSS Distributions char *__null_terminated
strrchr(const char * const __null_terminated s __xnu_force_overload,int c)738*2c2f96dcSApple OSS Distributions strrchr(const char *const __null_terminated s __xnu_force_overload, int c)
739*2c2f96dcSApple OSS Distributions {
740*2c2f96dcSApple OSS Distributions 	return __builtin_strrchr(s, c);
741*2c2f96dcSApple OSS Distributions }
742*2c2f96dcSApple OSS Distributions #endif
743*2c2f96dcSApple OSS Distributions #endif
744*2c2f96dcSApple OSS Distributions 
745*2c2f96dcSApple OSS Distributions 
746*2c2f96dcSApple OSS Distributions extern char *__null_terminated strnstr(const char *__null_terminated s, const char *__null_terminated find, size_t slen) __stateful_pure;
747*2c2f96dcSApple OSS Distributions 
748*2c2f96dcSApple OSS Distributions 
749*2c2f96dcSApple OSS Distributions extern size_t strlcpy(char *__counted_by(n) dst, const char *__null_terminated src, size_t n);
750*2c2f96dcSApple OSS Distributions 
751*2c2f96dcSApple OSS Distributions __xnu_string_inline
752*2c2f96dcSApple OSS Distributions size_t
strlcpy(char * const dst __xnu_pass_member_size __counted_by (n),const char * const src __null_terminated,size_t n)753*2c2f96dcSApple OSS Distributions strlcpy(
754*2c2f96dcSApple OSS Distributions 	char *const             dst __xnu_pass_member_size __counted_by(n),
755*2c2f96dcSApple OSS Distributions 	const char *const       src __null_terminated,
756*2c2f96dcSApple OSS Distributions 	size_t                  n)
757*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(dst, n, "write overflow")
758*2c2f96dcSApple OSS Distributions {
759*2c2f96dcSApple OSS Distributions 	extern size_t __xnu_strlcpy(
760*2c2f96dcSApple OSS Distributions 		char * __counted_by(n),
761*2c2f96dcSApple OSS Distributions 		const char *__null_terminated,
762*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_strlcpy");
763*2c2f96dcSApple OSS Distributions 
764*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(dst, n);
765*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strlcpy)
766*2c2f96dcSApple OSS Distributions 	return __builtin_strlcpy(dst, src, n);
767*2c2f96dcSApple OSS Distributions #else
768*2c2f96dcSApple OSS Distributions 	return __xnu_strlcpy(dst, src, n);
769*2c2f96dcSApple OSS Distributions #endif
770*2c2f96dcSApple OSS Distributions }
771*2c2f96dcSApple OSS Distributions 
772*2c2f96dcSApple OSS Distributions 
773*2c2f96dcSApple OSS Distributions /*
774*2c2f96dcSApple OSS Distributions  * strbufcpy returns its destination as a NUL-terminated string, which makes a
775*2c2f96dcSApple OSS Distributions  * difference when -fbounds-safety is enabled.
776*2c2f96dcSApple OSS Distributions  * See docs/primitives/string-handling.md for more information.
777*2c2f96dcSApple OSS Distributions  */
778*2c2f96dcSApple OSS Distributions extern const char *__null_terminated
779*2c2f96dcSApple OSS Distributions     strbufcpy(
780*2c2f96dcSApple OSS Distributions 	char *__counted_by(dstsz) dst,
781*2c2f96dcSApple OSS Distributions 	size_t dstsz,
782*2c2f96dcSApple OSS Distributions 	const char *__counted_by(srcsz) src,
783*2c2f96dcSApple OSS Distributions 	size_t srcsz);
784*2c2f96dcSApple OSS Distributions 
785*2c2f96dcSApple OSS Distributions __xnu_string_inline
786*2c2f96dcSApple OSS Distributions const char *
strbufcpy(char * const dst __xnu_pass_member_size __counted_by (dstsz),size_t dstsz,const char * const src __xnu_pass_member_size __counted_by (srcsz),size_t srcsz)787*2c2f96dcSApple OSS Distributions strbufcpy(
788*2c2f96dcSApple OSS Distributions 	char *const             dst __xnu_pass_member_size __counted_by(dstsz),
789*2c2f96dcSApple OSS Distributions 	size_t                  dstsz,
790*2c2f96dcSApple OSS Distributions 	const char *const       src __xnu_pass_member_size __counted_by(srcsz),
791*2c2f96dcSApple OSS Distributions 	size_t                  srcsz)
792*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(dst, dstsz, "write overflow")
793*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(src, srcsz, "read overflow")
794*2c2f96dcSApple OSS Distributions {
795*2c2f96dcSApple OSS Distributions 	extern const char *__xnu_strbufcpy(
796*2c2f96dcSApple OSS Distributions 		char *__counted_by(dstsz) dst,
797*2c2f96dcSApple OSS Distributions 		size_t dstsz,
798*2c2f96dcSApple OSS Distributions 		const char *__counted_by(srcsz) src,
799*2c2f96dcSApple OSS Distributions 		size_t srcsz) __asm("_strbufcpy");
800*2c2f96dcSApple OSS Distributions 
801*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(dst, dstsz);
802*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(src, srcsz);
803*2c2f96dcSApple OSS Distributions 	return __xnu_strbufcpy(dst, dstsz, src, srcsz);
804*2c2f96dcSApple OSS Distributions }
805*2c2f96dcSApple OSS Distributions 
806*2c2f96dcSApple OSS Distributions #define strbufcpy_2(DST, SRC) ({ \
807*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(DST, "dst is not an array"); \
808*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(SRC, "src is not an array"); \
809*2c2f96dcSApple OSS Distributions 	(strbufcpy)((DST), sizeof(DST), (SRC), sizeof(SRC)); \
810*2c2f96dcSApple OSS Distributions })
811*2c2f96dcSApple OSS Distributions #define strbufcpy_4     (strbufcpy)
812*2c2f96dcSApple OSS Distributions #define strbufcpy(...)  __xnu_argc_overload(strbufcpy, __VA_ARGS__)
813*2c2f96dcSApple OSS Distributions 
814*2c2f96dcSApple OSS Distributions extern size_t strlcat(char *__counted_by(n) dst, const char *__null_terminated src, size_t n);
815*2c2f96dcSApple OSS Distributions 
816*2c2f96dcSApple OSS Distributions __xnu_string_inline
817*2c2f96dcSApple OSS Distributions size_t
strlcat(char * const dst __xnu_pass_member_size __counted_by (n),const char * const src __null_terminated,size_t n)818*2c2f96dcSApple OSS Distributions strlcat(
819*2c2f96dcSApple OSS Distributions 	char *const             dst __xnu_pass_member_size __counted_by(n),
820*2c2f96dcSApple OSS Distributions 	const char *const       src __null_terminated,
821*2c2f96dcSApple OSS Distributions 	size_t                  n)
822*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(dst, n, "write overflow")
823*2c2f96dcSApple OSS Distributions {
824*2c2f96dcSApple OSS Distributions 	extern size_t __xnu_strlcat(
825*2c2f96dcSApple OSS Distributions 		char * __sized_by(n),
826*2c2f96dcSApple OSS Distributions 		const char *__null_terminated,
827*2c2f96dcSApple OSS Distributions 		size_t n) __asm("_strlcat");
828*2c2f96dcSApple OSS Distributions 
829*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(dst, n);
830*2c2f96dcSApple OSS Distributions #if __has_builtin(__builtin_strlcat)
831*2c2f96dcSApple OSS Distributions 	return __builtin_strlcat(dst, src, n);
832*2c2f96dcSApple OSS Distributions #else
833*2c2f96dcSApple OSS Distributions 	return __xnu_strlcat(dst, src, n);
834*2c2f96dcSApple OSS Distributions #endif
835*2c2f96dcSApple OSS Distributions }
836*2c2f96dcSApple OSS Distributions 
837*2c2f96dcSApple OSS Distributions 
838*2c2f96dcSApple OSS Distributions /*
839*2c2f96dcSApple OSS Distributions  * strbufcat returns its destination as a NUL-terminated string, which makes a
840*2c2f96dcSApple OSS Distributions  * difference when -fbounds-safety is enabled.
841*2c2f96dcSApple OSS Distributions  * See docs/primitives/string-handling.md for more information.
842*2c2f96dcSApple OSS Distributions  */
843*2c2f96dcSApple OSS Distributions extern const char *__null_terminated
844*2c2f96dcSApple OSS Distributions     strbufcat(
845*2c2f96dcSApple OSS Distributions 	char *__counted_by(dstsz) dst,
846*2c2f96dcSApple OSS Distributions 	size_t dstsz,
847*2c2f96dcSApple OSS Distributions 	const char *__counted_by(srcsz) src,
848*2c2f96dcSApple OSS Distributions 	size_t srcsz);
849*2c2f96dcSApple OSS Distributions 
850*2c2f96dcSApple OSS Distributions __xnu_string_inline
851*2c2f96dcSApple OSS Distributions const char *
strbufcat(char * const dst __xnu_pass_member_size __counted_by (dstsz),size_t dstsz,const char * const src __xnu_pass_member_size __counted_by (srcsz),size_t srcsz)852*2c2f96dcSApple OSS Distributions strbufcat(
853*2c2f96dcSApple OSS Distributions 	char *const             dst __xnu_pass_member_size __counted_by(dstsz),
854*2c2f96dcSApple OSS Distributions 	size_t                  dstsz,
855*2c2f96dcSApple OSS Distributions 	const char *const       src __xnu_pass_member_size __counted_by(srcsz),
856*2c2f96dcSApple OSS Distributions 	size_t                  srcsz)
857*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(dst, dstsz, "write overflow")
858*2c2f96dcSApple OSS Distributions __xnu_member_size_precondition(src, srcsz, "read overflow")
859*2c2f96dcSApple OSS Distributions {
860*2c2f96dcSApple OSS Distributions 	extern const char *__xnu_strbufcat(
861*2c2f96dcSApple OSS Distributions 		char *__counted_by(dstsz) dst,
862*2c2f96dcSApple OSS Distributions 		size_t dstsz,
863*2c2f96dcSApple OSS Distributions 		const char *__counted_by(srcsz) src,
864*2c2f96dcSApple OSS Distributions 		size_t srcsz) __asm("_strbufcat");
865*2c2f96dcSApple OSS Distributions 
866*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(dst, dstsz);
867*2c2f96dcSApple OSS Distributions 	__xnu_member_size_check(src, srcsz);
868*2c2f96dcSApple OSS Distributions 	return __xnu_strbufcat(dst, dstsz, src, srcsz);
869*2c2f96dcSApple OSS Distributions }
870*2c2f96dcSApple OSS Distributions 
871*2c2f96dcSApple OSS Distributions #define strbufcat_2(DST, SRC) ({ \
872*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(DST, "dst is not an array"); \
873*2c2f96dcSApple OSS Distributions 	__xnu_assert_is_array(SRC, "src is not an array"); \
874*2c2f96dcSApple OSS Distributions 	(strbufcat)((DST), sizeof(DST), (SRC), sizeof(SRC)); \
875*2c2f96dcSApple OSS Distributions })
876*2c2f96dcSApple OSS Distributions #define strbufcat_4     (strbufcat)
877*2c2f96dcSApple OSS Distributions #define strbufcat(...) __xnu_argc_overload(strbufcat, __VA_ARGS__)
878*2c2f96dcSApple OSS Distributions 
879*2c2f96dcSApple OSS Distributions #pragma mark deprecated functions
880*2c2f96dcSApple OSS Distributions #if !__has_ptrcheck && !__has_include(<__xnu_libcxx_sentinel.h>)
881*2c2f96dcSApple OSS Distributions 
882*2c2f96dcSApple OSS Distributions /*
883*2c2f96dcSApple OSS Distributions  * char *strncat(char *dst, const char *src, size_t n);
884*2c2f96dcSApple OSS Distributions  * char *strncpy(char *dst, const char *src, size_t n);
885*2c2f96dcSApple OSS Distributions  *
886*2c2f96dcSApple OSS Distributions  * char *strcat(char *dst, const char *src);
887*2c2f96dcSApple OSS Distributions  * char *strcpy(char *, const char *);
888*2c2f96dcSApple OSS Distributions  *
889*2c2f96dcSApple OSS Distributions  * char *STRDUP(const char *, int);
890*2c2f96dcSApple OSS Distributions  */
891*2c2f96dcSApple OSS Distributions 
892*2c2f96dcSApple OSS Distributions __deprecated_msg("use strlcat")
893*2c2f96dcSApple OSS Distributions __kpi_deprecated_arm64_macos_unavailable
894*2c2f96dcSApple OSS Distributions extern char *strncat(char *dst, const char *src, size_t n);
895*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE && __has_builtin(__builtin___strncat_chk)
896*2c2f96dcSApple OSS Distributions #define strncat(dst, src, n)            __builtin___strncat_chk(dst, src, n, __xnu_member_size(dst))
897*2c2f96dcSApple OSS Distributions #endif
898*2c2f96dcSApple OSS Distributions 
899*2c2f96dcSApple OSS Distributions 
900*2c2f96dcSApple OSS Distributions __deprecated_msg("use strlcpy")
901*2c2f96dcSApple OSS Distributions __kpi_deprecated_arm64_macos_unavailable
902*2c2f96dcSApple OSS Distributions extern char *strncpy(char *dst, const char *src, size_t n);
903*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE && __has_builtin(__builtin___strncpy_chk)
904*2c2f96dcSApple OSS Distributions #define strncpy(dst, src, n)            __builtin___strncpy_chk(dst, src, n, __xnu_member_size(dst))
905*2c2f96dcSApple OSS Distributions #endif
906*2c2f96dcSApple OSS Distributions 
907*2c2f96dcSApple OSS Distributions __deprecated_msg("use strlcpy")
908*2c2f96dcSApple OSS Distributions __kpi_deprecated_arm64_macos_unavailable
909*2c2f96dcSApple OSS Distributions extern char *strcpy(char *, const char *);
910*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE && __has_builtin(__builtin___strcpy_chk)
911*2c2f96dcSApple OSS Distributions /* rdar://103287225 */
912*2c2f96dcSApple OSS Distributions #define strcpy(dst, src, len)           __builtin___strcpy_chk(dst, src, __xnu_member_size(dst))
913*2c2f96dcSApple OSS Distributions #endif
914*2c2f96dcSApple OSS Distributions 
915*2c2f96dcSApple OSS Distributions __deprecated_msg("use strlcat")
916*2c2f96dcSApple OSS Distributions __kpi_deprecated_arm64_macos_unavailable
917*2c2f96dcSApple OSS Distributions extern char *strcat(char *dst, const char *src);
918*2c2f96dcSApple OSS Distributions #if __XNU_FORTIFY_SOURCE && __has_builtin(__builtin___strcat_chk)
919*2c2f96dcSApple OSS Distributions #define strcat(dst, src)                __builtin___strcat_chk(dst, src, __xnu_member_size(dst))
920*2c2f96dcSApple OSS Distributions #endif
921*2c2f96dcSApple OSS Distributions 
922*2c2f96dcSApple OSS Distributions #if XNU_PLATFORM_MacOSX
923*2c2f96dcSApple OSS Distributions #ifndef KERNEL_PRIVATE
924*2c2f96dcSApple OSS Distributions extern char *STRDUP(const char *, int);
925*2c2f96dcSApple OSS Distributions #endif
926*2c2f96dcSApple OSS Distributions #endif /* XNU_PLATFORM_MacOSX */
927*2c2f96dcSApple OSS Distributions 
928*2c2f96dcSApple OSS Distributions #endif /* !__has_ptrcheck && !__has_include(<__xnu_libcxx_sentinel.h>) */
929*2c2f96dcSApple OSS Distributions 
930*2c2f96dcSApple OSS Distributions #if __has_include(<san/memintrinsics.h>)
931*2c2f96dcSApple OSS Distributions #include <san/memintrinsics.h>
932*2c2f96dcSApple OSS Distributions #endif
933*2c2f96dcSApple OSS Distributions 
934*2c2f96dcSApple OSS Distributions __END_DECLS
935*2c2f96dcSApple OSS Distributions 
936*2c2f96dcSApple OSS Distributions #endif  /* _STRING_H_ */
937*2c2f96dcSApple OSS Distributions 
938*2c2f96dcSApple OSS Distributions #endif
939