summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vi/symbols.c
blob: e3f885352cd2bd659944cb84fa67be43cc6de149 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#define Extern extern
#include "mips.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[29];
	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.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 ");
		symoff(buf, sizeof(buf), pc-8, 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;
		}
	}
}