]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/Common/MyAlloc.c
Sync EDKII BaseTools to BaseTools project r1971
[mirror_edk2.git] / BaseTools / Source / C / Common / MyAlloc.c
CommitLineData
30fdf114
LG
1/** @file\r
2\r
40d841f6
LG
3Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials \r
30fdf114
LG
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 MyAlloc.c\r
15\r
16Abstract:\r
17\r
18 File for memory allocation tracking functions.\r
19\r
20**/\r
21\r
22#include "MyAlloc.h"\r
23\r
24#if USE_MYALLOC\r
25//\r
26// Get back to original alloc/free calls.\r
27//\r
28#undef malloc\r
29#undef calloc\r
30#undef realloc\r
31#undef free\r
32//\r
33// Start of allocation list.\r
34//\r
35STATIC MY_ALLOC_STRUCT *MyAllocData = NULL;\r
36\r
37//\r
38//\r
39//\r
40STATIC UINT32 MyAllocHeadMagik = MYALLOC_HEAD_MAGIK;\r
41STATIC UINT32 MyAllocTailMagik = MYALLOC_TAIL_MAGIK;\r
42\r
43//\r
44// ////////////////////////////////////////////////////////////////////////////\r
45//\r
46//\r
47VOID\r
48MyCheck (\r
49 BOOLEAN Final,\r
50 UINT8 File[],\r
51 UINTN Line\r
52 )\r
53// *++\r
54// Description:\r
55//\r
56// Check for corruptions in the allocated memory chain. If a corruption\r
57// is detection program operation stops w/ an exit(1) call.\r
58//\r
59// Parameters:\r
60//\r
61// Final := When FALSE, MyCheck() returns if the allocated memory chain\r
62// has not been corrupted. When TRUE, MyCheck() returns if there\r
63// are no un-freed allocations. If there are un-freed allocations,\r
64// they are displayed and exit(1) is called.\r
65//\r
66//\r
67// File := Set to __FILE__ by macro expansion.\r
68//\r
69// Line := Set to __LINE__ by macro expansion.\r
70//\r
71// Returns:\r
72//\r
73// n/a\r
74//\r
75// --*/\r
76//\r
77{\r
78 MY_ALLOC_STRUCT *Tmp;\r
79\r
80 //\r
81 // Check parameters.\r
82 //\r
83 if (File == NULL || Line == 0) {\r
84 printf (\r
85 "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
86 "Invalid parameter(s).\n",\r
87 Final,\r
88 File,\r
fd171542 89 (unsigned)Line\r
30fdf114
LG
90 );\r
91\r
92 exit (1);\r
93 }\r
94\r
95 if (strlen ((CHAR8 *)File) == 0) {\r
96 printf (\r
97 "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
98 "Invalid parameter.\n",\r
99 Final,\r
100 File,\r
fd171542 101 (unsigned)Line\r
30fdf114
LG
102 );\r
103\r
104 exit (1);\r
105 }\r
106 //\r
107 // Check structure contents.\r
108 //\r
109 for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {\r
110 if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) ||\r
111 memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) {\r
112 break;\r
113 }\r
114 }\r
115 //\r
116 // If Tmp is not NULL, the structure is corrupt.\r
117 //\r
118 if (Tmp != NULL) {\r
119 printf (\r
120 "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!"\r
121 "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",\r
122 Final,\r
123 File,\r
fd171542 124 (unsigned)Line,\r
30fdf114 125 Tmp->File,\r
fd171542 126 (unsigned) Tmp->Line,\r
127 (unsigned) Tmp->Size,\r
128 (unsigned) *(UINT32 *) (Tmp->Buffer),\r
129 (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
30fdf114
LG
130 );\r
131\r
132 exit (1);\r
133 }\r
134 //\r
135 // If Final is TRUE, display the state of the structure chain.\r
136 //\r
137 if (Final) {\r
138 if (MyAllocData != NULL) {\r
139 printf (\r
140 "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
141 "\nSome allocated items have not been freed.\n",\r
142 Final,\r
143 File,\r
fd171542 144 (unsigned)Line\r
30fdf114
LG
145 );\r
146\r
147 for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {\r
148 printf (\r
149 "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",\r
150 Tmp->File,\r
fd171542 151 (unsigned) Tmp->Line,\r
152 (unsigned) Tmp->Size,\r
153 (unsigned) *(UINT32 *) (Tmp->Buffer),\r
154 (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
30fdf114
LG
155 );\r
156 }\r
157 }\r
158 }\r
159}\r
160//\r
161// ////////////////////////////////////////////////////////////////////////////\r
162//\r
163//\r
164VOID *\r
165MyAlloc (\r
166 UINTN Size,\r
167 UINT8 File[],\r
168 UINTN Line\r
169 )\r
170// *++\r
171// Description:\r
172//\r
173// Allocate a new link in the allocation chain along with enough storage\r
174// for the File[] string, requested Size and alignment overhead. If\r
175// memory cannot be allocated or the allocation chain has been corrupted,\r
176// exit(1) will be called.\r
177//\r
178// Parameters:\r
179//\r
180// Size := Number of bytes (UINT8) requested by the called.\r
181// Size cannot be zero.\r
182//\r
183// File := Set to __FILE__ by macro expansion.\r
184//\r
185// Line := Set to __LINE__ by macro expansion.\r
186//\r
187// Returns:\r
188//\r
189// Pointer to the caller's buffer.\r
190//\r
191// --*/\r
192//\r
193{\r
194 MY_ALLOC_STRUCT *Tmp;\r
195 UINTN Len;\r
196\r
197 //\r
198 // Check for invalid parameters.\r
199 //\r
200 if (Size == 0 || File == NULL || Line == 0) {\r
201 printf (\r
202 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
203 "\nInvalid parameter(s).\n",\r
fd171542 204 (unsigned)Size,\r
30fdf114 205 File,\r
fd171542 206 (unsigned)Line\r
30fdf114
LG
207 );\r
208\r
209 exit (1);\r
210 }\r
211\r
212 Len = strlen ((CHAR8 *)File);\r
213 if (Len == 0) {\r
214 printf (\r
215 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
216 "\nInvalid parameter.\n",\r
fd171542 217 (unsigned)Size,\r
30fdf114 218 File,\r
fd171542 219 (unsigned)Line\r
30fdf114
LG
220 );\r
221\r
222 exit (1);\r
223 }\r
224 //\r
225 // Check the allocation list for corruption.\r
226 //\r
227 MyCheck (0, (UINT8 *)__FILE__, __LINE__);\r
228\r
229 //\r
230 // Allocate a new entry.\r
231 //\r
232 Tmp = calloc (\r
233 1,\r
234 sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik)\r
235 );\r
236\r
237 if (Tmp == NULL) {\r
238 printf (\r
239 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
240 "\nOut of memory.\n",\r
fd171542 241 (unsigned)Size,\r
30fdf114 242 File,\r
fd171542 243 (unsigned)Line\r
30fdf114
LG
244 );\r
245\r
246 exit (1);\r
247 }\r
248 //\r
249 // Fill in the new entry.\r
250 //\r
251 Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT);\r
252 strcpy ((CHAR8 *)Tmp->File, (CHAR8 *)File);\r
253 Tmp->Line = Line;\r
254 Tmp->Size = Size;\r
255 Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7);\r
256\r
257 memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik);\r
258\r
259 memcpy (\r
260 &Tmp->Buffer[Size + sizeof (UINT32)],\r
261 &MyAllocTailMagik,\r
262 sizeof MyAllocTailMagik\r
263 );\r
264\r
265 Tmp->Next = MyAllocData;\r
266 Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer);\r
267\r
268 MyAllocData = Tmp;\r
269\r
270 return Tmp->Buffer + sizeof (UINT32);\r
271}\r
272//\r
273// ////////////////////////////////////////////////////////////////////////////\r
274//\r
275//\r
276VOID *\r
277MyRealloc (\r
278 VOID *Ptr,\r
279 UINTN Size,\r
280 UINT8 File[],\r
281 UINTN Line\r
282 )\r
283// *++\r
284// Description:\r
285//\r
286// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization\r
287// for shrinking or expanding buffers. An invalid parameter will cause\r
288// MyRealloc() to fail with a call to exit(1).\r
289//\r
290// Parameters:\r
291//\r
292// Ptr := Pointer to the caller's buffer to be re-allocated.\r
293//\r
294// Size := Size of new buffer. Size cannot be zero.\r
295//\r
296// File := Set to __FILE__ by macro expansion.\r
297//\r
298// Line := Set to __LINE__ by macro expansion.\r
299//\r
300// Returns:\r
301//\r
302// Pointer to new caller's buffer.\r
303//\r
304// --*/\r
305//\r
306{\r
307 MY_ALLOC_STRUCT *Tmp;\r
308 VOID *Buffer;\r
309\r
310 //\r
311 // Check for invalid parameter(s).\r
312 //\r
313 if (Size == 0 || File == NULL || Line == 0) {\r
314 printf (\r
315 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"\r
316 "\nInvalid parameter(s).\n",\r
317 Ptr,\r
fd171542 318 (unsigned)Size,\r
30fdf114 319 File,\r
fd171542 320 (unsigned)Line\r
30fdf114
LG
321 );\r
322\r
323 exit (1);\r
324 }\r
325\r
326 if (strlen ((CHAR8 *)File) == 0) {\r
327 printf (\r
328 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"\r
329 "\nInvalid parameter.\n",\r
330 Ptr,\r
fd171542 331 (unsigned)Size,\r
30fdf114 332 File,\r
fd171542 333 (unsigned)Line\r
30fdf114
LG
334 );\r
335\r
336 exit (1);\r
337 }\r
338 //\r
339 // Find existing buffer in allocation list.\r
340 //\r
341 if (Ptr == NULL) {\r
342 Tmp = NULL;\r
343 } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {\r
344 Tmp = MyAllocData;\r
345 } else {\r
346 for (Tmp = MyAllocData;; Tmp = Tmp->Next) {\r
347 if (Tmp->Next == NULL) {\r
348 printf (\r
349 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"\r
350 "\nCould not find buffer.\n",\r
351 Ptr,\r
fd171542 352 (unsigned)Size,\r
30fdf114 353 File,\r
fd171542 354 (unsigned)Line\r
30fdf114
LG
355 );\r
356\r
357 exit (1);\r
358 }\r
359\r
360 Tmp = Tmp->Next;\r
361 }\r
362 }\r
363 //\r
364 // Allocate new buffer, copy old data, free old buffer.\r
365 //\r
366 Buffer = MyAlloc (Size, File, Line);\r
367\r
368 if (Buffer != NULL && Tmp != NULL) {\r
369 memcpy (\r
370 Buffer,\r
371 &Tmp->Buffer[sizeof (UINT32)],\r
372 ((Size <= Tmp->Size) ? Size : Tmp->Size)\r
373 );\r
374\r
375 MyFree (Ptr, (UINT8 *)__FILE__, __LINE__);\r
376 }\r
377\r
378 return Buffer;\r
379}\r
380//\r
381// ////////////////////////////////////////////////////////////////////////////\r
382//\r
383//\r
384VOID\r
385MyFree (\r
386 VOID *Ptr,\r
387 UINT8 File[],\r
388 UINTN Line\r
389 )\r
390// *++\r
391// Description:\r
392//\r
393// Release a previously allocated buffer. Invalid parameters will cause\r
394// MyFree() to fail with an exit(1) call.\r
395//\r
396// Parameters:\r
397//\r
398// Ptr := Pointer to the caller's buffer to be freed.\r
399// A NULL pointer will be ignored.\r
400//\r
401// File := Set to __FILE__ by macro expansion.\r
402//\r
403// Line := Set to __LINE__ by macro expansion.\r
404//\r
405// Returns:\r
406//\r
407// n/a\r
408//\r
409// --*/\r
410//\r
411{\r
412 MY_ALLOC_STRUCT *Tmp;\r
413 MY_ALLOC_STRUCT *Tmp2;\r
414\r
415 //\r
416 // Check for invalid parameter(s).\r
417 //\r
418 if (File == NULL || Line == 0) {\r
419 printf (\r
420 "\nMyFree(Ptr=%p, File=%s, Line=%u)"\r
421 "\nInvalid parameter(s).\n",\r
422 Ptr,\r
423 File,\r
fd171542 424 (unsigned)Line\r
30fdf114
LG
425 );\r
426\r
427 exit (1);\r
428 }\r
429\r
430 if (strlen ((CHAR8 *)File) == 0) {\r
431 printf (\r
432 "\nMyFree(Ptr=%p, File=%s, Line=%u)"\r
433 "\nInvalid parameter.\n",\r
434 Ptr,\r
435 File,\r
fd171542 436 (unsigned)Line\r
30fdf114
LG
437 );\r
438\r
439 exit (1);\r
440 }\r
441 //\r
442 // Freeing NULL is always valid.\r
443 //\r
444 if (Ptr == NULL) {\r
445 return ;\r
446 }\r
447 //\r
448 // Fail if nothing is allocated.\r
449 //\r
450 if (MyAllocData == NULL) {\r
451 printf (\r
452 "\nMyFree(Ptr=%p, File=%s, Line=%u)"\r
453 "\nCalled before memory allocated.\n",\r
454 Ptr,\r
455 File,\r
fd171542 456 (unsigned)Line\r
30fdf114
LG
457 );\r
458\r
459 exit (1);\r
460 }\r
461 //\r
462 // Check for corrupted allocation list.\r
463 //\r
464 MyCheck (0, (UINT8 *)__FILE__, __LINE__);\r
465\r
466 //\r
467 // Need special check for first item in list.\r
468 //\r
469 if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {\r
470 //\r
471 // Unlink first item in list.\r
472 //\r
473 Tmp = MyAllocData;\r
474 MyAllocData = MyAllocData->Next;\r
475 } else {\r
476 //\r
477 // Walk list looking for matching item.\r
478 //\r
479 for (Tmp = MyAllocData;; Tmp = Tmp->Next) {\r
480 //\r
481 // Fail if end of list is reached.\r
482 //\r
483 if (Tmp->Next == NULL) {\r
484 printf (\r
485 "\nMyFree(Ptr=%p, File=%s, Line=%u)\n"\r
486 "\nNot found.\n",\r
487 Ptr,\r
488 File,\r
fd171542 489 (unsigned)Line\r
30fdf114
LG
490 );\r
491\r
492 exit (1);\r
493 }\r
494 //\r
495 // Leave loop when match is found.\r
496 //\r
497 if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) {\r
498 break;\r
499 }\r
500 }\r
501 //\r
502 // Unlink item from list.\r
503 //\r
504 Tmp2 = Tmp->Next;\r
505 Tmp->Next = Tmp->Next->Next;\r
506 Tmp = Tmp2;\r
507 }\r
508 //\r
509 // Release item.\r
510 //\r
511 free (Tmp);\r
512}\r
513\r
514#endif /* USE_MYALLOC */\r
515\r
516/* eof - MyAlloc.c */\r