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