* unwind-ia64.c (unw_print_brmask): Fix ISO C portability glitch.
[deliverable/binutils-gdb.git] / binutils / unwind-ia64.c
1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright 2000, 2001 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "unwind-ia64.h"
22 #include <stdio.h>
23 #include <string.h>
24
25 #if __GNUC__ >= 2
26 /* Define BFD64 here, even if our default architecture is 32 bit ELF
27 as this will allow us to read in and parse 64bit and 32bit ELF files.
28 Only do this if we belive that the compiler can support a 64 bit
29 data type. For now we only rely on GCC being able to do this. */
30 #define BFD64
31 #endif
32 #include "bfd.h"
33
34 static bfd_vma unw_rlen = 0;
35
36 static void unw_print_brmask PARAMS ((char *, unsigned int));
37 static void unw_print_grmask PARAMS ((char *, unsigned int));
38 static void unw_print_frmask PARAMS ((char *, unsigned int));
39 static void unw_print_abreg PARAMS ((char *, unsigned int));
40 static void unw_print_xyreg PARAMS ((char *, unsigned int, unsigned int));
41
42 static void
43 unw_print_brmask (cp, mask)
44 char * cp;
45 unsigned int mask;
46 {
47 char *sep = "";
48 int i;
49
50 for (i = 0; mask && (i < 5); ++i)
51 {
52 if (mask & 1)
53 {
54 cp += sprintf (cp, "%sb%u", sep, i + 1);
55 sep = ",";
56 }
57 mask >>= 1;
58 }
59 *cp = '\0';
60 }
61
62 static void
63 unw_print_grmask (cp, mask)
64 char * cp;
65 unsigned int mask;
66 {
67 char *sep = "";
68 int i;
69
70 *cp = '\0';
71 for (i = 0; i < 4; ++i)
72 {
73 if (mask & 1)
74 {
75 cp += sprintf (cp, "%sr%u", sep, i + 4);
76 sep = ",";
77 }
78 mask >>= 1;
79 }
80 }
81
82 static void
83 unw_print_frmask (cp, mask)
84 char * cp;
85 unsigned int mask;
86 {
87 char *sep = "";
88 int i;
89
90 *cp = '\0';
91 for (i = 0; i < 20; ++i)
92 {
93 if (mask & 1)
94 {
95 cp += sprintf (cp, "%sf%u", sep, (i < 4) ? (i + 2) : (i + 12));
96 sep = ",";
97 }
98 mask >>= 1;
99 }
100 }
101
102 static void
103 unw_print_abreg (cp, abreg)
104 char * cp;
105 unsigned int abreg;
106 {
107 static const char *special_reg[16] =
108 {
109 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
110 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
111 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
112 };
113
114 switch ((abreg >> 5) & 0x3)
115 {
116 case 0: /* gr */
117 sprintf (cp, "r%u", (abreg & 0x1f));
118 break;
119
120 case 1: /* fr */
121 sprintf (cp, "f%u", (abreg & 0x1f));
122 break;
123
124 case 2: /* br */
125 sprintf (cp, "b%u", (abreg & 0x1f));
126 break;
127
128 case 3: /* special */
129 strcpy (cp, special_reg[abreg & 0xf]);
130 break;
131 }
132 }
133
134 static void
135 unw_print_xyreg (cp, x, ytreg)
136 char * cp;
137 unsigned int x;
138 unsigned int ytreg;
139 {
140 switch ((x << 1) | ((ytreg >> 7) & 1))
141 {
142 case 0: /* gr */
143 sprintf (cp, "r%u", (ytreg & 0x1f));
144 break;
145
146 case 1: /* fr */
147 sprintf (cp, "f%u", (ytreg & 0x1f));
148 break;
149
150 case 2: /* br */
151 sprintf (cp, "b%u", (ytreg & 0x1f));
152 break;
153 }
154 }
155
156 #define UNW_REG_BSP "bsp"
157 #define UNW_REG_BSPSTORE "bspstore"
158 #define UNW_REG_FPSR "fpsr"
159 #define UNW_REG_LC "lc"
160 #define UNW_REG_PFS "pfs"
161 #define UNW_REG_PR "pr"
162 #define UNW_REG_PSP "psp"
163 #define UNW_REG_RNAT "rnat"
164 #define UNW_REG_RP "rp"
165 #define UNW_REG_UNAT "unat"
166
167 typedef bfd_vma unw_word;
168
169 #define UNW_DEC_BAD_CODE(code) \
170 printf ("Unknown code 0x%02x\n", code)
171
172 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
173 do \
174 { \
175 unw_rlen = rlen; \
176 *(int *)arg = body; \
177 printf (" %s:%s(rlen=%lu)\n", \
178 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
179 } \
180 while (0)
181
182 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
183 do \
184 { \
185 char regname[16], maskstr[64], *sep; \
186 \
187 unw_rlen = rlen; \
188 *(int *)arg = 0; \
189 \
190 maskstr[0] = '\0'; \
191 sep = ""; \
192 if (mask & 0x8) \
193 { \
194 strcat (maskstr, "rp"); \
195 sep = ","; \
196 } \
197 if (mask & 0x4) \
198 { \
199 strcat (maskstr, sep); \
200 strcat (maskstr, "ar.pfs"); \
201 sep = ","; \
202 } \
203 if (mask & 0x2) \
204 { \
205 strcat (maskstr, sep); \
206 strcat (maskstr, "psp"); \
207 sep = ","; \
208 } \
209 if (mask & 0x1) \
210 { \
211 strcat (maskstr, sep); \
212 strcat (maskstr, "pr"); \
213 } \
214 sprintf (regname, "r%u", grsave); \
215 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
216 fmt, maskstr, regname, (unsigned long) rlen); \
217 } \
218 while (0)
219
220 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
221 do \
222 { \
223 char frstr[200]; \
224 \
225 unw_print_frmask (frstr, frmask); \
226 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
227 } \
228 while (0)
229
230 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
231 do \
232 { \
233 char grstr[200]; \
234 \
235 unw_print_grmask (grstr, grmask); \
236 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
237 } \
238 while (0)
239
240 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
241 do \
242 { \
243 char frstr[200], grstr[20]; \
244 \
245 unw_print_grmask (grstr, grmask); \
246 unw_print_frmask (frstr, frmask); \
247 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
248 } \
249 while (0)
250
251 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
252 do \
253 { \
254 char brstr[20]; \
255 \
256 unw_print_brmask (brstr, brmask); \
257 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
258 } \
259 while (0)
260
261 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
262 do \
263 { \
264 char brstr[20]; \
265 \
266 unw_print_brmask (brstr, brmask); \
267 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
268 } \
269 while (0)
270
271 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
272 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
273
274 #define UNW_DEC_RP_BR(fmt, dst, arg) \
275 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
276
277 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
278 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
279
280 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
281 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
282 fmt, reg, 4*(unsigned long)spoff)
283
284 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
285 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
286 fmt, reg, 4*(unsigned long)pspoff)
287
288 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
289 do \
290 { \
291 char grstr[20]; \
292 \
293 unw_print_grmask (grstr, grmask); \
294 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
295 } \
296 while (0)
297
298 #define UNW_DEC_ABI(fmt, abi, context, arg) \
299 do \
300 { \
301 static const char *abiname[] = \
302 { \
303 "@svr4", "@hpux", "@nt" \
304 }; \
305 char buf[20]; \
306 const char *abistr = buf; \
307 \
308 if (abi < 3) \
309 abistr = abiname[abi]; \
310 else \
311 sprintf (buf, "0x%x", abi); \
312 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
313 fmt, abistr, context); \
314 } \
315 while (0)
316
317 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
318 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
319
320 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
321 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
322
323 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
324 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
325
326 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
327 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
328 fmt, 4*(unsigned long)pspoff)
329
330 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
331 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
332 fmt, 4*(unsigned long)spoff)
333
334 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
335 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
336 fmt, (unsigned long) t, 16*(unsigned long)size)
337
338 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
339 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
340
341 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
342 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
343 fmt, 4*(unsigned long)pspoff)
344
345 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
346 do \
347 { \
348 static const char * spill_type = "-frb"; \
349 unsigned const char * imaskp = dp; \
350 unsigned char mask = 0; \
351 bfd_vma insn = 0; \
352 \
353 printf ("\t%s:spill_mask(imask=[", fmt); \
354 for (insn = 0; insn < unw_rlen; ++insn) \
355 { \
356 if ((insn % 4) == 0) \
357 mask = *imaskp++; \
358 if (insn > 0 && (insn % 3) == 0) \
359 putchar (','); \
360 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
361 } \
362 printf ("])\n"); \
363 dp = imaskp; \
364 } \
365 while (0)
366
367 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
368 do \
369 { \
370 char regname[10]; \
371 \
372 unw_print_abreg (regname, abreg); \
373 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
374 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
375 } \
376 while (0)
377
378 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
379 do \
380 { \
381 char regname[10]; \
382 \
383 unw_print_abreg (regname, abreg); \
384 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
385 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
386 } \
387 while (0)
388
389 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
390 do \
391 { \
392 char regname[10]; \
393 \
394 unw_print_abreg (regname, abreg); \
395 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
396 fmt, (unsigned long) t, regname); \
397 } \
398 while (0)
399
400 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
401 do \
402 { \
403 char abregname[10], tregname[10]; \
404 \
405 unw_print_abreg (abregname, abreg); \
406 unw_print_xyreg (tregname, x, ytreg); \
407 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
408 fmt, (unsigned long) t, abregname, tregname); \
409 } \
410 while (0)
411
412 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
413 do \
414 { \
415 char regname[20]; \
416 \
417 unw_print_abreg (regname, abreg); \
418 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
419 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
420 } \
421 while (0)
422
423 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
424 do \
425 { \
426 char regname[20]; \
427 \
428 unw_print_abreg (regname, abreg); \
429 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
430 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
431 } \
432 while (0)
433
434 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
435 do \
436 { \
437 char regname[20]; \
438 \
439 unw_print_abreg (regname, abreg); \
440 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
441 fmt, qp, (unsigned long) t, regname); \
442 } \
443 while (0)
444
445 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
446 do \
447 { \
448 char regname[20], tregname[20]; \
449 \
450 unw_print_abreg (regname, abreg); \
451 unw_print_xyreg (tregname, x, ytreg); \
452 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
453 fmt, qp, (unsigned long) t, regname, tregname); \
454 } \
455 while (0)
456
457 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
458 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
459
460 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
461 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
462
463 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
464 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
465 fmt, (unsigned long) t, (unsigned long) ecount)
466
467 /*
468 * Generic IA-64 unwind info decoder.
469 *
470 * This file is used both by the Linux kernel and objdump. Please
471 * keep the two copies of this file in sync (modulo differences in the
472 * prototypes...).
473 *
474 * You need to customize the decoder by defining the following
475 * macros/constants before including this file:
476 *
477 * Types:
478 * unw_word Unsigned integer type with at least 64 bits
479 *
480 * Register names:
481 * UNW_REG_BSP
482 * UNW_REG_BSPSTORE
483 * UNW_REG_FPSR
484 * UNW_REG_LC
485 * UNW_REG_PFS
486 * UNW_REG_PR
487 * UNW_REG_RNAT
488 * UNW_REG_PSP
489 * UNW_REG_RP
490 * UNW_REG_UNAT
491 *
492 * Decoder action macros:
493 * UNW_DEC_BAD_CODE(code)
494 * UNW_DEC_ABI(fmt,abi,context,arg)
495 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
496 * UNW_DEC_BR_MEM(fmt,brmask,arg)
497 * UNW_DEC_COPY_STATE(fmt,label,arg)
498 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
499 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
500 * UNW_DEC_FR_MEM(fmt,frmask,arg)
501 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
502 * UNW_DEC_GR_MEM(fmt,grmask,arg)
503 * UNW_DEC_LABEL_STATE(fmt,label,arg)
504 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
505 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
506 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
507 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
508 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
509 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
510 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
511 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
512 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
513 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
514 * UNW_DEC_REG_REG(fmt,src,dst,arg)
515 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
516 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
517 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
518 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
519 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
520 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
521 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
522 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
523 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
524 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
525 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
526 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
527 */
528
529 static unw_word unw_decode_uleb128 PARAMS ((const unsigned char **));
530 static const unsigned char *unw_decode_x1 PARAMS ((const unsigned char *,
531 unsigned int, void *));
532 static const unsigned char *unw_decode_x2 PARAMS ((const unsigned char *,
533 unsigned int, void *));
534 static const unsigned char *unw_decode_x3 PARAMS ((const unsigned char *,
535 unsigned int, void *));
536 static const unsigned char *unw_decode_x4 PARAMS ((const unsigned char *,
537 unsigned int, void *));
538 static const unsigned char *unw_decode_r1 PARAMS ((const unsigned char *,
539 unsigned int, void *));
540 static const unsigned char *unw_decode_r2 PARAMS ((const unsigned char *,
541 unsigned int, void *));
542 static const unsigned char *unw_decode_r3 PARAMS ((const unsigned char *,
543 unsigned int, void *));
544 static const unsigned char *unw_decode_p1 PARAMS ((const unsigned char *,
545 unsigned int, void *));
546 static const unsigned char *unw_decode_p2_p5 PARAMS ((const unsigned char *,
547 unsigned int, void *));
548 static const unsigned char *unw_decode_p6 PARAMS ((const unsigned char *,
549 unsigned int, void *));
550 static const unsigned char *unw_decode_p7_p10 PARAMS ((const unsigned char *,
551 unsigned int, void *));
552 static const unsigned char *unw_decode_b1 PARAMS ((const unsigned char *,
553 unsigned int, void *));
554 static const unsigned char *unw_decode_b2 PARAMS ((const unsigned char *,
555 unsigned int, void *));
556 static const unsigned char *unw_decode_b3_x4 PARAMS ((const unsigned char *,
557 unsigned int, void *));
558
559 static unw_word
560 unw_decode_uleb128 (dpp)
561 const unsigned char **dpp;
562 {
563 unsigned shift = 0;
564 unw_word byte, result = 0;
565 const unsigned char *bp = *dpp;
566
567 while (1)
568 {
569 byte = *bp++;
570 result |= (byte & 0x7f) << shift;
571
572 if ((byte & 0x80) == 0)
573 break;
574
575 shift += 7;
576 }
577
578 *dpp = bp;
579
580 return result;
581 }
582
583 static const unsigned char *
584 unw_decode_x1 (dp, code, arg)
585 const unsigned char * dp;
586 unsigned int code ATTRIBUTE_UNUSED;
587 void * arg ATTRIBUTE_UNUSED;
588 {
589 unsigned char byte1, abreg;
590 unw_word t, off;
591
592 byte1 = *dp++;
593 t = unw_decode_uleb128 (&dp);
594 off = unw_decode_uleb128 (&dp);
595 abreg = (byte1 & 0x7f);
596 if (byte1 & 0x80)
597 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
598 else
599 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
600 return dp;
601 }
602
603 static const unsigned char *
604 unw_decode_x2 (dp, code, arg)
605 const unsigned char * dp;
606 unsigned int code ATTRIBUTE_UNUSED;
607 void * arg ATTRIBUTE_UNUSED;
608 {
609 unsigned char byte1, byte2, abreg, x, ytreg;
610 unw_word t;
611
612 byte1 = *dp++;
613 byte2 = *dp++;
614 t = unw_decode_uleb128 (&dp);
615 abreg = (byte1 & 0x7f);
616 ytreg = byte2;
617 x = (byte1 >> 7) & 1;
618 if ((byte1 & 0x80) == 0 && ytreg == 0)
619 UNW_DEC_RESTORE ("X2", t, abreg, arg);
620 else
621 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
622 return dp;
623 }
624
625 static const unsigned char *
626 unw_decode_x3 (dp, code, arg)
627 const unsigned char * dp;
628 unsigned int code ATTRIBUTE_UNUSED;
629 void * arg ATTRIBUTE_UNUSED;
630 {
631 unsigned char byte1, byte2, abreg, qp;
632 unw_word t, off;
633
634 byte1 = *dp++;
635 byte2 = *dp++;
636 t = unw_decode_uleb128 (&dp);
637 off = unw_decode_uleb128 (&dp);
638
639 qp = (byte1 & 0x3f);
640 abreg = (byte2 & 0x7f);
641
642 if (byte1 & 0x80)
643 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
644 else
645 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
646 return dp;
647 }
648
649 static const unsigned char *
650 unw_decode_x4 (dp, code, arg)
651 const unsigned char * dp;
652 unsigned int code ATTRIBUTE_UNUSED;
653 void * arg ATTRIBUTE_UNUSED;
654 {
655 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
656 unw_word t;
657
658 byte1 = *dp++;
659 byte2 = *dp++;
660 byte3 = *dp++;
661 t = unw_decode_uleb128 (&dp);
662
663 qp = (byte1 & 0x3f);
664 abreg = (byte2 & 0x7f);
665 x = (byte2 >> 7) & 1;
666 ytreg = byte3;
667
668 if ((byte2 & 0x80) == 0 && byte3 == 0)
669 UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
670 else
671 UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
672 return dp;
673 }
674
675 static const unsigned char *
676 unw_decode_r1 (dp, code, arg)
677 const unsigned char *dp;
678 unsigned int code;
679 void *arg;
680 {
681 int body = (code & 0x20) != 0;
682 unw_word rlen;
683
684 rlen = (code & 0x1f);
685 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
686 return dp;
687 }
688
689 static const unsigned char *
690 unw_decode_r2 (dp, code, arg)
691 const unsigned char *dp;
692 unsigned int code;
693 void *arg;
694 {
695 unsigned char byte1, mask, grsave;
696 unw_word rlen;
697
698 byte1 = *dp++;
699
700 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
701 grsave = (byte1 & 0x7f);
702 rlen = unw_decode_uleb128 (& dp);
703 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
704 return dp;
705 }
706
707 static const unsigned char *
708 unw_decode_r3 (dp, code, arg)
709 const unsigned char *dp;
710 unsigned int code;
711 void *arg;
712 {
713 unw_word rlen;
714
715 rlen = unw_decode_uleb128 (& dp);
716 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
717 return dp;
718 }
719
720 static const unsigned char *
721 unw_decode_p1 (dp, code, arg)
722 const unsigned char * dp;
723 unsigned int code;
724 void * arg ATTRIBUTE_UNUSED;
725 {
726 unsigned char brmask = (code & 0x1f);
727
728 UNW_DEC_BR_MEM ("P1", brmask, arg);
729 return dp;
730 }
731
732 static const unsigned char *
733 unw_decode_p2_p5 (dp, code, arg)
734 const unsigned char * dp;
735 unsigned int code;
736 void * arg ATTRIBUTE_UNUSED;
737 {
738 if ((code & 0x10) == 0)
739 {
740 unsigned char byte1 = *dp++;
741
742 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
743 (byte1 & 0x7f), arg);
744 }
745 else if ((code & 0x08) == 0)
746 {
747 unsigned char byte1 = *dp++, r, dst;
748
749 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
750 dst = (byte1 & 0x7f);
751 switch (r)
752 {
753 case 0:
754 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
755 break;
756 case 1:
757 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
758 break;
759 case 2:
760 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
761 break;
762 case 3:
763 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
764 break;
765 case 4:
766 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
767 break;
768 case 5:
769 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
770 break;
771 case 6:
772 UNW_DEC_RP_BR ("P3", dst, arg);
773 break;
774 case 7:
775 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
776 break;
777 case 8:
778 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
779 break;
780 case 9:
781 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
782 break;
783 case 10:
784 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
785 break;
786 case 11:
787 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
788 break;
789 default:
790 UNW_DEC_BAD_CODE (r);
791 break;
792 }
793 }
794 else if ((code & 0x7) == 0)
795 UNW_DEC_SPILL_MASK ("P4", dp, arg);
796 else if ((code & 0x7) == 1)
797 {
798 unw_word grmask, frmask, byte1, byte2, byte3;
799
800 byte1 = *dp++;
801 byte2 = *dp++;
802 byte3 = *dp++;
803 grmask = ((byte1 >> 4) & 0xf);
804 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
805 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
806 }
807 else
808 UNW_DEC_BAD_CODE (code);
809
810 return dp;
811 }
812
813 static const unsigned char *
814 unw_decode_p6 (dp, code, arg)
815 const unsigned char * dp;
816 unsigned int code;
817 void * arg ATTRIBUTE_UNUSED;
818 {
819 int gregs = (code & 0x10) != 0;
820 unsigned char mask = (code & 0x0f);
821
822 if (gregs)
823 UNW_DEC_GR_MEM ("P6", mask, arg);
824 else
825 UNW_DEC_FR_MEM ("P6", mask, arg);
826 return dp;
827 }
828
829 static const unsigned char *
830 unw_decode_p7_p10 (dp, code, arg)
831 const unsigned char *dp;
832 unsigned int code;
833 void *arg;
834 {
835 unsigned char r, byte1, byte2;
836 unw_word t, size;
837
838 if ((code & 0x10) == 0)
839 {
840 r = (code & 0xf);
841 t = unw_decode_uleb128 (&dp);
842 switch (r)
843 {
844 case 0:
845 size = unw_decode_uleb128 (&dp);
846 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
847 break;
848
849 case 1:
850 UNW_DEC_MEM_STACK_V ("P7", t, arg);
851 break;
852 case 2:
853 UNW_DEC_SPILL_BASE ("P7", t, arg);
854 break;
855 case 3:
856 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
857 break;
858 case 4:
859 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
860 break;
861 case 5:
862 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
863 break;
864 case 6:
865 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
866 break;
867 case 7:
868 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
869 break;
870 case 8:
871 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
872 break;
873 case 9:
874 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
875 break;
876 case 10:
877 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
878 break;
879 case 11:
880 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
881 break;
882 case 12:
883 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
884 break;
885 case 13:
886 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
887 break;
888 case 14:
889 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
890 break;
891 case 15:
892 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
893 break;
894 default:
895 UNW_DEC_BAD_CODE (r);
896 break;
897 }
898 }
899 else
900 {
901 switch (code & 0xf)
902 {
903 case 0x0: /* p8 */
904 {
905 r = *dp++;
906 t = unw_decode_uleb128 (&dp);
907 switch (r)
908 {
909 case 1:
910 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
911 break;
912 case 2:
913 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
914 break;
915 case 3:
916 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
917 break;
918 case 4:
919 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
920 break;
921 case 5:
922 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
923 break;
924 case 6:
925 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
926 break;
927 case 7:
928 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
929 break;
930 case 8:
931 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
932 break;
933 case 9:
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
935 break;
936 case 10:
937 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
938 break;
939 case 11:
940 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
941 break;
942 case 12:
943 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
944 break;
945 case 13:
946 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
947 break;
948 case 14:
949 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
950 break;
951 case 15:
952 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
953 break;
954 case 16:
955 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
956 break;
957 case 17:
958 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
959 break;
960 case 18:
961 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
962 break;
963 case 19:
964 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
965 break;
966 default:
967 UNW_DEC_BAD_CODE (r);
968 break;
969 }
970 }
971 break;
972
973 case 0x1:
974 byte1 = *dp++;
975 byte2 = *dp++;
976 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
977 break;
978
979 case 0xf: /* p10 */
980 byte1 = *dp++;
981 byte2 = *dp++;
982 UNW_DEC_ABI ("P10", byte1, byte2, arg);
983 break;
984
985 case 0x9:
986 return unw_decode_x1 (dp, code, arg);
987
988 case 0xa:
989 return unw_decode_x2 (dp, code, arg);
990
991 case 0xb:
992 return unw_decode_x3 (dp, code, arg);
993
994 case 0xc:
995 return unw_decode_x4 (dp, code, arg);
996
997 default:
998 UNW_DEC_BAD_CODE (code);
999 break;
1000 }
1001 }
1002 return dp;
1003 }
1004
1005 static const unsigned char *
1006 unw_decode_b1 (dp, code, arg)
1007 const unsigned char * dp;
1008 unsigned int code;
1009 void * arg ATTRIBUTE_UNUSED;
1010 {
1011 unw_word label = (code & 0x1f);
1012
1013 if ((code & 0x20) != 0)
1014 UNW_DEC_COPY_STATE ("B1", label, arg);
1015 else
1016 UNW_DEC_LABEL_STATE ("B1", label, arg);
1017 return dp;
1018 }
1019
1020 static const unsigned char *
1021 unw_decode_b2 (dp, code, arg)
1022 const unsigned char * dp;
1023 unsigned int code;
1024 void * arg ATTRIBUTE_UNUSED;
1025 {
1026 unw_word t;
1027
1028 t = unw_decode_uleb128 (& dp);
1029 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1030 return dp;
1031 }
1032
1033 static const unsigned char *
1034 unw_decode_b3_x4 (dp, code, arg)
1035 const unsigned char *dp;
1036 unsigned int code;
1037 void *arg;
1038 {
1039 unw_word t, ecount, label;
1040
1041 if ((code & 0x10) == 0)
1042 {
1043 t = unw_decode_uleb128 (&dp);
1044 ecount = unw_decode_uleb128 (&dp);
1045 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1046 }
1047 else if ((code & 0x07) == 0)
1048 {
1049 label = unw_decode_uleb128 (&dp);
1050 if ((code & 0x08) != 0)
1051 UNW_DEC_COPY_STATE ("B4", label, arg);
1052 else
1053 UNW_DEC_LABEL_STATE ("B4", label, arg);
1054 }
1055 else
1056 switch (code & 0x7)
1057 {
1058 case 1:
1059 return unw_decode_x1 (dp, code, arg);
1060 case 2:
1061 return unw_decode_x2 (dp, code, arg);
1062 case 3:
1063 return unw_decode_x3 (dp, code, arg);
1064 case 4:
1065 return unw_decode_x4 (dp, code, arg);
1066 default:
1067 UNW_DEC_BAD_CODE (code);
1068 break;
1069 }
1070 return dp;
1071 }
1072
1073 typedef const unsigned char *(*unw_decoder)
1074 PARAMS ((const unsigned char *, unsigned char, void *));
1075
1076 static unw_decoder unw_decode_table[2][8] =
1077 {
1078 /* prologue table: */
1079 {
1080 unw_decode_r1, /* 0 */
1081 unw_decode_r1,
1082 unw_decode_r2,
1083 unw_decode_r3,
1084 unw_decode_p1, /* 4 */
1085 unw_decode_p2_p5,
1086 unw_decode_p6,
1087 unw_decode_p7_p10
1088 },
1089 {
1090 unw_decode_r1, /* 0 */
1091 unw_decode_r1,
1092 unw_decode_r2,
1093 unw_decode_r3,
1094 unw_decode_b1, /* 4 */
1095 unw_decode_b1,
1096 unw_decode_b2,
1097 unw_decode_b3_x4
1098 }
1099 };
1100
1101 /* Decode one descriptor and return address of next descriptor. */
1102 const unsigned char *
1103 unw_decode (dp, inside_body, ptr_inside_body)
1104 const unsigned char * dp;
1105 int inside_body;
1106 void * ptr_inside_body;
1107 {
1108 unw_decoder decoder;
1109 unsigned char code;
1110
1111 code = *dp++;
1112 decoder = unw_decode_table[inside_body][code >> 5];
1113 return (*decoder) (dp, code, ptr_inside_body);
1114 }
This page took 0.054153 seconds and 5 git commands to generate.