summaryrefslogtreecommitdiff
path: root/BaseTools/Source/C/Common/MyAlloc.h
blob: de3323d30d97f3b4caaf357b6f70a5134a0729e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/** @file
Header file for memory allocation tracking functions.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _MYALLOC_H_
#define _MYALLOC_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <Common/BaseTypes.h>

//
// Default operation is to use the memory allocation tracking functions.
// To over-ride add "#define USE_MYALLOC 0" to your program header and/or
// source files as needed.  Or, just do not include this header file in
// your project.
//
#ifndef USE_MYALLOC
#define USE_MYALLOC 1
#endif

#if USE_MYALLOC
//
// Replace C library allocation routines with MyAlloc routines.
//
#define malloc(size)        MyAlloc ((size), __FILE__, __LINE__)
#define calloc(count, size) MyAlloc ((count) * (size), __FILE__, __LINE__)
#define realloc(ptr, size)  MyRealloc ((ptr), (size), __FILE__, __LINE__)
#define free(ptr)           MyFree ((ptr), __FILE__, __LINE__)
#define alloc_check(final)  MyCheck ((final), __FILE__, __LINE__)

//
// Structure for checking/tracking memory allocations.
//
typedef struct MyAllocStruct {
  UINTN                 Cksum;
  struct MyAllocStruct  *Next;
  UINTN                 Line;
  UINTN                 Size;
  UINT8                 *File;
  UINT8                 *Buffer;
} MY_ALLOC_STRUCT;
//
// Cksum := (UINTN)This + (UINTN)Next + Line + Size + (UINTN)File +
//          (UINTN)Buffer;
//
// Next := Pointer to next allocation structure in the list.
//
// Line := __LINE__
//
// Size := Size of allocation request.
//
// File := Pointer to __FILE__ string stored immediately following
//         MY_ALLOC_STRUCT in memory.
//
// Buffer := Pointer to UINT32 aligned storage immediately following
//           the NULL terminated __FILE__ string.  This is UINT32
//           aligned because the underflow signature is 32-bits and
//           this will place the first caller address on a 64-bit
//           boundary.
//
//
// Signatures used to check for buffer overflow/underflow conditions.
//
#define MYALLOC_HEAD_MAGIK  0xBADFACED
#define MYALLOC_TAIL_MAGIK  0xDEADBEEF

/**
  Check for corruptions in the allocated memory chain.  If a corruption
  is detection program operation stops w/ an exit(1) call.

  @param Final When FALSE, MyCheck() returns if the allocated memory chain
               has not been corrupted.  When TRUE, MyCheck() returns if there
               are no un-freed allocations.  If there are un-freed allocations,
               they are displayed and exit(1) is called.
  @param File Set to __FILE__ by macro expansion.
  @param Line Set to __LINE__ by macro expansion.
**/
VOID
MyCheck (
  BOOLEAN      Final,
  UINT8        File[],
  UINTN        Line
  )
;

/**
  Allocate a new link in the allocation chain along with enough storage
  for the File[] string, requested Size and alignment overhead.  If
  memory cannot be allocated or the allocation chain has been corrupted,
  exit(1) will be called.

  @param Size Number of bytes (UINT8) requested by the called.
              Size cannot be zero.
  @param File Set to __FILE__ by macro expansion.
  @param Line Set to __LINE__ by macro expansion.

  @return Pointer to the caller's buffer.
**/
VOID  *
MyAlloc (
  UINTN      Size,
  UINT8      File[],
  UINTN      Line
  )
;

/**
  This does a MyAlloc(), memcpy() and MyFree().  There is no optimization
  for shrinking or expanding buffers.  An invalid parameter will cause
  MyRealloc() to fail with a call to exit(1).

  @param Ptr Pointer to the caller's buffer to be re-allocated.
             Ptr cannot be NULL.
  @param Size Size of new buffer.  Size cannot be zero.
  @param File Set to __FILE__ by macro expansion.
  @param Line Set to __LINE__ by macro expansion.

  @return Pointer to new caller's buffer.
**/
VOID  *
MyRealloc (
  VOID       *Ptr,
  UINTN      Size,
  UINT8      File[],
  UINTN      Line
  )
;

/**
  Release a previously allocated buffer.  Invalid parameters will cause
  MyFree() to fail with an exit(1) call.

  @param Ptr Pointer to the caller's buffer to be freed.
             A NULL pointer will be ignored.
  @param File Set to __FILE__ by macro expansion.
  @param Line Set to __LINE__ by macro expansion.
**/
VOID
MyFree (
  VOID       *Ptr,
  UINT8      File[],
  UINTN      Line
  )
;

#else /* USE_MYALLOC */

//
// Nothing to do when USE_MYALLOC is zero.
//
#define alloc_check(final)

#endif /* USE_MYALLOC */
#endif /* _MYALLOC_H_ */

/* eof - MyAlloc.h */