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