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