]>
git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/cssmalloc.cpp
7994e803f2f0ab71f99e7a2c86bbc6a65080b937
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // cssmalloc - memory allocation in the CDSA world.
22 // Don't eat heavily before inspecting this code.
24 #include <Security/cssmalloc.h>
25 #include <Security/memutils.h>
26 #include <Security/globalizer.h>
30 using LowLevelMemoryUtilities::alignof;
31 using LowLevelMemoryUtilities::increment
;
32 using LowLevelMemoryUtilities::alignUp
;
36 // Features of the CssmAllocator root class
38 bool CssmAllocator::operator == (const CssmAllocator
&alloc
) const
40 return this == &alloc
;
43 CssmAllocator::~CssmAllocator()
49 // Standard CssmAllocator variants.
50 // Note that all calls to CssmAllocator::standard(xxx) with the same xxx argument
51 // must produce compatible allocators (i.e. they must be work on a common memory
52 // pool). This is trivially achieved here by using singletons.
54 struct DefaultCssmAllocator
: public CssmAllocator
{
55 void *malloc(size_t size
);
56 void free(void *addr
);
57 void *realloc(void *addr
, size_t size
);
60 static ModuleNexus
<DefaultCssmAllocator
> defaultAllocator
;
63 CssmAllocator
&CssmAllocator::standard(uint32
)
65 return defaultAllocator();
68 void *DefaultCssmAllocator::malloc(size_t size
)
70 if (void *result
= ::malloc(size
))
72 throw std::bad_alloc();
75 void DefaultCssmAllocator::free(void *addr
)
80 void *DefaultCssmAllocator::realloc(void *addr
, size_t newSize
)
82 if (void *result
= ::realloc(addr
, newSize
))
84 throw std::bad_alloc();
87 TrackingAllocator::~TrackingAllocator()
89 AllocSet::iterator first
= mAllocSet
.begin(), last
= mAllocSet
.end();
90 for (; first
!= last
; ++first
)
91 mAllocator
.free(*first
);
95 // CssmMemoryFunctionsAllocators
97 void *CssmMemoryFunctionsAllocator::malloc(size_t size
)
98 { return functions
.malloc(size
); }
100 void CssmMemoryFunctionsAllocator::free(void *addr
)
101 { return functions
.free(addr
); }
103 void *CssmMemoryFunctionsAllocator::realloc(void *addr
, size_t size
)
104 { return functions
.realloc(addr
, size
); }
108 // CssmAllocatorMemoryFunctions
110 CssmAllocatorMemoryFunctions::CssmAllocatorMemoryFunctions(CssmAllocator
&alloc
)
113 malloc_func
= relayMalloc
;
114 free_func
= relayFree
;
115 realloc_func
= relayRealloc
;
116 calloc_func
= relayCalloc
;
119 void *CssmAllocatorMemoryFunctions::relayMalloc(size_t size
, void *ref
)
120 { return allocator(ref
).malloc(size
); }
122 void CssmAllocatorMemoryFunctions::relayFree(void *mem
, void *ref
)
123 { allocator(ref
).free(mem
); }
125 void *CssmAllocatorMemoryFunctions::relayRealloc(void *mem
, size_t size
, void *ref
)
126 { return allocator(ref
).realloc(mem
, size
); }
128 void *CssmAllocatorMemoryFunctions::relayCalloc(uint32 count
, size_t size
, void *ref
)
130 // CssmAllocator doesn't have a calloc() method
131 void *mem
= allocator(ref
).malloc(size
* count
);
132 memset(mem
, 0, size
* count
);
138 // Memory allocators for CssmHeap objects.
139 // This implementation stores a pointer to the allocator used into memory
140 // *after* the object's proper storage block. This allows the usual free()
141 // functions to safely free our (hidden) pointer without knowing about it.
142 // An allocator argument of NULL is interpreted as the standard allocator.
144 void *CssmHeap::operator new (size_t size
, CssmAllocator
*alloc
)
147 alloc
= &CssmAllocator::standard();
148 size
= alignUp(size
, alignof<CssmAllocator
*>());
149 size_t totalSize
= size
+ sizeof(CssmAllocator
*);
150 void *addr
= alloc
->malloc(totalSize
);
151 *(CssmAllocator
**)increment(addr
, size
) = alloc
;
155 void CssmHeap::operator delete (void *addr
, size_t size
, CssmAllocator
*alloc
)
157 alloc
->free(addr
); // as per C++ std, called (only) if construction fails
160 void CssmHeap::operator delete (void *addr
, size_t size
)
162 void *end
= increment(addr
, alignUp(size
, alignof<CssmAllocator
*>()));
163 (*(CssmAllocator
**)end
)->free(addr
);