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
300typedef 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 */
343typedef 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