Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
/*
2
 *
3
 *	debugger
4
 *
5
 */
6
 
7
#include "defs.h"
8
#include "fns.h"
9
 
10
char	BADEQ[] = "unexpected `='";
11
 
12
BOOL	executing;
13
extern	Rune	*lp;
14
 
15
char	eqformat[ARB] = "z";
16
char	stformat[ARB] = "zMi";
17
 
18
ADDR	ditto;
19
 
20
ADDR	dot;
21
int	dotinc;
22
WORD	adrval, cntval, loopcnt;
23
int	adrflg, cntflg;
24
 
25
/* command decoding */
26
 
27
command(char *buf, int defcom)
28
{
29
	char	*reg;
30
	char	savc;
31
	Rune	*savlp=lp;
32
	char	savlc = lastc;
33
	char	savpc = peekc;
34
	static char lastcom = '=', savecom = '=';
35
 
36
	if (defcom == 0)
37
		defcom = lastcom;
38
	if (buf) {
39
		if (*buf==EOR)
40
			return(FALSE);
41
		clrinp();
42
		lp=(Rune*)buf;
43
	}
44
	do {
45
		adrflg=expr(0);		/* first address */
46
		if (adrflg){
47
			dot=expv;
48
			ditto=expv;
49
		}
50
		adrval=dot;
51
 
52
		if (rdc()==',' && expr(0)) {	/* count */
53
			cntflg=TRUE;
54
			cntval=expv;
55
		} else {
56
			cntflg=FALSE;
57
			cntval=1;
58
			reread();
59
		}
60
 
61
		if (!eol(rdc()))
62
			lastcom=lastc;		/* command */
63
		else {
64
			if (adrflg==0)
65
				dot=inkdot(dotinc);
66
			reread();
67
			lastcom=defcom;
68
		}
69
		switch(lastcom) {
70
		case '/':
71
		case '=':
72
		case '?':
73
			savecom = lastcom;
74
			acommand(lastcom);
75
			break;
76
 
77
		case '>':
78
			lastcom = savecom; 
79
			savc=rdc();
80
			if (reg=regname(savc))
81
				rput(cormap, reg, dot);
82
			else	
83
				error("bad variable");
84
			break;
85
 
86
		case '!':
87
			lastcom=savecom;
88
			shell(); 
89
			break;
90
 
91
		case '$':
92
			lastcom=savecom;
93
			printtrace(nextchar()); 
94
			break;
95
 
96
		case ':':
97
			if (!executing) { 
98
				executing=TRUE;
99
				subpcs(nextchar());
100
				executing=FALSE;
101
				lastcom=savecom;
102
			}
103
			break;
104
 
105
		case 0:
106
			prints(DBNAME);
107
			break;
108
 
109
		default: 
110
			error("bad command");
111
		}
112
		flushbuf();
113
	} while (rdc()==';');
114
	if (buf == 0)
115
		reread();
116
	else {
117
		clrinp();
118
		lp=savlp;
119
		lastc = savlc;
120
		peekc = savpc;
121
	}
122
 
123
	if(adrflg)
124
		return dot;
125
	return 1;
126
}
127
 
128
/*
129
 * [/?][wml]
130
 */
131
 
132
void
133
acommand(int pc)
134
{
135
	int eqcom;
136
	Map *map;
137
	char *fmt;
138
	char buf[512];
139
 
140
	if (pc == '=') {
141
		eqcom = 1;
142
		fmt = eqformat;
143
		map = dotmap;
144
	} else {
145
		eqcom = 0;
146
		fmt = stformat;
147
		if (pc == '/')
148
			map = cormap;
149
		else
150
			map = symmap;
151
	}
152
	if (!map) {
153
		snprint(buf, sizeof(buf), "no map for %c", pc);
154
		error(buf);
155
	}
156
 
157
	switch (rdc())
158
	{
159
	case 'm':
160
		if (eqcom)
161
			error(BADEQ); 
162
		cmdmap(map);
163
		break;
164
 
165
	case 'L':
166
	case 'l':
167
		if (eqcom)
168
			error(BADEQ); 
169
		cmdsrc(lastc, map);
170
		break;
171
 
172
	case 'W':
173
	case 'w':
174
		if (eqcom)
175
			error(BADEQ); 
176
		cmdwrite(lastc, map);
177
		break;
178
 
179
	default:
180
		reread();
181
		getformat(fmt);
182
		scanform(cntval, !eqcom, fmt, map, eqcom);
183
	}
184
}
185
 
186
void
187
cmdsrc(int c, Map *map)
188
{
189
	ulong w;
190
	long locval, locmsk;
191
	ADDR savdot;
192
	ushort sh;
193
	char buf[512];
194
	int ret;
195
 
196
	if (c == 'L')
197
		dotinc = 4;
198
	else
199
		dotinc = 2;
200
	savdot=dot;
201
	expr(1); 
202
	locval=expv;
203
	if (expr(0))
204
		locmsk=expv; 
205
	else
206
		locmsk = ~0;
207
	if (c == 'L')
208
		while ((ret = get4(map, dot, &w)) > 0 &&  (w&locmsk) != locval)
209
			dot = inkdot(dotinc);
210
	else
211
		while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval)
212
			dot = inkdot(dotinc);
213
	if (ret < 0) { 
214
		dot=savdot; 
215
		error("%r");
216
	}
217
	symoff(buf, 512, dot, CANY);
218
	dprint(buf);
219
}
220
 
221
static char badwrite[] = "can't write process memory or text image";
222
 
223
void
224
cmdwrite(int wcom, Map *map)
225
{
226
	ADDR savdot;
227
	char *format;
228
	int pass;
229
 
230
	if (wcom == 'w')
231
		format = "x";
232
	else
233
		format = "X";
234
	expr(1);
235
	pass = 0;
236
	do {
237
		pass++;  
238
		savdot=dot;
239
		exform(1, 1, format, map, 0, pass);
240
		dot=savdot;
241
		if (wcom == 'W') {
242
			if (put4(map, dot, expv) <= 0)
243
				error(badwrite);
244
		} else {
245
			if (put2(map, dot, expv) <= 0)
246
				error(badwrite);
247
		}
248
		savdot=dot;
249
		dprint("=%8t"); 
250
		exform(1, 0, format, map, 0, pass);
251
		newline();
252
	} while (expr(0));
253
	dot=savdot;
254
}
255
 
256
/*
257
 * collect a register name; return register offset
258
 * this is not what i'd call a good division of labour
259
 */
260
 
261
char *
262
regname(int regnam)
263
{
264
	static char buf[64];
265
	char *p;
266
	int c;
267
 
268
	p = buf;
269
	*p++ = regnam;
270
	while (isalnum(c = readchar())) {
271
		if (p >= buf+sizeof(buf)-1)
272
			error("register name too long");
273
		*p++ = c;
274
	}
275
	*p = 0;
276
	reread();
277
	return (buf);
278
}
279
 
280
/*
281
 * shell escape
282
 */
283
 
284
void
285
shell(void)
286
{
287
	int	rc, unixpid;
288
	char *argp = (char*)lp;
289
 
290
	while (lastc!=EOR)
291
		rdc();
292
	if ((unixpid=fork())==0) {
293
		*lp=0;
294
		execl("/bin/rc", "rc", "-c", argp, nil);
295
		exits("execl");				/* botch */
296
	} else if (unixpid == -1) {
297
		error("cannot fork");
298
	} else {
299
		mkfault = 0;
300
		while ((rc = waitpid()) != unixpid){
301
			if(rc == -1 && mkfault){
302
				mkfault = 0;
303
				continue;
304
			}
305
			break;
306
		}
307
		prints("!"); 
308
		reread();
309
	}
310
}