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