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