13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * 33e12c5d1SDavid du Colombier * debugger 43e12c5d1SDavid du Colombier * 53e12c5d1SDavid du Colombier */ 63e12c5d1SDavid du Colombier #include "defs.h" 73e12c5d1SDavid du Colombier #include "fns.h" 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier extern int infile; 103e12c5d1SDavid du Colombier extern int outfile; 113e12c5d1SDavid du Colombier extern int maxpos; 123e12c5d1SDavid du Colombier extern char lastc; 133e12c5d1SDavid du Colombier 143e12c5d1SDavid du Colombier 153e12c5d1SDavid du Colombier /* general printing routines ($) */ 163e12c5d1SDavid du Colombier 173e12c5d1SDavid du Colombier char *Ipath = INCDIR; 18*219b2ee8SDavid du Colombier static int tracetype; 19*219b2ee8SDavid du Colombier static void printfp(Map*, int); 20*219b2ee8SDavid du Colombier 21*219b2ee8SDavid du Colombier /* 22*219b2ee8SDavid du Colombier * callback on stack trace 23*219b2ee8SDavid du Colombier */ 24*219b2ee8SDavid du Colombier static void 25*219b2ee8SDavid du Colombier ptrace(Map *map, ulong pc, ulong sp, Symbol *sym) 26*219b2ee8SDavid du Colombier { 27*219b2ee8SDavid du Colombier char buf[512]; 28*219b2ee8SDavid du Colombier 29*219b2ee8SDavid du Colombier USED(map); 30*219b2ee8SDavid du Colombier dprint("%s(", sym->name); 31*219b2ee8SDavid du Colombier printparams(sym, sp); 32*219b2ee8SDavid du Colombier dprint(") "); 33*219b2ee8SDavid du Colombier printsource(sym->value); 34*219b2ee8SDavid du Colombier dprint(" called from "); 35*219b2ee8SDavid du Colombier symoff(buf, 512, pc, CTEXT); 36*219b2ee8SDavid du Colombier dprint("%s ", buf); 37*219b2ee8SDavid du Colombier printsource(pc); 38*219b2ee8SDavid du Colombier dprint("\n"); 39*219b2ee8SDavid du Colombier if(tracetype == 'C') 40*219b2ee8SDavid du Colombier printlocals(sym, sp); 41*219b2ee8SDavid du Colombier } 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier void 443e12c5d1SDavid du Colombier printtrace(int modif) 453e12c5d1SDavid du Colombier { 463e12c5d1SDavid du Colombier int i; 47*219b2ee8SDavid du Colombier ulong pc, sp, link; 483e12c5d1SDavid du Colombier long v; 493e12c5d1SDavid du Colombier BKPT *bk; 503e12c5d1SDavid du Colombier Symbol s; 513e12c5d1SDavid du Colombier int stack; 523e12c5d1SDavid du Colombier char *fname; 53*219b2ee8SDavid du Colombier char buf[512]; 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier if (cntflg==0) 563e12c5d1SDavid du Colombier cntval = -1; 573e12c5d1SDavid du Colombier switch (modif) { 583e12c5d1SDavid du Colombier 593e12c5d1SDavid du Colombier case '<': 603e12c5d1SDavid du Colombier if (cntval == 0) { 613e12c5d1SDavid du Colombier while (readchar() != EOR) 623e12c5d1SDavid du Colombier ; 633e12c5d1SDavid du Colombier reread(); 643e12c5d1SDavid du Colombier break; 653e12c5d1SDavid du Colombier } 663e12c5d1SDavid du Colombier if (rdc() == '<') 673e12c5d1SDavid du Colombier stack = 1; 683e12c5d1SDavid du Colombier else { 693e12c5d1SDavid du Colombier stack = 0; 703e12c5d1SDavid du Colombier reread(); 713e12c5d1SDavid du Colombier } 723e12c5d1SDavid du Colombier fname = getfname(); 733e12c5d1SDavid du Colombier redirin(stack, fname); 743e12c5d1SDavid du Colombier break; 753e12c5d1SDavid du Colombier 763e12c5d1SDavid du Colombier case '>': 773e12c5d1SDavid du Colombier fname = getfname(); 783e12c5d1SDavid du Colombier redirout(fname); 793e12c5d1SDavid du Colombier break; 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier case 'a': 823e12c5d1SDavid du Colombier attachproc(); 833e12c5d1SDavid du Colombier break; 843e12c5d1SDavid du Colombier 853e12c5d1SDavid du Colombier case 'k': 863e12c5d1SDavid du Colombier kmsys(); 873e12c5d1SDavid du Colombier break; 883e12c5d1SDavid du Colombier 893e12c5d1SDavid du Colombier case 'q': 903e12c5d1SDavid du Colombier case 'Q': 913e12c5d1SDavid du Colombier done(); 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier case 'w': 943e12c5d1SDavid du Colombier maxpos=(adrflg?adrval:MAXPOS); 953e12c5d1SDavid du Colombier break; 963e12c5d1SDavid du Colombier 973e12c5d1SDavid du Colombier case 'S': 983e12c5d1SDavid du Colombier printsym(); 993e12c5d1SDavid du Colombier break; 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier case 's': 1023e12c5d1SDavid du Colombier maxoff=(adrflg?adrval:MAXOFF); 1033e12c5d1SDavid du Colombier break; 1043e12c5d1SDavid du Colombier 1053e12c5d1SDavid du Colombier case 'm': 1063e12c5d1SDavid du Colombier printmap("? map", symmap); 1073e12c5d1SDavid du Colombier printmap("/ map", cormap); 1083e12c5d1SDavid du Colombier break; 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier case 0: 1113e12c5d1SDavid du Colombier case '?': 1123e12c5d1SDavid du Colombier if (pid) 1133e12c5d1SDavid du Colombier dprint("pid = %d\n",pid); 1143e12c5d1SDavid du Colombier else 1153e12c5d1SDavid du Colombier prints("no process\n"); 1163e12c5d1SDavid du Colombier flushbuf(); 1173e12c5d1SDavid du Colombier 1183e12c5d1SDavid du Colombier case 'r': 1193e12c5d1SDavid du Colombier case 'R': 1203e12c5d1SDavid du Colombier printregs(modif); 1213e12c5d1SDavid du Colombier return; 1223e12c5d1SDavid du Colombier 1233e12c5d1SDavid du Colombier case 'f': 1243e12c5d1SDavid du Colombier case 'F': 125*219b2ee8SDavid du Colombier printfp(cormap, modif); 1263e12c5d1SDavid du Colombier return; 1273e12c5d1SDavid du Colombier 1283e12c5d1SDavid du Colombier case 'c': 1293e12c5d1SDavid du Colombier case 'C': 130*219b2ee8SDavid du Colombier tracetype = modif; 131*219b2ee8SDavid du Colombier if (machdata->ctrace) { 132*219b2ee8SDavid du Colombier if (adrflg) { /* trace from jmpbuf for multi-threaded code */ 133*219b2ee8SDavid du Colombier if (get4(cormap, adrval, (long*)&sp) < 0 || 134*219b2ee8SDavid du Colombier get4(cormap, adrval+4, (long*)&pc) < 0) 135*219b2ee8SDavid du Colombier error("%r"); 136*219b2ee8SDavid du Colombier } else { 137*219b2ee8SDavid du Colombier sp = rget(cormap, mach->sp); 138*219b2ee8SDavid du Colombier pc = rget(cormap, mach->pc); 139*219b2ee8SDavid du Colombier } 140*219b2ee8SDavid du Colombier if(mach->link) 141*219b2ee8SDavid du Colombier link = rget(cormap, mach->link); 142*219b2ee8SDavid du Colombier else 143*219b2ee8SDavid du Colombier link = 0; 144*219b2ee8SDavid du Colombier if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0) 145*219b2ee8SDavid du Colombier error("no stack frame"); 146*219b2ee8SDavid du Colombier } 1473e12c5d1SDavid du Colombier break; 1483e12c5d1SDavid du Colombier 1493e12c5d1SDavid du Colombier /*print externals*/ 1503e12c5d1SDavid du Colombier case 'e': 1513e12c5d1SDavid du Colombier for (i = 0; globalsym(&s, i); i++) { 152*219b2ee8SDavid du Colombier if (get4(cormap, s.value, &v) > 0) 1533e12c5d1SDavid du Colombier dprint("%s/%12t%lux\n", s.name, v); 1543e12c5d1SDavid du Colombier } 1553e12c5d1SDavid du Colombier break; 1563e12c5d1SDavid du Colombier 1573e12c5d1SDavid du Colombier /*print breakpoints*/ 1583e12c5d1SDavid du Colombier case 'b': 1593e12c5d1SDavid du Colombier case 'B': 1603e12c5d1SDavid du Colombier for (bk=bkpthead; bk; bk=bk->nxtbkpt) 1613e12c5d1SDavid du Colombier if (bk->flag) { 162*219b2ee8SDavid du Colombier symoff(buf, 512, (WORD)bk->loc, CTEXT); 163*219b2ee8SDavid du Colombier dprint(buf); 1643e12c5d1SDavid du Colombier if (bk->count != 1) 1653e12c5d1SDavid du Colombier dprint(",%d", bk->count); 1663e12c5d1SDavid du Colombier dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm); 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier break; 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier case 'M': 1713e12c5d1SDavid du Colombier fname = getfname(); 1723e12c5d1SDavid du Colombier if (machbyname(fname) == 0) 1733e12c5d1SDavid du Colombier dprint("unknown name\n");; 1743e12c5d1SDavid du Colombier break; 1753e12c5d1SDavid du Colombier default: 1763e12c5d1SDavid du Colombier error("bad `$' command"); 1773e12c5d1SDavid du Colombier } 1783e12c5d1SDavid du Colombier 1793e12c5d1SDavid du Colombier } 1803e12c5d1SDavid du Colombier 1813e12c5d1SDavid du Colombier char * 1823e12c5d1SDavid du Colombier getfname(void) 1833e12c5d1SDavid du Colombier { 1843e12c5d1SDavid du Colombier static char fname[ARB]; 1853e12c5d1SDavid du Colombier char *p; 1863e12c5d1SDavid du Colombier 1873e12c5d1SDavid du Colombier if (rdc() == EOR) { 1883e12c5d1SDavid du Colombier reread(); 1893e12c5d1SDavid du Colombier return (0); 1903e12c5d1SDavid du Colombier } 1913e12c5d1SDavid du Colombier p = fname; 1923e12c5d1SDavid du Colombier do { 1933e12c5d1SDavid du Colombier *p++ = lastc; 1943e12c5d1SDavid du Colombier if (p >= &fname[ARB-1]) 1953e12c5d1SDavid du Colombier error("filename too long"); 1963e12c5d1SDavid du Colombier } while (rdc() != EOR); 1973e12c5d1SDavid du Colombier *p = 0; 1983e12c5d1SDavid du Colombier reread(); 1993e12c5d1SDavid du Colombier return (fname); 2003e12c5d1SDavid du Colombier } 2013e12c5d1SDavid du Colombier 202*219b2ee8SDavid du Colombier static void 203*219b2ee8SDavid du Colombier printfp(Map *map, int modif) 204*219b2ee8SDavid du Colombier { 205*219b2ee8SDavid du Colombier Reglist *rp; 206*219b2ee8SDavid du Colombier int i; 207*219b2ee8SDavid du Colombier int ret; 208*219b2ee8SDavid du Colombier char buf[512]; 209*219b2ee8SDavid du Colombier 210*219b2ee8SDavid du Colombier for (i = 0, rp = mach->reglist; rp->rname; rp += ret) { 211*219b2ee8SDavid du Colombier ret = 1; 212*219b2ee8SDavid du Colombier if (!(rp->rflags&RFLT)) 213*219b2ee8SDavid du Colombier continue; 214*219b2ee8SDavid du Colombier ret = fpformat(map, rp, buf, sizeof(buf), modif); 215*219b2ee8SDavid du Colombier if (ret < 0) { 216*219b2ee8SDavid du Colombier werrstr("Register %s: %r", rp->rname); 217*219b2ee8SDavid du Colombier error("%r"); 218*219b2ee8SDavid du Colombier } 219*219b2ee8SDavid du Colombier /* double column print */ 220*219b2ee8SDavid du Colombier if (i&0x01) 221*219b2ee8SDavid du Colombier dprint("%40t%-8s%-12s\n", rp->rname, buf); 222*219b2ee8SDavid du Colombier else 223*219b2ee8SDavid du Colombier dprint("\t%-8s%-12s", rp->rname, buf); 224*219b2ee8SDavid du Colombier i++; 225*219b2ee8SDavid du Colombier } 226*219b2ee8SDavid du Colombier } 227*219b2ee8SDavid du Colombier 2283e12c5d1SDavid du Colombier void 2293e12c5d1SDavid du Colombier redirin(int stack, char *file) 2303e12c5d1SDavid du Colombier { 2313e12c5d1SDavid du Colombier char pfile[ARB]; 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier if (file == 0) { 2343e12c5d1SDavid du Colombier iclose(-1, 0); 2353e12c5d1SDavid du Colombier return; 2363e12c5d1SDavid du Colombier } 2373e12c5d1SDavid du Colombier iclose(stack, 0); 2383e12c5d1SDavid du Colombier if ((infile = open(file, 0)) < 0) { 2393e12c5d1SDavid du Colombier strcpy(pfile, Ipath); 2403e12c5d1SDavid du Colombier strcat(pfile, "/"); 2413e12c5d1SDavid du Colombier strcat(pfile, file); 2423e12c5d1SDavid du Colombier if ((infile = open(pfile, 0)) < 0) { 2433e12c5d1SDavid du Colombier infile = STDIN; 2443e12c5d1SDavid du Colombier error("cannot open"); 2453e12c5d1SDavid du Colombier } 2463e12c5d1SDavid du Colombier } 2473e12c5d1SDavid du Colombier } 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier void 250*219b2ee8SDavid du Colombier printmap(char *s, Map *map) 2513e12c5d1SDavid du Colombier { 252*219b2ee8SDavid du Colombier int i; 253*219b2ee8SDavid du Colombier 254*219b2ee8SDavid du Colombier if (!map) 255*219b2ee8SDavid du Colombier return; 256*219b2ee8SDavid du Colombier if (map == symmap) 2573e12c5d1SDavid du Colombier dprint("%s%12t`%s'\n", s, fsym < 0 ? "-" : symfil); 258*219b2ee8SDavid du Colombier else if (map == cormap) 2593e12c5d1SDavid du Colombier dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil); 2603e12c5d1SDavid du Colombier else 2613e12c5d1SDavid du Colombier dprint("%s\n", s); 262*219b2ee8SDavid du Colombier for (i = 0; i < map->nsegs; i++) { 263*219b2ee8SDavid du Colombier if (map->seg[i].inuse) 264*219b2ee8SDavid du Colombier dprint("%s%8t%-16lux %-16lux %-16lux\n", map->seg[i].name, 265*219b2ee8SDavid du Colombier map->seg[i].b, map->seg[i].e, map->seg[i].f); 266*219b2ee8SDavid du Colombier } 2673e12c5d1SDavid du Colombier } 2683e12c5d1SDavid du Colombier 2693e12c5d1SDavid du Colombier /* 2703e12c5d1SDavid du Colombier * dump the raw symbol table 2713e12c5d1SDavid du Colombier */ 2723e12c5d1SDavid du Colombier void 2733e12c5d1SDavid du Colombier printsym(void) 2743e12c5d1SDavid du Colombier { 2753e12c5d1SDavid du Colombier int i; 2763e12c5d1SDavid du Colombier Sym *sp; 2773e12c5d1SDavid du Colombier 2783e12c5d1SDavid du Colombier for (i = 0; sp = getsym(i); i++) { 2793e12c5d1SDavid du Colombier switch(sp->type) { 2803e12c5d1SDavid du Colombier case 't': 2813e12c5d1SDavid du Colombier case 'l': 2823e12c5d1SDavid du Colombier dprint("%8lux t %s\n", sp->value, sp->name); 2833e12c5d1SDavid du Colombier break; 2843e12c5d1SDavid du Colombier case 'T': 2853e12c5d1SDavid du Colombier case 'L': 2863e12c5d1SDavid du Colombier dprint("%8lux T %s\n", sp->value, sp->name); 2873e12c5d1SDavid du Colombier break; 2883e12c5d1SDavid du Colombier case 'D': 2893e12c5d1SDavid du Colombier case 'd': 2903e12c5d1SDavid du Colombier case 'B': 2913e12c5d1SDavid du Colombier case 'b': 2923e12c5d1SDavid du Colombier case 'a': 2933e12c5d1SDavid du Colombier case 'p': 2943e12c5d1SDavid du Colombier case 'm': 2953e12c5d1SDavid du Colombier dprint("%8lux %c %s\n", sp->value, sp->type, sp->name); 2963e12c5d1SDavid du Colombier break; 2973e12c5d1SDavid du Colombier default: 2983e12c5d1SDavid du Colombier break; 2993e12c5d1SDavid du Colombier } 3003e12c5d1SDavid du Colombier } 3013e12c5d1SDavid du Colombier } 3023e12c5d1SDavid du Colombier 3033e12c5d1SDavid du Colombier #define STRINGSZ 128 3043e12c5d1SDavid du Colombier 3053e12c5d1SDavid du Colombier /* 3063e12c5d1SDavid du Colombier * print the value of dot as file:line 3073e12c5d1SDavid du Colombier */ 3083e12c5d1SDavid du Colombier void 3093e12c5d1SDavid du Colombier printsource(long dot) 3103e12c5d1SDavid du Colombier { 3113e12c5d1SDavid du Colombier char str[STRINGSZ]; 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier if (fileline(str, STRINGSZ, dot)) 3143e12c5d1SDavid du Colombier dprint("%s", str); 3153e12c5d1SDavid du Colombier } 3163e12c5d1SDavid du Colombier 3173e12c5d1SDavid du Colombier void 3183e12c5d1SDavid du Colombier printpc(void) 3193e12c5d1SDavid du Colombier { 320*219b2ee8SDavid du Colombier char buf[512]; 321*219b2ee8SDavid du Colombier 322*219b2ee8SDavid du Colombier dot = (ulong)rget(cormap, mach->pc); 3233e12c5d1SDavid du Colombier if(dot){ 324*219b2ee8SDavid du Colombier printsource((long)dot); 3253e12c5d1SDavid du Colombier printc(' '); 326*219b2ee8SDavid du Colombier symoff(buf, sizeof(buf), (long)dot, CTEXT); 327*219b2ee8SDavid du Colombier dprint("%s?", buf); 328*219b2ee8SDavid du Colombier if (machdata->das(symmap, dot, 'i', buf, sizeof(buf)) < 0) 329*219b2ee8SDavid du Colombier error("%r"); 330*219b2ee8SDavid du Colombier dprint("%16t%s\n", buf); 3313e12c5d1SDavid du Colombier } 3323e12c5d1SDavid du Colombier } 3333e12c5d1SDavid du Colombier 3343e12c5d1SDavid du Colombier void 3353e12c5d1SDavid du Colombier printlocals(Symbol *fn, ADDR fp) 3363e12c5d1SDavid du Colombier { 3373e12c5d1SDavid du Colombier int i; 338*219b2ee8SDavid du Colombier long val; 3393e12c5d1SDavid du Colombier Symbol s; 3403e12c5d1SDavid du Colombier 3413e12c5d1SDavid du Colombier s = *fn; 3423e12c5d1SDavid du Colombier for (i = 0; localsym(&s, i); i++) { 3433e12c5d1SDavid du Colombier if (s.class != CAUTO) 3443e12c5d1SDavid du Colombier continue; 345*219b2ee8SDavid du Colombier if (get4(cormap, fp-s.value, &val) > 0) 3463e12c5d1SDavid du Colombier dprint("%8t%s.%s/%10t%lux\n", fn->name, s.name, val); 347*219b2ee8SDavid du Colombier else 3483e12c5d1SDavid du Colombier dprint("%8t%s.%s/%10t?\n", fn->name, s.name); 3493e12c5d1SDavid du Colombier } 3503e12c5d1SDavid du Colombier } 3513e12c5d1SDavid du Colombier 3523e12c5d1SDavid du Colombier void 353*219b2ee8SDavid du Colombier printparams(Symbol *fn, ulong fp) 3543e12c5d1SDavid du Colombier { 3553e12c5d1SDavid du Colombier int i; 3563e12c5d1SDavid du Colombier Symbol s; 3573e12c5d1SDavid du Colombier long v; 3583e12c5d1SDavid du Colombier int first = 0; 3593e12c5d1SDavid du Colombier 360*219b2ee8SDavid du Colombier fp += mach->szaddr; /* skip saved pc */ 3613e12c5d1SDavid du Colombier s = *fn; 3623e12c5d1SDavid du Colombier for (i = 0; localsym(&s, i); i++) { 3633e12c5d1SDavid du Colombier if (s.class != CPARAM) 3643e12c5d1SDavid du Colombier continue; 365*219b2ee8SDavid du Colombier if (get4(cormap, fp+s.value, &v) > 0) { 3663e12c5d1SDavid du Colombier if (first++) 3673e12c5d1SDavid du Colombier dprint(", "); 3683e12c5d1SDavid du Colombier dprint("%s=%lux", s.name, v); 3693e12c5d1SDavid du Colombier } 3703e12c5d1SDavid du Colombier } 371*219b2ee8SDavid du Colombier } 372