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