diff options
Diffstat (limited to 'src/cmd/db/print.c')
-rw-r--r-- | src/cmd/db/print.c | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/src/cmd/db/print.c b/src/cmd/db/print.c new file mode 100644 index 00000000..d136a78b --- /dev/null +++ b/src/cmd/db/print.c @@ -0,0 +1,406 @@ +/* + * + * debugger + * + */ +#include "defs.h" +#include "fns.h" + +extern int infile; +extern int outfile; +extern int maxpos; + +/* general printing routines ($) */ + +char *Ipath = INCDIR; +static int tracetype; +static void printfp(Map*, int); + +/* + * callback on stack trace + */ +static int +ptrace(Map *map, Regs *regs, ulong pc, ulong nextpc, Symbol *sym, int depth) +{ + char buf[512]; + + USED(map); + if(sym){ + dprint("%s(", sym->name); + printparams(sym, regs); + dprint(") "); + }else + dprint("%#lux ", pc); + printsource(pc); + + dprint(" called from "); + symoff(buf, 512, nextpc, CTEXT); + dprint("%s ", buf); +/* printsource(nextpc); */ + dprint("\n"); + if(tracetype == 'C' && sym) + printlocals(sym, regs); + return depth<40; +} + +static ulong *adrregvals; + +static int +adrrw(Regs *regs, char *name, ulong *val, int isr) +{ + int i; + + if((i = windindex(name)) == -1) + return correg->rw(correg, name, val, isr); + if(isr){ + *val = adrregvals[i]; + return 0; + } + werrstr("saved registers are immutable"); + return -1; +} + +Regs* +adrregs(void) +{ + int i; + static Regs r; + static u32int x; + + if(adrregvals== nil){ + adrregvals = malloc(mach->nwindreg*sizeof(adrregvals[0])); + if(adrregvals == nil) + error("%r"); + } + for(i=0; i<mach->nwindreg; i++){ + if(get4(cormap, adrval+4*i, &x) < 0) + error("%r"); + adrregvals[i] = x; + } + r.rw = adrrw; + return &r; +} + +void +printdollar(int modif) +{ + int i; + u32int u4; + BKPT *bk; + Symbol s; + int stack; + char *fname; + char buf[512]; + Regs *r; + + if (cntflg==0) + cntval = -1; + switch (modif) { + + case '<': + if (cntval == 0) { + while (readchar() != EOR) + ; + reread(); + break; + } + if (rdc() == '<') + stack = 1; + else { + stack = 0; + reread(); + } + fname = getfname(); + redirin(stack, fname); + break; + + case '>': + fname = getfname(); + redirout(fname); + break; + + case 'a': + attachprocess(); + break; + + case 'k': + kmsys(); + break; + + case 'q': + case 'Q': + done(); + + case 'w': + maxpos=(adrflg?adrval:MAXPOS); + break; + + case 'S': + printsym(); + break; + + case 's': + maxoff=(adrflg?adrval:MAXOFF); + break; + + case 'm': + printmap("? map", symmap); + printmap("/ map", cormap); + break; + + case 0: + case '?': + if (pid) + dprint("pid = %d\n",pid); + else + prints("no process\n"); + flushbuf(); + + case 'r': + case 'R': + printregs(modif); + return; + + case 'f': + case 'F': + printfp(cormap, modif); + return; + + case 'c': + case 'C': + tracetype = modif; + if (adrflg) + r = adrregs(); + else + r = correg; + if(stacktrace(cormap, correg, ptrace) <= 0) + error("no stack frame"); + break; + + /*print externals*/ + case 'e': + for (i = 0; indexsym(i, &s)>=0; i++) { + if (s.class==CDATA) + if (s.loc.type==LADDR) + if (get4(cormap, s.loc.addr, &u4) > 0) + dprint("%s/%12t%#lux\n", s.name, (ulong)u4); + } + break; + + /*print breakpoints*/ + case 'b': + case 'B': + for (bk=bkpthead; bk; bk=bk->nxtbkpt) + if (bk->flag) { + symoff(buf, 512, (WORD)bk->loc, CTEXT); + dprint(buf); + if (bk->count != 1) + dprint(",%d", bk->count); + dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm); + } + break; + + case 'M': + fname = getfname(); + if (machbyname(fname) == 0) + dprint("unknown name\n");; + break; + default: + error("bad `$' command"); + } + +} + +char * +getfname(void) +{ + static char fname[ARB]; + char *p; + + if (rdc() == EOR) { + reread(); + return (0); + } + p = fname; + do { + *p++ = lastc; + if (p >= &fname[ARB-1]) + error("filename too long"); + } while (rdc() != EOR); + *p = 0; + reread(); + return (fname); +} + +static void +printfp(Map *map, int modif) +{ + Regdesc *rp; + int i; + int ret; + char buf[512]; + + for (i = 0, rp = mach->reglist; rp->name; rp += ret) { + ret = 1; + if (!(rp->flags&RFLT)) + continue; + ret = fpformat(map, rp, buf, sizeof(buf), modif); + if (ret < 0) { + werrstr("Register %s: %r", rp->name); + error("%r"); + } + /* double column print */ + if (i&0x01) + dprint("%40t%-8s%-12s\n", rp->name, buf); + else + dprint("\t%-8s%-12s", rp->name, buf); + i++; + } +} + +void +redirin(int stack, char *file) +{ + char pfile[ARB]; + + if (file == 0) { + iclose(-1, 0); + return; + } + iclose(stack, 0); + if ((infile = open(file, 0)) < 0) { + strcpy(pfile, Ipath); + strcat(pfile, "/"); + strcat(pfile, file); + if ((infile = open(pfile, 0)) < 0) { + infile = STDIN; + error("cannot open"); + } + } +} + +void +printmap(char *s, Map *map) +{ + int i; + + if (!map) + return; + if (map == symmap) + dprint("%s%12t`%s'\n", s, symfil==nil ? "-" : symfil); + else if (map == cormap) + dprint("%s%12t`%s'\n", s, corfil==nil ? "-" : corfil); + else + dprint("%s\n", s); + for (i = 0; i < map->nseg; i++) { + dprint("%s%8t%-16#lux %-16#lux %-16#lux %s\n", map->seg[i].name, + map->seg[i].base, map->seg[i].base+map->seg[i].size, map->seg[i].offset, + map->seg[i].file ? map->seg[i].file : ""); + } +} + +/* + * dump the raw symbol table + */ +void +printsym(void) +{ + int i; + Symbol *sp, s; + + for (i=0; indexsym(i, &s)>=0; i++){ + sp = &s; + switch(sp->type) { + case 't': + case 'l': + dprint("%8#lux t %s\n", sp->loc.addr, sp->name); + break; + case 'T': + case 'L': + dprint("%8#lux T %s\n", sp->loc.addr, sp->name); + break; + case 'D': + case 'd': + case 'B': + case 'b': + case 'a': + case 'p': + case 'm': + dprint("%8#lux %c %s\n", sp->loc.addr, sp->type, sp->name); + break; + default: + break; + } + } +} + +#define STRINGSZ 128 + +/* + * print the value of dot as file:line + */ +void +printsource(long dot) +{ + char str[STRINGSZ]; + + if (fileline(dot, str, STRINGSZ) >= 0) + dprint("%s", str); +} + +void +printpc(void) +{ + char buf[512]; + ulong u; + + if(rget(correg, mach->pc, &u) < 0) + error("%r"); + dot = u; + if(dot){ + printsource((long)dot); + printc(' '); + symoff(buf, sizeof(buf), (long)dot, CTEXT); + dprint("%s/", buf); + if (mach->das(cormap, dot, 'i', buf, sizeof(buf)) < 0) + error("%r"); + dprint("%16t%s\n", buf); + } +} + +void +printlocals(Symbol *fn, Regs *regs) +{ + int i; + u32int v; + Symbol s; + + for (i = 0; indexlsym(fn, i, &s)>=0; i++) { + if (s.class != CAUTO) + continue; + if(lget4(cormap, correg, s.loc, &v) >= 0) + dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, v); + else + dprint("%8t%s.%s/%10t?\n", fn->name, s.name); + } +} + +void +printparams(Symbol *fn, Regs *regs) +{ + int i; + Symbol s; + u32int v; + int first = 0; + + for (i = 0; indexlsym(fn, i, &s)>=0; i++) { + if (s.class != CPARAM) + continue; + if (first++) + dprint(", "); + if(lget4(cormap, correg, s.loc, &v) >= 0) + dprint("%s=%#lux", s.name, v); + else + dprint("%s=?", s.name); + } +} |