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