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 #define OS_SWIFT_NONISOLATED __attribute__((__swift_attr__("nonisolated"))) 250 #define OS_SWIFT_NONISOLATED_UNSAFE __attribute__((__swift_attr__("nonisolated(unsafe)"))) 251 #else 252 #define OS_SWIFT_UNAVAILABLE_FROM_ASYNC(msg) 253 #define OS_SWIFT_NONISOLATED 254 #define OS_SWIFT_NONISOLATED_UNSAFE 255 #endif 256 257 #if __has_attribute(swift_private) 258 # define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__)) 259 #else 260 # define OS_REFINED_FOR_SWIFT 261 #endif 262 263 #if __has_attribute(swift_name) 264 # define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) 265 #else 266 # define OS_SWIFT_NAME(_name) 267 #endif 268 269 #define __OS_STRINGIFY(s) #s 270 #define OS_STRINGIFY(s) __OS_STRINGIFY(s) 271 #define __OS_CONCAT(x, y) x ## y 272 #define OS_CONCAT(x, y) __OS_CONCAT(x, y) 273 274 #ifdef __GNUC__ 275 #define os_prevent_tail_call_optimization() __asm__("") 276 #define os_is_compile_time_constant(expr) __builtin_constant_p(expr) 277 #define os_compiler_barrier() __asm__ __volatile__("" ::: "memory") 278 #else 279 #define os_prevent_tail_call_optimization() do { } while (0) 280 #define os_is_compile_time_constant(expr) 0 281 #define os_compiler_barrier() do { } while (0) 282 #endif 283 284 #if __has_attribute(not_tail_called) 285 #define OS_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) 286 #else 287 #define OS_NOT_TAIL_CALLED 288 #endif 289 290 #if KERNEL 291 /* 292 * LIBKERN_ALWAYS_DESTROY attribute can be applied to global variables with 293 * destructors. It specifies that and object should have its exit-time 294 * destructor run. This attribute is the default unless clang was invoked with 295 * -fno-c++-static-destructors. 296 */ 297 #if __has_attribute(always_destroy) 298 #define LIBKERN_ALWAYS_DESTROY __attribute__((__always_destroy__)) 299 #else 300 #define LIBKERN_ALWAYS_DESTROY 301 #endif 302 #endif 303 304 typedef void (*os_function_t)(void *_Nullable); 305 306 #ifdef __BLOCKS__ 307 /*! 308 * @typedef os_block_t 309 * 310 * @abstract 311 * Generic type for a block taking no arguments and returning no value. 312 * 313 * @discussion 314 * When not building with Objective-C ARC, a block object allocated on or 315 * copied to the heap must be released with a -[release] message or the 316 * Block_release() function. 317 * 318 * The declaration of a block literal allocates storage on the stack. 319 * Therefore, this is an invalid construct: 320 * <code> 321 * os_block_t block; 322 * if (x) { 323 * block = ^{ printf("true\n"); }; 324 * } else { 325 * block = ^{ printf("false\n"); }; 326 * } 327 * block(); // unsafe!!! 328 * </code> 329 * 330 * What is happening behind the scenes: 331 * <code> 332 * if (x) { 333 * struct Block __tmp_1 = ...; // setup details 334 * block = &__tmp_1; 335 * } else { 336 * struct Block __tmp_2 = ...; // setup details 337 * block = &__tmp_2; 338 * } 339 * </code> 340 * 341 * As the example demonstrates, the address of a stack variable is escaping the 342 * scope in which it is allocated. That is a classic C bug. 343 * 344 * Instead, the block literal must be copied to the heap with the Block_copy() 345 * function or by sending it a -[copy] message. 346 */ 347 typedef void (^os_block_t)(void); 348 #endif 349 350 #if KERNEL 351 #if __has_feature(ptrauth_calls) 352 #include <ptrauth.h> 353 #define OS_PTRAUTH_SIGNED_PTR(type) __ptrauth(ptrauth_key_process_independent_data, 1, ptrauth_string_discriminator(type)) 354 #define OS_PTRAUTH_SIGNED_PTR_AUTH_NULL(type) __ptrauth(ptrauth_key_process_independent_data, 1, ptrauth_string_discriminator(type), "authenticates-null-values") 355 #define OS_PTRAUTH_DISCRIMINATOR(str) ptrauth_string_discriminator(str) 356 #define __ptrauth_only 357 #else // __has_feature(ptrauth_calls) 358 #define OS_PTRAUTH_SIGNED_PTR(type) 359 #define OS_PTRAUTH_SIGNED_PTR_AUTH_NULL(type) 360 #define OS_PTRAUTH_DISCRIMINATOR(str) 0 361 #define __ptrauth_only __unused 362 #endif // __has_feature(ptrauth_calls) 363 #endif // KERNEL 364 365 #if KERNEL 366 #if __has_feature(ptrauth_calls) 367 #define XNU_PTRAUTH_SIGNED_FUNCTION_PTR(type) \ 368 __ptrauth(ptrauth_key_function_pointer, 1, ptrauth_string_discriminator(type)) 369 #else 370 #define XNU_PTRAUTH_SIGNED_FUNCTION_PTR(type) 371 #endif 372 #define XNU_PTRAUTH_SIGNED_PTR OS_PTRAUTH_SIGNED_PTR 373 #define XNU_PTRAUTH_SIGNED_PTR_AUTH_NULL OS_PTRAUTH_SIGNED_PTR_AUTH_NULL 374 #endif // KERNEL 375 376 #define OS_ASSUME_PTR_ABI_SINGLE_BEGIN __ASSUME_PTR_ABI_SINGLE_BEGIN 377 #define OS_ASSUME_PTR_ABI_SINGLE_END __ASSUME_PTR_ABI_SINGLE_END 378 #define OS_UNSAFE_INDEXABLE __unsafe_indexable 379 #define OS_HEADER_INDEXABLE __header_indexable 380 #define OS_COUNTED_BY(N) __counted_by(N) 381 #define OS_SIZED_BY(N) __sized_by(N) 382 383 #endif // __OS_BASE__ 384