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