// // tightbeam_base.h // Tightbeam #ifndef __TIGHTBEAM_BASE_H #define __TIGHTBEAM_BASE_H #ifndef __RTKIT__ #ifndef KERNEL #include #define __TB_TARGET_CONDITIONALS_ENABLED__ 1 #endif #endif // __RTKIT__ #include #include #include #include #if __has_include() #include #elif __has_include() #include #elif __has_include() #include #endif #define TB_API_VERSION 20240820 #define TB_MAX_CAPS 4 #if defined(KERNEL) #include #define TB_ASSERT2(e, fmt, ...) ({ \ if (!(e)) { \ panic("TB_ASSERT: " #e ", " fmt " (%s:%d)", ##__VA_ARGS__, __FILE_NAME__, __LINE__); \ __builtin_trap(); \ } \ }) #define TB_ASSERT(e) TB_ASSERT2(e, "\b\b") #define TB_FATAL(fmt, ...) ({ \ panic("TB_FATAL: " fmt, ##__VA_ARGS__); \ __builtin_trap(); \ }) #elif defined(__RTKIT__) #include #define TB_ASSERT(e) \ if (!(e)) { \ RTK_abort("TB_ASSERT: (%s:%d)", __FILE_NAME__, __LINE__); \ __builtin_trap(); \ } #define TB_ASSERT2(e, fmt, ...) TB_ASSERT(e) #define TB_FATAL(fmt, ...) RTK_abort(fmt, ##__VA_ARGS__) #elif (defined(TARGET_OS_EXCLAVECORE) || defined(TARGET_OS_EXCLAVEKIT)) && (TARGET_OS_EXCLAVECORE || TARGET_OS_EXCLAVEKIT) #include #define TB_ASSERT2(e, fmt, ...) \ if (!(e)) { \ printf("TB_ASSERT: " #e ", " fmt " (%s:%d)\n", ##__VA_ARGS__, __FILE_NAME__, __LINE__); \ __builtin_trap(); \ } #define TB_ASSERT(e) TB_ASSERT2(e, "\b\b") #define TB_FATAL(fmt, ...) ({ \ printf("TB_FATAL: " fmt " (%s:%d)\n", \ ##__VA_ARGS__, __FILE__, __LINE__); \ __builtin_trap(); \ }) #else #include #include #define TB_ASSERT2(e, fmt, ...) ({ \ if (!(e)) { \ printf("TB_ASSERT: " #e ", " fmt " (%s:%d)\n", ##__VA_ARGS__, __FILE_NAME__, __LINE__); \ os_crash("TB_ASSERT: " #e); \ } \ }) #define TB_ASSERT(e) TB_ASSERT2(e, "\b\b") #define TB_FATAL(fmt, ...) ({ \ printf("TB_FATAL: " fmt " (%s:%d)\n", \ ##__VA_ARGS__, __FILE__, __LINE__); \ os_crash("TB_FATAL: " fmt); \ }) #endif // defined(KERNEL) #if defined(__cplusplus) #define __TB_BEGIN_DECLS extern "C" { #define __TB_END_DECLS } #else #define __TB_BEGIN_DECLS #define __TB_END_DECLS #endif #define TB_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #define TB_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") #define TB_EXPORT extern __attribute__((__visibility__("default"))) #define TB_NOEXPORT __attribute__((visibility("hidden"))) #define TB_UNUSED __attribute__((unused)) #define TB_NOESCAPE __attribute__((noescape)) #define TB_NOINLINE __attribute__((noinline)) #define TB_PACKED __attribute__((packed)) #ifndef __cplusplus #define TB_TRANSPARENT_UNION __attribute__((__transparent_union__)) #else // __cplusplus #define TB_TRANSPARENT_UNION #endif // __cplusplus #define __TB_ENUM_ATTR __attribute__((enum_extensibility(open))) #define __TB_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed))) #define __TB_OPTIONS_ATTR __attribute__((flag_enum)) #define __TB_WEAK_IMPORT __attribute__((weak_import)) #define __TB_ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__))) #define __TB_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #define TB_OS_MUL_OVERFLOW(...) \ if (__builtin_mul_overflow(__VA_ARGS__)) { \ TB_FATAL("overflow detected when multiplying"); \ } #define TB_OS_ADD_OVERFLOW(...) \ if (__builtin_add_overflow(__VA_ARGS__)) { \ TB_FATAL("overflow detected when adding"); \ } #define TB_OS_SUB_OVERFLOW(...) \ if (__builtin_sub_overflow(__VA_ARGS__)) { \ TB_FATAL("overflow detected when subtracting"); \ } #if defined(TARGET_OS_EXCLAVECORE) && TARGET_OS_EXCLAVECORE // For ExclaveCore, we put all of the vtables together in their own // section, which reduces the overhead of fixing up tables we may not use. // This is not necessary on other platforms, where fixup costs are not as // high. #define __TB_COMPONENT_VTABLE_ATTRIBUTE \ __attribute ((section("__DATA,__TIGHTBEAM_VT"))) #else #define __TB_COMPONENT_VTABLE_ATTRIBUTE #endif #define __TB_COMPONENT_DECLARATION(_sym) \ TB_EXPORT __attribute__((no_sanitize("address"))) \ void const* __set_tightbeam_sym_##_sym #define __TB_COMPONENT_DEFINITION(_sym, _vis) \ void const* __set_tightbeam_sym_##_sym \ __attribute__ ((section("__DATA,__TIGHTBEAM"))) \ __attribute__ ((visibility(_vis))) \ __attribute__((no_sanitize("address"))) \ __attribute__ ((used)) \ = (void const *)&_sym #define TB_ENUM(_name, _type, ...) \ typedef enum : _type { __VA_ARGS__ } __TB_ENUM_ATTR _name##_t #define TB_CLOSED_ENUM(_name, _type, ...) \ typedef enum : _type { __VA_ARGS__ } __TB_ENUM_ATTR_CLOSED _name##_t #define TB_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) #define TB_OPTIONS(_name, _type, ...) \ typedef enum : _type { __VA_ARGS__ } __TB_ENUM_ATTR __TB_OPTIONS_ATTR _name##_t #if defined(__unsafe_unretained) #define __TB_UNSAFE_UNRETAINED __unsafe_unretained #else #define __TB_UNSAFE_UNRETAINED #endif #if __clang__ #define TB_DEPRECATED(m) __attribute__((deprecated(m))) #else // __clang__ #define TB_DEPRECATED(m) __attribute__((deprecated)) #endif // __clang // Define our own versions of Block_copy and Block_release until the build // platform gets: rdar://problem/97945654 #define TB_BLOCK_COPY(...) \ ((__typeof(__VA_ARGS__))_Block_copy( \ __unsafe_forge_single(const void *, (const void *)(__VA_ARGS__))) \ ) #define TB_BLOCK_RELEASE(...) \ _Block_release( \ __unsafe_forge_single(const void *, (const void *)(__VA_ARGS__)) \ ) TB_ENUM(tb_error, uint32_t, TB_ERROR_SUCCESS TB_SWIFT_NAME(success) = 0, TB_ERROR_COULD_NOT_SEND TB_SWIFT_NAME(couldNotSend), TB_ERROR_MESSAGE_CREATE_FAILED TB_SWIFT_NAME(messageCreateFailed), TB_ERROR_ACTIVATION_FAILED TB_SWIFT_NAME(activationFailed), TB_ERROR_MESSAGE_RECEIVE_FAILED TB_SWIFT_NAME(messageReceiveFailed), TB_ERROR_REPLY_SEND_FAILED TB_SWIFT_NAME(replySendFailed), TB_ERROR_MESSAGE_ENCODE_FAILED TB_SWIFT_NAME(messageEncodeFailed), TB_ERROR_MESSAGE_DECODE_FAILED TB_SWIFT_NAME(messageDecodeFailed), TB_ERROR_VALIDATION_FAILED TB_SWIFT_NAME(validationFailed), TB_ERROR_USER_FAILURE TB_SWIFT_NAME(userFailure), TB_ERROR_MESSAGE_FORWARD_FAILURE TB_SWIFT_NAME(forwardFailure), TB_ERROR_CONFIGURATION_INVALID TB_SWIFT_NAME(configurationInvalid), TB_ERROR_SERVICE_DISABLED TB_SWIFT_NAME(serviceDisabled), TB_ERROR_ALLOCATE_FAILED TB_SWIFT_NAME(allocateFailed), TB_ERROR_MESSAGE_DEFERRED_SEND_UNSUPPORTED TB_SWIFT_NAME( deferredSendUnsupported), TB_ERROR_REPLY_NOT_FOUND TB_SWIFT_NAME(replyNotFound), TB_ERROR_SELECTOR_DISALLOWED TB_SWIFT_NAME(selectorDisallowed), TB_ERROR_NO_NOTIFICATION_PENDING TB_SWIFT_NAME(noNotificationPending), TB_ERROR_NOTIFICATION_CHECKIN_FAILED TB_SWIFT_NAME(notificationCheckinFailed), TB_ERROR_NOTIFICATION_RECEIVE_FAILED TB_SWIFT_NAME(notificationReceiveFailed), ) TB_SWIFT_NAME(TransportError); TB_OPTIONS(tb_connection_flags, uint64_t, TB_CONNECTION_FLAGS_NONE TB_SWIFT_NAME(none) = 0, TB_CONNECTION_FAIL_ON_WAIT TB_SWIFT_NAME(failOnWait) = 1 << 0, TB_CONNECTION_WAIT_FOR_REPLY TB_SWIFT_NAME(waitForReply) = 1 << 1, ); TB_OPTIONS(tb_transport_flags, uint16_t, TB_TRANSPORT_FLAG_NONE TB_SWIFT_NAME(none) = 0, TB_TRANSPORT_FLAG_MULTIPART_MESSAGE TB_SWIFT_NAME(multipartMessage) = 1 << 0, TB_TRANSPORT_FLAG_MULTIPART_MESSAGE_COMPLETE TB_SWIFT_NAME( multipartMessageComplete) = 1 << 1, TB_TRANSPORT_FLAG_MULTIPART_REPLY_POLL TB_SWIFT_NAME(multipartReplyPoll) = 1 << 2, TB_TRANSPORT_FLAG_ERROR TB_SWIFT_NAME(error) = 1 << 3, TB_TRANSPORT_FLAG_NO_REPLY TB_SWIFT_NAME(noReply) = 1 << 4, TB_TRANSPORT_FLAG_TRANSPORT_DECODED TB_SWIFT_NAME(transportDecoded) = 1 << 5 ); #define TB_CHECK_FLAG(flags, f) ((flags & f) != 0) #if __swift__ || !defined(__arm__) && !defined(__aarch64__) /* * For all platforms, assume Swift has floating-point support * (merely because it is convenient to not have conditional * compilation clutter in our Swift source until we need it) * * For non-Swift, i.e., C, assume all non-ARM cases also have * floating-point (although those cases may not be relevant) */ #define TB_HAS_FP32 1 #define TB_HAS_FP64 1 #else /* __swift__, __arm__, __aarch64__ */ /* * ARM does not always support floating-point; for example, * `-mgeneral-regs-only` means no floating-point available */ #if defined(__ARM_FP) && (__ARM_FP & 0x04) #define TB_HAS_FP32 1 #else /* __ARM_FP & 0x04 */ #define TB_HAS_FP32 0 #endif /* __ARM_FP & 0x04 */ /* * NB: We check the bits for supported levels individually, * but, technically, `__ARM_FP` cannot have only 64-bit */ #if defined(__ARM_FP) && (__ARM_FP & 0x08) _Static_assert(__ARM_FP & 0x04, "Single precision must be supported as well"); #define TB_HAS_FP64 1 #else /* __ARM_FP & 0x08 */ #define TB_HAS_FP64 0 #endif /* __ARM_FP & 0x08 */ #endif /* __swift__, __arm__, __aarch64__ */ #if TB_HAS_FP32 typedef float tb_float32_t; #endif /* TB_HAS_FP32 */ #if TB_HAS_FP64 typedef double tb_float64_t; #endif /* TB_HAS_FP64 */ #if __TB_TARGET_CONDITIONALS_ENABLED__ #if !TARGET_OS_MACCATALYST \ && (TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_TV || TARGET_OS_WATCH || TARGET_OS_VISION) \ && __has_include() \ && __has_include() #define TB_DISPATCH_NOTIFICATION_SUPPORTED 0 #if (TARGET_OS_IOS && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_17_4)) \ || (TARGET_OS_OSX && (__MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_14_4)) \ || (TARGET_OS_TV && (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_17_4)) \ || (TARGET_OS_WATCH && (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_12_0)) \ || (TARGET_OS_VISION && (__VISION_OS_VERSION_MIN_REQUIRED >= __VISIONOS_3_0)) #undef TB_DISPATCH_NOTIFICATION_SUPPORTED #define TB_DISPATCH_NOTIFICATION_SUPPORTED 1 #endif // __IPHONE_OS_VERSION_MIN_REQUIRED ... #endif // !TARGET_OS_MACCATALYST && (TARGET_OS_IOS || TARGET_OS_OSX ... // TB_DAEMON_NOTIFICATION_SUPPORTED: for daemon notifications via bootstrap/mach #if __has_include() \ && __has_include() \ && __has_include() #define TB_DAEMON_NOTIFICATION_SUPPORTED 1 #else #define TB_DAEMON_NOTIFICATION_SUPPORTED 0 #endif #undef __TB_TARGET_CONDITIONALS_ENABLED__ #endif // __TB_TARGET_CONDITIONALS_ENABLED__ #endif // __TIGHTBEAM_BASE_H