#include #include #include #include #define Extern extern #include "mips.h" /* * Print value v as name[+offset] and then the string s. */ void psymoff(ulong v, int type, char *str) { Symbol s; int t; int r; int delta; switch(type) { case SEGREGS: Bprint(bioout, "%%#%lux", v); Bprint(bioout, str); return; case SEGANY: t = CANY; break; case SEGDATA: t = CDATA; break; case SEGTEXT: t = CTEXT; break; case SEGNONE: default: return; } r = 0; delta = 0x1000; if (v) { r = findsym(v, t, &s); if (r) delta = v-s.value; } if (v == 0 || r == 0 || delta >= 0x1000) Bprint(bioout, "#%lux", v); else { Bprint(bioout, "%s", s.name); if (delta) Bprint(bioout, "+#%lux", delta); } Bprint(bioout, str); } #define STRINGSZ 128 /* * print the value of dot as file:line */ void printsource(long dot) { char str[STRINGSZ]; if (fileline(str, STRINGSZ, dot)) Bprint(bioout, "%s", str); } void printlocals(Symbol *fn, ulong fp) { int i; Symbol s; s = *fn; for (i = 0; localsym(&s, i); i++) { if (s.class != CAUTO) continue; Bprint(bioout, "\t%s=#%lux\n", s.name, getmem_4(fp-s.value)); } } void printparams(Symbol *fn, ulong fp) { int i; Symbol s; int first; fp += mach->szreg; /* skip saved pc */ s = *fn; for (first = i = 0; localsym(&s, i); i++) { if (s.class != CPARAM) continue; if (first++) Bprint(bioout, ", "); Bprint(bioout, "%s=#%lux", s.name, getmem_4(fp+s.value)); } Bprint(bioout, ") "); } #define STARTSYM "_main" #define FRAMENAME ".frame" ulong findframe(ulong addr) { ulong pc, fp; Symbol s, f; pc = reg.pc; fp = reg.r[29]; while (findsym(pc, CTEXT, &s)) { if (strcmp(STARTSYM, s.name) == 0) break; if (findlocal(&s, FRAMENAME, &f) == 0) break; fp += f.value; if (s.value == addr) return fp; if (s.type == 'L' || s.type == 'l') pc = reg.r[31]; else pc = getmem_4(fp-f.value); } return 0; } void stktrace(int modif) { ulong pc, sp; Symbol s, f; int i; pc = reg.pc; sp = reg.r[29]; i = 0; while (findsym(pc, CTEXT, &s)) { if(strcmp(STARTSYM, s.name) == 0) { Bprint(bioout, "%s() at #%lux\n", s.name, s.value); break; } if (pc == s.value) /* at first instruction */ f.value = 0; else if (findlocal(&s, FRAMENAME, &f) == 0) break; if (s.type == 'L' || s.type == 'l' || pc <= s.value+4) pc = reg.r[31]; else pc = getmem_4(sp); sp += f.value; Bprint(bioout, "%s(", s.name); printparams(&s, sp); printsource(s.value); Bprint(bioout, " called from "); psymoff(pc-8, SEGTEXT, " "); printsource(pc-8); Bprint(bioout, "\n"); if(modif == 'C') printlocals(&s, sp); if(++i > 40){ Bprint(bioout, "(trace truncated)\n"); break; } } }