1 /* $NetBSD: decode.c,v 1.2 2006/11/24 21:20:05 wiz Exp $ */
2
3 /* Contributed to the NetBSD foundation by Cherry G. Mathew
4 * This file contains routines to decode unwind descriptors into
5 * easily an readable data structure ( unwind_desc )
6 * This is the lowest layer of the unwind stack hierarchy.
7 */
8
9 #include <sys/cdefs.h>
10 #include <sys/types.h>
11 #include <sys/param.h>
12 #include <sys/systm.h>
13
14 #include <ia64/unwind/decode.h>
15
16 /* Decode ULE128 string */
17
18 char *
unwind_decode_ule128(char * buf,unsigned long * val)19 unwind_decode_ule128(char *buf, unsigned long *val)
20 {
21 int i = 0;
22
23 val[0] = 0;
24 do {
25 val[0] += ((buf[i] & 0x7f) << (i * 7));
26
27 }while((0x80 & buf[i++]) && (i < 9));
28
29 if(i > 9) {
30 printf("Warning: ULE128 won't fit in an unsigned long. decode aborted!!!\n");
31 return 0;
32 }
33
34 buf+= i;
35 return buf;
36 }
37
38
39 char *
unwind_decode_R1(char * buf,union unwind_desc * uwd)40 unwind_decode_R1(char *buf, union unwind_desc *uwd)
41 {
42
43 if(!IS_R1(buf[0])) return NULL;
44 uwd->R1.r = ((buf[0] & 0x20) == 0x20);
45 uwd->R1.rlen = (buf[0] & 0x1f);
46 buf++;
47 return buf;
48 }
49
50 char *
unwind_decode_R2(char * buf,union unwind_desc * uwd)51 unwind_decode_R2(char *buf, union unwind_desc *uwd)
52 {
53
54 if(!IS_R2(buf[0])) return NULL;
55
56 uwd->R2.mask = (((buf[0] & 0x07) << 1) | ( (buf[1] >> 7) & 0xff));
57 uwd->R2.grsave = (buf[1] & 0x7f);
58
59 buf += 2;
60 buf = unwind_decode_ule128(buf, &uwd->R2.rlen);
61 return buf;
62 }
63
64 char *
unwind_decode_R3(char * buf,union unwind_desc * uwd)65 unwind_decode_R3(char *buf, union unwind_desc *uwd)
66 {
67
68 if(!IS_R3(buf[0])) return NULL;
69
70 uwd->R3.r = ((buf[0] & 0x03) == 0x01);
71
72 buf++;
73 buf = unwind_decode_ule128(buf, &uwd->R3.rlen);
74 return buf;
75 }
76
77 char *
unwind_decode_P1(char * buf,union unwind_desc * uwd)78 unwind_decode_P1(char *buf, union unwind_desc *uwd)
79 {
80
81
82 if(!IS_P1(buf[0])) return NULL;
83
84 uwd->P1.brmask = (buf[0] & 0x1f);
85 buf++;
86 return buf;
87 }
88
89 char *
unwind_decode_P2(char * buf,union unwind_desc * uwd)90 unwind_decode_P2(char *buf, union unwind_desc *uwd)
91 {
92
93 if(!IS_P2(buf[0])) return NULL;
94
95 uwd->P2.brmask = (((buf[0] & 0x0f) << 1) | ( (buf[1] >> 7) & 0xff));
96 uwd->P2.gr = (buf[1] & 0x7f);
97 buf += 2;
98 return buf;
99 }
100
101 char *
unwind_decode_P3(char * buf,union unwind_desc * uwd)102 unwind_decode_P3(char *buf, union unwind_desc *uwd)
103 {
104
105 if(!IS_P3(buf[0])) return NULL;
106
107 uwd->P3.r = (((0x07 & buf[0]) << 1) | ((0x80 & buf[1]) >> 7));
108 uwd->P3.grbr = (buf[1] & 0x7f);
109 buf +=2;
110 return buf;
111 }
112
113 char *
unwind_decode_P4(char * buf,union unwind_desc * uwd,vsize_t len)114 unwind_decode_P4(char *buf, union unwind_desc *uwd, vsize_t len)
115 {
116
117 if(!IS_P4(buf[0])) return NULL;
118
119 uwd->P4.imask = 0; /* XXX: Unimplemented */
120
121 /* XXX: adjust buf for imask length on return!!!
122 * don't know the length of imask here.
123 */
124 buf += roundup(len << 1, 8);
125 return buf;
126 }
127
128 char *
unwind_decode_P5(char * buf,union unwind_desc * uwd)129 unwind_decode_P5(char *buf, union unwind_desc *uwd)
130 {
131
132 if(!IS_P5(buf[0])) return NULL;
133
134 uwd->P5.grmask = (buf[1] >> 4);
135 uwd->P5.frmask = ((buf[1] & 0x0f << 16) | (buf[2] << 8) | buf[3]);
136 buf += 4;
137 return buf;
138 }
139
140 char *
unwind_decode_P6(char * buf,union unwind_desc * uwd)141 unwind_decode_P6(char *buf, union unwind_desc *uwd)
142 {
143
144 if(!IS_P6(buf[0])) return NULL;
145
146 uwd->P6.r = ((buf[0] & 0x10) == 0x10);
147 uwd->P6.rmask = (buf[0] & 0x0f);
148 buf++;
149 return buf;
150 }
151
152
153 char *
unwind_decode_P7(char * buf,union unwind_desc * uwd)154 unwind_decode_P7(char *buf, union unwind_desc *uwd)
155 {
156
157 if (!IS_P7(buf[0])) return NULL;
158
159 uwd->P7.r = (buf[0] & 0x0f);
160
161 buf++;
162
163 buf = unwind_decode_ule128(buf, &uwd->P7.t);
164 if (uwd->P7.r == 0) /* memstack_f */
165 buf = unwind_decode_ule128(buf, &uwd->P7.size);
166 return buf;
167 }
168
169 char *
unwind_decode_P8(char * buf,union unwind_desc * uwd)170 unwind_decode_P8(char *buf, union unwind_desc *uwd)
171 {
172
173 if(!IS_P8(buf[0])) return NULL;
174
175 uwd->P8.r = buf[1];
176
177 buf +=2;
178 buf = unwind_decode_ule128(buf, &uwd->P8.t);
179 return buf;
180 }
181
182 char *
unwind_decode_P9(char * buf,union unwind_desc * uwd)183 unwind_decode_P9(char *buf, union unwind_desc *uwd)
184 {
185
186
187 if(!IS_P9(buf[0])) return NULL;
188
189 uwd->P9.grmask = buf[1] & 0x0f;
190 uwd->P9.gr = buf[2] & 0x7f;
191 buf += 3;
192 return buf;
193 }
194
195
196 char *
unwind_decode_P10(char * buf,union unwind_desc * uwd)197 unwind_decode_P10(char *buf, union unwind_desc *uwd)
198 {
199
200
201 if(!IS_P10(buf[0])) return NULL;
202
203 uwd->P10.abi = buf[1];
204 uwd->P10.context = buf[2];
205 buf += 3;
206 return buf;
207 }
208
209 char *
unwind_decode_B1(char * buf,union unwind_desc * uwd)210 unwind_decode_B1(char *buf, union unwind_desc *uwd)
211 {
212
213
214 if(!IS_B1(buf[0])) return NULL;
215
216 uwd->B1.r = ((buf[0] & 0x20) == 0x20);
217 uwd->B1.label = (buf[0] & 0x1f);
218
219 buf++;
220 return buf;
221 }
222
223 char *
unwind_decode_B2(char * buf,union unwind_desc * uwd)224 unwind_decode_B2(char *buf, union unwind_desc *uwd)
225 {
226
227
228 if(!IS_B2(buf[0])) return NULL;
229
230 uwd->B2.ecount = (buf[0] & 0x1f);
231
232 buf++;
233 buf = unwind_decode_ule128(buf, &uwd->B2.t);
234 return buf;
235 }
236
237 char *
unwind_decode_B3(char * buf,union unwind_desc * uwd)238 unwind_decode_B3(char *buf, union unwind_desc *uwd)
239 {
240
241
242 if(!IS_B3(buf[0])) return NULL;
243
244 buf++;
245 buf = unwind_decode_ule128(buf, &uwd->B3.t);
246 buf = unwind_decode_ule128(buf, &uwd->B3.ecount);
247 return buf;
248 }
249
250 char *
unwind_decode_B4(char * buf,union unwind_desc * uwd)251 unwind_decode_B4(char *buf, union unwind_desc *uwd)
252 {
253
254
255 if(!IS_B4(buf[0])) return NULL;
256
257 uwd->B4.r = ((buf[0] & 0x08) == 0x08);
258
259 buf++;
260 buf = unwind_decode_ule128(buf, &uwd->B4.label);
261 return buf;
262 }
263
264
265 char *
unwind_decode_X1(char * buf,union unwind_desc * uwd)266 unwind_decode_X1(char *buf, union unwind_desc *uwd)
267 {
268
269
270 if(!IS_X1(buf[0])) return NULL;
271
272 uwd->X1.r = ((buf[1] & 0x80) == 0x80);
273 uwd->X1.a = ((buf[1] & 0x40) == 0x40);
274 uwd->X1.b = ((buf[1] & 0x20) == 0x20);
275 uwd->X1.reg = (buf[1] & 0x1f);
276
277 buf += 2;
278 buf = unwind_decode_ule128(buf, &uwd->X1.t);
279 buf = unwind_decode_ule128(buf, &uwd->X1.offset);
280 return buf;
281 }
282
283
284 char *
unwind_decode_X2(char * buf,union unwind_desc * uwd)285 unwind_decode_X2(char *buf, union unwind_desc *uwd)
286 {
287
288
289 if(!IS_X2(buf[0])) return NULL;
290
291 uwd->X2.x = ((buf[1] & 0x80) == 0x80);
292 uwd->X2.a = ((buf[1] & 0x40) == 0x40);
293 uwd->X2.b = ((buf[1] & 0x20) == 0x20);
294 uwd->X2.reg = (buf[1] & 0x1f);
295 uwd->X2.y = ((buf[2] & 0x80) == 0x80);
296 uwd->X2.treg = (buf[2] & 0x7f);
297
298 buf += 3;
299 buf = unwind_decode_ule128(buf, &uwd->X2.t);
300 return buf;
301 }
302
303 char *
unwind_decode_X3(char * buf,union unwind_desc * uwd)304 unwind_decode_X3(char *buf, union unwind_desc *uwd)
305 {
306
307
308 if(!IS_X3(buf[0])) return NULL;
309
310 uwd->X3.r = ((buf[1] & 0x80) == 0x80);
311 uwd->X3.qp = (buf[1] & 0x3f);
312 uwd->X3.a = ((buf[1] & 0x40) == 0x40);
313 uwd->X3.b = ((buf[1] & 0x20) == 0x20);
314 uwd->X3.reg = (buf[1] & 0x1f);
315
316 buf += 3;
317 buf = unwind_decode_ule128(buf, &uwd->X3.t);
318 buf = unwind_decode_ule128(buf, &uwd->X3.offset );
319 return buf;
320 }
321
322 char *
unwind_decode_X4(char * buf,union unwind_desc * uwd)323 unwind_decode_X4(char *buf, union unwind_desc *uwd)
324 {
325
326
327 if(!IS_X4(buf[0])) return NULL;
328
329 uwd->X4.qp = (buf[1] & 0x3f);
330 uwd->X4.x = ((buf[2] & 0x80) == 0x80);
331 uwd->X4.a = ((buf[2] & 0x40) == 0x40);
332 uwd->X4.b = ((buf[2] & 0x20) == 0x20);
333 uwd->X4.reg = (buf[2] & 0x1f);
334 uwd->X4.y = ((buf[3] & 0x80) == 0x80);
335 uwd->X4.treg = (buf[3] & 0x7f);
336
337 buf +=4;
338 buf = unwind_decode_ule128(buf, &uwd->X4.t);
339 return buf;
340 }
341
342