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