blob: 3739b62695371f114d05df554c11670783bbd41a [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include <malloc.h>
2#include <common.h>
3#include <config.h>
4
5#define MARK (0xCD)
6#define INICONTENT (0x0)
7#define MARK_SIZE (4)
8
9#define ALIGN_SIZE (sizeof(Align))
10#define REVALUEUPALIGN(val) ((val) ? (((val) - 1) / ALIGN_SIZE + 1) : 0)
11#define HEADER_ALIGN_SIZE (REVALUEUPALIGN(sizeof(HeaderStruct)))
12
13typedef union Header_tag Header;
14
15static Header *g_Header = NULL;
16
17typedef union
18{
19 long l_dummy;
20 double d_dummy;
21 void *p_dummy;
22} Align;
23
24typedef struct
25{
26 int size;
27 char *filename;
28 int line;
29 Header *prev;
30 Header *next;
31 unsigned char mark[MARK_SIZE];
32} HeaderStruct;
33
34union Header_tag
35{
36 HeaderStruct s;
37 Align u[HEADER_ALIGN_SIZE];
38};
39
40static void chain_block(Header *header)
41{
42 if (g_Header)
43 {
44 g_Header->s.prev = header;
45 }
46
47 header->s.prev = NULL;
48 header->s.next = g_Header;
49 g_Header = header;
50}
51
52static void unchain_block(Header *header)
53{
54 if (header->s.prev)
55 {
56 header->s.prev->s.next = header->s.next;
57 }
58 else
59 {
60 g_Header = header->s.next;
61 }
62
63 if (header->s.next)
64 {
65 header->s.next->s.prev = header->s.prev;
66 }
67}
68
69static void set_header(Header *header, int size, char *filename, int line)
70{
71 header->s.size = size;
72 header->s.filename = filename;
73 header->s.line = line;
74 header->s.prev = NULL;
75 header->s.next = NULL;
76
77 memset(header->s.mark, MARK, (char*)&header[1] - (char*)header->s.mark);
78}
79
80static void set_tail(void *ptr, int alloc_size)
81{
82 char *tail;
83
84 tail = ((char*)ptr) + alloc_size - MARK_SIZE;
85 memset(tail, MARK, MARK_SIZE);
86}
87
88static int check_mark_sub(unsigned char *mark, int size)
89{
90 int i;
91
92 for (i = 0; i < size; i++)
93 {
94 if (mark[i] != MARK) {
95 return -1;
96 }
97 }
98
99 return 0;
100}
101
102static int check_mark(Header *header)
103{
104 unsigned char *tail;
105
106 if (check_mark_sub(header->s.mark, (char*)&header[1] - (char*)header->s.mark))
107 {
108 printf("bad mark at header allocated in %s:%d\n", header->s.filename, header->s.line);
109 return -1;
110 }
111
112 tail = ((unsigned char*)header) + header->s.size + sizeof(Header);
113
114 if (check_mark_sub(tail, MARK_SIZE))
115 {
116 printf("bad mark at tail allocated in %s:%d\n", header->s.filename, header->s.line);
117 return -2;
118 }
119
120 return 0;
121}
122
123void* MEM_malloc(char *filename, int line, size_t size)
124{
125 void *ptr;
126 size_t alloc_size;
127
128#if DEBUG
129 alloc_size = size + sizeof(Header) + MARK_SIZE;
130#else
131 alloc_size = size;
132#endif /* DEBUG */
133
134 ptr = malloc(alloc_size);
135 if (ptr == NULL)
136 {
137 return NULL;
138 }
139
140#if DEBUG
141 memset(ptr, INICONTENT, alloc_size);
142 set_header(ptr, size, filename, line);
143 set_tail(ptr, alloc_size);
144 chain_block((Header*)ptr);
145 ptr = (char*)ptr + sizeof(Header);
146#endif /* DEBUG */
147
148 return ptr;
149}
150
151void MEM_free(void *ptr)
152{
153 void *real_ptr;
154
155 if (ptr == NULL)
156 return;
157
158#if DEBUG
159 real_ptr = (char*)ptr - sizeof(Header);
160 check_mark((Header*)real_ptr);
161 unchain_block(real_ptr);
162#else
163 real_ptr = ptr;
164#endif /* DEBUG */
165
166 free(real_ptr);
167}
168
169