1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright 2000, 2001, 2002, 2003, 2005, 2007, 2012
3 Free Software Foundation, Inc.
5 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
7 This file is part of GNU Binutils.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
25 #include "unwind-ia64.h"
30 /* Define BFD64 here, even if our default architecture is 32 bit ELF
31 as this will allow us to read in and parse 64bit and 32bit ELF files.
32 Only do this if we believe that the compiler can support a 64 bit
33 data type. For now we only rely on GCC being able to do this. */
38 static bfd_vma unw_rlen
= 0;
40 static void unw_print_brmask (char *, unsigned int);
41 static void unw_print_grmask (char *, unsigned int);
42 static void unw_print_frmask (char *, unsigned int);
43 static void unw_print_abreg (char *, unsigned int);
44 static void unw_print_xyreg (char *, unsigned int, unsigned int);
47 unw_print_brmask (char *cp
, unsigned int mask
)
52 for (i
= 0; mask
&& (i
< 5); ++i
)
68 unw_print_grmask (char *cp
, unsigned int mask
)
73 for (i
= 0; i
< 4; ++i
)
89 unw_print_frmask (char *cp
, unsigned int mask
)
94 for (i
= 0; i
< 20; ++i
)
105 *cp
++ = (i
+ 2) / 10 + 1 + '0';
106 *cp
++ = (i
+ 2) % 10 + '0';
116 unw_print_abreg (char *cp
, unsigned int abreg
)
118 static const char * const special_reg
[16] =
120 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
121 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
122 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
125 switch ((abreg
>> 5) & 0x3)
128 sprintf (cp
, "r%u", (abreg
& 0x1f));
132 sprintf (cp
, "f%u", (abreg
& 0x1f));
136 sprintf (cp
, "b%u", (abreg
& 0x1f));
139 case 3: /* special */
140 strcpy (cp
, special_reg
[abreg
& 0xf]);
146 unw_print_xyreg (char *cp
, unsigned int x
, unsigned int ytreg
)
148 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
151 sprintf (cp
, "r%u", (ytreg
& 0x1f));
155 sprintf (cp
, "f%u", (ytreg
& 0x1f));
159 sprintf (cp
, "b%u", (ytreg
& 0x1f));
164 #define UNW_REG_BSP "bsp"
165 #define UNW_REG_BSPSTORE "bspstore"
166 #define UNW_REG_FPSR "fpsr"
167 #define UNW_REG_LC "lc"
168 #define UNW_REG_PFS "pfs"
169 #define UNW_REG_PR "pr"
170 #define UNW_REG_PSP "psp"
171 #define UNW_REG_RNAT "rnat"
172 #define UNW_REG_RP "rp"
173 #define UNW_REG_UNAT "unat"
175 typedef bfd_vma unw_word
;
177 #define UNW_DEC_BAD_CODE(code) \
178 printf ("Unknown code 0x%02x\n", code)
180 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
184 *(int *)arg = body; \
185 printf (" %s:%s(rlen=%lu)\n", \
186 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
190 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
193 char regname[16], maskstr[64], *sep; \
202 strcat (maskstr, "rp"); \
207 strcat (maskstr, sep); \
208 strcat (maskstr, "ar.pfs"); \
213 strcat (maskstr, sep); \
214 strcat (maskstr, "psp"); \
219 strcat (maskstr, sep); \
220 strcat (maskstr, "pr"); \
222 sprintf (regname, "r%u", grsave); \
223 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
224 fmt, maskstr, regname, (unsigned long) rlen); \
228 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
233 unw_print_frmask (frstr, frmask); \
234 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
238 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
243 unw_print_grmask (grstr, grmask); \
244 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
248 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
251 char frstr[200], grstr[20]; \
253 unw_print_grmask (grstr, grmask); \
254 unw_print_frmask (frstr, frmask); \
255 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
259 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
264 unw_print_brmask (brstr, brmask); \
265 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
269 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
274 unw_print_brmask (brstr, brmask); \
275 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
279 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
280 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
282 #define UNW_DEC_RP_BR(fmt, dst, arg) \
283 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
285 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
286 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
288 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
289 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
290 fmt, reg, 4*(unsigned long)spoff)
292 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
293 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
294 fmt, reg, 4*(unsigned long)pspoff)
296 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
301 unw_print_grmask (grstr, grmask); \
302 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
306 #define UNW_DEC_ABI(fmt, abi, context, arg) \
309 static const char * const abiname[] = \
311 "@svr4", "@hpux", "@nt" \
314 const char *abistr = buf; \
317 abistr = abiname[abi]; \
319 sprintf (buf, "0x%x", abi); \
320 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
321 fmt, abistr, context); \
325 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
326 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
328 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
329 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
331 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
332 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
334 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
335 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
336 fmt, 4*(unsigned long)pspoff)
338 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
339 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
340 fmt, 4*(unsigned long)spoff)
342 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
343 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
344 fmt, (unsigned long) t, 16*(unsigned long)size)
346 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
347 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
349 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
350 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
351 fmt, 4*(unsigned long)pspoff)
353 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
356 static const char *spill_type = "-frb"; \
357 unsigned const char *imaskp = dp; \
358 unsigned char mask = 0; \
361 printf ("\t%s:spill_mask(imask=[", fmt); \
362 for (insn = 0; insn < unw_rlen; ++insn) \
364 if ((insn % 4) == 0) \
366 if (insn > 0 && (insn % 3) == 0) \
368 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
375 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
380 unw_print_abreg (regname, abreg); \
381 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
382 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
386 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
391 unw_print_abreg (regname, abreg); \
392 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
393 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
397 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
402 unw_print_abreg (regname, abreg); \
403 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
404 fmt, (unsigned long) t, regname); \
408 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
411 char abregname[20], tregname[20]; \
413 unw_print_abreg (abregname, abreg); \
414 unw_print_xyreg (tregname, x, ytreg); \
415 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
416 fmt, (unsigned long) t, abregname, tregname); \
420 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
425 unw_print_abreg (regname, abreg); \
426 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
427 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
431 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
436 unw_print_abreg (regname, abreg); \
437 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
438 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
442 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
447 unw_print_abreg (regname, abreg); \
448 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
449 fmt, qp, (unsigned long) t, regname); \
453 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
456 char regname[20], tregname[20]; \
458 unw_print_abreg (regname, abreg); \
459 unw_print_xyreg (tregname, x, ytreg); \
460 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
461 fmt, qp, (unsigned long) t, regname, tregname); \
465 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
466 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
468 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
469 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
471 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
472 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
473 fmt, (unsigned long) t, (unsigned long) ecount)
476 * Generic IA-64 unwind info decoder.
478 * This file is used both by the Linux kernel and objdump. Please
479 * keep the two copies of this file in sync (modulo differences in the
482 * You need to customize the decoder by defining the following
483 * macros/constants before including this file:
486 * unw_word Unsigned integer type with at least 64 bits
500 * Decoder action macros:
501 * UNW_DEC_BAD_CODE(code)
502 * UNW_DEC_ABI(fmt,abi,context,arg)
503 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
504 * UNW_DEC_BR_MEM(fmt,brmask,arg)
505 * UNW_DEC_COPY_STATE(fmt,label,arg)
506 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
507 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
508 * UNW_DEC_FR_MEM(fmt,frmask,arg)
509 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
510 * UNW_DEC_GR_MEM(fmt,grmask,arg)
511 * UNW_DEC_LABEL_STATE(fmt,label,arg)
512 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
513 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
514 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
515 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
516 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
517 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
518 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
519 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
520 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
521 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
522 * UNW_DEC_REG_REG(fmt,src,dst,arg)
523 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
524 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
525 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
526 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
527 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
528 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
529 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
530 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
531 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
532 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
533 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
534 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
537 static unw_word
unw_decode_uleb128 (const unsigned char **);
538 static const unsigned char *unw_decode_x1
539 (const unsigned char *, unsigned int, void *);
540 static const unsigned char *unw_decode_x2
541 (const unsigned char *, unsigned int, void *);
542 static const unsigned char *unw_decode_x3
543 (const unsigned char *, unsigned int, void *);
544 static const unsigned char *unw_decode_x4
545 (const unsigned char *, unsigned int, void *);
546 static const unsigned char *unw_decode_r1
547 (const unsigned char *, unsigned int, void *);
548 static const unsigned char *unw_decode_r2
549 (const unsigned char *, unsigned int, void *);
550 static const unsigned char *unw_decode_r3
551 (const unsigned char *, unsigned int, void *);
552 static const unsigned char *unw_decode_p1
553 (const unsigned char *, unsigned int, void *);
554 static const unsigned char *unw_decode_p2_p5
555 (const unsigned char *, unsigned int, void *);
556 static const unsigned char *unw_decode_p6
557 (const unsigned char *, unsigned int, void *);
558 static const unsigned char *unw_decode_p7_p10
559 (const unsigned char *, unsigned int, void *);
560 static const unsigned char *unw_decode_b1
561 (const unsigned char *, unsigned int, void *);
562 static const unsigned char *unw_decode_b2
563 (const unsigned char *, unsigned int, void *);
564 static const unsigned char *unw_decode_b3_x4
565 (const unsigned char *, unsigned int, void *);
568 unw_decode_uleb128 (const unsigned char **dpp
)
571 unw_word byte
, result
= 0;
572 const unsigned char *bp
= *dpp
;
577 result
|= (byte
& 0x7f) << shift
;
579 if ((byte
& 0x80) == 0)
590 static const unsigned char *
591 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
592 void *arg ATTRIBUTE_UNUSED
)
594 unsigned char byte1
, abreg
;
598 t
= unw_decode_uleb128 (&dp
);
599 off
= unw_decode_uleb128 (&dp
);
600 abreg
= (byte1
& 0x7f);
602 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
604 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
608 static const unsigned char *
609 unw_decode_x2 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
610 void *arg ATTRIBUTE_UNUSED
)
612 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
617 t
= unw_decode_uleb128 (&dp
);
618 abreg
= (byte1
& 0x7f);
620 x
= (byte1
>> 7) & 1;
621 if ((byte1
& 0x80) == 0 && ytreg
== 0)
622 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
624 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
628 static const unsigned char *
629 unw_decode_x3 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
630 void *arg ATTRIBUTE_UNUSED
)
632 unsigned char byte1
, byte2
, abreg
, qp
;
637 t
= unw_decode_uleb128 (&dp
);
638 off
= unw_decode_uleb128 (&dp
);
641 abreg
= (byte2
& 0x7f);
644 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
646 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
650 static const unsigned char *
651 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
652 void *arg ATTRIBUTE_UNUSED
)
654 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
660 t
= unw_decode_uleb128 (&dp
);
663 abreg
= (byte2
& 0x7f);
664 x
= (byte2
>> 7) & 1;
667 if ((byte2
& 0x80) == 0 && byte3
== 0)
668 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
670 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
674 static const unsigned char *
675 unw_decode_r1 (const unsigned char *dp
, unsigned int code
, void *arg
)
677 int body
= (code
& 0x20) != 0;
680 rlen
= (code
& 0x1f);
681 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
685 static const unsigned char *
686 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
)
688 unsigned char byte1
, mask
, grsave
;
693 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
694 grsave
= (byte1
& 0x7f);
695 rlen
= unw_decode_uleb128 (& dp
);
696 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
700 static const unsigned char *
701 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
)
705 rlen
= unw_decode_uleb128 (& dp
);
706 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
710 static const unsigned char *
711 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
712 void *arg ATTRIBUTE_UNUSED
)
714 unsigned char brmask
= (code
& 0x1f);
716 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
720 static const unsigned char *
721 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
722 void *arg ATTRIBUTE_UNUSED
)
724 if ((code
& 0x10) == 0)
726 unsigned char byte1
= *dp
++;
728 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
729 (byte1
& 0x7f), arg
);
731 else if ((code
& 0x08) == 0)
733 unsigned char byte1
= *dp
++, r
, dst
;
735 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
736 dst
= (byte1
& 0x7f);
740 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
743 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
746 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
749 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
752 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
755 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
758 UNW_DEC_RP_BR ("P3", dst
, arg
);
761 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
764 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
767 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
770 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
773 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
776 UNW_DEC_BAD_CODE (r
);
780 else if ((code
& 0x7) == 0)
781 UNW_DEC_SPILL_MASK ("P4", dp
, arg
);
782 else if ((code
& 0x7) == 1)
784 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
789 grmask
= ((byte1
>> 4) & 0xf);
790 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
791 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
794 UNW_DEC_BAD_CODE (code
);
799 static const unsigned char *
800 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
801 void *arg ATTRIBUTE_UNUSED
)
803 int gregs
= (code
& 0x10) != 0;
804 unsigned char mask
= (code
& 0x0f);
807 UNW_DEC_GR_MEM ("P6", mask
, arg
);
809 UNW_DEC_FR_MEM ("P6", mask
, arg
);
813 static const unsigned char *
814 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
)
816 unsigned char r
, byte1
, byte2
;
819 if ((code
& 0x10) == 0)
822 t
= unw_decode_uleb128 (&dp
);
826 size
= unw_decode_uleb128 (&dp
);
827 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
831 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
834 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
837 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
840 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
843 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
846 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
849 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
852 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
855 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
858 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
861 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
864 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
867 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
870 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
873 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
876 UNW_DEC_BAD_CODE (r
);
887 t
= unw_decode_uleb128 (&dp
);
891 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
894 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
897 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
900 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
903 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
906 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
909 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
912 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
915 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
918 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
921 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
924 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
927 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
930 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
933 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
936 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
939 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
942 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
945 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
948 UNW_DEC_BAD_CODE (r
);
957 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
963 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
967 return unw_decode_x1 (dp
, code
, arg
);
970 return unw_decode_x2 (dp
, code
, arg
);
973 return unw_decode_x3 (dp
, code
, arg
);
976 return unw_decode_x4 (dp
, code
, arg
);
979 UNW_DEC_BAD_CODE (code
);
986 static const unsigned char *
987 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
988 void *arg ATTRIBUTE_UNUSED
)
990 unw_word label
= (code
& 0x1f);
992 if ((code
& 0x20) != 0)
993 UNW_DEC_COPY_STATE ("B1", label
, arg
);
995 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
999 static const unsigned char *
1000 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
1001 void *arg ATTRIBUTE_UNUSED
)
1005 t
= unw_decode_uleb128 (& dp
);
1006 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1010 static const unsigned char *
1011 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
)
1013 unw_word t
, ecount
, label
;
1015 if ((code
& 0x10) == 0)
1017 t
= unw_decode_uleb128 (&dp
);
1018 ecount
= unw_decode_uleb128 (&dp
);
1019 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1021 else if ((code
& 0x07) == 0)
1023 label
= unw_decode_uleb128 (&dp
);
1024 if ((code
& 0x08) != 0)
1025 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1027 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1033 return unw_decode_x1 (dp
, code
, arg
);
1035 return unw_decode_x2 (dp
, code
, arg
);
1037 return unw_decode_x3 (dp
, code
, arg
);
1039 return unw_decode_x4 (dp
, code
, arg
);
1041 UNW_DEC_BAD_CODE (code
);
1047 typedef const unsigned char *(*unw_decoder
)
1048 (const unsigned char *, unsigned int, void *);
1050 static const unw_decoder unw_decode_table
[2][8] =
1052 /* prologue table: */
1054 unw_decode_r1
, /* 0 */
1058 unw_decode_p1
, /* 4 */
1064 unw_decode_r1
, /* 0 */
1068 unw_decode_b1
, /* 4 */
1075 /* Decode one descriptor and return address of next descriptor. */
1076 const unsigned char *
1077 unw_decode (const unsigned char *dp
, int inside_body
,
1078 void *ptr_inside_body
)
1080 unw_decoder decoder
;
1084 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1085 return (*decoder
) (dp
, code
, ptr_inside_body
);