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