xref: /xnu-8020.140.41/libkern/os/base.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1*27b03b36SApple OSS Distributions /*
2*27b03b36SApple OSS Distributions  * Copyright (c) 2008-2020 Apple Inc. All rights reserved.
3*27b03b36SApple OSS Distributions  *
4*27b03b36SApple OSS Distributions  * @APPLE_APACHE_LICENSE_HEADER_START@
5*27b03b36SApple OSS Distributions  *
6*27b03b36SApple OSS Distributions  * Licensed under the Apache License, Version 2.0 (the "License");
7*27b03b36SApple OSS Distributions  * you may not use this file except in compliance with the License.
8*27b03b36SApple OSS Distributions  * You may obtain a copy of the License at
9*27b03b36SApple OSS Distributions  *
10*27b03b36SApple OSS Distributions  *     http://www.apache.org/licenses/LICENSE-2.0
11*27b03b36SApple OSS Distributions  *
12*27b03b36SApple OSS Distributions  * Unless required by applicable law or agreed to in writing, software
13*27b03b36SApple OSS Distributions  * distributed under the License is distributed on an "AS IS" BASIS,
14*27b03b36SApple OSS Distributions  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*27b03b36SApple OSS Distributions  * See the License for the specific language governing permissions and
16*27b03b36SApple OSS Distributions  * limitations under the License.
17*27b03b36SApple OSS Distributions  *
18*27b03b36SApple OSS Distributions  * @APPLE_APACHE_LICENSE_HEADER_END@
19*27b03b36SApple OSS Distributions  */
20*27b03b36SApple OSS Distributions 
21*27b03b36SApple OSS Distributions #ifndef __OS_BASE__
22*27b03b36SApple OSS Distributions #define __OS_BASE__
23*27b03b36SApple OSS Distributions 
24*27b03b36SApple OSS Distributions #include <sys/cdefs.h>
25*27b03b36SApple OSS Distributions 
26*27b03b36SApple OSS Distributions 
27*27b03b36SApple OSS Distributions #ifndef __has_builtin
28*27b03b36SApple OSS Distributions #define __has_builtin(x) 0
29*27b03b36SApple OSS Distributions #endif
30*27b03b36SApple OSS Distributions #ifndef __has_include
31*27b03b36SApple OSS Distributions #define __has_include(x) 0
32*27b03b36SApple OSS Distributions #endif
33*27b03b36SApple OSS Distributions #ifndef __has_feature
34*27b03b36SApple OSS Distributions #define __has_feature(x) 0
35*27b03b36SApple OSS Distributions #endif
36*27b03b36SApple OSS Distributions #ifndef __has_attribute
37*27b03b36SApple OSS Distributions #define __has_attribute(x) 0
38*27b03b36SApple OSS Distributions #endif
39*27b03b36SApple OSS Distributions #ifndef __has_extension
40*27b03b36SApple OSS Distributions #define __has_extension(x) 0
41*27b03b36SApple OSS Distributions #endif
42*27b03b36SApple OSS Distributions 
43*27b03b36SApple OSS Distributions #undef OS_INLINE // <sys/_types/_os_inline.h>
44*27b03b36SApple OSS Distributions #if __GNUC__
45*27b03b36SApple OSS Distributions #define OS_NORETURN __attribute__((__noreturn__))
46*27b03b36SApple OSS Distributions #define OS_NOTHROW __attribute__((__nothrow__))
47*27b03b36SApple OSS Distributions #define OS_NONNULL1 __attribute__((__nonnull__(1)))
48*27b03b36SApple OSS Distributions #define OS_NONNULL2 __attribute__((__nonnull__(2)))
49*27b03b36SApple OSS Distributions #define OS_NONNULL3 __attribute__((__nonnull__(3)))
50*27b03b36SApple OSS Distributions #define OS_NONNULL4 __attribute__((__nonnull__(4)))
51*27b03b36SApple OSS Distributions #define OS_NONNULL5 __attribute__((__nonnull__(5)))
52*27b03b36SApple OSS Distributions #define OS_NONNULL6 __attribute__((__nonnull__(6)))
53*27b03b36SApple OSS Distributions #define OS_NONNULL7 __attribute__((__nonnull__(7)))
54*27b03b36SApple OSS Distributions #define OS_NONNULL8 __attribute__((__nonnull__(8)))
55*27b03b36SApple OSS Distributions #define OS_NONNULL9 __attribute__((__nonnull__(9)))
56*27b03b36SApple OSS Distributions #define OS_NONNULL10 __attribute__((__nonnull__(10)))
57*27b03b36SApple OSS Distributions #define OS_NONNULL11 __attribute__((__nonnull__(11)))
58*27b03b36SApple OSS Distributions #define OS_NONNULL12 __attribute__((__nonnull__(12)))
59*27b03b36SApple OSS Distributions #define OS_NONNULL13 __attribute__((__nonnull__(13)))
60*27b03b36SApple OSS Distributions #define OS_NONNULL14 __attribute__((__nonnull__(14)))
61*27b03b36SApple OSS Distributions #define OS_NONNULL15 __attribute__((__nonnull__(15)))
62*27b03b36SApple OSS Distributions #define OS_NONNULL_ALL __attribute__((__nonnull__))
63*27b03b36SApple OSS Distributions #define OS_SENTINEL __attribute__((__sentinel__))
64*27b03b36SApple OSS Distributions #define OS_PURE __attribute__((__pure__))
65*27b03b36SApple OSS Distributions #define OS_CONST __attribute__((__const__))
66*27b03b36SApple OSS Distributions #define OS_WARN_RESULT __attribute__((__warn_unused_result__))
67*27b03b36SApple OSS Distributions #define OS_MALLOC __attribute__((__malloc__))
68*27b03b36SApple OSS Distributions #define OS_USED __attribute__((__used__))
69*27b03b36SApple OSS Distributions #define OS_UNUSED __attribute__((__unused__))
70*27b03b36SApple OSS Distributions #define OS_COLD __attribute__((__cold__))
71*27b03b36SApple OSS Distributions #define OS_WEAK __attribute__((__weak__))
72*27b03b36SApple OSS Distributions #define OS_WEAK_IMPORT __attribute__((__weak_import__))
73*27b03b36SApple OSS Distributions #define OS_NOINLINE __attribute__((__noinline__))
74*27b03b36SApple OSS Distributions #define OS_ALWAYS_INLINE __attribute__((__always_inline__))
75*27b03b36SApple OSS Distributions #define OS_TRANSPARENT_UNION __attribute__((__transparent_union__))
76*27b03b36SApple OSS Distributions #define OS_ALIGNED(n) __attribute__((__aligned__((n))))
77*27b03b36SApple OSS Distributions #define OS_FORMAT_PRINTF(x, y) __attribute__((__format__(printf,x,y)))
78*27b03b36SApple OSS Distributions #define OS_EXPORT extern __attribute__((__visibility__("default")))
79*27b03b36SApple OSS Distributions #define OS_INLINE static __inline__
80*27b03b36SApple OSS Distributions #define OS_EXPECT(x, v) __builtin_expect((x), (v))
81*27b03b36SApple OSS Distributions #else
82*27b03b36SApple OSS Distributions #define OS_NORETURN
83*27b03b36SApple OSS Distributions #define OS_NOTHROW
84*27b03b36SApple OSS Distributions #define OS_NONNULL1
85*27b03b36SApple OSS Distributions #define OS_NONNULL2
86*27b03b36SApple OSS Distributions #define OS_NONNULL3
87*27b03b36SApple OSS Distributions #define OS_NONNULL4
88*27b03b36SApple OSS Distributions #define OS_NONNULL5
89*27b03b36SApple OSS Distributions #define OS_NONNULL6
90*27b03b36SApple OSS Distributions #define OS_NONNULL7
91*27b03b36SApple OSS Distributions #define OS_NONNULL8
92*27b03b36SApple OSS Distributions #define OS_NONNULL9
93*27b03b36SApple OSS Distributions #define OS_NONNULL10
94*27b03b36SApple OSS Distributions #define OS_NONNULL11
95*27b03b36SApple OSS Distributions #define OS_NONNULL12
96*27b03b36SApple OSS Distributions #define OS_NONNULL13
97*27b03b36SApple OSS Distributions #define OS_NONNULL14
98*27b03b36SApple OSS Distributions #define OS_NONNULL15
99*27b03b36SApple OSS Distributions #define OS_NONNULL_ALL
100*27b03b36SApple OSS Distributions #define OS_SENTINEL
101*27b03b36SApple OSS Distributions #define OS_PURE
102*27b03b36SApple OSS Distributions #define OS_CONST
103*27b03b36SApple OSS Distributions #define OS_WARN_RESULT
104*27b03b36SApple OSS Distributions #define OS_MALLOC
105*27b03b36SApple OSS Distributions #define OS_USED
106*27b03b36SApple OSS Distributions #define OS_UNUSED
107*27b03b36SApple OSS Distributions #define OS_COLD
108*27b03b36SApple OSS Distributions #define OS_WEAK
109*27b03b36SApple OSS Distributions #define OS_WEAK_IMPORT
110*27b03b36SApple OSS Distributions #define OS_NOINLINE
111*27b03b36SApple OSS Distributions #define OS_ALWAYS_INLINE
112*27b03b36SApple OSS Distributions #define OS_TRANSPARENT_UNION
113*27b03b36SApple OSS Distributions #define OS_ALIGNED(n)
114*27b03b36SApple OSS Distributions #define OS_FORMAT_PRINTF(x, y)
115*27b03b36SApple OSS Distributions #define OS_EXPORT extern
116*27b03b36SApple OSS Distributions #define OS_INLINE static inline
117*27b03b36SApple OSS Distributions #define OS_EXPECT(x, v) (x)
118*27b03b36SApple OSS Distributions #endif
119*27b03b36SApple OSS Distributions 
120*27b03b36SApple OSS Distributions #if __has_attribute(noescape)
121*27b03b36SApple OSS Distributions #define OS_NOESCAPE __attribute__((__noescape__))
122*27b03b36SApple OSS Distributions #else
123*27b03b36SApple OSS Distributions #define OS_NOESCAPE
124*27b03b36SApple OSS Distributions #endif
125*27b03b36SApple OSS Distributions 
126*27b03b36SApple OSS Distributions #if defined(__cplusplus) && defined(__clang__)
127*27b03b36SApple OSS Distributions #define OS_FALLTHROUGH [[clang::fallthrough]]
128*27b03b36SApple OSS Distributions #elif __has_attribute(fallthrough)
129*27b03b36SApple OSS Distributions #define OS_FALLTHROUGH __attribute__((__fallthrough__))
130*27b03b36SApple OSS Distributions #else
131*27b03b36SApple OSS Distributions #define OS_FALLTHROUGH
132*27b03b36SApple OSS Distributions #endif
133*27b03b36SApple OSS Distributions 
134*27b03b36SApple OSS Distributions #if __has_feature(assume_nonnull)
135*27b03b36SApple OSS Distributions #define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
136*27b03b36SApple OSS Distributions #define OS_ASSUME_NONNULL_END   _Pragma("clang assume_nonnull end")
137*27b03b36SApple OSS Distributions #else
138*27b03b36SApple OSS Distributions #define OS_ASSUME_NONNULL_BEGIN
139*27b03b36SApple OSS Distributions #define OS_ASSUME_NONNULL_END
140*27b03b36SApple OSS Distributions #endif
141*27b03b36SApple OSS Distributions 
142*27b03b36SApple OSS Distributions #if __has_builtin(__builtin_assume)
143*27b03b36SApple OSS Distributions #define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
144*27b03b36SApple OSS Distributions #else
145*27b03b36SApple OSS Distributions #define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr))
146*27b03b36SApple OSS Distributions #endif
147*27b03b36SApple OSS Distributions 
148*27b03b36SApple OSS Distributions #if __has_extension(attribute_overloadable)
149*27b03b36SApple OSS Distributions #define OS_OVERLOADABLE __attribute__((__overloadable__))
150*27b03b36SApple OSS Distributions #else
151*27b03b36SApple OSS Distributions #define OS_OVERLOADABLE
152*27b03b36SApple OSS Distributions #endif
153*27b03b36SApple OSS Distributions 
154*27b03b36SApple OSS Distributions #if __has_attribute(analyzer_suppress)
155*27b03b36SApple OSS Distributions #define OS_ANALYZER_SUPPRESS(RADAR) __attribute__((analyzer_suppress))
156*27b03b36SApple OSS Distributions #else
157*27b03b36SApple OSS Distributions #define OS_ANALYZER_SUPPRESS(RADAR)
158*27b03b36SApple OSS Distributions #endif
159*27b03b36SApple OSS Distributions 
160*27b03b36SApple OSS Distributions #if __has_attribute(enum_extensibility)
161*27b03b36SApple OSS Distributions #define __OS_ENUM_ATTR __attribute__((enum_extensibility(open)))
162*27b03b36SApple OSS Distributions #define __OS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed)))
163*27b03b36SApple OSS Distributions #else
164*27b03b36SApple OSS Distributions #define __OS_ENUM_ATTR
165*27b03b36SApple OSS Distributions #define __OS_ENUM_ATTR_CLOSED
166*27b03b36SApple OSS Distributions #endif // __has_attribute(enum_extensibility)
167*27b03b36SApple OSS Distributions 
168*27b03b36SApple OSS Distributions #if __has_attribute(flag_enum)
169*27b03b36SApple OSS Distributions /*!
170*27b03b36SApple OSS Distributions  * Compile with -Wflag-enum and -Wassign-enum to enforce at definition and
171*27b03b36SApple OSS Distributions  * assignment, respectively, i.e. -Wflag-enum prevents you from creating new
172*27b03b36SApple OSS Distributions  * enumeration values from illegal values within the enum definition, and
173*27b03b36SApple OSS Distributions  * -Wassign-enum prevents you from assigning illegal values to a variable of the
174*27b03b36SApple OSS Distributions  * enum type.
175*27b03b36SApple OSS Distributions  */
176*27b03b36SApple OSS Distributions #define __OS_OPTIONS_ATTR __attribute__((flag_enum))
177*27b03b36SApple OSS Distributions #else
178*27b03b36SApple OSS Distributions #define __OS_OPTIONS_ATTR
179*27b03b36SApple OSS Distributions #endif // __has_attribute(flag_enum)
180*27b03b36SApple OSS Distributions 
181*27b03b36SApple OSS Distributions #if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || \
182*27b03b36SApple OSS Distributions         __has_extension(cxx_strong_enums)
183*27b03b36SApple OSS Distributions #define OS_ENUM(_name, _type, ...) \
184*27b03b36SApple OSS Distributions 	typedef enum : _type { __VA_ARGS__ } _name##_t
185*27b03b36SApple OSS Distributions #define OS_CLOSED_ENUM(_name, _type, ...) \
186*27b03b36SApple OSS Distributions 	typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED _name##_t
187*27b03b36SApple OSS Distributions #define OS_OPTIONS(_name, _type, ...) \
188*27b03b36SApple OSS Distributions 	typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR __OS_OPTIONS_ATTR _name##_t
189*27b03b36SApple OSS Distributions #define OS_CLOSED_OPTIONS(_name, _type, ...) \
190*27b03b36SApple OSS Distributions 	typedef enum : _type { __VA_ARGS__ } __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR _name##_t
191*27b03b36SApple OSS Distributions #else
192*27b03b36SApple OSS Distributions /*!
193*27b03b36SApple OSS Distributions  * There is unfortunately no good way in plain C to have both fixed-type enums
194*27b03b36SApple OSS Distributions  * and enforcement for clang's enum_extensibility extensions. The primary goal
195*27b03b36SApple OSS Distributions  * of these macros is to allow you to define an enum and specify its width in a
196*27b03b36SApple OSS Distributions  * single statement, and for plain C that is accomplished by defining an
197*27b03b36SApple OSS Distributions  * anonymous enum and then separately typedef'ing the requested type name to the
198*27b03b36SApple OSS Distributions  * requested underlying integer type. So the type emitted actually has no
199*27b03b36SApple OSS Distributions  * relationship at all to the enum, and therefore while the compiler could
200*27b03b36SApple OSS Distributions  * enforce enum extensibility if you used the enum type, it cannot do so if you
201*27b03b36SApple OSS Distributions  * use the "_t" type resulting from this expression.
202*27b03b36SApple OSS Distributions  *
203*27b03b36SApple OSS Distributions  * But we still define a named enum type and decorate it appropriately for you,
204*27b03b36SApple OSS Distributions  * so if you really want the enum extensibility enforcement, you can use the
205*27b03b36SApple OSS Distributions  * enum type yourself, i.e. when compiling with a C compiler:
206*27b03b36SApple OSS Distributions  *
207*27b03b36SApple OSS Distributions  *     OS_CLOSED_ENUM(my_type, uint64_t,
208*27b03b36SApple OSS Distributions  *         FOO,
209*27b03b36SApple OSS Distributions  *         BAR,
210*27b03b36SApple OSS Distributions  *         BAZ,
211*27b03b36SApple OSS Distributions  *     );
212*27b03b36SApple OSS Distributions  *
213*27b03b36SApple OSS Distributions  *     my_type_t mt = 98; // legal
214*27b03b36SApple OSS Distributions  *     enum my_type emt = 98; // illegal
215*27b03b36SApple OSS Distributions  *
216*27b03b36SApple OSS Distributions  * But be aware that the underlying enum type's width is subject only to the C
217*27b03b36SApple OSS Distributions  * language's guarantees -- namely that it will be compatible with int, char,
218*27b03b36SApple OSS Distributions  * and unsigned char. It is not safe to rely on the size of this type.
219*27b03b36SApple OSS Distributions  *
220*27b03b36SApple OSS Distributions  * When compiling in ObjC or C++, both of the above assignments are illegal.
221*27b03b36SApple OSS Distributions  */
222*27b03b36SApple OSS Distributions #define __OS_ENUM_C_FALLBACK(_name, _type, ...) \
223*27b03b36SApple OSS Distributions 	typedef _type _name##_t; enum _name { __VA_ARGS__ }
224*27b03b36SApple OSS Distributions 
225*27b03b36SApple OSS Distributions #define OS_ENUM(_name, _type, ...) \
226*27b03b36SApple OSS Distributions 	typedef _type _name##_t; enum { __VA_ARGS__ }
227*27b03b36SApple OSS Distributions #define OS_CLOSED_ENUM(_name, _type, ...) \
228*27b03b36SApple OSS Distributions 	__OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
229*27b03b36SApple OSS Distributions 	__OS_ENUM_ATTR_CLOSED
230*27b03b36SApple OSS Distributions #define OS_OPTIONS(_name, _type, ...) \
231*27b03b36SApple OSS Distributions 	__OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
232*27b03b36SApple OSS Distributions 	__OS_ENUM_ATTR __OS_OPTIONS_ATTR
233*27b03b36SApple OSS Distributions #define OS_CLOSED_OPTIONS(_name, _type, ...) \
234*27b03b36SApple OSS Distributions 	__OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
235*27b03b36SApple OSS Distributions 	__OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR
236*27b03b36SApple OSS Distributions #endif // __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
237*27b03b36SApple OSS Distributions 
238*27b03b36SApple OSS Distributions #if __has_feature(attribute_availability_swift)
239*27b03b36SApple OSS Distributions // equivalent to __SWIFT_UNAVAILABLE from Availability.h
240*27b03b36SApple OSS Distributions #define OS_SWIFT_UNAVAILABLE(_msg) \
241*27b03b36SApple OSS Distributions 	__attribute__((__availability__(swift, unavailable, message=_msg)))
242*27b03b36SApple OSS Distributions #else
243*27b03b36SApple OSS Distributions #define OS_SWIFT_UNAVAILABLE(_msg)
244*27b03b36SApple OSS Distributions #endif
245*27b03b36SApple OSS Distributions 
246*27b03b36SApple OSS Distributions #if __has_attribute(swift_private)
247*27b03b36SApple OSS Distributions # define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__))
248*27b03b36SApple OSS Distributions #else
249*27b03b36SApple OSS Distributions # define OS_REFINED_FOR_SWIFT
250*27b03b36SApple OSS Distributions #endif
251*27b03b36SApple OSS Distributions 
252*27b03b36SApple OSS Distributions #if __has_attribute(swift_name)
253*27b03b36SApple OSS Distributions # define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name)))
254*27b03b36SApple OSS Distributions #else
255*27b03b36SApple OSS Distributions # define OS_SWIFT_NAME(_name)
256*27b03b36SApple OSS Distributions #endif
257*27b03b36SApple OSS Distributions 
258*27b03b36SApple OSS Distributions #define __OS_STRINGIFY(s) #s
259*27b03b36SApple OSS Distributions #define OS_STRINGIFY(s) __OS_STRINGIFY(s)
260*27b03b36SApple OSS Distributions #define __OS_CONCAT(x, y) x ## y
261*27b03b36SApple OSS Distributions #define OS_CONCAT(x, y) __OS_CONCAT(x, y)
262*27b03b36SApple OSS Distributions 
263*27b03b36SApple OSS Distributions #ifdef __GNUC__
264*27b03b36SApple OSS Distributions #define os_prevent_tail_call_optimization()  __asm__("")
265*27b03b36SApple OSS Distributions #define os_is_compile_time_constant(expr)    __builtin_constant_p(expr)
266*27b03b36SApple OSS Distributions #define os_compiler_barrier()                __asm__ __volatile__("" ::: "memory")
267*27b03b36SApple OSS Distributions #else
268*27b03b36SApple OSS Distributions #define os_prevent_tail_call_optimization()  do { } while (0)
269*27b03b36SApple OSS Distributions #define os_is_compile_time_constant(expr)    0
270*27b03b36SApple OSS Distributions #define os_compiler_barrier()                do { } while (0)
271*27b03b36SApple OSS Distributions #endif
272*27b03b36SApple OSS Distributions 
273*27b03b36SApple OSS Distributions #if __has_attribute(not_tail_called)
274*27b03b36SApple OSS Distributions #define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__))
275*27b03b36SApple OSS Distributions #else
276*27b03b36SApple OSS Distributions #define OS_NOT_TAIL_CALLED
277*27b03b36SApple OSS Distributions #endif
278*27b03b36SApple OSS Distributions 
279*27b03b36SApple OSS Distributions #if KERNEL
280*27b03b36SApple OSS Distributions /*
281*27b03b36SApple OSS Distributions  * LIBKERN_ALWAYS_DESTROY attribute can be applied to global variables with
282*27b03b36SApple OSS Distributions  * destructors. It specifies that and object should have its exit-time
283*27b03b36SApple OSS Distributions  * destructor run. This attribute is the default unless clang was invoked with
284*27b03b36SApple OSS Distributions  * -fno-c++-static-destructors.
285*27b03b36SApple OSS Distributions  */
286*27b03b36SApple OSS Distributions #if __has_attribute(always_destroy)
287*27b03b36SApple OSS Distributions #define LIBKERN_ALWAYS_DESTROY __attribute__((__always_destroy__))
288*27b03b36SApple OSS Distributions #else
289*27b03b36SApple OSS Distributions #define LIBKERN_ALWAYS_DESTROY
290*27b03b36SApple OSS Distributions #endif
291*27b03b36SApple OSS Distributions #endif
292*27b03b36SApple OSS Distributions 
293*27b03b36SApple OSS Distributions typedef void (*os_function_t)(void *_Nullable);
294*27b03b36SApple OSS Distributions 
295*27b03b36SApple OSS Distributions #ifdef __BLOCKS__
296*27b03b36SApple OSS Distributions /*!
297*27b03b36SApple OSS Distributions  * @typedef os_block_t
298*27b03b36SApple OSS Distributions  *
299*27b03b36SApple OSS Distributions  * @abstract
300*27b03b36SApple OSS Distributions  * Generic type for a block taking no arguments and returning no value.
301*27b03b36SApple OSS Distributions  *
302*27b03b36SApple OSS Distributions  * @discussion
303*27b03b36SApple OSS Distributions  * When not building with Objective-C ARC, a block object allocated on or
304*27b03b36SApple OSS Distributions  * copied to the heap must be released with a -[release] message or the
305*27b03b36SApple OSS Distributions  * Block_release() function.
306*27b03b36SApple OSS Distributions  *
307*27b03b36SApple OSS Distributions  * The declaration of a block literal allocates storage on the stack.
308*27b03b36SApple OSS Distributions  * Therefore, this is an invalid construct:
309*27b03b36SApple OSS Distributions  * <code>
310*27b03b36SApple OSS Distributions  * os_block_t block;
311*27b03b36SApple OSS Distributions  * if (x) {
312*27b03b36SApple OSS Distributions  *     block = ^{ printf("true\n"); };
313*27b03b36SApple OSS Distributions  * } else {
314*27b03b36SApple OSS Distributions  *     block = ^{ printf("false\n"); };
315*27b03b36SApple OSS Distributions  * }
316*27b03b36SApple OSS Distributions  * block(); // unsafe!!!
317*27b03b36SApple OSS Distributions  * </code>
318*27b03b36SApple OSS Distributions  *
319*27b03b36SApple OSS Distributions  * What is happening behind the scenes:
320*27b03b36SApple OSS Distributions  * <code>
321*27b03b36SApple OSS Distributions  * if (x) {
322*27b03b36SApple OSS Distributions  *     struct Block __tmp_1 = ...; // setup details
323*27b03b36SApple OSS Distributions  *     block = &__tmp_1;
324*27b03b36SApple OSS Distributions  * } else {
325*27b03b36SApple OSS Distributions  *     struct Block __tmp_2 = ...; // setup details
326*27b03b36SApple OSS Distributions  *     block = &__tmp_2;
327*27b03b36SApple OSS Distributions  * }
328*27b03b36SApple OSS Distributions  * </code>
329*27b03b36SApple OSS Distributions  *
330*27b03b36SApple OSS Distributions  * As the example demonstrates, the address of a stack variable is escaping the
331*27b03b36SApple OSS Distributions  * scope in which it is allocated. That is a classic C bug.
332*27b03b36SApple OSS Distributions  *
333*27b03b36SApple OSS Distributions  * Instead, the block literal must be copied to the heap with the Block_copy()
334*27b03b36SApple OSS Distributions  * function or by sending it a -[copy] message.
335*27b03b36SApple OSS Distributions  */
336*27b03b36SApple OSS Distributions typedef void (^os_block_t)(void);
337*27b03b36SApple OSS Distributions #endif
338*27b03b36SApple OSS Distributions 
339*27b03b36SApple OSS Distributions #if KERNEL
340*27b03b36SApple OSS Distributions #if __has_feature(ptrauth_calls)
341*27b03b36SApple OSS Distributions #include <ptrauth.h>
342*27b03b36SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR(type) __ptrauth(ptrauth_key_process_independent_data, 1, ptrauth_string_discriminator(type))
343*27b03b36SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR_AUTH_NULL(type) __ptrauth(ptrauth_key_process_independent_data, 1, ptrauth_string_discriminator(type), "authenticates-null-values")
344*27b03b36SApple OSS Distributions #define OS_PTRAUTH_DISCRIMINATOR(str) ptrauth_string_discriminator(str)
345*27b03b36SApple OSS Distributions #define __ptrauth_only
346*27b03b36SApple OSS Distributions #else //  __has_feature(ptrauth_calls)
347*27b03b36SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR(type)
348*27b03b36SApple OSS Distributions #define OS_PTRAUTH_SIGNED_PTR_AUTH_NULL(type)
349*27b03b36SApple OSS Distributions #define OS_PTRAUTH_DISCRIMINATOR(str) 0
350*27b03b36SApple OSS Distributions #define __ptrauth_only __unused
351*27b03b36SApple OSS Distributions #endif // __has_feature(ptrauth_calls)
352*27b03b36SApple OSS Distributions #endif // KERNEL
353*27b03b36SApple OSS Distributions 
354*27b03b36SApple OSS Distributions #if KERNEL_PRIVATE
355*27b03b36SApple OSS Distributions #if __has_feature(ptrauth_calls)
356*27b03b36SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_FUNCTION_PTR(type) \
357*27b03b36SApple OSS Distributions 	__ptrauth(ptrauth_key_function_pointer, 1, ptrauth_string_discriminator(type))
358*27b03b36SApple OSS Distributions #else
359*27b03b36SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_FUNCTION_PTR(type)
360*27b03b36SApple OSS Distributions #endif
361*27b03b36SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_PTR OS_PTRAUTH_SIGNED_PTR
362*27b03b36SApple OSS Distributions #define XNU_PTRAUTH_SIGNED_PTR_AUTH_NULL OS_PTRAUTH_SIGNED_PTR_AUTH_NULL
363*27b03b36SApple OSS Distributions #endif // KERNEL_PRIVATE
364*27b03b36SApple OSS Distributions 
365*27b03b36SApple OSS Distributions #endif // __OS_BASE__
366