blob: 3958e24314ed211aeaadf30a813684303624864d [file] [log] [blame]
rsc9c635582004-06-09 14:22:08 +00001#include <u.h>
2#define NOPLAN9DEFINES
3#include <libc.h>
4
5/*
6 * The Unix libc routines cannot be trusted to do their own locking.
7 * Sad but apparently true.
8 */
9static Lock malloclock;
10static int mallocpid;
11
12/*
13 * The Unix mallocs don't do nearly enough error checking
14 * for my tastes. We'll waste another 24 bytes per guy so that
15 * we can. This is severely antisocial, since now free and p9free
16 * are not interchangeable.
17 */
18int debugmalloc;
19
20#define Overhead (debugmalloc ? (6*sizeof(ulong)) : 0)
21#define MallocMagic 0xA110C09
22#define ReallocMagic 0xB110C09
23#define CallocMagic 0xC110C09
24#define FreeMagic 0xF533F533
25#define CheckMagic 0
26#define END "\x7F\x2E\x55\x23"
27
28static void
29whoops(void *v)
30{
31 fprint(2, "bad malloc block %p\n", v);
32 abort();
33}
34
35static void*
36mark(void *v, ulong pc, ulong n, ulong magic)
37{
38 ulong *u;
39 char *p;
40
41 if(!debugmalloc)
42 return v;
43
44 if(v == nil)
45 return nil;
46
47 if(magic == FreeMagic || magic == CheckMagic){
48 u = (ulong*)((char*)v-4*sizeof(ulong));
49 if(u[0] != MallocMagic && u[0] != ReallocMagic && u[0] != CallocMagic)
50 whoops(v);
51 n = u[1];
52 p = (char*)v+n;
53 if(memcmp(p, END, 4) != 0)
54 whoops(v);
55 if(magic != CheckMagic){
56 u[0] = FreeMagic;
57 u[1] = u[2] = u[3] = pc;
58 if(n > 16){
59 u[4] = u[5] = u[6] = u[7] = pc;
60 memset((char*)v+16, 0xFB, n-16);
61 }
62 }
63 return u;
64 }else{
65 u = v;
66 u[0] = magic;
67 u[1] = n;
68 u[2] = 0;
69 u[3] = 0;
70 if(magic == ReallocMagic)
71 u[3] = pc;
72 else
73 u[2] = pc;
74 p = (char*)(u+4)+n;
75 memmove(p, END, 4);
76 return u+4;
77 }
78}
79
80void
81setmalloctag(void *v, ulong t)
82{
83 ulong *u;
84
85 if(!debugmalloc)
86 return;
87
88 if(v == nil)
89 return;
90 u = mark(v, 0, 0, 0);
91 u[2] = t;
92}
93
94void
95setrealloctag(void *v, ulong t)
96{
97 ulong *u;
98
99 if(!debugmalloc)
100 return;
101
102 if(v == nil)
103 return;
104 u = mark(v, 0, 0, 0);
105 u[3] = t;
106}
107
108void*
109p9malloc(ulong n)
110{
111 void *v;
112 if(n == 0)
113 n++;
114//fprint(2, "%s %d malloc\n", argv0, getpid());
115 lock(&malloclock);
116 mallocpid = getpid();
117 v = malloc(n+Overhead);
118 v = mark(v, getcallerpc(&n), n, MallocMagic);
119 unlock(&malloclock);
120//fprint(2, "%s %d donemalloc\n", argv0, getpid());
121 return v;
122}
123
124void
125p9free(void *v)
126{
127 if(v == nil)
128 return;
129
130//fprint(2, "%s %d free\n", argv0, getpid());
131 lock(&malloclock);
132 mallocpid = getpid();
133 v = mark(v, getcallerpc(&v), 0, FreeMagic);
134 free(v);
135 unlock(&malloclock);
136//fprint(2, "%s %d donefree\n", argv0, getpid());
137}
138
139void*
140p9calloc(ulong a, ulong b)
141{
142 void *v;
143
144//fprint(2, "%s %d calloc\n", argv0, getpid());
145 lock(&malloclock);
146 mallocpid = getpid();
147 v = calloc(a*b+Overhead, 1);
148 v = mark(v, getcallerpc(&a), a*b, CallocMagic);
149 unlock(&malloclock);
150//fprint(2, "%s %d donecalloc\n", argv0, getpid());
151 return v;
152}
153
154void*
155p9realloc(void *v, ulong n)
156{
157//fprint(2, "%s %d realloc\n", argv0, getpid());
158 lock(&malloclock);
159 mallocpid = getpid();
160 v = mark(v, getcallerpc(&v), 0, CheckMagic);
161 v = realloc(v, n+Overhead);
162 v = mark(v, getcallerpc(&v), n, ReallocMagic);
163 unlock(&malloclock);
164//fprint(2, "%s %d donerealloc\n", argv0, getpid());
165 return v;
166}