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