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