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 #include "elf.h"
6 a84cbb2a 2004-04-19 devnull #include "dwarf.h"
7 a84cbb2a 2004-04-19 devnull
8 a84cbb2a 2004-04-19 devnull static void dwarfsymclose(Fhdr*);
9 443d6288 2012-02-19 rsc static int dwarfpc2file(Fhdr*, u64int, char*, uint, ulong*);
10 443d6288 2012-02-19 rsc static int dwarfline2pc(Fhdr*, u64int, ulong, u64int*);
11 a84cbb2a 2004-04-19 devnull static int dwarflookuplsym(Fhdr*, Symbol*, char*, Symbol*);
12 a84cbb2a 2004-04-19 devnull static int dwarfindexlsym(Fhdr*, Symbol*, uint, Symbol*);
13 a84cbb2a 2004-04-19 devnull static int dwarffindlsym(Fhdr*, Symbol*, Loc, Symbol*);
14 a84cbb2a 2004-04-19 devnull static void dwarfsyminit(Fhdr*);
15 a84cbb2a 2004-04-19 devnull static int dwarftosym(Fhdr*, Dwarf*, DwarfSym*, Symbol*, int);
16 443d6288 2012-02-19 rsc static int _dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, u64int *next, Symbol*);
17 a84cbb2a 2004-04-19 devnull
18 a84cbb2a 2004-04-19 devnull int
19 a84cbb2a 2004-04-19 devnull symdwarf(Fhdr *hdr)
20 a84cbb2a 2004-04-19 devnull {
21 a84cbb2a 2004-04-19 devnull if(hdr->dwarf == nil){
22 a84cbb2a 2004-04-19 devnull werrstr("no dwarf debugging symbols");
23 a84cbb2a 2004-04-19 devnull return -1;
24 a84cbb2a 2004-04-19 devnull }
25 a84cbb2a 2004-04-19 devnull
26 a84cbb2a 2004-04-19 devnull hdr->symclose = dwarfsymclose;
27 a84cbb2a 2004-04-19 devnull hdr->pc2file = dwarfpc2file;
28 a84cbb2a 2004-04-19 devnull hdr->line2pc = dwarfline2pc;
29 a84cbb2a 2004-04-19 devnull hdr->lookuplsym = dwarflookuplsym;
30 a84cbb2a 2004-04-19 devnull hdr->indexlsym = dwarfindexlsym;
31 a84cbb2a 2004-04-19 devnull hdr->findlsym = dwarffindlsym;
32 a84cbb2a 2004-04-19 devnull hdr->unwind = _dwarfunwind;
33 a84cbb2a 2004-04-19 devnull dwarfsyminit(hdr);
34 a84cbb2a 2004-04-19 devnull
35 a84cbb2a 2004-04-19 devnull return 0;
36 a84cbb2a 2004-04-19 devnull }
37 a84cbb2a 2004-04-19 devnull
38 a84cbb2a 2004-04-19 devnull static void
39 a84cbb2a 2004-04-19 devnull dwarfsymclose(Fhdr *hdr)
40 a84cbb2a 2004-04-19 devnull {
41 a84cbb2a 2004-04-19 devnull dwarfclose(hdr->dwarf);
42 a84cbb2a 2004-04-19 devnull hdr->dwarf = nil;
43 a84cbb2a 2004-04-19 devnull }
44 a84cbb2a 2004-04-19 devnull
45 a84cbb2a 2004-04-19 devnull static int
46 443d6288 2012-02-19 rsc dwarfpc2file(Fhdr *fhdr, u64int pc, char *buf, uint nbuf, ulong *line)
47 a84cbb2a 2004-04-19 devnull {
48 a84cbb2a 2004-04-19 devnull char *cdir, *dir, *file;
49 a84cbb2a 2004-04-19 devnull
50 a84cbb2a 2004-04-19 devnull if(dwarfpctoline(fhdr->dwarf, pc, &cdir, &dir, &file, line, nil, nil) < 0)
51 a84cbb2a 2004-04-19 devnull return -1;
52 a84cbb2a 2004-04-19 devnull
53 a84cbb2a 2004-04-19 devnull if(file[0] == '/' || (dir==nil && cdir==nil))
54 a84cbb2a 2004-04-19 devnull strecpy(buf, buf+nbuf, file);
55 a84cbb2a 2004-04-19 devnull else if((dir && dir[0] == '/') || cdir==nil)
56 a84cbb2a 2004-04-19 devnull snprint(buf, nbuf, "%s/%s", dir, file);
57 a84cbb2a 2004-04-19 devnull else
58 a84cbb2a 2004-04-19 devnull snprint(buf, nbuf, "%s/%s/%s", cdir, dir ? dir : "", file);
59 a84cbb2a 2004-04-19 devnull cleanname(buf);
60 a84cbb2a 2004-04-19 devnull return 0;;
61 a84cbb2a 2004-04-19 devnull }
62 a84cbb2a 2004-04-19 devnull
63 a84cbb2a 2004-04-19 devnull static int
64 443d6288 2012-02-19 rsc dwarfline2pc(Fhdr *fhdr, u64int basepc, ulong line, u64int *pc)
65 a84cbb2a 2004-04-19 devnull {
66 a84cbb2a 2004-04-19 devnull werrstr("dwarf line2pc not implemented");
67 a84cbb2a 2004-04-19 devnull return -1;
68 a84cbb2a 2004-04-19 devnull }
69 a84cbb2a 2004-04-19 devnull
70 a84cbb2a 2004-04-19 devnull static uint
71 a84cbb2a 2004-04-19 devnull typesize(Dwarf *dwarf, ulong unit, ulong tref, char *name)
72 a84cbb2a 2004-04-19 devnull {
73 a84cbb2a 2004-04-19 devnull DwarfSym ds;
74 a84cbb2a 2004-04-19 devnull
75 a84cbb2a 2004-04-19 devnull top:
76 a84cbb2a 2004-04-19 devnull if(dwarfseeksym(dwarf, unit, tref-unit, &ds) < 0){
77 a84cbb2a 2004-04-19 devnull cannot:
78 a84cbb2a 2004-04-19 devnull fprint(2, "warning: cannot compute size of parameter %s (%lud %lud: %r)\n",
79 a84cbb2a 2004-04-19 devnull name, unit, tref);
80 a84cbb2a 2004-04-19 devnull return 0;
81 a84cbb2a 2004-04-19 devnull }
82 fa325e9b 2020-01-10 cross
83 a84cbb2a 2004-04-19 devnull if(ds.attrs.have.bytesize)
84 a84cbb2a 2004-04-19 devnull return ds.attrs.bytesize;
85 a84cbb2a 2004-04-19 devnull
86 a84cbb2a 2004-04-19 devnull switch(ds.attrs.tag){
87 a84cbb2a 2004-04-19 devnull case TagVolatileType:
88 a84cbb2a 2004-04-19 devnull case TagRestrictType:
89 a84cbb2a 2004-04-19 devnull case TagTypedef:
90 a84cbb2a 2004-04-19 devnull if(ds.attrs.have.type != TReference)
91 a84cbb2a 2004-04-19 devnull goto cannot;
92 a84cbb2a 2004-04-19 devnull tref = ds.attrs.type;
93 a84cbb2a 2004-04-19 devnull goto top;
94 a84cbb2a 2004-04-19 devnull }
95 a84cbb2a 2004-04-19 devnull
96 a84cbb2a 2004-04-19 devnull goto cannot;
97 a84cbb2a 2004-04-19 devnull }
98 a84cbb2a 2004-04-19 devnull
99 a84cbb2a 2004-04-19 devnull static int
100 a84cbb2a 2004-04-19 devnull roundup(int s, int n)
101 a84cbb2a 2004-04-19 devnull {
102 a84cbb2a 2004-04-19 devnull return (s+n-1)&~(n-1);
103 a84cbb2a 2004-04-19 devnull }
104 a84cbb2a 2004-04-19 devnull
105 a84cbb2a 2004-04-19 devnull static int
106 a84cbb2a 2004-04-19 devnull dwarflenum(Fhdr *fhdr, Symbol *p, char *name, uint j, Loc l, Symbol *s)
107 a84cbb2a 2004-04-19 devnull {
108 a84cbb2a 2004-04-19 devnull int depth, bpoff;
109 a84cbb2a 2004-04-19 devnull DwarfSym ds;
110 a84cbb2a 2004-04-19 devnull Symbol s1;
111 a84cbb2a 2004-04-19 devnull
112 a84cbb2a 2004-04-19 devnull if(p == nil)
113 a84cbb2a 2004-04-19 devnull return -1;
114 a84cbb2a 2004-04-19 devnull
115 eaf56db5 2004-04-21 devnull if(p->u.dwarf.unit == 0 && p->u.dwarf.uoff == 0)
116 eaf56db5 2004-04-21 devnull return -1;
117 eaf56db5 2004-04-21 devnull
118 a84cbb2a 2004-04-19 devnull if(dwarfseeksym(fhdr->dwarf, p->u.dwarf.unit, p->u.dwarf.uoff, &ds) < 0)
119 a84cbb2a 2004-04-19 devnull return -1;
120 a84cbb2a 2004-04-19 devnull
121 a84cbb2a 2004-04-19 devnull ds.depth = 1;
122 a84cbb2a 2004-04-19 devnull depth = 1;
123 a84cbb2a 2004-04-19 devnull
124 a84cbb2a 2004-04-19 devnull bpoff = 8;
125 95f57b01 2004-04-21 devnull while(dwarfnextsym(fhdr->dwarf, &ds) == 1 && depth < ds.depth){
126 a84cbb2a 2004-04-19 devnull if(ds.attrs.tag != TagVariable){
127 a84cbb2a 2004-04-19 devnull if(ds.attrs.tag != TagFormalParameter
128 a84cbb2a 2004-04-19 devnull && ds.attrs.tag != TagUnspecifiedParameters)
129 a84cbb2a 2004-04-19 devnull continue;
130 a84cbb2a 2004-04-19 devnull if(ds.depth != depth+1)
131 a84cbb2a 2004-04-19 devnull continue;
132 a84cbb2a 2004-04-19 devnull }
133 a84cbb2a 2004-04-19 devnull if(dwarftosym(fhdr, fhdr->dwarf, &ds, &s1, 1) < 0)
134 a84cbb2a 2004-04-19 devnull continue;
135 a84cbb2a 2004-04-19 devnull /* XXX move this out once there is another architecture */
136 a84cbb2a 2004-04-19 devnull /*
137 a84cbb2a 2004-04-19 devnull * gcc tells us the registers where the parameters might be
138 a84cbb2a 2004-04-19 devnull * held for an instruction or two. use the parameter list to
139 a84cbb2a 2004-04-19 devnull * recompute the actual stack locations.
140 a84cbb2a 2004-04-19 devnull */
141 a84cbb2a 2004-04-19 devnull if(fhdr->mtype == M386)
142 a84cbb2a 2004-04-19 devnull if(ds.attrs.tag==TagFormalParameter || ds.attrs.tag==TagUnspecifiedParameters){
143 a84cbb2a 2004-04-19 devnull if(s1.loc.type==LOFFSET
144 a84cbb2a 2004-04-19 devnull && strcmp(s1.loc.reg, "BP")==0
145 a84cbb2a 2004-04-19 devnull && s1.loc.offset >= 8)
146 a84cbb2a 2004-04-19 devnull bpoff = s1.loc.offset;
147 a84cbb2a 2004-04-19 devnull else{
148 a84cbb2a 2004-04-19 devnull s1.loc.type = LOFFSET;
149 a84cbb2a 2004-04-19 devnull s1.loc.reg = "BP";
150 a84cbb2a 2004-04-19 devnull s1.loc.offset = bpoff;
151 a84cbb2a 2004-04-19 devnull }
152 a84cbb2a 2004-04-19 devnull if(ds.attrs.tag == TagFormalParameter){
153 a84cbb2a 2004-04-19 devnull if(ds.attrs.have.type)
154 a84cbb2a 2004-04-19 devnull bpoff += roundup(typesize(fhdr->dwarf, p->u.dwarf.unit, ds.attrs.type, s1.name), 4);
155 a84cbb2a 2004-04-19 devnull else
156 a84cbb2a 2004-04-19 devnull fprint(2, "warning: cannot compute size of parameter %s\n", s1.name);
157 a84cbb2a 2004-04-19 devnull }
158 a84cbb2a 2004-04-19 devnull }
159 a84cbb2a 2004-04-19 devnull if(name){
160 a84cbb2a 2004-04-19 devnull if(strcmp(ds.attrs.name, name) != 0)
161 a84cbb2a 2004-04-19 devnull continue;
162 a84cbb2a 2004-04-19 devnull }else if(l.type){
163 a84cbb2a 2004-04-19 devnull if(loccmp(&s1.loc, &l) != 0)
164 a84cbb2a 2004-04-19 devnull continue;
165 a84cbb2a 2004-04-19 devnull }else{
166 a84cbb2a 2004-04-19 devnull if(j-- > 0)
167 a84cbb2a 2004-04-19 devnull continue;
168 a84cbb2a 2004-04-19 devnull }
169 a84cbb2a 2004-04-19 devnull *s = s1;
170 a84cbb2a 2004-04-19 devnull return 0;
171 a84cbb2a 2004-04-19 devnull }
172 a84cbb2a 2004-04-19 devnull return -1;
173 a84cbb2a 2004-04-19 devnull }
174 a84cbb2a 2004-04-19 devnull
175 a84cbb2a 2004-04-19 devnull static Loc zl;
176 a84cbb2a 2004-04-19 devnull
177 a84cbb2a 2004-04-19 devnull static int
178 a84cbb2a 2004-04-19 devnull dwarflookuplsym(Fhdr *fhdr, Symbol *p, char *name, Symbol *s)
179 a84cbb2a 2004-04-19 devnull {
180 a84cbb2a 2004-04-19 devnull return dwarflenum(fhdr, p, name, 0, zl, s);
181 a84cbb2a 2004-04-19 devnull }
182 a84cbb2a 2004-04-19 devnull
183 a84cbb2a 2004-04-19 devnull static int
184 a84cbb2a 2004-04-19 devnull dwarfindexlsym(Fhdr *fhdr, Symbol *p, uint i, Symbol *s)
185 a84cbb2a 2004-04-19 devnull {
186 a84cbb2a 2004-04-19 devnull return dwarflenum(fhdr, p, nil, i, zl, s);
187 a84cbb2a 2004-04-19 devnull }
188 a84cbb2a 2004-04-19 devnull
189 a84cbb2a 2004-04-19 devnull static int
190 a84cbb2a 2004-04-19 devnull dwarffindlsym(Fhdr *fhdr, Symbol *p, Loc l, Symbol *s)
191 a84cbb2a 2004-04-19 devnull {
192 a84cbb2a 2004-04-19 devnull return dwarflenum(fhdr, p, nil, 0, l, s);
193 a84cbb2a 2004-04-19 devnull }
194 a84cbb2a 2004-04-19 devnull
195 a84cbb2a 2004-04-19 devnull static void
196 a84cbb2a 2004-04-19 devnull dwarfsyminit(Fhdr *fp)
197 a84cbb2a 2004-04-19 devnull {
198 a84cbb2a 2004-04-19 devnull Dwarf *d;
199 a84cbb2a 2004-04-19 devnull DwarfSym s;
200 a84cbb2a 2004-04-19 devnull Symbol sym;
201 a84cbb2a 2004-04-19 devnull
202 a84cbb2a 2004-04-19 devnull d = fp->dwarf;
203 a84cbb2a 2004-04-19 devnull if(dwarfenum(d, &s) < 0)
204 a84cbb2a 2004-04-19 devnull return;
205 a84cbb2a 2004-04-19 devnull
206 eaf56db5 2004-04-21 devnull while(dwarfnextsymat(d, &s, 0) == 1)
207 95f57b01 2004-04-21 devnull while(dwarfnextsymat(d, &s, 1) == 1){
208 a84cbb2a 2004-04-19 devnull if(s.attrs.name == nil)
209 a84cbb2a 2004-04-19 devnull continue;
210 a84cbb2a 2004-04-19 devnull switch(s.attrs.tag){
211 a84cbb2a 2004-04-19 devnull case TagSubprogram:
212 a84cbb2a 2004-04-19 devnull case TagVariable:
213 a84cbb2a 2004-04-19 devnull if(dwarftosym(fp, d, &s, &sym, 0) < 0)
214 a84cbb2a 2004-04-19 devnull continue;
215 39dbe6e7 2005-01-07 devnull _addsym(fp, &sym);
216 a84cbb2a 2004-04-19 devnull }
217 a84cbb2a 2004-04-19 devnull }
218 a84cbb2a 2004-04-19 devnull }
219 a84cbb2a 2004-04-19 devnull
220 a84cbb2a 2004-04-19 devnull static char*
221 a84cbb2a 2004-04-19 devnull regname(Dwarf *d, int i)
222 a84cbb2a 2004-04-19 devnull {
223 a84cbb2a 2004-04-19 devnull if(i < 0 || i >= d->nreg)
224 a84cbb2a 2004-04-19 devnull return nil;
225 a84cbb2a 2004-04-19 devnull return d->reg[i];
226 a84cbb2a 2004-04-19 devnull }
227 a84cbb2a 2004-04-19 devnull
228 a84cbb2a 2004-04-19 devnull static int
229 a84cbb2a 2004-04-19 devnull dwarftosym(Fhdr *fp, Dwarf *d, DwarfSym *ds, Symbol *s, int infn)
230 a84cbb2a 2004-04-19 devnull {
231 a84cbb2a 2004-04-19 devnull DwarfBuf buf;
232 a84cbb2a 2004-04-19 devnull DwarfBlock b;
233 fa325e9b 2020-01-10 cross
234 a84cbb2a 2004-04-19 devnull memset(s, 0, sizeof *s);
235 a84cbb2a 2004-04-19 devnull s->u.dwarf.uoff = ds->uoff;
236 a84cbb2a 2004-04-19 devnull s->u.dwarf.unit = ds->unit;
237 a84cbb2a 2004-04-19 devnull switch(ds->attrs.tag){
238 a84cbb2a 2004-04-19 devnull default:
239 a84cbb2a 2004-04-19 devnull return -1;
240 a84cbb2a 2004-04-19 devnull case TagUnspecifiedParameters:
241 a84cbb2a 2004-04-19 devnull ds->attrs.name = "...";
242 a84cbb2a 2004-04-19 devnull s->type = 'p';
243 a84cbb2a 2004-04-19 devnull goto sym;
244 a84cbb2a 2004-04-19 devnull case TagFormalParameter:
245 a84cbb2a 2004-04-19 devnull s->type = 'p';
246 a84cbb2a 2004-04-19 devnull s->class = CPARAM;
247 a84cbb2a 2004-04-19 devnull goto sym;
248 a84cbb2a 2004-04-19 devnull case TagSubprogram:
249 a84cbb2a 2004-04-19 devnull s->type = 't';
250 a84cbb2a 2004-04-19 devnull s->class = CTEXT;
251 a84cbb2a 2004-04-19 devnull goto sym;
252 a84cbb2a 2004-04-19 devnull case TagVariable:
253 a84cbb2a 2004-04-19 devnull if(infn){
254 a84cbb2a 2004-04-19 devnull s->type = 'a';
255 a84cbb2a 2004-04-19 devnull s->class = CAUTO;
256 a84cbb2a 2004-04-19 devnull }else{
257 a84cbb2a 2004-04-19 devnull s->type = 'd';
258 a84cbb2a 2004-04-19 devnull s->class = CDATA;
259 a84cbb2a 2004-04-19 devnull }
260 a84cbb2a 2004-04-19 devnull sym:
261 a84cbb2a 2004-04-19 devnull s->name = ds->attrs.name;
262 a84cbb2a 2004-04-19 devnull if(ds->attrs.have.lowpc){
263 a84cbb2a 2004-04-19 devnull s->loc.type = LADDR;
264 a84cbb2a 2004-04-19 devnull s->loc.addr = ds->attrs.lowpc;
265 a84cbb2a 2004-04-19 devnull if(ds->attrs.have.highpc){
266 a84cbb2a 2004-04-19 devnull s->hiloc.type = LADDR;
267 a84cbb2a 2004-04-19 devnull s->hiloc.addr = ds->attrs.highpc;
268 a84cbb2a 2004-04-19 devnull }
269 a84cbb2a 2004-04-19 devnull }else if(ds->attrs.have.location == TConstant){
270 a84cbb2a 2004-04-19 devnull s->loc.type = LADDR;
271 a84cbb2a 2004-04-19 devnull s->loc.addr = ds->attrs.location.c;
272 a84cbb2a 2004-04-19 devnull }else if(ds->attrs.have.location == TBlock){
273 a84cbb2a 2004-04-19 devnull b = ds->attrs.location.b;
274 a84cbb2a 2004-04-19 devnull if(b.len == 0)
275 a84cbb2a 2004-04-19 devnull return -1;
276 a84cbb2a 2004-04-19 devnull buf.p = b.data+1;
277 a84cbb2a 2004-04-19 devnull buf.ep = b.data+b.len;
278 a84cbb2a 2004-04-19 devnull buf.d = d;
279 a84cbb2a 2004-04-19 devnull buf.addrsize = 0;
280 a84cbb2a 2004-04-19 devnull if(b.data[0]==OpAddr){
281 a84cbb2a 2004-04-19 devnull if(b.len != 5)
282 a84cbb2a 2004-04-19 devnull return -1;
283 a84cbb2a 2004-04-19 devnull s->loc.type = LADDR;
284 a84cbb2a 2004-04-19 devnull s->loc.addr = dwarfgetaddr(&buf);
285 a84cbb2a 2004-04-19 devnull }else if(OpReg0 <= b.data[0] && b.data[0] < OpReg0+0x20){
286 a84cbb2a 2004-04-19 devnull if(b.len != 1 || (s->loc.reg = regname(d, b.data[0]-OpReg0)) == nil)
287 a84cbb2a 2004-04-19 devnull return -1;
288 a84cbb2a 2004-04-19 devnull s->loc.type = LREG;
289 a84cbb2a 2004-04-19 devnull }else if(OpBreg0 <= b.data[0] && b.data[0] < OpBreg0+0x20){
290 a84cbb2a 2004-04-19 devnull s->loc.type = LOFFSET;
291 a84cbb2a 2004-04-19 devnull s->loc.reg = regname(d, b.data[0]-0x70);
292 a84cbb2a 2004-04-19 devnull s->loc.offset = dwarfget128s(&buf);
293 a84cbb2a 2004-04-19 devnull if(s->loc.reg == nil)
294 a84cbb2a 2004-04-19 devnull return -1;
295 a84cbb2a 2004-04-19 devnull }else if(b.data[0] == OpRegx){
296 a84cbb2a 2004-04-19 devnull s->loc.type = LREG;
297 a84cbb2a 2004-04-19 devnull s->loc.reg = regname(d, dwarfget128(&buf));
298 a84cbb2a 2004-04-19 devnull if(s->loc.reg == nil)
299 a84cbb2a 2004-04-19 devnull return -1;
300 a84cbb2a 2004-04-19 devnull }else if(b.data[0] == OpFbreg){
301 a84cbb2a 2004-04-19 devnull s->loc.type = LOFFSET;
302 a84cbb2a 2004-04-19 devnull s->loc.reg = mach->fp;
303 a84cbb2a 2004-04-19 devnull s->loc.offset = dwarfget128s(&buf);
304 a84cbb2a 2004-04-19 devnull }else if(b.data[0] == OpBregx){
305 a84cbb2a 2004-04-19 devnull s->loc.type = LOFFSET;
306 a84cbb2a 2004-04-19 devnull s->loc.reg = regname(d, dwarfget128(&buf));
307 a84cbb2a 2004-04-19 devnull s->loc.offset = dwarfget128s(&buf);
308 a84cbb2a 2004-04-19 devnull if(s->loc.reg == nil)
309 a84cbb2a 2004-04-19 devnull return -1;
310 a84cbb2a 2004-04-19 devnull }else
311 a84cbb2a 2004-04-19 devnull s->loc.type = LNONE;
312 a84cbb2a 2004-04-19 devnull if(buf.p != buf.ep)
313 a84cbb2a 2004-04-19 devnull s->loc.type = LNONE;
314 a84cbb2a 2004-04-19 devnull }else
315 a84cbb2a 2004-04-19 devnull return -1;
316 a84cbb2a 2004-04-19 devnull if(ds->attrs.isexternal)
317 a84cbb2a 2004-04-19 devnull s->type += 'A' - 'a';
318 a84cbb2a 2004-04-19 devnull if(ds->attrs.tag==TagVariable && s->loc.type==LADDR && s->loc.addr>=fp->dataddr+fp->datsz)
319 a84cbb2a 2004-04-19 devnull s->type += 'b' - 'd';
320 a84cbb2a 2004-04-19 devnull s->fhdr = fp;
321 a84cbb2a 2004-04-19 devnull return 0;
322 a84cbb2a 2004-04-19 devnull }
323 a84cbb2a 2004-04-19 devnull }
324 a84cbb2a 2004-04-19 devnull
325 a84cbb2a 2004-04-19 devnull static int
326 443d6288 2012-02-19 rsc dwarfeval(Dwarf *d, Map *map, Regs *regs, ulong cfa, int rno, DwarfExpr e, u64int *u)
327 a84cbb2a 2004-04-19 devnull {
328 a84cbb2a 2004-04-19 devnull int i;
329 a84cbb2a 2004-04-19 devnull u32int u4;
330 443d6288 2012-02-19 rsc u64int uu;
331 a84cbb2a 2004-04-19 devnull
332 a84cbb2a 2004-04-19 devnull switch(e.type){
333 a84cbb2a 2004-04-19 devnull case RuleUndef:
334 a84cbb2a 2004-04-19 devnull *u = 0;
335 a84cbb2a 2004-04-19 devnull return 0;
336 a84cbb2a 2004-04-19 devnull case RuleSame:
337 a84cbb2a 2004-04-19 devnull if(rno == -1){
338 a84cbb2a 2004-04-19 devnull werrstr("pc cannot be `same'");
339 a84cbb2a 2004-04-19 devnull return -1;
340 a84cbb2a 2004-04-19 devnull }
341 a84cbb2a 2004-04-19 devnull return rget(regs, regname(d, rno), u);
342 a84cbb2a 2004-04-19 devnull case RuleRegister:
343 a84cbb2a 2004-04-19 devnull if((i = windindex(regname(d, e.reg))) < 0)
344 a84cbb2a 2004-04-19 devnull return -1;
345 a84cbb2a 2004-04-19 devnull return rget(regs, regname(d, i), u);
346 a84cbb2a 2004-04-19 devnull case RuleCfaOffset:
347 a84cbb2a 2004-04-19 devnull if(cfa == 0){
348 a84cbb2a 2004-04-19 devnull werrstr("unknown cfa");
349 a84cbb2a 2004-04-19 devnull return -1;
350 a84cbb2a 2004-04-19 devnull }
351 a84cbb2a 2004-04-19 devnull if(get4(map, cfa + e.offset, &u4) < 0)
352 a84cbb2a 2004-04-19 devnull return -1;
353 a84cbb2a 2004-04-19 devnull *u = u4;
354 a84cbb2a 2004-04-19 devnull return 0;
355 a84cbb2a 2004-04-19 devnull case RuleRegOff:
356 a84cbb2a 2004-04-19 devnull if(rget(regs, regname(d, e.reg), &uu) < 0)
357 a84cbb2a 2004-04-19 devnull return -1;
358 a84cbb2a 2004-04-19 devnull if(get4(map, uu+e.offset, &u4) < 0)
359 fa325e9b 2020-01-10 cross return -1;
360 a84cbb2a 2004-04-19 devnull *u = u4;
361 a84cbb2a 2004-04-19 devnull return 0;
362 a84cbb2a 2004-04-19 devnull case RuleLocation:
363 a84cbb2a 2004-04-19 devnull werrstr("not evaluating dwarf loc expressions");
364 a84cbb2a 2004-04-19 devnull return -1;
365 a84cbb2a 2004-04-19 devnull }
366 a84cbb2a 2004-04-19 devnull werrstr("not reached in dwarfeval");
367 a84cbb2a 2004-04-19 devnull return -1;
368 a84cbb2a 2004-04-19 devnull }
369 a84cbb2a 2004-04-19 devnull
370 a84cbb2a 2004-04-19 devnull #if 0
371 a84cbb2a 2004-04-19 devnull static int
372 a84cbb2a 2004-04-19 devnull dwarfexprfmt(Fmt *fmt)
373 a84cbb2a 2004-04-19 devnull {
374 a84cbb2a 2004-04-19 devnull DwarfExpr *e;
375 a84cbb2a 2004-04-19 devnull
376 a84cbb2a 2004-04-19 devnull if((e = va_arg(fmt->args, DwarfExpr*)) == nil)
377 a84cbb2a 2004-04-19 devnull return fmtstrcpy(fmt, "<nil>");
378 a84cbb2a 2004-04-19 devnull
379 a84cbb2a 2004-04-19 devnull switch(e->type){
380 a84cbb2a 2004-04-19 devnull case RuleUndef:
381 a84cbb2a 2004-04-19 devnull return fmtstrcpy(fmt, "undef");
382 a84cbb2a 2004-04-19 devnull case RuleSame:
383 a84cbb2a 2004-04-19 devnull return fmtstrcpy(fmt, "same");
384 a84cbb2a 2004-04-19 devnull case RuleCfaOffset:
385 a84cbb2a 2004-04-19 devnull return fmtprint(fmt, "%ld(cfa)", e->offset);
386 a84cbb2a 2004-04-19 devnull case RuleRegister:
387 a84cbb2a 2004-04-19 devnull return fmtprint(fmt, "r%ld", e->reg);
388 a84cbb2a 2004-04-19 devnull case RuleRegOff:
389 a84cbb2a 2004-04-19 devnull return fmtprint(fmt, "%ld(r%ld)", e->offset, e->reg);
390 a84cbb2a 2004-04-19 devnull case RuleLocation:
391 a84cbb2a 2004-04-19 devnull return fmtprint(fmt, "l.%.*H", e->loc.len, e->loc.data);
392 a84cbb2a 2004-04-19 devnull default:
393 a84cbb2a 2004-04-19 devnull return fmtprint(fmt, "?%d", e->type);
394 a84cbb2a 2004-04-19 devnull }
395 a84cbb2a 2004-04-19 devnull }
396 a84cbb2a 2004-04-19 devnull #endif
397 a84cbb2a 2004-04-19 devnull
398 a84cbb2a 2004-04-19 devnull static int
399 443d6288 2012-02-19 rsc _dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, u64int *next, Symbol *sym)
400 a84cbb2a 2004-04-19 devnull {
401 a84cbb2a 2004-04-19 devnull char *name;
402 a84cbb2a 2004-04-19 devnull int i, j;
403 443d6288 2012-02-19 rsc u64int cfa, pc, u;
404 a84cbb2a 2004-04-19 devnull Dwarf *d;
405 a84cbb2a 2004-04-19 devnull DwarfExpr *e, epc, ecfa;
406 a84cbb2a 2004-04-19 devnull
407 a84cbb2a 2004-04-19 devnull
408 a84cbb2a 2004-04-19 devnull /*
409 a84cbb2a 2004-04-19 devnull * Use dwarfunwind to tell us what to do.
410 a84cbb2a 2004-04-19 devnull */
411 a84cbb2a 2004-04-19 devnull d = fhdr->dwarf;
412 a84cbb2a 2004-04-19 devnull e = malloc(d->nreg*sizeof(e[0]));
413 a84cbb2a 2004-04-19 devnull if(e == nil)
414 a84cbb2a 2004-04-19 devnull return -1;
415 a84cbb2a 2004-04-19 devnull if(rget(regs, mach->pc, &pc) < 0)
416 a84cbb2a 2004-04-19 devnull goto err;
417 a84cbb2a 2004-04-19 devnull if(dwarfunwind(d, pc, &ecfa, &epc, e, d->nreg) < 0)
418 a84cbb2a 2004-04-19 devnull goto err;
419 a84cbb2a 2004-04-19 devnull
420 a84cbb2a 2004-04-19 devnull /*
421 a84cbb2a 2004-04-19 devnull * Compute CFA.
422 a84cbb2a 2004-04-19 devnull */
423 a84cbb2a 2004-04-19 devnull switch(ecfa.type){
424 a84cbb2a 2004-04-19 devnull default:
425 a84cbb2a 2004-04-19 devnull werrstr("invalid call-frame-address in _dwarfunwind");
426 a84cbb2a 2004-04-19 devnull goto err;
427 a84cbb2a 2004-04-19 devnull case RuleRegister:
428 a84cbb2a 2004-04-19 devnull ecfa.offset = 0;
429 a84cbb2a 2004-04-19 devnull case RuleRegOff:
430 a84cbb2a 2004-04-19 devnull if((name = regname(d, ecfa.reg)) == nil){
431 a84cbb2a 2004-04-19 devnull werrstr("invalid call-frame-address register %d", (int)ecfa.reg);
432 a84cbb2a 2004-04-19 devnull goto err;
433 a84cbb2a 2004-04-19 devnull }
434 a84cbb2a 2004-04-19 devnull if(rget(regs, name, &cfa) < 0){
435 a84cbb2a 2004-04-19 devnull werrstr("fetching %s for call-frame-address: %r", name);
436 a84cbb2a 2004-04-19 devnull goto err;
437 a84cbb2a 2004-04-19 devnull }
438 a84cbb2a 2004-04-19 devnull cfa += ecfa.offset;
439 a84cbb2a 2004-04-19 devnull }
440 a84cbb2a 2004-04-19 devnull
441 a84cbb2a 2004-04-19 devnull /*
442 a84cbb2a 2004-04-19 devnull * Compute registers.
443 a84cbb2a 2004-04-19 devnull */
444 a84cbb2a 2004-04-19 devnull for(i=0; i<d->nreg; i++){
445 a84cbb2a 2004-04-19 devnull j = windindex(d->reg[i]);
446 a84cbb2a 2004-04-19 devnull if(j == -1)
447 a84cbb2a 2004-04-19 devnull continue;
448 a84cbb2a 2004-04-19 devnull if(dwarfeval(d, map, regs, cfa, i, e[i], &u) < 0)
449 a84cbb2a 2004-04-19 devnull u = ~(ulong)0;
450 a84cbb2a 2004-04-19 devnull next[j] = u;
451 a84cbb2a 2004-04-19 devnull }
452 a84cbb2a 2004-04-19 devnull
453 a84cbb2a 2004-04-19 devnull /*
454 a84cbb2a 2004-04-19 devnull * Compute caller pc
455 a84cbb2a 2004-04-19 devnull */
456 a84cbb2a 2004-04-19 devnull if(dwarfeval(d, map, regs, cfa, -1, epc, &u) < 0){
457 a84cbb2a 2004-04-19 devnull werrstr("computing caller %s: %r", mach->pc);
458 a84cbb2a 2004-04-19 devnull goto err;
459 a84cbb2a 2004-04-19 devnull }
460 a84cbb2a 2004-04-19 devnull next[windindex(mach->pc)] = u;
461 a84cbb2a 2004-04-19 devnull free(e);
462 a84cbb2a 2004-04-19 devnull return 0;
463 a84cbb2a 2004-04-19 devnull
464 a84cbb2a 2004-04-19 devnull err:
465 a84cbb2a 2004-04-19 devnull free(e);
466 a84cbb2a 2004-04-19 devnull return -1;
467 a84cbb2a 2004-04-19 devnull }