From 93218eacaada52eb028e5569b48b47ac38b1df70 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 16 Sep 2025 21:15:13 +0100 Subject: libc: Update macOS headers to SDK 26.0 --- lib/libc/include/any-macos-any/malloc/_malloc.h | 71 ++++++++- .../include/any-macos-any/malloc/_malloc_type.h | 101 +++++++++--- lib/libc/include/any-macos-any/malloc/malloc.h | 175 ++++++++++++++++++--- 3 files changed, 309 insertions(+), 38 deletions(-) (limited to 'lib/libc/include/any-macos-any/malloc') diff --git a/lib/libc/include/any-macos-any/malloc/_malloc.h b/lib/libc/include/any-macos-any/malloc/_malloc.h index 4389be04d1..cbd5253d50 100644 --- a/lib/libc/include/any-macos-any/malloc/_malloc.h +++ b/lib/libc/include/any-macos-any/malloc/_malloc.h @@ -55,8 +55,8 @@ void * __sized_by_or_null(__size) malloc(size_t __size) __result_use_check __all void * __sized_by_or_null(__count * __size) calloc(size_t __count, size_t __size) __result_use_check __alloc_size(1,2) _MALLOC_TYPED(malloc_type_calloc, 2); void free(void * __unsafe_indexable); void * __sized_by_or_null(__size) realloc(void * __unsafe_indexable __ptr, size_t __size) __result_use_check __alloc_size(2) _MALLOC_TYPED(malloc_type_realloc, 2); -void * __sized_by_or_null(__size) reallocf(void * __unsafe_indexable __ptr, size_t __size) __result_use_check __alloc_size(2); #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +void * __sized_by_or_null(__size) reallocf(void * __unsafe_indexable __ptr, size_t __size) __result_use_check __alloc_size(2); void * __sized_by_or_null(__size) valloc(size_t __size) __result_use_check __alloc_size(1) _MALLOC_TYPED(malloc_type_valloc, 1); #endif /* !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */ #if (defined(__DARWIN_C_LEVEL) && defined(__DARWIN_C_FULL) && __DARWIN_C_LEVEL >= __DARWIN_C_FULL) || \ @@ -67,6 +67,75 @@ void * __sized_by_or_null(__size) aligned_alloc(size_t __alignment, size_t __siz /* rdar://120689514 */ int posix_memalign(void * __unsafe_indexable *__memptr, size_t __alignment, size_t __size) _MALLOC_TYPED(malloc_type_posix_memalign, 3) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +#if defined(_MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING) && _MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_malloc_backdeploy(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1) { + __attribute__((weak_import)) void * __sized_by_or_null(size) malloc_type_malloc(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); + __auto_type func = malloc; + if (malloc_type_malloc) { + return malloc_type_malloc(size, type_id); + } + return func(size); +} + +static void * __sized_by_or_null(count * size) __attribute__((always_inline)) malloc_type_calloc_backdeploy(size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1,2) { + __attribute__((weak_import)) void * __sized_by_or_null(count * size) malloc_type_calloc(size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1,2); + __auto_type func = calloc; + if (malloc_type_calloc) { + return malloc_type_calloc(count, size, type_id); + } + return func(count, size); +} + +static void __attribute__((always_inline)) malloc_type_free_backdeploy(void * __unsafe_indexable ptr, malloc_type_id_t type_id) { + __attribute__((weak_import)) void malloc_type_free(void * __unsafe_indexable ptr, malloc_type_id_t type_id); + __auto_type func = free; + if (malloc_type_free) { + malloc_type_free(ptr, type_id); + } else { + func(ptr); + } +} + +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_realloc_backdeploy(void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2) { + __attribute__((weak_import)) void * __sized_by_or_null(size) malloc_type_realloc(void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); + __auto_type func = realloc; + if (malloc_type_realloc) { + return malloc_type_realloc(ptr, size, type_id); + } + return func(ptr, size); +} + +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_valloc_backdeploy(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1) { + __attribute__((weak_import)) void * __sized_by_or_null(size) malloc_type_valloc(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); + __auto_type func = valloc; + if (malloc_type_valloc) { + return malloc_type_valloc(size, type_id); + } + return func(size); +} + +#if (defined(__DARWIN_C_LEVEL) && defined(__DARWIN_C_FULL) && __DARWIN_C_LEVEL >= __DARWIN_C_FULL) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_aligned_alloc_backdeploy(size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(1) __alloc_size(2) { + __attribute__((weak_import)) void * __sized_by_or_null(size) malloc_type_aligned_alloc(size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(1) __alloc_size(2); + __auto_type func = aligned_alloc; + if (malloc_type_aligned_alloc) { + return malloc_type_aligned_alloc(alignment, size, type_id); + } + return func(alignment, size); +} +#endif + +static int __attribute__((always_inline)) malloc_type_posix_memalign_backdeploy(void * __unsafe_indexable *memptr, size_t alignment, size_t size, malloc_type_id_t type_id) { + __attribute__((weak_import)) int malloc_type_posix_memalign(void * __unsafe_indexable *memptr, size_t alignment, size_t size, malloc_type_id_t type_id); + __auto_type func = posix_memalign; + if (malloc_type_posix_memalign) { + return malloc_type_posix_memalign(memptr, alignment, size, type_id); + } + return func(memptr, alignment, size); +} +#endif __END_DECLS #endif /* _MALLOC_UNDERSCORE_MALLOC_H_ */ diff --git a/lib/libc/include/any-macos-any/malloc/_malloc_type.h b/lib/libc/include/any-macos-any/malloc/_malloc_type.h index 44474cbb91..81713b125c 100644 --- a/lib/libc/include/any-macos-any/malloc/_malloc_type.h +++ b/lib/libc/include/any-macos-any/malloc/_malloc_type.h @@ -39,44 +39,107 @@ typedef unsigned long long malloc_type_id_t; #define __need_size_t #include #undef __need_size_t -#endif +#endif /* size_t */ #include /* __BEGIN_DECLS */ -#define _MALLOC_TYPE_AVAILABILITY __API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) - __BEGIN_DECLS +#define _MALLOC_TYPE_MALLOC_BACKDEPLOY_PUBLIC 1 + + +#if _MALLOC_TYPE_MALLOC_BACKDEPLOY_PUBLIC && defined(__has_feature) && __has_feature(typed_memory_operations) && __has_builtin(__is_target_os) && defined(__LP64__) && !defined(_MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING) +#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100000) + #define _MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING 1 +#endif +#endif + +/** If we are in a TMO backdeployment configuration we do not globally declare the + * real TMO entry points, so that we error out if someone is trying to use them + * when their presence is not guaranteed + */ +#if defined(_MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING) && _MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING + +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_malloc_backdeploy(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); +static void * __sized_by_or_null(count * size) __attribute__((always_inline)) malloc_type_calloc_backdeploy(size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1,2); +static void __attribute__((always_inline)) malloc_type_free_backdeploy(void * __unsafe_indexable ptr, malloc_type_id_t type_id); +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_realloc_backdeploy(void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_valloc_backdeploy(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); +#if (defined(__DARWIN_C_LEVEL) && defined(__DARWIN_C_FULL) && __DARWIN_C_LEVEL >= __DARWIN_C_FULL) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_aligned_alloc_backdeploy(size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(1) __alloc_size(2); +#endif +static int __attribute__((always_inline)) malloc_type_posix_memalign_backdeploy(void * __unsafe_indexable *memptr, size_t alignment, size_t size, malloc_type_id_t type_id) /*__alloc_align(2) __alloc_size(3)*/; + +/* */ + +typedef struct _malloc_zone_t malloc_zone_t; + +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_malloc_backdeploy(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +static void * __sized_by_or_null(count * size) __attribute__((always_inline)) malloc_type_zone_calloc_backdeploy(malloc_zone_t *zone, size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2,3); +static void __attribute__((always_inline)) malloc_type_zone_free_backdeploy(malloc_zone_t *zone, void * __unsafe_indexable ptr, malloc_type_id_t type_id); +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_realloc_backdeploy(malloc_zone_t *zone, void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(3); +static void *__sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_valloc_backdeploy(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +static void *__sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_memalign_backdeploy(malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(2) __alloc_size(3); + +#else + /* */ -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(size) malloc_type_malloc(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(count * size) malloc_type_calloc(size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1,2); -_MALLOC_TYPE_AVAILABILITY void malloc_type_free(void * __unsafe_indexable ptr, malloc_type_id_t type_id); -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(size) malloc_type_realloc(void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(size) malloc_type_valloc(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(size) malloc_type_aligned_alloc(size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(size) malloc_type_malloc(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(count * size) malloc_type_calloc(size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1,2); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void malloc_type_free(void * __unsafe_indexable ptr, malloc_type_id_t type_id); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(size) malloc_type_realloc(void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(size) malloc_type_valloc(size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(1); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(size) malloc_type_aligned_alloc(size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(1) __alloc_size(2); /* rdar://120689514 */ -_MALLOC_TYPE_AVAILABILITY int malloc_type_posix_memalign(void * __unsafe_indexable *memptr, size_t alignment, size_t size, malloc_type_id_t type_id) /*__alloc_size(3)*/; - +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +int malloc_type_posix_memalign(void * __unsafe_indexable *memptr, size_t alignment, size_t size, malloc_type_id_t type_id) /*__alloc_align(2) __alloc_size(3)*/; /* */ typedef struct _malloc_zone_t malloc_zone_t; -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(size) malloc_type_zone_malloc(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(count * size) malloc_type_zone_calloc(malloc_zone_t *zone, size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2,3); -_MALLOC_TYPE_AVAILABILITY void malloc_type_zone_free(malloc_zone_t *zone, void * __unsafe_indexable ptr, malloc_type_id_t type_id); -_MALLOC_TYPE_AVAILABILITY void * __sized_by_or_null(size) malloc_type_zone_realloc(malloc_zone_t *zone, void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(3); -_MALLOC_TYPE_AVAILABILITY void *__sized_by_or_null(size) malloc_type_zone_valloc(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); -_MALLOC_TYPE_AVAILABILITY void *__sized_by_or_null(size) malloc_type_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(3); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(size) malloc_type_zone_malloc(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(count * size) malloc_type_zone_calloc(malloc_zone_t *zone, size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2,3); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void malloc_type_zone_free(malloc_zone_t *zone, void * __unsafe_indexable ptr, malloc_type_id_t type_id); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void * __sized_by_or_null(size) malloc_type_zone_realloc(malloc_zone_t *zone, void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(3); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void *__sized_by_or_null(size) malloc_type_zone_valloc(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); +__API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0), visionos(1.0), driverkit(23.0)) +void *__sized_by_or_null(size) malloc_type_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(2) __alloc_size(3); + +#endif __END_DECLS /* Rewrite enablement */ + #if defined(__has_feature) && __has_feature(typed_memory_operations) -#if __has_builtin(__is_target_os) && (__is_target_os(ios) || __is_target_os(driverkit) || __is_target_os(macos) || __is_target_os(xros) || __is_target_os(watchos) || __is_target_os(tvos) || (__has_builtin(__is_target_environment) && (__is_target_environment(exclavekit) || __is_target_environment(exclavecore)))) + +#if (__has_builtin(__is_target_os) && __is_target_os(darwin) && !__is_target_os(bridgeos)) ||\ + (__has_builtin(__is_target_environment) && (__is_target_environment(exclavekit) || __is_target_environment(exclavecore))) +#if defined(_MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING) && _MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING +#define _MALLOC_TYPE_ENABLED 1 +#define _MALLOC_TYPED(override, type_param_pos) __attribute__((typed_memory_operation(override##_backdeploy, type_param_pos))) +#else #define _MALLOC_TYPED(override, type_param_pos) __attribute__((typed_memory_operation(override, type_param_pos))) #define _MALLOC_TYPE_ENABLED 1 -#endif +#endif +#endif #endif /* defined(__has_feature) && __has_feature(typed_memory_operations) */ #endif /* MALLOC_TARGET_64BIT */ diff --git a/lib/libc/include/any-macos-any/malloc/malloc.h b/lib/libc/include/any-macos-any/malloc/malloc.h index 477a0022ba..d65d15642a 100644 --- a/lib/libc/include/any-macos-any/malloc/malloc.h +++ b/lib/libc/include/any-macos-any/malloc/malloc.h @@ -2,14 +2,14 @@ * Copyright (c) 1999-2023 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -62,6 +62,57 @@ __ptrcheck_abi_assume_single() #endif // MALLOC_ZONE_FN_PTR __BEGIN_DECLS + +/********* Typed zone functions ************/ + +#if defined(__has_attribute) && __has_attribute(swift_name) +#define MALLOC_SWIFT_NAME(x) __attribute__((swift_name(#x))) +#else +#define MALLOC_SWIFT_NAME(x) +#endif // defined(__has_attribute) && __has_attribute(swift_name) + +/*! + * @constant MALLOC_ZONE_MALLOC_DEFAULT_ALIGN + * Default alignment for malloc_type_zone_malloc_with_options + */ +#define MALLOC_ZONE_MALLOC_DEFAULT_ALIGN __SIZEOF_POINTER__ + +/*! + * @enum malloc_zone_malloc_options_t + * + * @constant MALLOC_ZONE_MALLOC_OPTION_NONE + * Empty placeholder option. + * + * @constant MALLOC_ZONE_MALLOC_OPTION_CLEAR + * Zero out the allocated memory, similar to calloc(). + * + */ +/*! + * @constant MALLOC_ZONE_MALLOC_OPTION_CANONICAL_TAG + * Under MTE, use a tag of zero (canonical) instead of a random value. + */ +typedef enum __enum_options : uint64_t { + MALLOC_ZONE_MALLOC_OPTION_NONE = 0u, + MALLOC_ZONE_MALLOC_OPTION_CLEAR MALLOC_SWIFT_NAME(clear) = 1u << 0, + MALLOC_ZONE_MALLOC_OPTION_CANONICAL_TAG MALLOC_SWIFT_NAME(canonicalTag) = 1u << 1, +} malloc_zone_malloc_options_t; + +/*! + * @function malloc_type_zone_malloc_with_options + * + * Like the other functions declared in malloc/_malloc_type.h, this function + * is not intended to be called directly, but is rather the rewrite target for + * calls to malloc_zone_malloc_with_options when typed memory operations are + * enabled. + */ +#if defined(__LP64__) +__API_AVAILABLE(macos(26.0), ios(26.0), tvos(26.0), watchos(26.0), visionos(26.0), driverkit(25.0)) +void * __sized_by_or_null(size) malloc_type_zone_malloc_with_options(malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id, malloc_zone_malloc_options_t opts) __result_use_check __alloc_align(2) __alloc_size(3); +#endif /* __LP64__ */ + +// The remainder of these functions are declared in malloc/_malloc_type.h, and +// the backdeployment variant definitions are at the bottom of this file. + /********* Type definitions ************/ /* @@ -160,8 +211,7 @@ typedef struct _malloc_zone_t { void * __unsafe_indexable ptr); /* - * Memory allocation with an extensible binary flags option. Currently for - * libmalloc-internal zone implementations only - should be NULL otherwise. + * Memory allocation with an extensible binary flags option. * Added in version >= 15. */ void * __sized_by_or_null(size) (* MALLOC_ZONE_FN_PTR(malloc_with_options))( @@ -188,10 +238,9 @@ typedef struct _malloc_zone_t { struct _malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id); - /* Must be NULL for non-libmalloc zone implementations */ void * __sized_by_or_null(size) (* MALLOC_ZONE_FN_PTR(malloc_type_malloc_with_options))( - struct _malloc_zone_t *zone, size_t align, size_t size, uint64_t options, - malloc_type_id_t type_id); + struct _malloc_zone_t *zone, size_t align, size_t size, + uint64_t options, malloc_type_id_t type_id); } malloc_zone_t; /*! @@ -352,6 +401,38 @@ extern void malloc_destroy_zone(malloc_zone_t *zone); extern void * __sized_by_or_null(size) malloc_zone_malloc(malloc_zone_t *zone, size_t size) __alloc_size(2) _MALLOC_TYPED(malloc_type_zone_malloc, 2); /* Allocates a new pointer of size size; zone must be non-NULL */ +/*! + * @function malloc_zone_malloc_with_options + * + * @param zone + * The malloc zone that should be used to used to serve the allocation. This + * parameter may be NULL, in which case the default zone will be used. + * + * @param align + * The minimum alignment of the requested allocation. This parameter must be + * MALLOC_ZONE_MALLOC_DEFAULT_ALIGN to request default alignment, or a power + * of 2 >= sizeof(void *). + * + * @param size + * The size, in bytes, of the requested allocation. Must be an integral + * multiple of align if align is non-zero. + * + * @param options + * A bitmask of options defining how the memory should be allocated. See the + * available bit values in the malloc_zone_malloc_options_t enum definition. + * + * @result + * A pointer to the newly allocated block of memory, or NULL if the allocation + * failed. + * + * @discussion + * This API does not use errno to signal information about the reason for its + * success or failure, and makes no guarantees about preserving or settings its + * value in any case. + */ +__API_AVAILABLE(macos(26.0), ios(26.0), tvos(26.0), watchos(26.0), visionos(26.0), driverkit(25.0)) +extern void * __sized_by_or_null(size) malloc_zone_malloc_with_options(malloc_zone_t *zone, size_t align, size_t size, malloc_zone_malloc_options_t opts) __alloc_align(2) __alloc_size(3) _MALLOC_TYPED(malloc_type_zone_malloc_with_options, 3); + extern void * __sized_by_or_null(num_items * size) malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) __alloc_size(2,3) _MALLOC_TYPED(malloc_type_zone_calloc, 3); /* Allocates a new pointer of size num_items * size; block is cleared; zone must be non-NULL */ @@ -590,22 +671,80 @@ extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void // Version 13: // - malloc_zone_t::malloc and malloc_zone_t::calloc assume responsibility for // setting errno to ENOMEM on failure -// - malloc_zone_t::try_free_default +// - malloc_zone_t::try_free_default (libmalloc only, NULL otherwise) // Version 14: -// malloc_introspection_t::zone_type +// malloc_introspection_t::zone_type (mandatory, should be 0) // Version 15: -// malloc_zone_t::malloc_with_options +// malloc_zone_t::malloc_with_options (optional) // Version 16: -// malloc_zone_t::malloc_type_malloc -// malloc_zone_t::malloc_type_calloc -// malloc_zone_t::malloc_type_realloc -// malloc_zone_t::malloc_type_memalign -// malloc_zone_t::malloc_type_malloc_with_options - -// These functions are optional and calling them requires two checks: +// malloc_zone_t::malloc_type_malloc (mandatory) +// malloc_zone_t::malloc_type_calloc (mandatory) +// malloc_zone_t::malloc_type_realloc (mandatory) +// malloc_zone_t::malloc_type_memalign (mandatory) +// malloc_zone_t::malloc_type_malloc_with_options (optional) + +// Zone functions are optional unless specified otherwise above. Calling a zone +// function requires two checks: // * Check zone version to ensure zone struct is large enough to include the member. // * Check that the function pointer is not null. +#if defined(_MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING) && _MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_malloc_backdeploy(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2) { + __attribute__((weak_import)) void * __sized_by_or_null(size) malloc_type_zone_malloc(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); + __auto_type func = malloc_zone_malloc; + if (malloc_type_zone_malloc) { + return malloc_type_zone_malloc(zone, size, type_id); + } + return func(zone, size); +} + +static void * __sized_by_or_null(count * size) __attribute__((always_inline)) malloc_type_zone_calloc_backdeploy(malloc_zone_t *zone, size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2,3) { + __attribute__((weak_import)) void * __sized_by_or_null(count * size) malloc_type_zone_calloc(malloc_zone_t *zone, size_t count, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2,3); + __auto_type func = malloc_zone_calloc; + if (malloc_type_zone_calloc) { + return malloc_type_zone_calloc(zone, count, size, type_id); + } + return func(zone, count, size); +} + +static void __attribute__((always_inline)) malloc_type_zone_free_backdeploy(malloc_zone_t *zone, void * __unsafe_indexable ptr, malloc_type_id_t type_id) { + __attribute__((weak_import)) void malloc_type_zone_free(malloc_zone_t *zone, void * __unsafe_indexable ptr, malloc_type_id_t type_id); + __auto_type func = malloc_zone_free; + if (malloc_type_zone_free) { + malloc_type_zone_free(zone, ptr, type_id); + } else { + func(zone, ptr); + } +} + +static void * __sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_realloc_backdeploy(malloc_zone_t *zone, void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(3) { + __auto_type func = malloc_zone_realloc; + __attribute__((weak_import)) void * __sized_by_or_null(size) malloc_type_zone_realloc(malloc_zone_t *zone, void * __unsafe_indexable ptr, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(3); + if (malloc_type_zone_realloc) { + return malloc_type_zone_realloc(zone, ptr, size, type_id); + } + return func(zone, ptr, size); +} + +static void *__sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_valloc_backdeploy(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2) { + __attribute__((weak_import)) void *__sized_by_or_null(size) malloc_type_zone_valloc(malloc_zone_t *zone, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_size(2); + __auto_type func = malloc_zone_valloc; + if (malloc_type_zone_valloc) { + return malloc_type_zone_valloc(zone, size, type_id); + } + return func(zone, size); +} + +static void *__sized_by_or_null(size) __attribute__((always_inline)) malloc_type_zone_memalign_backdeploy(malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(2) __alloc_size(3) { + __attribute__((weak_import)) void *__sized_by_or_null(size) malloc_type_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size, malloc_type_id_t type_id) __result_use_check __alloc_align(2) __alloc_size(3); + __auto_type func = malloc_zone_memalign; + if (malloc_type_zone_memalign) { + return malloc_type_zone_memalign(zone, alignment, size, type_id); + } + return func(zone, alignment, size); +} +#endif // defined(_MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING) && _MALLOC_TYPE_MALLOC_IS_BACKDEPLOYING + __END_DECLS #endif /* _MALLOC_MALLOC_H_ */ -- cgit v1.2.3