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