Blame


1 a84cbb2a 2004-04-19 devnull #include <u.h>
2 a84cbb2a 2004-04-19 devnull #include <libc.h>
3 a84cbb2a 2004-04-19 devnull #include <bio.h>
4 a84cbb2a 2004-04-19 devnull #include <mach.h>
5 a84cbb2a 2004-04-19 devnull
6 a84cbb2a 2004-04-19 devnull typedef struct LocRegs LocRegs;
7 a84cbb2a 2004-04-19 devnull struct LocRegs
8 a84cbb2a 2004-04-19 devnull {
9 a84cbb2a 2004-04-19 devnull Regs r;
10 a84cbb2a 2004-04-19 devnull Regs *oldregs;
11 a84cbb2a 2004-04-19 devnull Map *map;
12 443d6288 2012-02-19 rsc u64int *val;
13 a84cbb2a 2004-04-19 devnull };
14 a84cbb2a 2004-04-19 devnull
15 a84cbb2a 2004-04-19 devnull static int
16 443d6288 2012-02-19 rsc locregrw(Regs *regs, char *name, u64int *val, int isr)
17 a84cbb2a 2004-04-19 devnull {
18 a84cbb2a 2004-04-19 devnull int i;
19 a84cbb2a 2004-04-19 devnull LocRegs *lr;
20 a84cbb2a 2004-04-19 devnull
21 a84cbb2a 2004-04-19 devnull lr = (LocRegs*)regs;
22 a84cbb2a 2004-04-19 devnull i = windindex(name);
23 a84cbb2a 2004-04-19 devnull if(i == -1)
24 a84cbb2a 2004-04-19 devnull return lr->oldregs->rw(lr->oldregs, name, val, isr);
25 a84cbb2a 2004-04-19 devnull if(isr){
26 a84cbb2a 2004-04-19 devnull *val = lr->val[i];
27 a84cbb2a 2004-04-19 devnull return 0;
28 a84cbb2a 2004-04-19 devnull }else{
29 a84cbb2a 2004-04-19 devnull werrstr("saved registers are immutable");
30 a84cbb2a 2004-04-19 devnull return -1;
31 a84cbb2a 2004-04-19 devnull }
32 a84cbb2a 2004-04-19 devnull }
33 a84cbb2a 2004-04-19 devnull
34 a84cbb2a 2004-04-19 devnull int
35 a84cbb2a 2004-04-19 devnull stacktrace(Map *map, Regs *regs, Tracer trace)
36 a84cbb2a 2004-04-19 devnull {
37 a84cbb2a 2004-04-19 devnull char *rname;
38 a84cbb2a 2004-04-19 devnull int i, ipc, ret;
39 443d6288 2012-02-19 rsc u64int nextpc, pc, v;
40 443d6288 2012-02-19 rsc u64int *cur, *next;
41 a84cbb2a 2004-04-19 devnull LocRegs lr;
42 a84cbb2a 2004-04-19 devnull Symbol s, *sp;
43 a84cbb2a 2004-04-19 devnull
44 a84cbb2a 2004-04-19 devnull /*
45 a84cbb2a 2004-04-19 devnull * Allocate location arrays.
46 a84cbb2a 2004-04-19 devnull */
47 a84cbb2a 2004-04-19 devnull ret = -1;
48 a84cbb2a 2004-04-19 devnull cur = malloc(mach->nwindreg*sizeof(cur[0]));
49 a84cbb2a 2004-04-19 devnull next = malloc(mach->nwindreg*sizeof(cur[0]));
50 a84cbb2a 2004-04-19 devnull if(cur==nil || next==nil)
51 a84cbb2a 2004-04-19 devnull goto out;
52 fa325e9b 2020-01-10 cross
53 a84cbb2a 2004-04-19 devnull /*
54 a84cbb2a 2004-04-19 devnull * Initialize current registers using regs.
55 a84cbb2a 2004-04-19 devnull */
56 a84cbb2a 2004-04-19 devnull if(rget(regs, mach->pc, &pc) < 0){
57 a84cbb2a 2004-04-19 devnull werrstr("cannot fetch initial pc: %r");
58 fa325e9b 2020-01-10 cross goto out;
59 a84cbb2a 2004-04-19 devnull }
60 a84cbb2a 2004-04-19 devnull
61 a84cbb2a 2004-04-19 devnull for(i=0; i<mach->nwindreg; i++){
62 a84cbb2a 2004-04-19 devnull rname = mach->windreg[i];
63 a84cbb2a 2004-04-19 devnull if(rget(regs, rname, &v) < 0)
64 a84cbb2a 2004-04-19 devnull v = ~(ulong)0;
65 a84cbb2a 2004-04-19 devnull cur[i] = v;
66 a84cbb2a 2004-04-19 devnull }
67 a84cbb2a 2004-04-19 devnull
68 a84cbb2a 2004-04-19 devnull ipc = windindex(mach->pc);
69 a84cbb2a 2004-04-19 devnull ret = 0;
70 a84cbb2a 2004-04-19 devnull
71 a84cbb2a 2004-04-19 devnull /* set up cur[i]==next[i] for unwindframe */
72 a84cbb2a 2004-04-19 devnull memmove(next, cur, mach->nwindreg*sizeof(next[0]));
73 a84cbb2a 2004-04-19 devnull for(;;){
74 a84cbb2a 2004-04-19 devnull sp = &s;
75 a84cbb2a 2004-04-19 devnull if(findsym(locaddr(pc), CTEXT, &s) < 0)
76 a84cbb2a 2004-04-19 devnull sp = nil;
77 a84cbb2a 2004-04-19 devnull
78 a84cbb2a 2004-04-19 devnull lr.r.rw = locregrw;
79 a84cbb2a 2004-04-19 devnull lr.oldregs = regs;
80 a84cbb2a 2004-04-19 devnull lr.val = cur;
81 a84cbb2a 2004-04-19 devnull lr.map = map;
82 1cc215aa 2004-12-25 devnull if((i = unwindframe(map, &lr.r, next, sp)) >= 0)
83 a84cbb2a 2004-04-19 devnull nextpc = next[ipc];
84 a84cbb2a 2004-04-19 devnull else
85 a84cbb2a 2004-04-19 devnull nextpc = ~(ulong)0;
86 a84cbb2a 2004-04-19 devnull if((*trace)(map, &lr.r, pc, nextpc, sp, ++ret) <= 0)
87 a84cbb2a 2004-04-19 devnull break;
88 a84cbb2a 2004-04-19 devnull if(i < 0)
89 a84cbb2a 2004-04-19 devnull break;
90 dd944ec7 2005-01-23 devnull if(sp){
91 dd944ec7 2005-01-23 devnull if(strcmp(sp->name, "main") == 0
92 dd944ec7 2005-01-23 devnull || strcmp(sp->name, "procscheduler") == 0
93 dd944ec7 2005-01-23 devnull || strcmp(sp->name, "threadstart") == 0)
94 dd944ec7 2005-01-23 devnull break;
95 dd944ec7 2005-01-23 devnull }
96 a84cbb2a 2004-04-19 devnull pc = nextpc;
97 a84cbb2a 2004-04-19 devnull memmove(cur, next, mach->nwindreg*sizeof(cur[0]));
98 a84cbb2a 2004-04-19 devnull }
99 a84cbb2a 2004-04-19 devnull
100 a84cbb2a 2004-04-19 devnull out:
101 a84cbb2a 2004-04-19 devnull free(cur);
102 a84cbb2a 2004-04-19 devnull free(next);
103 a84cbb2a 2004-04-19 devnull return ret;
104 a84cbb2a 2004-04-19 devnull }
105 a84cbb2a 2004-04-19 devnull
106 a84cbb2a 2004-04-19 devnull int
107 a84cbb2a 2004-04-19 devnull windindex(char *reg)
108 a84cbb2a 2004-04-19 devnull {
109 a84cbb2a 2004-04-19 devnull char **p;
110 a84cbb2a 2004-04-19 devnull int i;
111 a84cbb2a 2004-04-19 devnull
112 a84cbb2a 2004-04-19 devnull p = mach->windreg;
113 a84cbb2a 2004-04-19 devnull for(i=0; i<mach->nwindreg; i++)
114 a84cbb2a 2004-04-19 devnull if(strcmp(p[i], reg) == 0)
115 a84cbb2a 2004-04-19 devnull return i;
116 a84cbb2a 2004-04-19 devnull werrstr("%s is not a winding register", reg);
117 a84cbb2a 2004-04-19 devnull return -1;
118 a84cbb2a 2004-04-19 devnull }
119 a84cbb2a 2004-04-19 devnull
120 a84cbb2a 2004-04-19 devnull Loc*
121 a84cbb2a 2004-04-19 devnull windreglocs(void)
122 a84cbb2a 2004-04-19 devnull {
123 a84cbb2a 2004-04-19 devnull int i;
124 a84cbb2a 2004-04-19 devnull Loc *loc;
125 a84cbb2a 2004-04-19 devnull
126 a84cbb2a 2004-04-19 devnull loc = malloc(mach->nwindreg*sizeof(loc[0]));
127 a84cbb2a 2004-04-19 devnull if(loc == nil)
128 a84cbb2a 2004-04-19 devnull return nil;
129 a84cbb2a 2004-04-19 devnull for(i=0; i<mach->nwindreg; i++){
130 a84cbb2a 2004-04-19 devnull loc[i].type = LREG;
131 a84cbb2a 2004-04-19 devnull loc[i].reg = mach->windreg[i];
132 a84cbb2a 2004-04-19 devnull }
133 a84cbb2a 2004-04-19 devnull return loc;
134 a84cbb2a 2004-04-19 devnull }