BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file balloc.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * Memory allocation functions.
32 */
33  
34 #ifndef BADVPN_MISC_BALLOC_H
35 #define BADVPN_MISC_BALLOC_H
36  
37 #include <stddef.h>
38 #include <stdint.h>
39 #include <stdlib.h>
40 #include <limits.h>
41  
42 #include <misc/debug.h>
43 #include <misc/bsize.h>
44 #include <misc/maxalign.h>
45  
46 /**
47 * Allocates memory.
48 *
49 * @param bytes number of bytes to allocate.
50 * @return a non-NULL pointer to the memory, or NULL on failure.
51 * The memory allocated can be freed using {@link BFree}.
52 */
53 static void * BAlloc (size_t bytes);
54  
55 /**
56 * Frees memory.
57 *
58 * @param m memory to free. Must have been obtained with {@link BAlloc},
59 * {@link BAllocArray}, or {@link BAllocArray2}. May be NULL;
60 * in this case, this function does nothing.
61 */
62 static void BFree (void *m);
63  
64 /**
65 * Changes the size of a memory block. On success, the memory block
66 * may be moved to a different address.
67 *
68 * @param m pointer to a memory block obtained from {@link BAlloc}
69 * or other functions in this group. If this is NULL, the
70 * call is equivalent to {@link BAlloc}(bytes).
71 * @param bytes new size of the memory block
72 * @return new pointer to the memory block, or NULL on failure
73 */
74 static void * BRealloc (void *m, size_t bytes);
75  
76 /**
77 * Allocates memory, with size given as a {@link bsize_t}.
78 *
79 * @param bytes number of bytes to allocate. If the size is overflow,
80 * this function will return NULL.
81 * @return a non-NULL pointer to the memory, or NULL on failure.
82 * The memory allocated can be freed using {@link BFree}.
83 */
84 static void * BAllocSize (bsize_t bytes);
85  
86 /**
87 * Allocates memory for an array.
88 * A check is first done to make sure the multiplication doesn't overflow;
89 * otherwise, this is equivalent to {@link BAlloc}(count * bytes).
90 * This may be slightly faster if 'bytes' is constant, because a division
91 * with 'bytes' is performed.
92 *
93 * @param count number of elements.
94 * @param bytes size of one array element.
95 * @return a non-NULL pointer to the memory, or NULL on failure.
96 * The memory allocated can be freed using {@link BFree}.
97 */
98 static void * BAllocArray (size_t count, size_t bytes);
99  
100 /**
101 * Reallocates memory that was allocated using one of the allocation
102 * functions in this file. On success, the memory may be moved to a
103 * different address, leaving the old address invalid.
104 *
105 * @param mem pointer to an existing memory block. May be NULL, in which
106 * case this is equivalent to {@link BAllocArray}.
107 * @param count number of elements for reallocation
108 * @param bytes size of one array element for reallocation
109 * @return a non-NULL pointer to the address of the reallocated memory
110 * block, or NULL on failure. On failure, the original memory
111 * block is left intact.
112 */
113 static void * BReallocArray (void *mem, size_t count, size_t bytes);
114  
115 /**
116 * Allocates memory for a two-dimensional array.
117 *
118 * Checks are first done to make sure the multiplications don't overflow;
119 * otherwise, this is equivalent to {@link BAlloc}((count2 * (count1 * bytes)).
120 *
121 * @param count2 number of elements in one dimension.
122 * @param count1 number of elements in the other dimension.
123 * @param bytes size of one array element.
124 * @return a non-NULL pointer to the memory, or NULL on failure.
125 * The memory allocated can be freed using {@link BFree}.
126 */
127 static void * BAllocArray2 (size_t count2, size_t count1, size_t bytes);
128  
129 /**
130 * Adds to a size_t with overflow detection.
131 *
132 * @param s pointer to a size_t to add to
133 * @param add number to add
134 * @return 1 on success, 0 on failure
135 */
136 static int BSizeAdd (size_t *s, size_t add);
137  
138 /**
139 * Aligns a size_t upwards with overflow detection.
140 *
141 * @param s pointer to a size_t to align
142 * @param align alignment value. Must be >0.
143 * @return 1 on success, 0 on failure
144 */
145 static int BSizeAlign (size_t *s, size_t align);
146  
147 void * BAlloc (size_t bytes)
148 {
149 if (bytes == 0) {
150 return malloc(1);
151 }
152  
153 return malloc(bytes);
154 }
155  
156 void BFree (void *m)
157 {
158 free(m);
159 }
160  
161 void * BRealloc (void *m, size_t bytes)
162 {
163 if (bytes == 0) {
164 return realloc(m, 1);
165 }
166  
167 return realloc(m, bytes);
168 }
169  
170 void * BAllocSize (bsize_t bytes)
171 {
172 if (bytes.is_overflow) {
173 return NULL;
174 }
175  
176 return BAlloc(bytes.value);
177 }
178  
179 void * BAllocArray (size_t count, size_t bytes)
180 {
181 if (count == 0 || bytes == 0) {
182 return malloc(1);
183 }
184  
185 if (count > SIZE_MAX / bytes) {
186 return NULL;
187 }
188  
189 return BAlloc(count * bytes);
190 }
191  
192 void * BReallocArray (void *mem, size_t count, size_t bytes)
193 {
194 if (count == 0 || bytes == 0) {
195 return realloc(mem, 1);
196 }
197  
198 if (count > SIZE_MAX / bytes) {
199 return NULL;
200 }
201  
202 return realloc(mem, count * bytes);
203 }
204  
205 void * BAllocArray2 (size_t count2, size_t count1, size_t bytes)
206 {
207 if (count2 == 0 || count1 == 0 || bytes == 0) {
208 return malloc(1);
209 }
210  
211 if (count1 > SIZE_MAX / bytes) {
212 return NULL;
213 }
214  
215 if (count2 > SIZE_MAX / (count1 * bytes)) {
216 return NULL;
217 }
218  
219 return BAlloc(count2 * (count1 * bytes));
220 }
221  
222 int BSizeAdd (size_t *s, size_t add)
223 {
224 ASSERT(s)
225  
226 if (add > SIZE_MAX - *s) {
227 return 0;
228 }
229 *s += add;
230 return 1;
231 }
232  
233 int BSizeAlign (size_t *s, size_t align)
234 {
235 ASSERT(s)
236 ASSERT(align > 0)
237  
238 size_t mod = *s % align;
239 if (mod > 0) {
240 if (align - mod > SIZE_MAX - *s) {
241 return 0;
242 }
243 *s += align - mod;
244 }
245 return 1;
246 }
247  
248 #endif