xref: /inferno-os/lib/acid/port (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
1// portable acid for all architectures
2
3defn pfl(addr)
4{
5	print(pcfile(addr), ":", pcline(addr), "\n");
6}
7
8defn
9notestk(addr)
10{
11	local pc, sp;
12	complex Ureg addr;
13
14	pc = addr.pc\X;
15	sp = addr.sp\X;
16
17	print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
18	pfl(pc);
19	_stk(pc, sp, linkreg(addr), 1);
20}
21
22defn labstk(l)				// trace from a label
23{
24	_stk(*(l+4), *l, linkreg(0), 0);
25}
26
27defn params(param)
28{
29	while param do {
30		sym = head param;
31		print(sym[0], "=", sym[1]);
32		param = tail param;
33		if param then
34			print (",");
35	}
36}
37
38defn locals(l)
39{
40	local sym;
41
42	while l do {
43		sym = head l;
44		print("\t", sym[0], "=", sym[1], "\n");
45		l = tail l;
46	}
47}
48
49defn _stk(pc, sp, link, dolocals)
50{
51	local stk;
52
53	print("At pc:", pc, ":", fmt(pc, 'a'), " ");
54	pfl(pc);
55
56	stk = strace(pc, sp, link);
57
58	while stk do {
59		frame = head stk;
60		print(fmt(frame[0], 'a'), "(");
61		params(frame[2]);
62		print(") ", pcfile(frame[0]), ":", pcline(frame[0]));
63		print("\n\tcalled from ", fmt(frame[1], 'a'), " ");
64		pfl(frame[1]);
65		stk = tail stk;
66		if dolocals then
67			locals(frame[3]);
68	}
69}
70
71defn findsrc(file)
72{
73	local lst, src;
74
75	if file[0] == '/' then {
76		src = file(file);
77		if src != {} then {
78			srcfiles = append srcfiles, file;
79			srctext = append srctext, src;
80			return src;
81		}
82		return {};
83	}
84
85	lst = srcpath;
86	while head lst do {
87		src = file(head lst+file);
88		if src != {} then {
89			srcfiles = append srcfiles, file;
90			srctext = append srctext, src;
91			return src;
92		}
93		lst = tail lst;
94	}
95}
96
97defn line(addr)
98{
99	local src, file;
100
101	file = pcfile(addr);
102	src = match(file, srcfiles);
103
104	if src >= 0 then
105		src = srctext[src];
106	else
107		src = findsrc(file);
108
109	if src == {} then {
110		print("no source for ", file, "\n");
111		return {};
112	}
113	line = pcline(addr)-1;
114	print(file, ":", src[line], "\n");
115}
116
117defn addsrcdir(dir)
118{
119	dir = dir+"/";
120
121	if match(dir, srcpath) >= 0 then {
122		print("already in srcpath\n");
123		return {};
124	}
125
126	srcpath = {dir}+srcpath;
127}
128
129defn source()
130{
131	local l;
132
133	l = srcpath;
134	while l do {
135		print(head l, "\n");
136		l = tail l;
137	}
138	l = srcfiles;
139
140	while l do {
141		print("\t", head l, "\n");
142		l = tail l;
143	}
144}
145
146defn Bsrc(addr)
147{
148	local lst;
149
150	lst = srcpath;
151	file = pcfile(addr);
152	if file[0] == '/' && access(file) then {
153		rc("B "+itoa(-pcline(addr))+" "+file);
154		return {};
155	}
156	while head lst do {
157		name = head lst+file;
158		if access(name) then {
159			rc("B "+itoa(-pcline(addr))+" "+name);
160			return {};
161		}
162		lst = tail lst;
163	}
164	print("no source for ", file, "\n");
165}
166
167defn src(addr)
168{
169	local src, file, line, cline, text;
170
171	file = pcfile(addr);
172	src = match(file, srcfiles);
173
174	if src >= 0 then
175		src = srctext[src];
176	else
177		src = findsrc(file);
178
179	if src == {} then {
180		print("no source for ", file, "\n");
181		return {};
182	}
183
184	cline = pcline(addr)-1;
185	print(file, ":", cline, "\n");
186	line = cline-5;
187	loop 0,10 do {
188		if line >= 0 then {
189			if line == cline then
190				print(">");
191			else
192				print(" ");
193			text = src[line];
194			if text == {} then
195				return {};
196			print(line, "\t", text, "\n");
197		}
198		line = line+1;
199	}
200}
201
202defn stopped(pid)		// called from acid when a process changes state
203{
204	pstop(pid);		// stub so this is easy to replace
205}
206
207defn procs()			// print status of processes
208{
209	local c, lst, cpid;
210
211	cpid = pid;
212	lst = proclist;
213	while lst do {
214		np = head lst;
215		setproc(np);
216		if np == cpid then
217			c = '>';
218		else
219			c = ' ';
220		print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
221		lst = tail lst;
222	}
223	pid = cpid;
224	if pid != 0 then
225		setproc(pid);
226}
227
228defn asm(addr)
229{
230	local bound;
231
232	bound = fnbound(addr);
233
234	addr = fmt(addr, 'i');
235	loop 1,30 do {
236		print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
237		print("\t", @addr++, "\n");
238		if bound != {} && addr > bound[1] then {
239			lasmaddr = addr;
240			return {};
241		}
242	}
243	lasmaddr = addr;
244}
245
246defn casm()
247{
248	asm(lasmaddr);
249}
250
251defn new()
252{
253	bplist = {};
254	newproc(progargs);
255	// Dont miss the delay slot calls
256	bpset(follow(main)[0]);
257	cont();
258	bpdel(*PC);
259}
260
261defn stmnt()			// step one statement
262{
263	local line;
264
265	line = pcline(*PC);
266	while 1 do {
267		step();
268		if line != pcline(*PC) then {
269			src(*PC);
270			return {};
271		}
272	}
273}
274
275defn func()			// step until we leave the current function
276{
277	local bound, end, start, pc;
278
279	bound = fnbound(*PC);
280	if bound == {} then {
281		print("cannot locate text symbol\n");
282		return {};
283	}
284
285	pc = *PC;
286	start = bound[0];
287	end = bound[1];
288	while pc >= start && pc < end do {
289		step();
290		pc = *PC;
291	}
292}
293
294defn next()
295{
296	local sp, bound;
297
298	sp = *SP;
299	bound = fnbound(*PC);
300	stmnt();
301	pc = *PC;
302	if pc >= bound[0] && pc < bound[1] then
303		return {};
304
305	while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
306		step();
307		pc = *PC;
308	}
309	src(*PC);
310}
311
312defn dump(addr, n, fmt)
313{
314	loop 0, n do {
315		print(fmt(addr, 'X'), ": ");
316		addr = mem(addr, fmt);
317	}
318}
319
320defn mem(addr, fmt)
321{
322
323	local i, c, n;
324
325	i = 0;
326	while fmt[i] != 0 do {
327		c = fmt[i];
328		n = 0;
329		while '0' <= fmt[i] && fmt[i] <= '9' do {
330			n = 10*n + fmt[i]-'0';
331			i = i+1;
332		}
333		if n <= 0 then n = 1;
334		addr = fmt(addr, fmt[i]);
335		while n > 0 do {
336			print(*addr++, " ");
337			n = n-1;
338		}
339		i = i+1;
340	}
341	print("\n");
342	return addr;
343}
344
345defn symbols(pattern)
346{
347	local l, s;
348
349	l = symbols;
350	while l do {
351		s = head l;
352		if regexp(pattern, s[0]) then
353			print(s[0], "\t", s[1], "\t", s[2], "\n");
354		l = tail l;
355	}
356}
357
358defn spsrch(len)
359{
360	local addr, a, s, e;
361
362	addr = *SP;
363	s = origin & 0x7fffffff;
364	e = etext & 0x7fffffff;
365	loop 1, len do {
366		a = *addr++;
367		c = a & 0x7fffffff;
368		if c > s && c < e then {
369			print("src(", a, ")\n");
370			pfl(a);
371		}
372	}
373}
374
375defn bppush(val)
376{
377	return {"p", val};
378}
379
380defn bpderef()
381{
382	return {"*", 0};
383}
384
385defn bpmask()
386{
387	return {"&", 0};
388}
389
390defn bpeq()
391{
392	return {"=", 0};
393}
394
395defn bpneq()
396{
397	return {"!", 0};
398}
399
400defn bpand()
401{
402	return {"a", 0};
403}
404
405defn bpor()
406{
407	return {"o", 0};
408}
409
410defn bpcondset(pid, addr, conds)
411{
412	local l;
413	local id;
414	local found;
415
416 	if status(pid) != "Stopped" then {
417 		print("Waiting...\n");
418 		stop(pid);
419 	}
420
421	id = 0;
422	found = 0;
423
424	while !found && id <= 255 do {
425		l = bpl;
426		while l && head head l != id do {
427			l = tail l;
428		}
429
430		if !l then
431			found = 1;
432		else
433			id = id + 1;
434	}
435
436	if !found then {
437		print("error: no breakpoints available\n");
438		return -1;
439	}
440
441	bpl = append bpl, {id\d, pid\d, addr\X, conds};
442
443	_bpcondset(id, pid, addr, conds);
444
445	return id;
446}
447
448defn bpconddel(id)
449{
450	local i;
451	local l;
452
453	l = bpl;
454	i = 0;
455	while l do {
456		if id == head head l then {
457			bpl = delete bpl, i;
458			_bpconddel(id);
459			if id == bpid then
460				bpid = -1;
461			return {};
462		}
463		i = i + 1;
464		l = tail l;
465	}
466	print("no breakpoint with id ", id\d, ".\n");
467}
468
469defn bpprint(b)
470{
471	local l;
472
473	print(b[0], "\t", b[1], "\t", fmt(b[2], 'a'), " ", b[2]);
474	print("\t{");
475	l = b[3];
476	while l do {
477		print("\n\t\t\t\t\t", head l);
478		l = tail l;
479	}
480	print(" }\n");
481}
482
483defn bptab()
484{
485	local l;
486
487	l = bpl;
488	print("ID	PID	ADDR			CONDITIONS\n");
489	while l do {
490		bpprint(head l);
491		l = tail l;
492	}
493}
494
495defn cont()
496{
497	local b, c, l, found;
498
499	l = bpl;
500	found = 0;
501	c = *PC;
502	while !found && l do {
503		b = head l;
504		if b[2] == c then {
505			nopstop = 1;
506			step();
507			nopstop = 0;
508			found = 1;
509		} else {
510			l = tail l;
511		}
512	}
513
514	return startstop(pid);
515}
516
517defn bpset(addr)				// set a breakpoint
518{
519	return bpcondset(pid, addr, {});
520}
521
522defn bpdel(id)
523{
524	bpconddel(id);
525}
526
527defn bpaddr(id)
528{
529	local i;
530	local l;
531	local b;
532
533	l = bpl;
534	i = 0;
535	while l do {
536		b = head l;
537		if id == b[0] then
538			return b[2];
539		i = i + 1;
540		l = tail l;
541	}
542	print("bpaddr(", id\d, "): no match\n");
543	return {};
544}
545
546progargs="";
547print("$ROOT/lib/acid/port");
548