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