]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/C/Common/MyAlloc.c
BaseTools: Fix compile error on VS2010
[mirror_edk2.git] / BaseTools / Source / C / Common / MyAlloc.c
... / ...
CommitLineData
1/** @file\r
2File for memory allocation tracking functions.\r
3\r
4Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials \r
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
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) {\r
77 printf (\r
78 "\nMyCheck(Final=%u, File=NULL, Line=%u)"\r
79 "Invalid parameter(s).\n",\r
80 Final,\r
81 (unsigned)Line\r
82 );\r
83\r
84 exit (1);\r
85 }\r
86\r
87 if (Line == 0) {\r
88 printf (\r
89 "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
90 "Invalid parameter(s).\n",\r
91 Final,\r
92 File,\r
93 (unsigned)Line\r
94 );\r
95\r
96 exit (1);\r
97 }\r
98\r
99 if (strlen ((CHAR8 *)File) == 0) {\r
100 printf (\r
101 "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
102 "Invalid parameter.\n",\r
103 Final,\r
104 File,\r
105 (unsigned)Line\r
106 );\r
107\r
108 exit (1);\r
109 }\r
110 //\r
111 // Check structure contents.\r
112 //\r
113 for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {\r
114 if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) ||\r
115 memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) {\r
116 break;\r
117 }\r
118 }\r
119 //\r
120 // If Tmp is not NULL, the structure is corrupt.\r
121 //\r
122 if (Tmp != NULL) {\r
123 printf (\r
124 "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!"\r
125 "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",\r
126 Final,\r
127 File,\r
128 (unsigned)Line,\r
129 Tmp->File,\r
130 (unsigned) Tmp->Line,\r
131 (unsigned) Tmp->Size,\r
132 (unsigned) *(UINT32 *) (Tmp->Buffer),\r
133 (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
134 );\r
135\r
136 exit (1);\r
137 }\r
138 //\r
139 // If Final is TRUE, display the state of the structure chain.\r
140 //\r
141 if (Final) {\r
142 if (MyAllocData != NULL) {\r
143 printf (\r
144 "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
145 "\nSome allocated items have not been freed.\n",\r
146 Final,\r
147 File,\r
148 (unsigned)Line\r
149 );\r
150\r
151 for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {\r
152 printf (\r
153 "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",\r
154 Tmp->File,\r
155 (unsigned) Tmp->Line,\r
156 (unsigned) Tmp->Size,\r
157 (unsigned) *(UINT32 *) (Tmp->Buffer),\r
158 (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
159 );\r
160 }\r
161 }\r
162 }\r
163}\r
164//\r
165// ////////////////////////////////////////////////////////////////////////////\r
166//\r
167//\r
168VOID *\r
169MyAlloc (\r
170 UINTN Size,\r
171 UINT8 File[],\r
172 UINTN Line\r
173 )\r
174// *++\r
175// Description:\r
176//\r
177// Allocate a new link in the allocation chain along with enough storage\r
178// for the File[] string, requested Size and alignment overhead. If\r
179// memory cannot be allocated or the allocation chain has been corrupted,\r
180// exit(1) will be called.\r
181//\r
182// Parameters:\r
183//\r
184// Size := Number of bytes (UINT8) requested by the called.\r
185// Size cannot be zero.\r
186//\r
187// File := Set to __FILE__ by macro expansion.\r
188//\r
189// Line := Set to __LINE__ by macro expansion.\r
190//\r
191// Returns:\r
192//\r
193// Pointer to the caller's buffer.\r
194//\r
195// --*/\r
196//\r
197{\r
198 MY_ALLOC_STRUCT *Tmp;\r
199 UINTN Len;\r
200\r
201 //\r
202 // Check for invalid parameters.\r
203 //\r
204 if (File == NULL) {\r
205 printf (\r
206 "\nMyAlloc(Size=%u, File=NULL, Line=%u)"\r
207 "\nInvalid parameter(s).\n",\r
208 (unsigned)Size,\r
209 (unsigned)Line\r
210 );\r
211\r
212 exit (1);\r
213 }\r
214\r
215 if (Size == 0 || Line == 0) {\r
216 printf (\r
217 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
218 "\nInvalid parameter(s).\n",\r
219 (unsigned)Size,\r
220 File,\r
221 (unsigned)Line\r
222 );\r
223\r
224 exit (1);\r
225 }\r
226\r
227 Len = strlen ((CHAR8 *)File);\r
228 if (Len == 0) {\r
229 printf (\r
230 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
231 "\nInvalid parameter.\n",\r
232 (unsigned)Size,\r
233 File,\r
234 (unsigned)Line\r
235 );\r
236\r
237 exit (1);\r
238 }\r
239 //\r
240 // Check the allocation list for corruption.\r
241 //\r
242 MyCheck (0, (UINT8 *)__FILE__, __LINE__);\r
243\r
244 //\r
245 // Allocate a new entry.\r
246 //\r
247 Tmp = calloc (\r
248 1,\r
249 sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik)\r
250 );\r
251\r
252 if (Tmp == NULL) {\r
253 printf (\r
254 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
255 "\nOut of memory.\n",\r
256 (unsigned)Size,\r
257 File,\r
258 (unsigned)Line\r
259 );\r
260\r
261 exit (1);\r
262 }\r
263 //\r
264 // Fill in the new entry.\r
265 //\r
266 Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT);\r
267 strcpy ((CHAR8 *)Tmp->File, (CHAR8 *)File);\r
268 Tmp->Line = Line;\r
269 Tmp->Size = Size;\r
270 Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7);\r
271\r
272 memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik);\r
273\r
274 memcpy (\r
275 &Tmp->Buffer[Size + sizeof (UINT32)],\r
276 &MyAllocTailMagik,\r
277 sizeof MyAllocTailMagik\r
278 );\r
279\r
280 Tmp->Next = MyAllocData;\r
281 Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer);\r
282\r
283 MyAllocData = Tmp;\r
284\r
285 return Tmp->Buffer + sizeof (UINT32);\r
286}\r
287//\r
288// ////////////////////////////////////////////////////////////////////////////\r
289//\r
290//\r
291VOID *\r
292MyRealloc (\r
293 VOID *Ptr,\r
294 UINTN Size,\r
295 UINT8 File[],\r
296 UINTN Line\r
297 )\r
298// *++\r
299// Description:\r
300//\r
301// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization\r
302// for shrinking or expanding buffers. An invalid parameter will cause\r
303// MyRealloc() to fail with a call to exit(1).\r
304//\r
305// Parameters:\r
306//\r
307// Ptr := Pointer to the caller's buffer to be re-allocated.\r
308//\r
309// Size := Size of new buffer. Size cannot be zero.\r
310//\r
311// File := Set to __FILE__ by macro expansion.\r
312//\r
313// Line := Set to __LINE__ by macro expansion.\r
314//\r
315// Returns:\r
316//\r
317// Pointer to new caller's buffer.\r
318//\r
319// --*/\r
320//\r
321{\r
322 MY_ALLOC_STRUCT *Tmp;\r
323 VOID *Buffer;\r
324\r
325 //\r
326 // Check for invalid parameter(s).\r
327 //\r
328 if (File == NULL) {\r
329 printf (\r
330 "\nMyRealloc(Ptr=%p, Size=%u, File=NULL, Line=%u)"\r
331 "\nInvalid parameter(s).\n",\r
332 Ptr,\r
333 (unsigned)Size,\r
334 (unsigned)Line\r
335 );\r
336\r
337 exit (1);\r
338 }\r
339\r
340 if (Size == 0 || Line == 0) {\r
341 printf (\r
342 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"\r
343 "\nInvalid parameter(s).\n",\r
344 Ptr,\r
345 (unsigned)Size,\r
346 File,\r
347 (unsigned)Line\r
348 );\r
349\r
350 exit (1);\r
351 }\r
352\r
353 if (strlen ((CHAR8 *)File) == 0) {\r
354 printf (\r
355 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"\r
356 "\nInvalid parameter.\n",\r
357 Ptr,\r
358 (unsigned)Size,\r
359 File,\r
360 (unsigned)Line\r
361 );\r
362\r
363 exit (1);\r
364 }\r
365 //\r
366 // Find existing buffer in allocation list.\r
367 //\r
368 if (Ptr == NULL) {\r
369 Tmp = NULL;\r
370 } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {\r
371 Tmp = MyAllocData;\r
372 } else {\r
373 for (Tmp = MyAllocData;; Tmp = Tmp->Next) {\r
374 if (Tmp->Next == NULL) {\r
375 printf (\r
376 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"\r
377 "\nCould not find buffer.\n",\r
378 Ptr,\r
379 (unsigned)Size,\r
380 File,\r
381 (unsigned)Line\r
382 );\r
383\r
384 exit (1);\r
385 }\r
386\r
387 Tmp = Tmp->Next;\r
388 }\r
389 }\r
390 //\r
391 // Allocate new buffer, copy old data, free old buffer.\r
392 //\r
393 Buffer = MyAlloc (Size, File, Line);\r
394\r
395 if (Buffer != NULL && Tmp != NULL) {\r
396 memcpy (\r
397 Buffer,\r
398 &Tmp->Buffer[sizeof (UINT32)],\r
399 ((Size <= Tmp->Size) ? Size : Tmp->Size)\r
400 );\r
401\r
402 MyFree (Ptr, (UINT8 *)__FILE__, __LINE__);\r
403 }\r
404\r
405 return Buffer;\r
406}\r
407//\r
408// ////////////////////////////////////////////////////////////////////////////\r
409//\r
410//\r
411VOID\r
412MyFree (\r
413 VOID *Ptr,\r
414 UINT8 File[],\r
415 UINTN Line\r
416 )\r
417// *++\r
418// Description:\r
419//\r
420// Release a previously allocated buffer. Invalid parameters will cause\r
421// MyFree() to fail with an exit(1) call.\r
422//\r
423// Parameters:\r
424//\r
425// Ptr := Pointer to the caller's buffer to be freed.\r
426// A NULL pointer will be ignored.\r
427//\r
428// File := Set to __FILE__ by macro expansion.\r
429//\r
430// Line := Set to __LINE__ by macro expansion.\r
431//\r
432// Returns:\r
433//\r
434// n/a\r
435//\r
436// --*/\r
437//\r
438{\r
439 MY_ALLOC_STRUCT *Tmp;\r
440 MY_ALLOC_STRUCT *Tmp2;\r
441\r
442 //\r
443 // Check for invalid parameter(s).\r
444 //\r
445 if (File == NULL) {\r
446 printf (\r
447 "\nMyFree(Ptr=%p, File=NULL, Line=%u)"\r
448 "\nInvalid parameter(s).\n",\r
449 Ptr,\r
450 (unsigned)Line\r
451 );\r
452\r
453 exit (1);\r
454 }\r
455\r
456 if (Line == 0) {\r
457 printf (\r
458 "\nMyFree(Ptr=%p, File=%s, Line=%u)"\r
459 "\nInvalid parameter(s).\n",\r
460 Ptr,\r
461 File,\r
462 (unsigned)Line\r
463 );\r
464\r
465 exit (1);\r
466 }\r
467\r
468 if (strlen ((CHAR8 *)File) == 0) {\r
469 printf (\r
470 "\nMyFree(Ptr=%p, File=%s, Line=%u)"\r
471 "\nInvalid parameter.\n",\r
472 Ptr,\r
473 File,\r
474 (unsigned)Line\r
475 );\r
476\r
477 exit (1);\r
478 }\r
479 //\r
480 // Freeing NULL is always valid.\r
481 //\r
482 if (Ptr == NULL) {\r
483 return ;\r
484 }\r
485 //\r
486 // Fail if nothing is allocated.\r
487 //\r
488 if (MyAllocData == NULL) {\r
489 printf (\r
490 "\nMyFree(Ptr=%p, File=%s, Line=%u)"\r
491 "\nCalled before memory allocated.\n",\r
492 Ptr,\r
493 File,\r
494 (unsigned)Line\r
495 );\r
496\r
497 exit (1);\r
498 }\r
499 //\r
500 // Check for corrupted allocation list.\r
501 //\r
502 MyCheck (0, (UINT8 *)__FILE__, __LINE__);\r
503\r
504 //\r
505 // Need special check for first item in list.\r
506 //\r
507 if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {\r
508 //\r
509 // Unlink first item in list.\r
510 //\r
511 Tmp = MyAllocData;\r
512 MyAllocData = MyAllocData->Next;\r
513 } else {\r
514 //\r
515 // Walk list looking for matching item.\r
516 //\r
517 for (Tmp = MyAllocData;; Tmp = Tmp->Next) {\r
518 //\r
519 // Fail if end of list is reached.\r
520 //\r
521 if (Tmp->Next == NULL) {\r
522 printf (\r
523 "\nMyFree(Ptr=%p, File=%s, Line=%u)\n"\r
524 "\nNot found.\n",\r
525 Ptr,\r
526 File,\r
527 (unsigned)Line\r
528 );\r
529\r
530 exit (1);\r
531 }\r
532 //\r
533 // Leave loop when match is found.\r
534 //\r
535 if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) {\r
536 break;\r
537 }\r
538 }\r
539 //\r
540 // Unlink item from list.\r
541 //\r
542 Tmp2 = Tmp->Next;\r
543 Tmp->Next = Tmp->Next->Next;\r
544 Tmp = Tmp2;\r
545 }\r
546 //\r
547 // Release item.\r
548 //\r
549 free (Tmp);\r
550}\r
551\r
552#endif /* USE_MYALLOC */\r
553\r
554/* eof - MyAlloc.c */\r