plan9fox/sys/src/cmd/qi/symbols.c
2011-03-30 19:35:09 +03:00

98 lines
1.7 KiB
C

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#define Extern extern
#include "power.h"
#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"
void
stktrace(int modif)
{
ulong pc, sp;
Symbol s, f;
int i;
char buf[512];
pc = reg.pc;
sp = reg.r[1];
i = 0;
while (findsym(pc, CTEXT, &s)) {
if(strcmp(STARTSYM, s.name) == 0) {
Bprint(bioout, "%s() at #%llux\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.lr;
else pc = getmem_4(sp);
sp += f.value;
Bprint(bioout, "%s(", s.name);
printparams(&s, sp);
printsource(s.value);
Bprint(bioout, " called from ");
symoff(buf, sizeof(buf), pc-4, CTEXT);
Bprint(bioout, buf);
printsource(pc-8);
Bprint(bioout, "\n");
if(modif == 'C')
printlocals(&s, sp);
if(++i > 40){
Bprint(bioout, "(trace truncated)\n");
break;
}
}
}