]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / Common / MyAlloc.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright (c) 2004, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
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=%xh, Line=%u)"\r
86 "Invalid parameter(s).\n",\r
87 Final,\r
88 File,\r
89 Line\r
90 );\r
91\r
92 exit (1);\r
93 }\r
94\r
95 if (strlen (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
101 Line\r
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
124 Line,\r
125 Tmp->File,\r
126 Tmp->Line,\r
127 Tmp->Size,\r
128 *(UINT32 *) (Tmp->Buffer),\r
129 *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
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
144 Line\r
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
151 Tmp->Line,\r
152 Tmp->Size,\r
153 *(UINT32 *) (Tmp->Buffer),\r
154 *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
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=%xh, Line=%u)"\r
203 "\nInvalid parameter(s).\n",\r
204 Size,\r
205 File,\r
206 Line\r
207 );\r
208\r
209 exit (1);\r
210 }\r
211\r
212 Len = strlen (File);\r
213 if (Len == 0) {\r
214 printf (\r
215 "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
216 "\nInvalid parameter.\n",\r
217 Size,\r
218 File,\r
219 Line\r
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, __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
241 Size,\r
242 File,\r
243 Line\r
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 (Tmp->File, 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=%xh, Size=%u, File=%xh, Line=%u)"\r
316 "\nInvalid parameter(s).\n",\r
317 Ptr,\r
318 Size,\r
319 File,\r
320 Line\r
321 );\r
322\r
323 exit (1);\r
324 }\r
325\r
326 if (strlen (File) == 0) {\r
327 printf (\r
328 "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)"\r
329 "\nInvalid parameter.\n",\r
330 Ptr,\r
331 Size,\r
332 File,\r
333 Line\r
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=%xh, Size=%u, File=%s, Line=%u)"\r
350 "\nCould not find buffer.\n",\r
351 Ptr,\r
352 Size,\r
353 File,\r
354 Line\r
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, __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=%xh, File=%xh, Line=%u)"\r
421 "\nInvalid parameter(s).\n",\r
422 Ptr,\r
423 File,\r
424 Line\r
425 );\r
426\r
427 exit (1);\r
428 }\r
429\r
430 if (strlen (File) == 0) {\r
431 printf (\r
432 "\nMyFree(Ptr=%xh, File=%s, Line=%u)"\r
433 "\nInvalid parameter.\n",\r
434 Ptr,\r
435 File,\r
436 Line\r
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=%xh, File=%s, Line=%u)"\r
453 "\nCalled before memory allocated.\n",\r
454 Ptr,\r
455 File,\r
456 Line\r
457 );\r
458\r
459 exit (1);\r
460 }\r
461 //\r
462 // Check for corrupted allocation list.\r
463 //\r
464 MyCheck (0, __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=%xh, File=%s, Line=%u)\n"\r
486 "\nNot found.\n",\r
487 Ptr,\r
488 File,\r
489 Line\r
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