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
133e12c5d1SDavid du Colombier /* general printing routines ($) */
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier char *Ipath = INCDIR;
16219b2ee8SDavid du Colombier static int tracetype;
17219b2ee8SDavid du Colombier static void printfp(Map*, int);
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier /*
20219b2ee8SDavid du Colombier * callback on stack trace
21219b2ee8SDavid du Colombier */
22219b2ee8SDavid du Colombier static void
ptrace(Map * map,uvlong pc,uvlong sp,Symbol * sym)23*4de34a7eSDavid du Colombier ptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
24219b2ee8SDavid du Colombier {
25219b2ee8SDavid du Colombier char buf[512];
26219b2ee8SDavid du Colombier
27219b2ee8SDavid du Colombier USED(map);
28219b2ee8SDavid du Colombier dprint("%s(", sym->name);
29219b2ee8SDavid du Colombier printparams(sym, sp);
30219b2ee8SDavid du Colombier dprint(") ");
31219b2ee8SDavid du Colombier printsource(sym->value);
32219b2ee8SDavid du Colombier dprint(" called from ");
33219b2ee8SDavid du Colombier symoff(buf, 512, pc, CTEXT);
34219b2ee8SDavid du Colombier dprint("%s ", buf);
35219b2ee8SDavid du Colombier printsource(pc);
36219b2ee8SDavid du Colombier dprint("\n");
37219b2ee8SDavid du Colombier if(tracetype == 'C')
38219b2ee8SDavid du Colombier printlocals(sym, sp);
39219b2ee8SDavid du Colombier }
403e12c5d1SDavid du Colombier
413e12c5d1SDavid du Colombier void
printtrace(int modif)423e12c5d1SDavid du Colombier printtrace(int modif)
433e12c5d1SDavid du Colombier {
443e12c5d1SDavid du Colombier int i;
45*4de34a7eSDavid du Colombier uvlong pc, sp, link;
46*4de34a7eSDavid du Colombier ulong w;
473e12c5d1SDavid du Colombier BKPT *bk;
483e12c5d1SDavid du Colombier Symbol s;
493e12c5d1SDavid du Colombier int stack;
503e12c5d1SDavid du Colombier char *fname;
51219b2ee8SDavid du Colombier char buf[512];
523e12c5d1SDavid du Colombier
533e12c5d1SDavid du Colombier if (cntflg==0)
543e12c5d1SDavid du Colombier cntval = -1;
553e12c5d1SDavid du Colombier switch (modif) {
563e12c5d1SDavid du Colombier
573e12c5d1SDavid du Colombier case '<':
583e12c5d1SDavid du Colombier if (cntval == 0) {
593e12c5d1SDavid du Colombier while (readchar() != EOR)
603e12c5d1SDavid du Colombier ;
613e12c5d1SDavid du Colombier reread();
623e12c5d1SDavid du Colombier break;
633e12c5d1SDavid du Colombier }
643e12c5d1SDavid du Colombier if (rdc() == '<')
653e12c5d1SDavid du Colombier stack = 1;
663e12c5d1SDavid du Colombier else {
673e12c5d1SDavid du Colombier stack = 0;
683e12c5d1SDavid du Colombier reread();
693e12c5d1SDavid du Colombier }
703e12c5d1SDavid du Colombier fname = getfname();
713e12c5d1SDavid du Colombier redirin(stack, fname);
723e12c5d1SDavid du Colombier break;
733e12c5d1SDavid du Colombier
743e12c5d1SDavid du Colombier case '>':
753e12c5d1SDavid du Colombier fname = getfname();
763e12c5d1SDavid du Colombier redirout(fname);
773e12c5d1SDavid du Colombier break;
783e12c5d1SDavid du Colombier
793e12c5d1SDavid du Colombier case 'a':
807dd7cddfSDavid du Colombier attachprocess();
813e12c5d1SDavid du Colombier break;
823e12c5d1SDavid du Colombier
833e12c5d1SDavid du Colombier case 'k':
843e12c5d1SDavid du Colombier kmsys();
853e12c5d1SDavid du Colombier break;
863e12c5d1SDavid du Colombier
873e12c5d1SDavid du Colombier case 'q':
883e12c5d1SDavid du Colombier case 'Q':
893e12c5d1SDavid du Colombier done();
903e12c5d1SDavid du Colombier
913e12c5d1SDavid du Colombier case 'w':
923e12c5d1SDavid du Colombier maxpos=(adrflg?adrval:MAXPOS);
933e12c5d1SDavid du Colombier break;
943e12c5d1SDavid du Colombier
953e12c5d1SDavid du Colombier case 'S':
963e12c5d1SDavid du Colombier printsym();
973e12c5d1SDavid du Colombier break;
983e12c5d1SDavid du Colombier
993e12c5d1SDavid du Colombier case 's':
1003e12c5d1SDavid du Colombier maxoff=(adrflg?adrval:MAXOFF);
1013e12c5d1SDavid du Colombier break;
1023e12c5d1SDavid du Colombier
1033e12c5d1SDavid du Colombier case 'm':
1043e12c5d1SDavid du Colombier printmap("? map", symmap);
1053e12c5d1SDavid du Colombier printmap("/ map", cormap);
1063e12c5d1SDavid du Colombier break;
1073e12c5d1SDavid du Colombier
1083e12c5d1SDavid du Colombier case 0:
1093e12c5d1SDavid du Colombier case '?':
1103e12c5d1SDavid du Colombier if (pid)
1113e12c5d1SDavid du Colombier dprint("pid = %d\n",pid);
1123e12c5d1SDavid du Colombier else
1133e12c5d1SDavid du Colombier prints("no process\n");
1143e12c5d1SDavid du Colombier flushbuf();
1153e12c5d1SDavid du Colombier
1163e12c5d1SDavid du Colombier case 'r':
1173e12c5d1SDavid du Colombier case 'R':
1183e12c5d1SDavid du Colombier printregs(modif);
1193e12c5d1SDavid du Colombier return;
1203e12c5d1SDavid du Colombier
1213e12c5d1SDavid du Colombier case 'f':
1223e12c5d1SDavid du Colombier case 'F':
123219b2ee8SDavid du Colombier printfp(cormap, modif);
1243e12c5d1SDavid du Colombier return;
1253e12c5d1SDavid du Colombier
1263e12c5d1SDavid du Colombier case 'c':
1273e12c5d1SDavid du Colombier case 'C':
128219b2ee8SDavid du Colombier tracetype = modif;
129219b2ee8SDavid du Colombier if (machdata->ctrace) {
130*4de34a7eSDavid du Colombier if (adrflg) {
131*4de34a7eSDavid du Colombier /*
132*4de34a7eSDavid du Colombier * trace from jmpbuf for multi-threaded code.
133*4de34a7eSDavid du Colombier * assume sp and pc are in adjacent locations
134*4de34a7eSDavid du Colombier * and mach->szaddr in size.
135*4de34a7eSDavid du Colombier */
136*4de34a7eSDavid du Colombier if (geta(cormap, adrval, &sp) < 0 ||
137*4de34a7eSDavid du Colombier geta(cormap, adrval+mach->szaddr, &pc) < 0)
138219b2ee8SDavid du Colombier error("%r");
139219b2ee8SDavid du Colombier } else {
140219b2ee8SDavid du Colombier sp = rget(cormap, mach->sp);
141219b2ee8SDavid du Colombier pc = rget(cormap, mach->pc);
142219b2ee8SDavid du Colombier }
143219b2ee8SDavid du Colombier if(mach->link)
144219b2ee8SDavid du Colombier link = rget(cormap, mach->link);
145219b2ee8SDavid du Colombier else
146219b2ee8SDavid du Colombier link = 0;
147219b2ee8SDavid du Colombier if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0)
148219b2ee8SDavid du Colombier error("no stack frame");
149219b2ee8SDavid du Colombier }
1503e12c5d1SDavid du Colombier break;
1513e12c5d1SDavid du Colombier
1523e12c5d1SDavid du Colombier /*print externals*/
1533e12c5d1SDavid du Colombier case 'e':
1543e12c5d1SDavid du Colombier for (i = 0; globalsym(&s, i); i++) {
155*4de34a7eSDavid du Colombier if (get4(cormap, s.value, &w) > 0)
156*4de34a7eSDavid du Colombier dprint("%s/%12t%#lux\n", s.name, w);
1573e12c5d1SDavid du Colombier }
1583e12c5d1SDavid du Colombier break;
1593e12c5d1SDavid du Colombier
1603e12c5d1SDavid du Colombier /*print breakpoints*/
1613e12c5d1SDavid du Colombier case 'b':
1623e12c5d1SDavid du Colombier case 'B':
1633e12c5d1SDavid du Colombier for (bk=bkpthead; bk; bk=bk->nxtbkpt)
1643e12c5d1SDavid du Colombier if (bk->flag) {
165219b2ee8SDavid du Colombier symoff(buf, 512, (WORD)bk->loc, CTEXT);
166219b2ee8SDavid du Colombier dprint(buf);
1673e12c5d1SDavid du Colombier if (bk->count != 1)
1683e12c5d1SDavid du Colombier dprint(",%d", bk->count);
1693e12c5d1SDavid du Colombier dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier break;
1723e12c5d1SDavid du Colombier
1733e12c5d1SDavid du Colombier case 'M':
1743e12c5d1SDavid du Colombier fname = getfname();
1753e12c5d1SDavid du Colombier if (machbyname(fname) == 0)
1763e12c5d1SDavid du Colombier dprint("unknown name\n");;
1773e12c5d1SDavid du Colombier break;
1783e12c5d1SDavid du Colombier default:
1793e12c5d1SDavid du Colombier error("bad `$' command");
1803e12c5d1SDavid du Colombier }
1813e12c5d1SDavid du Colombier
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier
1843e12c5d1SDavid du Colombier char *
getfname(void)1853e12c5d1SDavid du Colombier getfname(void)
1863e12c5d1SDavid du Colombier {
1873e12c5d1SDavid du Colombier static char fname[ARB];
1883e12c5d1SDavid du Colombier char *p;
1893e12c5d1SDavid du Colombier
1903e12c5d1SDavid du Colombier if (rdc() == EOR) {
1913e12c5d1SDavid du Colombier reread();
1923e12c5d1SDavid du Colombier return (0);
1933e12c5d1SDavid du Colombier }
1943e12c5d1SDavid du Colombier p = fname;
1953e12c5d1SDavid du Colombier do {
1963e12c5d1SDavid du Colombier *p++ = lastc;
1973e12c5d1SDavid du Colombier if (p >= &fname[ARB-1])
1983e12c5d1SDavid du Colombier error("filename too long");
1993e12c5d1SDavid du Colombier } while (rdc() != EOR);
2003e12c5d1SDavid du Colombier *p = 0;
2013e12c5d1SDavid du Colombier reread();
2023e12c5d1SDavid du Colombier return (fname);
2033e12c5d1SDavid du Colombier }
2043e12c5d1SDavid du Colombier
205219b2ee8SDavid du Colombier static void
printfp(Map * map,int modif)206219b2ee8SDavid du Colombier printfp(Map *map, int modif)
207219b2ee8SDavid du Colombier {
208219b2ee8SDavid du Colombier Reglist *rp;
209219b2ee8SDavid du Colombier int i;
210219b2ee8SDavid du Colombier int ret;
211219b2ee8SDavid du Colombier char buf[512];
212219b2ee8SDavid du Colombier
213219b2ee8SDavid du Colombier for (i = 0, rp = mach->reglist; rp->rname; rp += ret) {
214219b2ee8SDavid du Colombier ret = 1;
215219b2ee8SDavid du Colombier if (!(rp->rflags&RFLT))
216219b2ee8SDavid du Colombier continue;
217219b2ee8SDavid du Colombier ret = fpformat(map, rp, buf, sizeof(buf), modif);
218219b2ee8SDavid du Colombier if (ret < 0) {
219219b2ee8SDavid du Colombier werrstr("Register %s: %r", rp->rname);
220219b2ee8SDavid du Colombier error("%r");
221219b2ee8SDavid du Colombier }
222219b2ee8SDavid du Colombier /* double column print */
223219b2ee8SDavid du Colombier if (i&0x01)
224219b2ee8SDavid du Colombier dprint("%40t%-8s%-12s\n", rp->rname, buf);
225219b2ee8SDavid du Colombier else
226219b2ee8SDavid du Colombier dprint("\t%-8s%-12s", rp->rname, buf);
227219b2ee8SDavid du Colombier i++;
228219b2ee8SDavid du Colombier }
229219b2ee8SDavid du Colombier }
230219b2ee8SDavid du Colombier
2313e12c5d1SDavid du Colombier void
redirin(int stack,char * file)2323e12c5d1SDavid du Colombier redirin(int stack, char *file)
2333e12c5d1SDavid du Colombier {
234*4de34a7eSDavid du Colombier char *pfile;
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier if (file == 0) {
2373e12c5d1SDavid du Colombier iclose(-1, 0);
2383e12c5d1SDavid du Colombier return;
2393e12c5d1SDavid du Colombier }
2403e12c5d1SDavid du Colombier iclose(stack, 0);
2413e12c5d1SDavid du Colombier if ((infile = open(file, 0)) < 0) {
242*4de34a7eSDavid du Colombier pfile = smprint("%s/%s", Ipath, file);
243*4de34a7eSDavid du Colombier infile = open(pfile, 0);
244*4de34a7eSDavid du Colombier free(pfile);
245*4de34a7eSDavid du Colombier if(infile < 0) {
2463e12c5d1SDavid du Colombier infile = STDIN;
2473e12c5d1SDavid du Colombier error("cannot open");
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier }
2503e12c5d1SDavid du Colombier }
2513e12c5d1SDavid du Colombier
2523e12c5d1SDavid du Colombier void
printmap(char * s,Map * map)253219b2ee8SDavid du Colombier printmap(char *s, Map *map)
2543e12c5d1SDavid du Colombier {
255219b2ee8SDavid du Colombier int i;
256219b2ee8SDavid du Colombier
257219b2ee8SDavid du Colombier if (!map)
258219b2ee8SDavid du Colombier return;
259219b2ee8SDavid du Colombier if (map == symmap)
2603e12c5d1SDavid du Colombier dprint("%s%12t`%s'\n", s, fsym < 0 ? "-" : symfil);
261219b2ee8SDavid du Colombier else if (map == cormap)
2623e12c5d1SDavid du Colombier dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil);
2633e12c5d1SDavid du Colombier else
2643e12c5d1SDavid du Colombier dprint("%s\n", s);
265219b2ee8SDavid du Colombier for (i = 0; i < map->nsegs; i++) {
266219b2ee8SDavid du Colombier if (map->seg[i].inuse)
267*4de34a7eSDavid du Colombier dprint("%s%8t%-16#llux %-16#llux %-16#llux\n",
268*4de34a7eSDavid du Colombier map->seg[i].name, map->seg[i].b,
269*4de34a7eSDavid du Colombier map->seg[i].e, map->seg[i].f);
270219b2ee8SDavid du Colombier }
2713e12c5d1SDavid du Colombier }
2723e12c5d1SDavid du Colombier
2733e12c5d1SDavid du Colombier /*
2743e12c5d1SDavid du Colombier * dump the raw symbol table
2753e12c5d1SDavid du Colombier */
2763e12c5d1SDavid du Colombier void
printsym(void)2773e12c5d1SDavid du Colombier printsym(void)
2783e12c5d1SDavid du Colombier {
2793e12c5d1SDavid du Colombier int i;
2803e12c5d1SDavid du Colombier Sym *sp;
2813e12c5d1SDavid du Colombier
2823e12c5d1SDavid du Colombier for (i = 0; sp = getsym(i); i++) {
2833e12c5d1SDavid du Colombier switch(sp->type) {
2843e12c5d1SDavid du Colombier case 't':
2853e12c5d1SDavid du Colombier case 'l':
286*4de34a7eSDavid du Colombier dprint("%16#llux t %s\n", sp->value, sp->name);
2873e12c5d1SDavid du Colombier break;
2883e12c5d1SDavid du Colombier case 'T':
2893e12c5d1SDavid du Colombier case 'L':
290*4de34a7eSDavid du Colombier dprint("%16#llux T %s\n", sp->value, sp->name);
2913e12c5d1SDavid du Colombier break;
2923e12c5d1SDavid du Colombier case 'D':
2933e12c5d1SDavid du Colombier case 'd':
2943e12c5d1SDavid du Colombier case 'B':
2953e12c5d1SDavid du Colombier case 'b':
2963e12c5d1SDavid du Colombier case 'a':
2973e12c5d1SDavid du Colombier case 'p':
2983e12c5d1SDavid du Colombier case 'm':
299*4de34a7eSDavid du Colombier dprint("%16#llux %c %s\n", sp->value, sp->type, sp->name);
3003e12c5d1SDavid du Colombier break;
3013e12c5d1SDavid du Colombier default:
3023e12c5d1SDavid du Colombier break;
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier }
3053e12c5d1SDavid du Colombier }
3063e12c5d1SDavid du Colombier
3073e12c5d1SDavid du Colombier #define STRINGSZ 128
3083e12c5d1SDavid du Colombier
3093e12c5d1SDavid du Colombier /*
3103e12c5d1SDavid du Colombier * print the value of dot as file:line
3113e12c5d1SDavid du Colombier */
3123e12c5d1SDavid du Colombier void
printsource(ADDR dot)313*4de34a7eSDavid du Colombier printsource(ADDR dot)
3143e12c5d1SDavid du Colombier {
3153e12c5d1SDavid du Colombier char str[STRINGSZ];
3163e12c5d1SDavid du Colombier
3173e12c5d1SDavid du Colombier if (fileline(str, STRINGSZ, dot))
3183e12c5d1SDavid du Colombier dprint("%s", str);
3193e12c5d1SDavid du Colombier }
3203e12c5d1SDavid du Colombier
3213e12c5d1SDavid du Colombier void
printpc(void)3223e12c5d1SDavid du Colombier printpc(void)
3233e12c5d1SDavid du Colombier {
324219b2ee8SDavid du Colombier char buf[512];
325219b2ee8SDavid du Colombier
326*4de34a7eSDavid du Colombier dot = rget(cormap, mach->pc);
3273e12c5d1SDavid du Colombier if(dot){
328219b2ee8SDavid du Colombier printsource((long)dot);
3293e12c5d1SDavid du Colombier printc(' ');
330219b2ee8SDavid du Colombier symoff(buf, sizeof(buf), (long)dot, CTEXT);
3317dd7cddfSDavid du Colombier dprint("%s/", buf);
3327dd7cddfSDavid du Colombier if (machdata->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
333219b2ee8SDavid du Colombier error("%r");
334219b2ee8SDavid du Colombier dprint("%16t%s\n", buf);
3353e12c5d1SDavid du Colombier }
3363e12c5d1SDavid du Colombier }
3373e12c5d1SDavid du Colombier
3383e12c5d1SDavid du Colombier void
printlocals(Symbol * fn,ADDR fp)3393e12c5d1SDavid du Colombier printlocals(Symbol *fn, ADDR fp)
3403e12c5d1SDavid du Colombier {
3413e12c5d1SDavid du Colombier int i;
342*4de34a7eSDavid du Colombier ulong w;
3433e12c5d1SDavid du Colombier Symbol s;
3443e12c5d1SDavid du Colombier
3453e12c5d1SDavid du Colombier s = *fn;
3463e12c5d1SDavid du Colombier for (i = 0; localsym(&s, i); i++) {
3473e12c5d1SDavid du Colombier if (s.class != CAUTO)
3483e12c5d1SDavid du Colombier continue;
349*4de34a7eSDavid du Colombier if (get4(cormap, fp-s.value, &w) > 0)
350*4de34a7eSDavid du Colombier dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, w);
351219b2ee8SDavid du Colombier else
3523e12c5d1SDavid du Colombier dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
3533e12c5d1SDavid du Colombier }
3543e12c5d1SDavid du Colombier }
3553e12c5d1SDavid du Colombier
3563e12c5d1SDavid du Colombier void
printparams(Symbol * fn,ADDR fp)3577dd7cddfSDavid du Colombier printparams(Symbol *fn, ADDR fp)
3583e12c5d1SDavid du Colombier {
3593e12c5d1SDavid du Colombier int i;
3603e12c5d1SDavid du Colombier Symbol s;
361*4de34a7eSDavid du Colombier ulong w;
3623e12c5d1SDavid du Colombier int first = 0;
3633e12c5d1SDavid du Colombier
364219b2ee8SDavid du Colombier fp += mach->szaddr; /* skip saved pc */
3653e12c5d1SDavid du Colombier s = *fn;
3663e12c5d1SDavid du Colombier for (i = 0; localsym(&s, i); i++) {
3673e12c5d1SDavid du Colombier if (s.class != CPARAM)
3683e12c5d1SDavid du Colombier continue;
3693e12c5d1SDavid du Colombier if (first++)
3703e12c5d1SDavid du Colombier dprint(", ");
371*4de34a7eSDavid du Colombier if (get4(cormap, fp+s.value, &w) > 0)
372*4de34a7eSDavid du Colombier dprint("%s=%#lux", s.name, w);
3733e12c5d1SDavid du Colombier }
3743e12c5d1SDavid du Colombier }
375