aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/db/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/db/print.c')
-rw-r--r--src/cmd/db/print.c406
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);
+ }
+}