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