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