xref: /xnu-10002.61.3/libkern/libkern/c++/OSAllocation.h (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
1 /*
2  * Copyright (c) 2019-2021 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef XNU_LIBKERN_LIBKERN_CXX_OS_ALLOCATION_H
30 #define XNU_LIBKERN_LIBKERN_CXX_OS_ALLOCATION_H
31 
32 #if !TAPI
33 
34 #include <stddef.h>
35 #if DRIVERKIT_FRAMEWORK_INCLUDE
36 #include <DriverKit/OSBoundedPtr.h>
37 #include <DriverKit/safe_allocation.h>
38 #include <DriverKit/IOLib.h> // IOMalloc/IOFree
39 #else
40 #include <libkern/c++/OSBoundedPtr.h>
41 #include <libkern/c++/safe_allocation.h>
42 #include <IOKit/IOLib.h> // IOMalloc/IOFree
43 #endif /* DRIVERKIT_FRAMEWORK_INCLUDE */
44 
45 namespace os_detail {
46 struct IOKit_allocator {
47 	static void*
allocateIOKit_allocator48 	allocate(size_t bytes)
49 	{
50 		return IOMalloc(bytes);
51 	}
52 
53 	static void*
allocate_zeroIOKit_allocator54 	allocate_zero(size_t bytes)
55 	{
56 		return IOMallocZero(bytes);
57 	}
58 
59 	static void
deallocateIOKit_allocator60 	deallocate(void* p, size_t bytes)
61 	{
62 		IOFree(p, bytes);
63 	}
64 };
65 
66 #ifdef KERNEL_PRIVATE
67 struct IOKit_data_allocator {
68 	static void*
allocateIOKit_data_allocator69 	allocate(size_t bytes)
70 	{
71 		return IOMallocData(bytes);
72 	}
73 
74 	static void*
allocate_zeroIOKit_data_allocator75 	allocate_zero(size_t bytes)
76 	{
77 		return IOMallocZeroData(bytes);
78 	}
79 
80 	static void
deallocateIOKit_data_allocator81 	deallocate(void* p, size_t bytes)
82 	{
83 		IOFreeData(p, bytes);
84 	}
85 };
86 
87 template <typename T>
88 constexpr bool IOKit_is_data_v = KALLOC_TYPE_IS_DATA_ONLY(T);
89 
90 template <typename T, bool DataOnly = IOKit_is_data_v<T> >
91 struct IOKit_typed_allocator;
92 
93 template <typename T>
94 struct IOKit_typed_allocator<T, false> {
95 	static inline kalloc_type_var_view_t
96 	kt_view(void)
97 	{
98 		static KALLOC_TYPE_VAR_DEFINE(kt_view, T, KT_SHARED_ACCT);
99 		return kt_view;
100 	}
101 
102 	static void*
103 	allocate(size_t bytes)
104 	{
105 		return IOMallocTypeVarImpl(kt_view(), bytes);
106 	}
107 
108 	static void*
109 	allocate_zero(size_t bytes)
110 	{
111 		return IOMallocTypeVarImpl(kt_view(), bytes);
112 	}
113 
114 	static void
115 	deallocate(void* p, size_t bytes)
116 	{
117 		IOFreeTypeVarImpl(kt_view(), p, bytes);
118 	}
119 };
120 
121 template <typename T>
122 struct IOKit_typed_allocator<T, true> : IOKit_data_allocator {
123 };
124 #endif
125 } // end namespace os_detail
126 
127 template <
128 	typename T,
129 #if KERNEL_PRIVATE
130 	typename Allocator = os_detail::IOKit_typed_allocator<T>
131 #else
132 	typename Allocator = os_detail::IOKit_allocator
133 #endif
134 	>
135 using OSAllocation = libkern::safe_allocation<T, Allocator, os_detail::panic_trapping_policy>;
136 
137 #ifdef KERNEL_PRIVATE
138 // obsolete: just use the determination that OSAllocation<> does already.
139 //           (this works around incorrect adoptions like 104478984).
140 template <typename T>
141 using OSDataAllocation = OSAllocation<T>;
142 #endif
143 
144 inline constexpr auto OSAllocateMemory = libkern::allocate_memory;
145 inline constexpr auto OSAllocateMemoryZero = libkern::allocate_memory_zero;
146 inline constexpr auto OSAdoptMemory = libkern::adopt_memory;
147 
148 #endif /* !TAPI */
149 
150 #endif /* !XNU_LIBKERN_LIBKERN_CXX_OS_ALLOCATION_H */
151