plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

command.c (4336B)


      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	char	*lp;
     14 
     15 char	eqformat[ARB] = "z";
     16 char	stformat[ARB] = "zMi";
     17 
     18 ADDR	ditto;
     19 
     20 ADDR	dot;
     21 WORD	dotinc;
     22 WORD	adrval, cntval, loopcnt;
     23 int	adrflg, cntflg;
     24 
     25 /* command decoding */
     26 
     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 = '=';
     36 
     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;
     52 
     53 		if (rdc()==',' && expr(0)) {	/* count */
     54 			cntflg=TRUE;
     55 			cntval=expv;
     56 		} else {
     57 			cntflg=FALSE;
     58 			cntval=1;
     59 			reread();
     60 		}
     61 
     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;
     77 
     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;
     86 
     87 		case '!':
     88 			lastcom=savecom;
     89 			shell();
     90 			break;
     91 
     92 		case '$':
     93 			lastcom=savecom;
     94 			printdollar(nextchar());
     95 			break;
     96 
     97 		case ':':
     98 			if (!executing) {
     99 				executing=TRUE;
    100 				subpcs(nextchar());
    101 				executing=FALSE;
    102 				lastcom=savecom;
    103 			}
    104 			break;
    105 
    106 		case 0:
    107 			prints(DBNAME);
    108 			break;
    109 
    110 		default:
    111 			error("bad command");
    112 		}
    113 		flushbuf();
    114 	} while (rdc()==';');
    115 	if (buf == 0)
    116 		reread();
    117 	else {
    118 		clrinp();
    119 		lp=savlp;
    120 		lastc = savlc;
    121 		peekc = savpc;
    122 	}
    123 
    124 	if(adrflg)
    125 		return dot;
    126 	return 1;
    127 }
    128 
    129 /*
    130  * [/?][wml]
    131  */
    132 
    133 void
    134 acommand(int pc)
    135 {
    136 	int eqcom;
    137 	Map *map;
    138 	char *fmt;
    139 	char buf[512];
    140 
    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;
    152 	}
    153 	if (!map) {
    154 		sprint(buf, "no map for %c", pc);
    155 		error(buf);
    156 	}
    157 
    158 	switch (rdc())
    159 	{
    160 	case 'm':
    161 		if (eqcom)
    162 			error(BADEQ);
    163 		cmdmap(map);
    164 		break;
    165 
    166 	case 'L':
    167 	case 'l':
    168 		if (eqcom)
    169 			error(BADEQ);
    170 		cmdsrc(lastc, map);
    171 		break;
    172 
    173 	case 'W':
    174 	case 'w':
    175 		if (eqcom)
    176 			error(BADEQ);
    177 		cmdwrite(lastc, map);
    178 		break;
    179 
    180 	default:
    181 		reread();
    182 		getformat(fmt);
    183 		scanform(cntval, !eqcom, fmt, map, eqcom);
    184 	}
    185 }
    186 
    187 void
    188 cmdsrc(int c, Map *map)
    189 {
    190 	u32int w;
    191 	long locval, locmsk;
    192 	ADDR savdot;
    193 	ushort sh;
    194 	char buf[512];
    195 	int ret;
    196 
    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");
    217 	}
    218 	symoff(buf, 512, dot, CANY);
    219 	dprint(buf);
    220 }
    221 
    222 static char badwrite[] = "can't write process memory or text image";
    223 
    224 void
    225 cmdwrite(int wcom, Map *map)
    226 {
    227 	ADDR savdot;
    228 	char *format;
    229 	int pass;
    230 
    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);
    248 		}
    249 		savdot=dot;
    250 		dprint("=%8t");
    251 		exform(1, 0, format, map, 0, pass);
    252 		newline();
    253 	} while (expr(0));
    254 	dot=savdot;
    255 }
    256 
    257 /*
    258  * collect a register name; return register offset
    259  * this is not what i'd call a good division of labour
    260  */
    261 
    262 char *
    263 regname(int regnam)
    264 {
    265 	static char buf[64];
    266 	char *p;
    267 	int c;
    268 
    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;
    275 	}
    276 	*p = 0;
    277 	reread();
    278 	return (buf);
    279 }
    280 
    281 /*
    282  * shell escape
    283  */
    284 
    285 void
    286 shell(void)
    287 {
    288 	int	rc, unixpid;
    289 	char *argp = lp;
    290 
    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;
    305 			}
    306 			break;
    307 		}
    308 		prints("!");
    309 		reread();
    310 	}
    311 }