plan9port

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

print.c (6525B)


      1 /*
      2  *
      3  *	debugger
      4  *
      5  */
      6 #include "defs.h"
      7 #include "fns.h"
      8 
      9 #define ptrace dbptrace
     10 
     11 extern	int	infile;
     12 extern	int	outfile;
     13 extern	int	maxpos;
     14 
     15 /* general printing routines ($) */
     16 
     17 char	*Ipath = INCDIR;
     18 static	int	tracetype;
     19 static void	printfp(Map*, int);
     20 
     21 /*
     22  *	callback on stack trace
     23  */
     24 static int
     25 ptrace(Map *map, Regs *regs, u64int pc, u64int nextpc, Symbol *sym, int depth)
     26 {
     27 	char buf[512];
     28 
     29 	USED(map);
     30 	if(sym){
     31 		dprint("%s(", sym->name);
     32 		printparams(sym, regs);
     33 		dprint(") ");
     34 	}else
     35 		dprint("%#lux ", pc);
     36 	printsource(pc);
     37 
     38 	dprint(" called from ");
     39 	symoff(buf, 512, nextpc, CTEXT);
     40 	dprint("%s ", buf);
     41 /*	printsource(nextpc); */
     42 	dprint("\n");
     43 	if(tracetype == 'C' && sym)
     44 		printlocals(sym, regs);
     45 	return depth<40;
     46 }
     47 
     48 static ulong *adrregvals;
     49 
     50 static int
     51 adrrw(Regs *regs, char *name, u64int *val, int isr)
     52 {
     53 	int i;
     54 
     55 	if((i = windindex(name)) == -1)
     56 		return correg->rw(correg, name, val, isr);
     57 	if(isr){
     58 		*val = adrregvals[i];
     59 		return 0;
     60 	}
     61 	werrstr("saved registers are immutable");
     62 	return -1;
     63 }
     64 
     65 Regs*
     66 adrregs(void)
     67 {
     68 	int i;
     69 	static Regs r;
     70 	static u32int x;
     71 
     72 	if(adrregvals== nil){
     73 		adrregvals = malloc(mach->nwindreg*sizeof(adrregvals[0]));
     74 		if(adrregvals == nil)
     75 			error("%r");
     76 	}
     77 	for(i=0; i<mach->nwindreg; i++){
     78 		if(get4(cormap, adrval+4*i, &x) < 0)
     79 			error("%r");
     80 		adrregvals[i] = x;
     81 	}
     82 	r.rw = adrrw;
     83 	return &r;
     84 }
     85 
     86 void
     87 printdollar(int modif)
     88 {
     89 	int	i;
     90 	u32int u4;
     91 	BKPT *bk;
     92 	Symbol s;
     93 	int	stack;
     94 	char	*fname;
     95 	char buf[512];
     96 	Regs *r;
     97 
     98 	if (cntflg==0)
     99 		cntval = -1;
    100 	switch (modif) {
    101 
    102 	case '<':
    103 		if (cntval == 0) {
    104 			while (readchar() != EOR)
    105 				;
    106 			reread();
    107 			break;
    108 		}
    109 		if (rdc() == '<')
    110 			stack = 1;
    111 		else {
    112 			stack = 0;
    113 			reread();
    114 		}
    115 		fname = getfname();
    116 		redirin(stack, fname);
    117 		break;
    118 
    119 	case '>':
    120 		fname = getfname();
    121 		redirout(fname);
    122 		break;
    123 
    124 	case 'a':
    125 		attachprocess();
    126 		break;
    127 
    128 /* maybe use this for lwpids?
    129 	case 'A':
    130 		attachpthread();
    131 		break;
    132 */
    133 	case 'k':
    134 		kmsys();
    135 		break;
    136 
    137 	case 'q':
    138 	case 'Q':
    139 		done();
    140 
    141 	case 'w':
    142 		maxpos=(adrflg?adrval:MAXPOS);
    143 		break;
    144 
    145 	case 'S':
    146 		printsym();
    147 		break;
    148 
    149 	case 's':
    150 		maxoff=(adrflg?adrval:MAXOFF);
    151 		break;
    152 
    153 	case 'm':
    154 		printmap("? map", symmap);
    155 		printmap("/ map", cormap);
    156 		break;
    157 
    158 	case 0:
    159 	case '?':
    160 		if (pid)
    161 			dprint("pid = %d\n",pid);
    162 		else
    163 			prints("no process\n");
    164 		flushbuf();
    165 
    166 	case 'r':
    167 	case 'R':
    168 		printregs(modif);
    169 		return;
    170 
    171 	case 'f':
    172 	case 'F':
    173 		printfp(cormap, modif);
    174 		return;
    175 
    176 	case 'c':
    177 	case 'C':
    178 		tracetype = modif;
    179 		if (adrflg)
    180 			r = adrregs();
    181 		else
    182 			r = correg;
    183 		if(stacktrace(cormap, correg, ptrace) <= 0)
    184 			error("no stack frame");
    185 		break;
    186 
    187 		/*print externals*/
    188 	case 'e':
    189 		for (i = 0; indexsym(i, &s)>=0; i++) {
    190 			if (s.class==CDATA)
    191 			if (s.loc.type==LADDR)
    192 			if (get4(cormap, s.loc.addr, &u4) > 0)
    193 				dprint("%s/%12t%#lux\n", s.name, (ulong)u4);
    194 		}
    195 		break;
    196 
    197 		/*print breakpoints*/
    198 	case 'b':
    199 	case 'B':
    200 		for (bk=bkpthead; bk; bk=bk->nxtbkpt)
    201 			if (bk->flag) {
    202 				symoff(buf, 512, (WORD)bk->loc, CTEXT);
    203 				dprint(buf);
    204 				if (bk->count != 1)
    205 					dprint(",%d", bk->count);
    206 				dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
    207 			}
    208 		break;
    209 
    210 	case 'M':
    211 		fname = getfname();
    212 		if (machbyname(fname) == 0)
    213 			dprint("unknown name\n");;
    214 		break;
    215 	default:
    216 		error("bad `$' command");
    217 	}
    218 	USED(r);
    219 
    220 }
    221 
    222 char *
    223 getfname(void)
    224 {
    225 	static char fname[ARB];
    226 	char *p;
    227 
    228 	if (rdc() == EOR) {
    229 		reread();
    230 		return (0);
    231 	}
    232 	p = fname;
    233 	do {
    234 		*p++ = lastc;
    235 		if (p >= &fname[ARB-1])
    236 			error("filename too long");
    237 	} while (rdc() != EOR);
    238 	*p = 0;
    239 	reread();
    240 	return (fname);
    241 }
    242 
    243 static void
    244 printfp(Map *map, int modif)
    245 {
    246 	Regdesc *rp;
    247 	int i;
    248 	int ret;
    249 	char buf[512];
    250 
    251 	for (i = 0, rp = mach->reglist; rp->name; rp += ret) {
    252 		ret = 1;
    253 		if (!(rp->flags&RFLT))
    254 			continue;
    255 		ret = fpformat(map, rp, buf, sizeof(buf), modif);
    256 		if (ret < 0) {
    257 			werrstr("Register %s: %r", rp->name);
    258 			error("%r");
    259 		}
    260 			/* double column print */
    261 		if (i&0x01)
    262 			dprint("%40t%-8s%-12s\n", rp->name, buf);
    263 		else
    264 			dprint("\t%-8s%-12s", rp->name, buf);
    265 		i++;
    266 	}
    267 }
    268 
    269 void
    270 redirin(int stack, char *file)
    271 {
    272 	char pfile[ARB];
    273 
    274 	if (file == 0) {
    275 		iclose(-1, 0);
    276 		return;
    277 	}
    278 	iclose(stack, 0);
    279 	if ((infile = open(file, 0)) < 0) {
    280 		strcpy(pfile, Ipath);
    281 		strcat(pfile, "/");
    282 		strcat(pfile, file);
    283 		if ((infile = open(pfile, 0)) < 0) {
    284 			infile = STDIN;
    285 			error("cannot open");
    286 		}
    287 	}
    288 }
    289 
    290 void
    291 printmap(char *s, Map *map)
    292 {
    293 	int i;
    294 
    295 	if (!map)
    296 		return;
    297 	if (map == symmap)
    298 		dprint("%s%12t`%s'\n", s, symfil==nil ? "-" : symfil);
    299 	else if (map == cormap)
    300 		dprint("%s%12t`%s'\n", s, corfil==nil ? "-" : corfil);
    301 	else
    302 		dprint("%s\n", s);
    303 	for (i = 0; i < map->nseg; i++) {
    304 		dprint("%s%8t%-16#lux %-16#lux %-16#lux %s\n", map->seg[i].name,
    305 			map->seg[i].base, map->seg[i].base+map->seg[i].size, map->seg[i].offset,
    306 			map->seg[i].file ? map->seg[i].file : "");
    307 	}
    308 }
    309 
    310 /*
    311  *	dump the raw symbol table
    312  */
    313 void
    314 printsym(void)
    315 {
    316 	int i;
    317 	Symbol *sp, s;
    318 
    319 	for (i=0; indexsym(i, &s)>=0; i++){
    320 		sp = &s;
    321 		switch(sp->type) {
    322 		case 't':
    323 		case 'l':
    324 			dprint("%8#lux t %s\n", sp->loc.addr, sp->name);
    325 			break;
    326 		case 'T':
    327 		case 'L':
    328 			dprint("%8#lux T %s\n", sp->loc.addr, sp->name);
    329 			break;
    330 		case 'D':
    331 		case 'd':
    332 		case 'B':
    333 		case 'b':
    334 		case 'a':
    335 		case 'p':
    336 		case 'm':
    337 			dprint("%8#lux %c %s\n", sp->loc.addr, sp->type, sp->name);
    338 			break;
    339 		default:
    340 			break;
    341 		}
    342 	}
    343 }
    344 
    345 #define	STRINGSZ	128
    346 
    347 /*
    348  *	print the value of dot as file:line
    349  */
    350 void
    351 printsource(long dot)
    352 {
    353 	char str[STRINGSZ];
    354 
    355 	if (fileline(dot, str, STRINGSZ) >= 0)
    356 		dprint("%s", str);
    357 }
    358 
    359 void
    360 printpc(void)
    361 {
    362 	char buf[512];
    363 	u64int u;
    364 
    365 	if(rget(correg, mach->pc, &u) < 0)
    366 		error("%r");
    367 	dot = u;
    368 	if(dot){
    369 		printsource((long)dot);
    370 		printc(' ');
    371 		symoff(buf, sizeof(buf), (long)dot, CTEXT);
    372 		dprint("%s/", buf);
    373 		if (mach->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
    374 			error("%r");
    375 		dprint("%16t%s\n", buf);
    376 	}
    377 }
    378 
    379 void
    380 printlocals(Symbol *fn, Regs *regs)
    381 {
    382 	int i;
    383 	u32int v;
    384 	Symbol s;
    385 
    386 	for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
    387 		if (s.class != CAUTO)
    388 			continue;
    389 		if(lget4(cormap, regs, s.loc, &v) >= 0)
    390 			dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, v);
    391 		else
    392 			dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
    393 	}
    394 }
    395 
    396 void
    397 printparams(Symbol *fn, Regs *regs)
    398 {
    399 	int i;
    400 	Symbol s;
    401 	u32int v;
    402 	int first = 0;
    403 
    404 	for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
    405 		if (s.class != CPARAM)
    406 			continue;
    407 		if (first++)
    408 			dprint(", ");
    409 		if(lget4(cormap, regs, s.loc, &v) >= 0)
    410 			dprint("%s=%#lux", s.name, v);
    411 		else
    412 			dprint("%s=?", s.name);
    413 	}
    414 }