1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright (c) 2000, 2001 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of GNU Binutils.
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)
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.
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. */
21 #include "unwind-ia64.h"
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. */
34 static bfd_vma unw_rlen = 0;
37 unw_print_brmask (cp, mask)
44 for (i = 0; mask && (i < 5); ++i)
48 cp += sprintf (cp, "%sb%u", sep, i + 1);
57 unw_print_grmask (cp, mask)
65 for (i = 0; i < 4; ++i)
69 cp += sprintf (cp, "%sr%u", sep, i + 4);
77 unw_print_frmask (cp, mask)
85 for (i = 0; i < 20; ++i)
89 cp += sprintf (cp, "%sf%u", sep, (i < 4) ? (i + 2) : (i + 12));
97 unw_print_abreg (cp, abreg)
101 static const char *special_reg[16] =
103 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
104 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
105 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
108 switch ((abreg >> 5) & 0x3)
111 sprintf (cp, "r%u", (abreg & 0x1f));
115 sprintf (cp, "f%u", (abreg & 0x1f));
119 sprintf (cp, "b%u", (abreg & 0x1f));
122 case 3: /* special */
123 strcpy (cp, special_reg[abreg & 0xf]);
129 unw_print_xyreg (cp, x, ytreg)
134 switch ((x << 1) | ((ytreg >> 7) & 1))
137 sprintf (cp, "r%u", (ytreg & 0x1f));
141 sprintf (cp, "f%u", (ytreg & 0x1f));
145 sprintf (cp, "b%u", (ytreg & 0x1f));
150 #define UNW_REG_BSP "bsp"
151 #define UNW_REG_BSPSTORE "bspstore"
152 #define UNW_REG_FPSR "fpsr"
153 #define UNW_REG_LC "lc"
154 #define UNW_REG_PFS "pfs"
155 #define UNW_REG_PR "pr"
156 #define UNW_REG_PSP "psp"
157 #define UNW_REG_RNAT "rnat"
158 #define UNW_REG_RP "rp"
159 #define UNW_REG_UNAT "unat"
161 typedef bfd_vma unw_word;
163 #define UNW_DEC_BAD_CODE(code) \
164 printf ("Unknown code 0x%02x\n", code)
166 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
170 *(int *)arg = body; \
171 printf (" %s:%s(rlen=%lu)\n", \
172 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
176 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
179 char regname[16], maskstr[64], *sep; \
188 strcat (maskstr, "rp"); \
193 strcat (maskstr, sep); \
194 strcat (maskstr, "ar.pfs"); \
199 strcat (maskstr, sep); \
200 strcat (maskstr, "psp"); \
205 strcat (maskstr, sep); \
206 strcat (maskstr, "pr"); \
208 sprintf (regname, "r%u", grsave); \
209 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
210 fmt, maskstr, regname, (unsigned long) rlen); \
214 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
219 unw_print_frmask (frstr, frmask); \
220 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
224 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
229 unw_print_grmask (grstr, grmask); \
230 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
234 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
237 char frstr[200], grstr[20]; \
239 unw_print_grmask (grstr, grmask); \
240 unw_print_frmask (frstr, frmask); \
241 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
245 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
250 unw_print_brmask (brstr, brmask); \
251 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
255 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
260 unw_print_brmask (brstr, brmask); \
261 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
265 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
266 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
268 #define UNW_DEC_RP_BR(fmt, dst, arg) \
269 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
271 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
272 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
274 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
275 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
276 fmt, reg, 4*(unsigned long)spoff)
278 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
279 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
280 fmt, reg, 4*(unsigned long)pspoff)
282 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
287 unw_print_grmask (grstr, grmask); \
288 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
292 #define UNW_DEC_ABI(fmt, abi, context, arg) \
295 static const char *abiname[] = \
297 "@svr4", "@hpux", "@nt" \
300 const char *abistr = buf; \
303 abistr = abiname[abi]; \
305 sprintf (buf, "0x%x", abi); \
306 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
307 fmt, abistr, context); \
311 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
312 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
314 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
315 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
317 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
318 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
320 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
321 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
322 fmt, 4*(unsigned long)pspoff)
324 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
325 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
326 fmt, 4*(unsigned long)spoff)
328 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
329 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
330 fmt, (unsigned long) t, 16*(unsigned long)size)
332 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
333 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
335 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
336 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
337 fmt, 4*(unsigned long)pspoff)
339 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
342 static const char * spill_type = "-frb"; \
343 unsigned const char * imaskp = dp; \
344 unsigned char mask = 0; \
347 printf ("\t%s:spill_mask(imask=[", fmt); \
348 for (insn = 0; insn < unw_rlen; ++insn) \
350 if ((insn % 4) == 0) \
352 if (insn > 0 && (insn % 3) == 0) \
354 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
361 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
366 unw_print_abreg (regname, abreg); \
367 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
368 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
372 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
377 unw_print_abreg (regname, abreg); \
378 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
379 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
383 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
388 unw_print_abreg (regname, abreg); \
389 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
390 fmt, (unsigned long) t, regname); \
394 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
397 char abregname[10], tregname[10]; \
399 unw_print_abreg (abregname, abreg); \
400 unw_print_xyreg (tregname, x, ytreg); \
401 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
402 fmt, (unsigned long) t, abregname, tregname); \
406 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
411 unw_print_abreg (regname, abreg); \
412 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
413 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
417 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
422 unw_print_abreg (regname, abreg); \
423 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
424 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
428 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
433 unw_print_abreg (regname, abreg); \
434 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
435 fmt, qp, (unsigned long) t, regname); \
439 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
442 char regname[20], tregname[20]; \
444 unw_print_abreg (regname, abreg); \
445 unw_print_xyreg (tregname, x, ytreg); \
446 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
447 fmt, qp, (unsigned long) t, regname, tregname); \
451 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
452 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
454 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
455 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
457 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
458 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
459 fmt, (unsigned long) t, (unsigned long) ecount)
462 * Generic IA-64 unwind info decoder.
464 * This file is used both by the Linux kernel and objdump. Please
465 * keep the two copies of this file in sync (modulo differences in the
468 * You need to customize the decoder by defining the following
469 * macros/constants before including this file:
472 * unw_word Unsigned integer type with at least 64 bits
486 * Decoder action macros:
487 * UNW_DEC_BAD_CODE(code)
488 * UNW_DEC_ABI(fmt,abi,context,arg)
489 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
490 * UNW_DEC_BR_MEM(fmt,brmask,arg)
491 * UNW_DEC_COPY_STATE(fmt,label,arg)
492 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
493 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
494 * UNW_DEC_FR_MEM(fmt,frmask,arg)
495 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
496 * UNW_DEC_GR_MEM(fmt,grmask,arg)
497 * UNW_DEC_LABEL_STATE(fmt,label,arg)
498 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
499 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
500 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
501 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
502 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
503 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
504 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
505 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
506 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
507 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
508 * UNW_DEC_REG_REG(fmt,src,dst,arg)
509 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
510 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
511 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
512 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
513 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
514 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
515 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
516 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
517 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
518 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
519 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
520 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
523 static unw_word unw_decode_uleb128 PARAMS ((const unsigned char **));
524 static const unsigned char *unw_decode_x1 PARAMS ((const unsigned char *,
525 unsigned char, void *));
526 static const unsigned char *unw_decode_x2 PARAMS ((const unsigned char *,
527 unsigned char, void *));
528 static const unsigned char *unw_decode_x3 PARAMS ((const unsigned char *,
529 unsigned char, void *));
530 static const unsigned char *unw_decode_x4 PARAMS ((const unsigned char *,
531 unsigned char, void *));
532 static const unsigned char *unw_decode_r1 PARAMS ((const unsigned char *,
533 unsigned char, void *));
534 static const unsigned char *unw_decode_r2 PARAMS ((const unsigned char *,
535 unsigned char, void *));
536 static const unsigned char *unw_decode_r3 PARAMS ((const unsigned char *,
537 unsigned char, void *));
538 static const unsigned char *unw_decode_p1 PARAMS ((const unsigned char *,
539 unsigned char, void *));
540 static const unsigned char *unw_decode_p2_p5 PARAMS ((const unsigned char *,
541 unsigned char, void *));
542 static const unsigned char *unw_decode_p6 PARAMS ((const unsigned char *,
543 unsigned char, void *));
544 static const unsigned char *unw_decode_p7_p10 PARAMS ((const unsigned char *,
545 unsigned char, void *));
546 static const unsigned char *unw_decode_b1 PARAMS ((const unsigned char *,
547 unsigned char, void *));
548 static const unsigned char *unw_decode_b2 PARAMS ((const unsigned char *,
549 unsigned char, void *));
550 static const unsigned char *unw_decode_b3_x4 PARAMS ((const unsigned char *,
551 unsigned char, void *));
554 unw_decode_uleb128 (dpp)
555 const unsigned char **dpp;
558 unw_word byte, result = 0;
559 const unsigned char *bp = *dpp;
564 result |= (byte & 0x7f) << shift;
566 if ((byte & 0x80) == 0)
577 static const unsigned char *
578 unw_decode_x1 (dp, code, arg)
579 const unsigned char * dp;
581 void * arg ATTRIBUTE_UNUSED;
583 unsigned char byte1, abreg;
587 t = unw_decode_uleb128 (&dp);
588 off = unw_decode_uleb128 (&dp);
589 abreg = (byte1 & 0x7f);
591 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
593 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
597 static const unsigned char *
598 unw_decode_x2 (dp, code, arg)
599 const unsigned char * dp;
601 void * arg ATTRIBUTE_UNUSED;
603 unsigned char byte1, byte2, abreg, x, ytreg;
608 t = unw_decode_uleb128 (&dp);
609 abreg = (byte1 & 0x7f);
611 x = (byte1 >> 7) & 1;
612 if ((byte1 & 0x80) == 0 && ytreg == 0)
613 UNW_DEC_RESTORE ("X2", t, abreg, arg);
615 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
619 static const unsigned char *
620 unw_decode_x3 (dp, code, arg)
621 const unsigned char * dp;
623 void * arg ATTRIBUTE_UNUSED;
625 unsigned char byte1, byte2, abreg, qp;
630 t = unw_decode_uleb128 (&dp);
631 off = unw_decode_uleb128 (&dp);
634 abreg = (byte2 & 0x7f);
637 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
639 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
643 static const unsigned char *
644 unw_decode_x4 (dp, code, arg)
645 const unsigned char * dp;
647 void * arg ATTRIBUTE_UNUSED;
649 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
655 t = unw_decode_uleb128 (&dp);
658 abreg = (byte2 & 0x7f);
659 x = (byte2 >> 7) & 1;
662 if ((byte2 & 0x80) == 0 && byte3 == 0)
663 UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
665 UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
669 static const unsigned char *
670 unw_decode_r1 (dp, code, arg)
671 const unsigned char *dp;
675 int body = (code & 0x20) != 0;
678 rlen = (code & 0x1f);
679 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
683 static const unsigned char *
684 unw_decode_r2 (dp, code, arg)
685 const unsigned char *dp;
689 unsigned char byte1, mask, grsave;
694 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
695 grsave = (byte1 & 0x7f);
696 rlen = unw_decode_uleb128 (& dp);
697 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
701 static const unsigned char *
702 unw_decode_r3 (dp, code, arg)
703 const unsigned char *dp;
709 rlen = unw_decode_uleb128 (& dp);
710 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
714 static const unsigned char *
715 unw_decode_p1 (dp, code, arg)
716 const unsigned char * dp;
718 void * arg ATTRIBUTE_UNUSED;
720 unsigned char brmask = (code & 0x1f);
722 UNW_DEC_BR_MEM ("P1", brmask, arg);
726 static const unsigned char *
727 unw_decode_p2_p5 (dp, code, arg)
728 const unsigned char * dp;
730 void * arg ATTRIBUTE_UNUSED;
732 if ((code & 0x10) == 0)
734 unsigned char byte1 = *dp++;
736 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
737 (byte1 & 0x7f), arg);
739 else if ((code & 0x08) == 0)
741 unsigned char byte1 = *dp++, r, dst;
743 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
744 dst = (byte1 & 0x7f);
748 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
751 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
754 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
757 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
760 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
763 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
766 UNW_DEC_RP_BR ("P3", dst, arg);
769 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
772 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
775 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
778 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
781 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
784 UNW_DEC_BAD_CODE (r);
788 else if ((code & 0x7) == 0)
789 UNW_DEC_SPILL_MASK ("P4", dp, arg);
790 else if ((code & 0x7) == 1)
792 unw_word grmask, frmask, byte1, byte2, byte3;
797 grmask = ((byte1 >> 4) & 0xf);
798 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
799 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
802 UNW_DEC_BAD_CODE (code);
807 static const unsigned char *
808 unw_decode_p6 (dp, code, arg)
809 const unsigned char * dp;
811 void * arg ATTRIBUTE_UNUSED;
813 int gregs = (code & 0x10) != 0;
814 unsigned char mask = (code & 0x0f);
817 UNW_DEC_GR_MEM ("P6", mask, arg);
819 UNW_DEC_FR_MEM ("P6", mask, arg);
823 static const unsigned char *
824 unw_decode_p7_p10 (dp, code, arg)
825 const unsigned char *dp;
829 unsigned char r, byte1, byte2;
832 if ((code & 0x10) == 0)
835 t = unw_decode_uleb128 (&dp);
839 size = unw_decode_uleb128 (&dp);
840 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
844 UNW_DEC_MEM_STACK_V ("P7", t, arg);
847 UNW_DEC_SPILL_BASE ("P7", t, arg);
850 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
853 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
856 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
859 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
862 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
865 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
868 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
871 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
874 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
877 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
880 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
883 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
886 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
889 UNW_DEC_BAD_CODE (r);
900 t = unw_decode_uleb128 (&dp);
904 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
907 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
910 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
913 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
916 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
919 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
922 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
925 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
928 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
931 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
934 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
937 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
940 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
943 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
946 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
949 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
952 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
955 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
958 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
961 UNW_DEC_BAD_CODE (r);
970 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
976 UNW_DEC_ABI ("P10", byte1, byte2, arg);
980 return unw_decode_x1 (dp, code, arg);
983 return unw_decode_x2 (dp, code, arg);
986 return unw_decode_x3 (dp, code, arg);
989 return unw_decode_x4 (dp, code, arg);
992 UNW_DEC_BAD_CODE (code);
999 static const unsigned char *
1000 unw_decode_b1 (dp, code, arg)
1001 const unsigned char * dp;
1003 void * arg ATTRIBUTE_UNUSED;
1005 unw_word label = (code & 0x1f);
1007 if ((code & 0x20) != 0)
1008 UNW_DEC_COPY_STATE ("B1", label, arg);
1010 UNW_DEC_LABEL_STATE ("B1", label, arg);
1014 static const unsigned char *
1015 unw_decode_b2 (dp, code, arg)
1016 const unsigned char * dp;
1018 void * arg ATTRIBUTE_UNUSED;
1022 t = unw_decode_uleb128 (& dp);
1023 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1027 static const unsigned char *
1028 unw_decode_b3_x4 (dp, code, arg)
1029 const unsigned char *dp;
1033 unw_word t, ecount, label;
1035 if ((code & 0x10) == 0)
1037 t = unw_decode_uleb128 (&dp);
1038 ecount = unw_decode_uleb128 (&dp);
1039 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1041 else if ((code & 0x07) == 0)
1043 label = unw_decode_uleb128 (&dp);
1044 if ((code & 0x08) != 0)
1045 UNW_DEC_COPY_STATE ("B4", label, arg);
1047 UNW_DEC_LABEL_STATE ("B4", label, arg);
1053 return unw_decode_x1 (dp, code, arg);
1055 return unw_decode_x2 (dp, code, arg);
1057 return unw_decode_x3 (dp, code, arg);
1059 return unw_decode_x4 (dp, code, arg);
1061 UNW_DEC_BAD_CODE (code);
1067 typedef const unsigned char *(*unw_decoder)
1068 PARAMS ((const unsigned char *, unsigned char, void *));
1070 static unw_decoder unw_decode_table[2][8] =
1072 /* prologue table: */
1074 unw_decode_r1, /* 0 */
1078 unw_decode_p1, /* 4 */
1084 unw_decode_r1, /* 0 */
1088 unw_decode_b1, /* 4 */
1095 /* Decode one descriptor and return address of next descriptor. */
1096 const unsigned char *
1097 unw_decode (dp, inside_body, ptr_inside_body)
1098 const unsigned char * dp;
1100 void * ptr_inside_body;
1102 unw_decoder decoder;
1106 decoder = unw_decode_table[inside_body][code >> 5];
1107 return (*decoder) (dp, code, ptr_inside_body);