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 }