Blob


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