Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
include("/sys/src/libc/port/pool.acid");
2
 
3
aggr Byte {
4
	'b' 0 byte;
5
};
6
 
7
defn
8
byteat(addr)
9
{
10
	local x;
11
	complex Byte addr;
12
	x = addr.byte;
13
	return x\d;
14
}
15
 
16
defn
17
B2T(addr) {
18
	complex Bhdr addr;
19
	addr = addr+addr.size-sizeofBtail;
20
	complex Btail addr;
21
	return addr;
22
}
23
 
24
defn
25
B2D(addr) {
26
	local x;
27
	x = addr+sizeofBhdr;
28
	return x\X;
29
}
30
 
31
defn
32
D2B(addr) {
33
	local x;
34
	x = addr-sizeofBhdr;
35
	complex Bhdr x;
36
	return x;
37
}
38
 
39
defn
40
B2NB(addr) {
41
	complex Bhdr addr;
42
	addr = addr+addr.size;
43
	complex Bhdr addr;
44
	return addr;
45
}
46
 
47
defn
48
A2TB(addr) {
49
	local b;
50
	complex Arena addr;
51
	b = addr+addr.asize-sizeofBhdr;
52
	complex Bhdr b;
53
	return b;
54
}
55
 
56
defn
57
A2B(addr) {
58
	return B2NB(addr);
59
}
60
 
61
defn
62
B2PT(addr) {
63
	complex Bhdr addr;
64
	addr = addr-sizeofBtail;
65
	complex Btail addr;
66
	return addr;
67
}
68
 
69
defn
70
SHORT(addr) {
71
	local hi, lo;
72
 
73
	hi = byteat(addr);
74
	lo = byteat(addr+1);
75
	return lo+hi*256;
76
}
77
 
78
defn
79
Btail(addr) {
80
	complex Btail addr;
81
	print("	magic0	", addr.magic0, "\n");
82
	print("	datadiff	", SHORT(addr.datasize), "\n");
83
	print("	magic1	", addr.magic1, "\n");
84
	print("	size	", addr.size\X, "\n");
85
	print("	hdr	", addr+sizeofBtail-addr.size\X, "\n");
86
};
87
 
88
defn
89
Tail(addr)
90
{
91
	print("	", B2T(addr)\X, "\n");
92
	Btail(B2T(addr));
93
}
94
 
95
defn
96
Magic(m)
97
{
98
	if m == FREE_MAGIC then
99
		return "free";
100
	if m == ARENA_MAGIC then
101
		return "arena";
102
	if m == UNKEMPT_MAGIC then
103
		return "unkempt";
104
	if m == KEMPT_MAGIC then
105
		return "kempt";
106
	if m == ARENATAIL_MAGIC then
107
		return "arenatail";
108
	if m == DEAD_MAGIC then
109
		return "dead";
110
	return "unknown magic";
111
}
112
 
113
defn
114
Block(addr)
115
{
116
	complex Bhdr addr;
117
	print("	", Magic(addr.magic), "\n");
118
	print("	data ", B2D(addr), "\n");
119
	print("	datasize ", getdsize(addr), "\n");
120
	Bhdr(addr);
121
	Tail(addr);
122
}
123
 
124
defn
125
getdsize(addr)
126
{
127
	complex Bhdr addr;
128
	local x;
129
 
130
	x = addr.size\d;
131
	x = x-SHORT(B2T(addr).datasize);
132
	return x\d;
133
}
134
 
135
defn
136
datamagic(x)
137
{
138
	x = x%4;
139
	if x == 0 then return 0xFE;
140
	if x == 1 then return 0xF1;
141
	if x == 2 then return 0xF0;
142
	if x == 3 then return 0xFA;
143
}
144
 
145
defn
146
checkblock(addr)
147
{
148
	local badmagic, datamagic, a, b, t, q, n, dsize, taddr, checked;
149
	complex Bhdr addr;
150
	taddr = B2T(addr);
151
	complex Btail taddr;
152
 
153
	if addr.magic == FREE_MAGIC || addr.magic == UNKEMPT_MAGIC then {
154
		if taddr.magic0 != TAIL_MAGIC0 || taddr.magic1 != TAIL_MAGIC1 then
155
			print(addr\X, " corrupt tail magic\n");
156
		if taddr.size != addr.size then
157
			print(addr\X, " corrupt tail header pointer\n");
158
	}
159
 
160
	if addr.magic == ARENA_MAGIC then {
161
		taddr = A2TB(addr);
162
		if taddr.magic != ARENATAIL_MAGIC then
163
			print(addr\X, " arena with bad tail block\n");
164
		else
165
			addr = taddr;
166
	}
167
 
168
	if addr.magic == ARENATAIL_MAGIC then {
169
		if addr.size != 0 then
170
			print(addr\X, " bad size in arena tail\n");
171
	}
172
 
173
	if addr.magic == KEMPT_MAGIC then {
174
		a = addr;
175
		complex Alloc a;
176
		if a.size > 1024*1024*1024 then 
177
			print(addr\X, " block ridiculously large\n");
178
		t = B2T(addr);
179
		if t.magic0 != TAIL_MAGIC0 || t.magic1 != TAIL_MAGIC1 then
180
			print(addr\X, " bad tail magic\n");
181
		if t.size != addr.size then
182
			print(addr\X, " bad tail pointer\n");
183
		dsize = getdsize(a);
184
		if dsize > a.size then
185
			print(addr\X, " too much data in block\n");
186
		q = B2D(a)\X+dsize;
187
		n = 4;
188
		if q+4 > t then
189
			n = t-q;
190
		badmagic = 0;
191
		loop 0,n-1 do {
192
			if byteat(q) != datamagic(q) then {
193
				badmagic=1;
194
			}
195
			q = q+1;
196
		}
197
		if badmagic then
198
			print(addr\X, " size ", dsize, " user has overwritten boundary\n");
199
	}
200
}
201
 
202
defn
203
checkarena(arena)
204
{
205
	local atail, b;
206
 
207
	atail = A2TB(arena);
208
	complex Bhdr arena;
209
	b = arena;
210
	while b.magic != ARENATAIL_MAGIC && b < atail do {
211
		checkblock(b);
212
		if B2NB(b) == b then {
213
			print("B2NB(", b\X, ") = b\n");
214
			b = atail;	// end loop
215
		}
216
		b = B2NB(b);
217
	}
218
 
219
	checkblock(b);
220
	if b != atail then
221
		print("found wrong tail to arena ", arena\X, "\n");
222
}
223
 
224
defn
225
checkpool(p)
226
{
227
	complex Pool p;
228
	local a;
229
	a = p.arenalist;
230
 
231
	while a != 0 do {
232
		complex Arena a;
233
		checkarena(a);
234
		a = a.down;
235
	}
236
}
237
 
238
defn
239
gendumptree(f, in, s)
240
{
241
	complex Free f;
242
 
243
	loop 1,in do {print(" ");}
244
	print(s, " size ", f.size\D, " left ", f.left\X, " right ", f.right\X, "\n");
245
	if f.left != 0 && f.left < 0x7FFFFFFF then
246
		gendumptree(f.left, in+1, "l");
247
	if f.right != 0 && f.right < 0x7FFFFFFF then
248
		gendumptree(f.right, in+1, "r");
249
}
250
 
251
defn
252
dumptree(f)
253
{
254
	gendumptree(f, 0, "*");
255
}
256
 
257
defn
258
poolwhopointsat(p, addr)
259
{
260
	complex Pool p;
261
	local a;
262
 
263
	a = p.arenalist;
264
	while a != 0 do {
265
		complex Arena a;
266
		arenawhopointsat(a, addr);
267
		a = a.down;
268
	}
269
}
270
 
271
defn 
272
arenawhopointsat(arena, addr)
273
{
274
	local atail, b;
275
 
276
	atail = A2TB(arena);
277
	complex Bhdr arena;
278
	b = arena;
279
	while b < atail do {
280
		if *b == addr then 
281
			print(b\X, "\n");
282
		b = b+4;
283
	}
284
}
285
 
286
defn
287
whopointsat(addr)
288
{
289
	poolwhopointsat(*mainmem, addr);
290
}
291
 
292
defn
293
blockhdr(addr)
294
{
295
	addr = addr & ~3;
296
 
297
	while *addr != FREE_MAGIC 
298
		&& *addr !=  ARENA_MAGIC
299
		&& *addr != UNKEMPT_MAGIC
300
		&& *addr != KEMPT_MAGIC
301
		&& *addr != ARENATAIL_MAGIC
302
	do
303
		addr = addr-4;
304
	return addr;
305
}
306