1 /* $NetBSD: decode.c,v 1.1 2006/04/07 14:21:37 cherry Exp $ */
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.
10 #include <sys/types.h>
11 #include <sys/param.h>
12 #include <sys/systm.h>
14 #include <ia64/unwind/decode.h>
16 /* Decode ULE128 string */
19 unwind_decode_ule128(char *buf
, unsigned long *val
)
25 val
[0] += ((buf
[i
] & 0x7f) << (i
* 7));
27 }while((0x80 & buf
[i
++]) && (i
< 9));
30 printf("Warning: ULE128 won't fit in an unsigned long. decode aborted!!!\n");
40 unwind_decode_R1(char *buf
, union unwind_desc
*uwd
)
43 if(!IS_R1(buf
[0])) return NULL
;
44 uwd
->R1
.r
= ((buf
[0] & 0x20) == 0x20);
45 uwd
->R1
.rlen
= (buf
[0] & 0x1f);
51 unwind_decode_R2(char *buf
, union unwind_desc
*uwd
)
54 if(!IS_R2(buf
[0])) return NULL
;
56 uwd
->R2
.mask
= (((buf
[0] & 0x07) << 1) | ( (buf
[1] >> 7) & 0xff));
57 uwd
->R2
.grsave
= (buf
[1] & 0x7f);
60 buf
= unwind_decode_ule128(buf
, &uwd
->R2
.rlen
);
65 unwind_decode_R3(char *buf
, union unwind_desc
*uwd
)
68 if(!IS_R3(buf
[0])) return NULL
;
70 uwd
->R3
.r
= ((buf
[0] & 0x03) == 0x01);
73 buf
= unwind_decode_ule128(buf
, &uwd
->R3
.rlen
);
78 unwind_decode_P1(char *buf
, union unwind_desc
*uwd
)
82 if(!IS_P1(buf
[0])) return NULL
;
84 uwd
->P1
.brmask
= (buf
[0] & 0x1f);
90 unwind_decode_P2(char *buf
, union unwind_desc
*uwd
)
93 if(!IS_P2(buf
[0])) return NULL
;
95 uwd
->P2
.brmask
= (((buf
[0] & 0x0f) << 1) | ( (buf
[1] >> 7) & 0xff));
96 uwd
->P2
.gr
= (buf
[1] & 0x7f);
102 unwind_decode_P3(char *buf
, union unwind_desc
*uwd
)
105 if(!IS_P3(buf
[0])) return NULL
;
107 uwd
->P3
.r
= (((0x07 & buf
[0]) << 1) | ((0x80 & buf
[1]) >> 7));
108 uwd
->P3
.grbr
= (buf
[1] & 0x7f);
114 unwind_decode_P4(char *buf
, union unwind_desc
*uwd
, vsize_t len
)
117 if(!IS_P4(buf
[0])) return NULL
;
119 uwd
->P4
.imask
= 0; /* XXX: Unimplemented */
121 /* XXX: adjust buf for imask length on return!!!
122 * don't know the length of imask here.
124 buf
+= roundup(len
<< 1, 8);
129 unwind_decode_P5(char *buf
, union unwind_desc
*uwd
)
132 if(!IS_P5(buf
[0])) return NULL
;
134 uwd
->P5
.grmask
= (buf
[1] >> 4);
135 uwd
->P5
.frmask
= ((buf
[1] & 0x0f << 16) | (buf
[2] << 8) | buf
[3]);
141 unwind_decode_P6(char *buf
, union unwind_desc
*uwd
)
144 if(!IS_P6(buf
[0])) return NULL
;
146 uwd
->P6
.r
= ((buf
[0] & 0x10) == 0x10);
147 uwd
->P6
.rmask
= (buf
[0] & 0x0f);
154 unwind_decode_P7(char *buf
, union unwind_desc
*uwd
)
157 if (!IS_P7(buf
[0])) return NULL
;
159 uwd
->P7
.r
= (buf
[0] & 0x0f);
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
);
170 unwind_decode_P8(char *buf
, union unwind_desc
*uwd
)
173 if(!IS_P8(buf
[0])) return NULL
;
178 buf
= unwind_decode_ule128(buf
, &uwd
->P8
.t
);
183 unwind_decode_P9(char *buf
, union unwind_desc
*uwd
)
187 if(!IS_P9(buf
[0])) return NULL
;
189 uwd
->P9
.grmask
= buf
[1] & 0x0f;
190 uwd
->P9
.gr
= buf
[2] & 0x7f;
197 unwind_decode_P10(char *buf
, union unwind_desc
*uwd
)
201 if(!IS_P10(buf
[0])) return NULL
;
203 uwd
->P10
.abi
= buf
[1];
204 uwd
->P10
.context
= buf
[2];
210 unwind_decode_B1(char *buf
, union unwind_desc
*uwd
)
214 if(!IS_B1(buf
[0])) return NULL
;
216 uwd
->B1
.r
= ((buf
[0] & 0x20) == 0x20);
217 uwd
->B1
.label
= (buf
[0] & 0x1f);
224 unwind_decode_B2(char *buf
, union unwind_desc
*uwd
)
228 if(!IS_B2(buf
[0])) return NULL
;
230 uwd
->B2
.ecount
= (buf
[0] & 0x1f);
233 buf
= unwind_decode_ule128(buf
, &uwd
->B2
.t
);
238 unwind_decode_B3(char *buf
, union unwind_desc
*uwd
)
242 if(!IS_B3(buf
[0])) return NULL
;
245 buf
= unwind_decode_ule128(buf
, &uwd
->B3
.t
);
246 buf
= unwind_decode_ule128(buf
, &uwd
->B3
.ecount
);
251 unwind_decode_B4(char *buf
, union unwind_desc
*uwd
)
255 if(!IS_B4(buf
[0])) return NULL
;
257 uwd
->B4
.r
= ((buf
[0] & 0x08) == 0x08);
260 buf
= unwind_decode_ule128(buf
, &uwd
->B4
.label
);
266 unwind_decode_X1(char *buf
, union unwind_desc
*uwd
)
270 if(!IS_X1(buf
[0])) return NULL
;
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);
278 buf
= unwind_decode_ule128(buf
, &uwd
->X1
.t
);
279 buf
= unwind_decode_ule128(buf
, &uwd
->X1
.offset
);
285 unwind_decode_X2(char *buf
, union unwind_desc
*uwd
)
289 if(!IS_X2(buf
[0])) return NULL
;
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);
299 buf
= unwind_decode_ule128(buf
, &uwd
->X2
.t
);
304 unwind_decode_X3(char *buf
, union unwind_desc
*uwd
)
308 if(!IS_X3(buf
[0])) return NULL
;
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);
317 buf
= unwind_decode_ule128(buf
, &uwd
->X3
.t
);
318 buf
= unwind_decode_ule128(buf
, &uwd
->X3
.offset
);
323 unwind_decode_X4(char *buf
, union unwind_desc
*uwd
)
327 if(!IS_X4(buf
[0])) return NULL
;
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);
338 buf
= unwind_decode_ule128(buf
, &uwd
->X4
.t
);