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