diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/db/print.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/db/print.c')
-rwxr-xr-x | sys/src/cmd/db/print.c | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/sys/src/cmd/db/print.c b/sys/src/cmd/db/print.c new file mode 100755 index 000000000..cb7938274 --- /dev/null +++ b/sys/src/cmd/db/print.c @@ -0,0 +1,374 @@ +/* + * + * 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 void +ptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym) +{ + char buf[512]; + + USED(map); + dprint("%s(", sym->name); + printparams(sym, sp); + dprint(") "); + printsource(sym->value); + dprint(" called from "); + symoff(buf, 512, pc, CTEXT); + dprint("%s ", buf); + printsource(pc); + dprint("\n"); + if(tracetype == 'C') + printlocals(sym, sp); +} + +void +printtrace(int modif) +{ + int i; + uvlong pc, sp, link; + ulong w; + BKPT *bk; + Symbol s; + int stack; + char *fname; + char buf[512]; + + 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 (machdata->ctrace) { + if (adrflg) { + /* + * trace from jmpbuf for multi-threaded code. + * assume sp and pc are in adjacent locations + * and mach->szaddr in size. + */ + if (geta(cormap, adrval, &sp) < 0 || + geta(cormap, adrval+mach->szaddr, &pc) < 0) + error("%r"); + } else { + sp = rget(cormap, mach->sp); + pc = rget(cormap, mach->pc); + } + if(mach->link) + link = rget(cormap, mach->link); + else + link = 0; + if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0) + error("no stack frame"); + } + break; + + /*print externals*/ + case 'e': + for (i = 0; globalsym(&s, i); i++) { + if (get4(cormap, s.value, &w) > 0) + dprint("%s/%12t%#lux\n", s.name, w); + } + 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) +{ + Reglist *rp; + int i; + int ret; + char buf[512]; + + for (i = 0, rp = mach->reglist; rp->rname; rp += ret) { + ret = 1; + if (!(rp->rflags&RFLT)) + continue; + ret = fpformat(map, rp, buf, sizeof(buf), modif); + if (ret < 0) { + werrstr("Register %s: %r", rp->rname); + error("%r"); + } + /* double column print */ + if (i&0x01) + dprint("%40t%-8s%-12s\n", rp->rname, buf); + else + dprint("\t%-8s%-12s", rp->rname, buf); + i++; + } +} + +void +redirin(int stack, char *file) +{ + char *pfile; + + if (file == 0) { + iclose(-1, 0); + return; + } + iclose(stack, 0); + if ((infile = open(file, 0)) < 0) { + pfile = smprint("%s/%s", Ipath, file); + infile = open(pfile, 0); + free(pfile); + if(infile < 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, fsym < 0 ? "-" : symfil); + else if (map == cormap) + dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil); + else + dprint("%s\n", s); + for (i = 0; i < map->nsegs; i++) { + if (map->seg[i].inuse) + dprint("%s%8t%-16#llux %-16#llux %-16#llux\n", + map->seg[i].name, map->seg[i].b, + map->seg[i].e, map->seg[i].f); + } +} + +/* + * dump the raw symbol table + */ +void +printsym(void) +{ + int i; + Sym *sp; + + for (i = 0; sp = getsym(i); i++) { + switch(sp->type) { + case 't': + case 'l': + dprint("%16#llux t %s\n", sp->value, sp->name); + break; + case 'T': + case 'L': + dprint("%16#llux T %s\n", sp->value, sp->name); + break; + case 'D': + case 'd': + case 'B': + case 'b': + case 'a': + case 'p': + case 'm': + dprint("%16#llux %c %s\n", sp->value, sp->type, sp->name); + break; + default: + break; + } + } +} + +#define STRINGSZ 128 + +/* + * print the value of dot as file:line + */ +void +printsource(ADDR dot) +{ + char str[STRINGSZ]; + + if (fileline(str, STRINGSZ, dot)) + dprint("%s", str); +} + +void +printpc(void) +{ + char buf[512]; + + dot = rget(cormap, mach->pc); + if(dot){ + printsource((long)dot); + printc(' '); + symoff(buf, sizeof(buf), (long)dot, CTEXT); + dprint("%s/", buf); + if (machdata->das(cormap, dot, 'i', buf, sizeof(buf)) < 0) + error("%r"); + dprint("%16t%s\n", buf); + } +} + +void +printlocals(Symbol *fn, ADDR fp) +{ + int i; + ulong w; + Symbol s; + + s = *fn; + for (i = 0; localsym(&s, i); i++) { + if (s.class != CAUTO) + continue; + if (get4(cormap, fp-s.value, &w) > 0) + dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, w); + else + dprint("%8t%s.%s/%10t?\n", fn->name, s.name); + } +} + +void +printparams(Symbol *fn, ADDR fp) +{ + int i; + Symbol s; + ulong w; + int first = 0; + + fp += mach->szaddr; /* skip saved pc */ + s = *fn; + for (i = 0; localsym(&s, i); i++) { + if (s.class != CPARAM) + continue; + if (first++) + dprint(", "); + if (get4(cormap, fp+s.value, &w) > 0) + dprint("%s=%#lux", s.name, w); + } +} |