~ubuntu-branches/ubuntu/trusty/batmand/trusty

« back to all changes in this revision

Viewing changes to allocate.c

  • Committer: Bazaar Package Importer
  • Author(s): Holger Levsen
  • Date: 2007-11-26 09:10:49 UTC
  • Revision ID: james.westby@ubuntu.com-20071126091049-9fqg546f2c4ct759
Tags: upstream-0.2
ImportĀ upstreamĀ versionĀ 0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006 B.A.T.M.A.N. contributors:
 
3
 * Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann, Marek Lindner
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of version 2 of the GNU General Public
 
6
 * License as published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
11
 * General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software
 
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
16
 * 02110-1301, USA
 
17
 *
 
18
 */
 
19
 
 
20
 
 
21
 
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
 
 
26
#include "os.h"
 
27
#include "allocate.h"
 
28
 
 
29
 
 
30
/* #define DEBUG_MALLOC */
 
31
/* #define MEMORY_USAGE */
 
32
 
 
33
#define MAGIC_NUMBER 0x12345678
 
34
 
 
35
#if defined DEBUG_MALLOC
 
36
 
 
37
struct chunkHeader *chunkList = NULL;
 
38
 
 
39
struct chunkHeader
 
40
{
 
41
        struct chunkHeader *next;
 
42
        uint32_t length;
 
43
        int32_t tag;
 
44
        uint32_t magicNumber;
 
45
};
 
46
 
 
47
struct chunkTrailer
 
48
{
 
49
        uint32_t magicNumber;
 
50
};
 
51
 
 
52
 
 
53
 
 
54
#if defined MEMORY_USAGE
 
55
 
 
56
struct memoryUsage *memoryList = NULL;
 
57
 
 
58
 
 
59
struct memoryUsage
 
60
{
 
61
        struct memoryUsage *next;
 
62
        uint32_t length;
 
63
        uint32_t counter;
 
64
        int32_t tag;
 
65
};
 
66
 
 
67
 
 
68
void addMemory( uint32_t length, int32_t tag ) {
 
69
 
 
70
        struct memoryUsage *walker;
 
71
 
 
72
 
 
73
        for ( walker = memoryList; walker != NULL; walker = walker->next ) {
 
74
 
 
75
                if ( walker->tag == tag ) {
 
76
 
 
77
                        walker->counter++;
 
78
                        break;
 
79
 
 
80
                }
 
81
 
 
82
        }
 
83
 
 
84
        if ( walker == NULL ) {
 
85
 
 
86
                walker = malloc( sizeof(struct memoryUsage) );
 
87
 
 
88
                walker->length = length;
 
89
                walker->tag = tag;
 
90
                walker->counter = 1;
 
91
 
 
92
                walker->next = memoryList;
 
93
                memoryList = walker;
 
94
 
 
95
        }
 
96
 
 
97
}
 
98
 
 
99
 
 
100
void removeMemory( int32_t tag, int32_t freetag ) {
 
101
 
 
102
        struct memoryUsage *walker;
 
103
 
 
104
 
 
105
        for ( walker = memoryList; walker != NULL; walker = walker->next ) {
 
106
 
 
107
                if ( walker->tag == tag ) {
 
108
 
 
109
                        if ( walker->counter == 0 ) {
 
110
 
 
111
                                debug_output( 0, "Freeing more memory than was allocated: malloc tag = %d, free tag = %d\n", tag, freetag );
 
112
                                restore_and_exit(0);
 
113
 
 
114
                        }
 
115
 
 
116
                        walker->counter--;
 
117
                        break;
 
118
 
 
119
                }
 
120
 
 
121
        }
 
122
 
 
123
        if ( walker == NULL ) {
 
124
 
 
125
                debug_output( 0, "Freeing memory that was never allocated: malloc tag = %d, free tag = %d\n", tag, freetag );
 
126
                restore_and_exit(0);
 
127
 
 
128
        }
 
129
 
 
130
}
 
131
 
 
132
#endif
 
133
 
 
134
 
 
135
 
 
136
void checkIntegrity(void)
 
137
{
 
138
        struct chunkHeader *walker;
 
139
        struct chunkTrailer *chunkTrailer;
 
140
        unsigned char *memory;
 
141
 
 
142
 
 
143
#if defined MEMORY_USAGE
 
144
 
 
145
        struct memoryUsage *memoryWalker;
 
146
 
 
147
        debug_output( 3, " \nMemory usage information:\n" );
 
148
 
 
149
        for ( memoryWalker = memoryList; memoryWalker != NULL; memoryWalker = memoryWalker->next ) {
 
150
 
 
151
                if ( memoryWalker->counter != 0 )
 
152
                        debug_output( 3, "   tag: %4i, num malloc: %4i, bytes per malloc: %4i, total: %6i\n", memoryWalker->tag, memoryWalker->counter, memoryWalker->length, memoryWalker->counter * memoryWalker->length );
 
153
 
 
154
        }
 
155
 
 
156
#endif
 
157
 
 
158
 
 
159
        for (walker = chunkList; walker != NULL; walker = walker->next)
 
160
        {
 
161
                if (walker->magicNumber != MAGIC_NUMBER)
 
162
                {
 
163
                        debug_output( 0, "checkIntegrity - invalid magic number in header: %08x, malloc tag = %d\n", walker->magicNumber, walker->tag );
 
164
                        restore_and_exit(0);
 
165
                }
 
166
 
 
167
                memory = (unsigned char *)walker;
 
168
 
 
169
                chunkTrailer = (struct chunkTrailer *)(memory + sizeof(struct chunkHeader) + walker->length);
 
170
 
 
171
                if (chunkTrailer->magicNumber != MAGIC_NUMBER)
 
172
                {
 
173
                        debug_output( 0, "checkIntegrity - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, walker->tag );
 
174
                        restore_and_exit(0);
 
175
                }
 
176
        }
 
177
}
 
178
 
 
179
void checkLeak(void)
 
180
{
 
181
        struct chunkHeader *walker;
 
182
 
 
183
        for (walker = chunkList; walker != NULL; walker = walker->next)
 
184
                debug_output( 0, "Memory leak detected, malloc tag = %d\n", walker->tag );
 
185
}
 
186
 
 
187
void *debugMalloc(uint32_t length, int32_t tag)
 
188
{
 
189
        unsigned char *memory;
 
190
        struct chunkHeader *chunkHeader;
 
191
        struct chunkTrailer *chunkTrailer;
 
192
        unsigned char *chunk;
 
193
 
 
194
//      printf("sizeof(struct chunkHeader) = %u, sizeof (struct chunkTrailer) = %u\n", sizeof (struct chunkHeader), sizeof (struct chunkTrailer));
 
195
 
 
196
        memory = malloc(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer));
 
197
 
 
198
        if (memory == NULL)
 
199
        {
 
200
                debug_output( 0, "Cannot allocate %u bytes, malloc tag = %d\n", (unsigned int)(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer)), tag );
 
201
                restore_and_exit(0);
 
202
        }
 
203
 
 
204
        chunkHeader = (struct chunkHeader *)memory;
 
205
        chunk = memory + sizeof(struct chunkHeader);
 
206
        chunkTrailer = (struct chunkTrailer *)(memory + sizeof(struct chunkHeader) + length);
 
207
 
 
208
        chunkHeader->length = length;
 
209
        chunkHeader->tag = tag;
 
210
        chunkHeader->magicNumber = MAGIC_NUMBER;
 
211
 
 
212
        chunkTrailer->magicNumber = MAGIC_NUMBER;
 
213
 
 
214
        chunkHeader->next = chunkList;
 
215
        chunkList = chunkHeader;
 
216
 
 
217
#if defined MEMORY_USAGE
 
218
 
 
219
        addMemory( length, tag );
 
220
 
 
221
#endif
 
222
 
 
223
        return chunk;
 
224
}
 
225
 
 
226
void *debugRealloc(void *memoryParameter, uint32_t length, int32_t tag)
 
227
{
 
228
        unsigned char *memory;
 
229
        struct chunkHeader *chunkHeader;
 
230
        struct chunkTrailer *chunkTrailer;
 
231
        unsigned char *result;
 
232
        uint32_t copyLength;
 
233
 
 
234
        if (memoryParameter) { /* if memoryParameter==NULL, realloc() should work like malloc() !! */
 
235
                memory = memoryParameter;
 
236
                chunkHeader = (struct chunkHeader *)(memory - sizeof(struct chunkHeader));
 
237
 
 
238
                if (chunkHeader->magicNumber != MAGIC_NUMBER)
 
239
                {
 
240
                        debug_output( 0, "debugRealloc - invalid magic number in header: %08x, malloc tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag );
 
241
                        restore_and_exit(0);
 
242
                }
 
243
 
 
244
                chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
 
245
 
 
246
                if (chunkTrailer->magicNumber != MAGIC_NUMBER)
 
247
                {
 
248
                        debug_output( 0, "debugRealloc - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag );
 
249
                        restore_and_exit(0);
 
250
                }
 
251
        }
 
252
 
 
253
 
 
254
        result = debugMalloc(length, tag);
 
255
        if (memoryParameter) {
 
256
                copyLength = length;
 
257
 
 
258
                if (copyLength > chunkHeader->length)
 
259
                        copyLength = chunkHeader->length;
 
260
 
 
261
                memcpy(result, memoryParameter, copyLength);
 
262
                debugFree(memoryParameter, 9999);
 
263
        }
 
264
 
 
265
 
 
266
        return result;
 
267
}
 
268
 
 
269
void debugFree(void *memoryParameter, int tag)
 
270
{
 
271
        unsigned char *memory;
 
272
        struct chunkHeader *chunkHeader;
 
273
        struct chunkTrailer *chunkTrailer;
 
274
        struct chunkHeader *walker;
 
275
        struct chunkHeader *previous;
 
276
 
 
277
        memory = memoryParameter;
 
278
        chunkHeader = (struct chunkHeader *)(memory - sizeof(struct chunkHeader));
 
279
 
 
280
        if (chunkHeader->magicNumber != MAGIC_NUMBER)
 
281
        {
 
282
                debug_output( 0, "debugFree - invalid magic number in header: %08x, malloc tag = %d, free tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag, tag );
 
283
                restore_and_exit(0);
 
284
        }
 
285
 
 
286
        previous = NULL;
 
287
 
 
288
        for (walker = chunkList; walker != NULL; walker = walker->next)
 
289
        {
 
290
                if (walker == chunkHeader)
 
291
                        break;
 
292
 
 
293
                previous = walker;
 
294
        }
 
295
 
 
296
        if (walker == NULL)
 
297
        {
 
298
                debug_output( 0, "Double free detected, malloc tag = %d, free tag = %d\n", chunkHeader->tag, tag );
 
299
                restore_and_exit(0);
 
300
        }
 
301
 
 
302
        if (previous == NULL)
 
303
                chunkList = walker->next;
 
304
 
 
305
        else
 
306
                previous->next = walker->next;
 
307
 
 
308
        chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
 
309
 
 
310
        if (chunkTrailer->magicNumber != MAGIC_NUMBER)
 
311
        {
 
312
                debug_output( 0, "debugFree - invalid magic number in trailer: %08x, malloc tag = %d, free tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag, tag );
 
313
                restore_and_exit(0);
 
314
        }
 
315
 
 
316
#if defined MEMORY_USAGE
 
317
 
 
318
        removeMemory( chunkHeader->tag, tag );
 
319
 
 
320
#endif
 
321
 
 
322
        free(chunkHeader);
 
323
 
 
324
}
 
325
 
 
326
#else
 
327
 
 
328
void checkIntegrity(void)
 
329
{
 
330
}
 
331
 
 
332
void checkLeak(void)
 
333
{
 
334
}
 
335
 
 
336
void *debugMalloc(uint32_t length, int32_t tag)
 
337
{
 
338
        void *result;
 
339
 
 
340
        result = malloc(length);
 
341
 
 
342
        if (result == NULL)
 
343
        {
 
344
                debug_output( 0, "Cannot allocate %u bytes, malloc tag = %d\n", length, tag );
 
345
                restore_and_exit(0);
 
346
        }
 
347
 
 
348
        return result;
 
349
}
 
350
 
 
351
void *debugRealloc(void *memory, uint32_t length, int32_t tag)
 
352
{
 
353
        void *result;
 
354
 
 
355
        result = realloc(memory, length);
 
356
 
 
357
        if (result == NULL)
 
358
        {
 
359
                debug_output( 0, "Cannot re-allocate %u bytes, malloc tag = %d\n", length, tag );
 
360
                restore_and_exit(0);
 
361
        }
 
362
 
 
363
        return result;
 
364
}
 
365
 
 
366
void debugFree(void *memory, int32_t tag)
 
367
{
 
368
        free(memory);
 
369
}
 
370
 
 
371
#endif