1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright (C) 2000-2018 Free Software Foundation, Inc.
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 #include "unwind-ia64.h"
29 /* Define BFD64 here, even if our default architecture is 32 bit ELF
30 as this will allow us to read in and parse 64bit and 32bit ELF files.
31 Only do this if we believe that the compiler can support a 64 bit
32 data type. For now we only rely on GCC being able to do this. */
37 static bfd_vma unw_rlen
= 0;
39 static void unw_print_brmask (char *, unsigned int);
40 static void unw_print_grmask (char *, unsigned int);
41 static void unw_print_frmask (char *, unsigned int);
42 static void unw_print_abreg (char *, unsigned int);
43 static void unw_print_xyreg (char *, unsigned int, unsigned int);
46 unw_print_brmask (char *cp
, unsigned int mask
)
51 for (i
= 0; mask
&& (i
< 5); ++i
)
67 unw_print_grmask (char *cp
, unsigned int mask
)
72 for (i
= 0; i
< 4; ++i
)
88 unw_print_frmask (char *cp
, unsigned int mask
)
93 for (i
= 0; i
< 20; ++i
)
104 *cp
++ = (i
+ 2) / 10 + 1 + '0';
105 *cp
++ = (i
+ 2) % 10 + '0';
115 unw_print_abreg (char *cp
, unsigned int abreg
)
117 static const char * const special_reg
[16] =
119 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
120 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
121 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
124 switch ((abreg
>> 5) & 0x3)
127 sprintf (cp
, "r%u", (abreg
& 0x1f));
131 sprintf (cp
, "f%u", (abreg
& 0x1f));
135 sprintf (cp
, "b%u", (abreg
& 0x1f));
138 case 3: /* special */
139 strcpy (cp
, special_reg
[abreg
& 0xf]);
145 unw_print_xyreg (char *cp
, unsigned int x
, unsigned int ytreg
)
147 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
150 sprintf (cp
, "r%u", (ytreg
& 0x1f));
154 sprintf (cp
, "f%u", (ytreg
& 0x1f));
158 sprintf (cp
, "b%u", (ytreg
& 0x1f));
163 #define UNW_REG_BSP "bsp"
164 #define UNW_REG_BSPSTORE "bspstore"
165 #define UNW_REG_FPSR "fpsr"
166 #define UNW_REG_LC "lc"
167 #define UNW_REG_PFS "pfs"
168 #define UNW_REG_PR "pr"
169 #define UNW_REG_PSP "psp"
170 #define UNW_REG_RNAT "rnat"
171 #define UNW_REG_RP "rp"
172 #define UNW_REG_UNAT "unat"
174 typedef bfd_vma unw_word
;
176 #define UNW_DEC_BAD_CODE(code) \
177 printf ("Unknown code 0x%02x\n", code)
179 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
183 *(int *)arg = body; \
184 printf (" %s:%s(rlen=%lu)\n", \
185 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
189 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
192 char regname[16], maskstr[64], *sep; \
201 strcat (maskstr, "rp"); \
206 strcat (maskstr, sep); \
207 strcat (maskstr, "ar.pfs"); \
212 strcat (maskstr, sep); \
213 strcat (maskstr, "psp"); \
218 strcat (maskstr, sep); \
219 strcat (maskstr, "pr"); \
221 sprintf (regname, "r%u", grsave); \
222 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
223 fmt, maskstr, regname, (unsigned long) rlen); \
227 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
232 unw_print_frmask (frstr, frmask); \
233 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
237 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
242 unw_print_grmask (grstr, grmask); \
243 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
247 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
250 char frstr[200], grstr[20]; \
252 unw_print_grmask (grstr, grmask); \
253 unw_print_frmask (frstr, frmask); \
254 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
258 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
263 unw_print_brmask (brstr, brmask); \
264 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
268 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
273 unw_print_brmask (brstr, brmask); \
274 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
278 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
279 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
281 #define UNW_DEC_RP_BR(fmt, dst, arg) \
282 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
284 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
285 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
287 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
288 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
289 fmt, reg, 4*(unsigned long)spoff)
291 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
292 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
293 fmt, reg, 4*(unsigned long)pspoff)
295 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
300 unw_print_grmask (grstr, grmask); \
301 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
305 #define UNW_DEC_ABI(fmt, abi, context, arg) \
308 static const char * const abiname[] = \
310 "@svr4", "@hpux", "@nt" \
313 const char *abistr = buf; \
316 abistr = abiname[abi]; \
318 sprintf (buf, "0x%x", abi); \
319 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
320 fmt, abistr, context); \
324 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
325 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
327 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
328 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
330 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
331 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
333 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
334 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
335 fmt, 4*(unsigned long)pspoff)
337 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
338 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
339 fmt, 4*(unsigned long)spoff)
341 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
342 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
343 fmt, (unsigned long) t, 16*(unsigned long)size)
345 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
346 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
348 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
349 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
350 fmt, 4*(unsigned long)pspoff)
352 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
355 static const char *spill_type = "-frb"; \
356 unsigned const char *imaskp = dp; \
357 unsigned char mask = 0; \
361 if ((dp + (unw_rlen / 4)) > end) \
363 printf ("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n",\
364 (long) (unw_rlen / 4), (long)(end - dp)); \
365 /* FIXME: Should we reset unw_rlen ? */ \
368 printf ("\t%s:spill_mask(imask=[", fmt); \
369 for (insn = 0; insn < unw_rlen; ++insn) \
371 if ((insn % 4) == 0) \
373 if (insn > 0 && (insn % 3) == 0) \
375 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
382 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
387 unw_print_abreg (regname, abreg); \
388 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
389 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
393 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
398 unw_print_abreg (regname, abreg); \
399 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
400 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
404 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
409 unw_print_abreg (regname, abreg); \
410 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
411 fmt, (unsigned long) t, regname); \
415 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
418 char abregname[20], tregname[20]; \
420 unw_print_abreg (abregname, abreg); \
421 unw_print_xyreg (tregname, x, ytreg); \
422 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
423 fmt, (unsigned long) t, abregname, tregname); \
427 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
432 unw_print_abreg (regname, abreg); \
433 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
434 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
438 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
443 unw_print_abreg (regname, abreg); \
444 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
445 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
449 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
454 unw_print_abreg (regname, abreg); \
455 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
456 fmt, qp, (unsigned long) t, regname); \
460 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
463 char regname[20], tregname[20]; \
465 unw_print_abreg (regname, abreg); \
466 unw_print_xyreg (tregname, x, ytreg); \
467 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
468 fmt, qp, (unsigned long) t, regname, tregname); \
472 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
473 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
475 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
476 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
478 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
479 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
480 fmt, (unsigned long) t, (unsigned long) ecount)
483 * Generic IA-64 unwind info decoder.
485 * This file is used both by the Linux kernel and objdump. Please
486 * keep the two copies of this file in sync (modulo differences in the
489 * You need to customize the decoder by defining the following
490 * macros/constants before including this file:
493 * unw_word Unsigned integer type with at least 64 bits
507 * Decoder action macros:
508 * UNW_DEC_BAD_CODE(code)
509 * UNW_DEC_ABI(fmt,abi,context,arg)
510 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
511 * UNW_DEC_BR_MEM(fmt,brmask,arg)
512 * UNW_DEC_COPY_STATE(fmt,label,arg)
513 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
514 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
515 * UNW_DEC_FR_MEM(fmt,frmask,arg)
516 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
517 * UNW_DEC_GR_MEM(fmt,grmask,arg)
518 * UNW_DEC_LABEL_STATE(fmt,label,arg)
519 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
520 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
521 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
522 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
523 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
524 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
525 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
526 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
527 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
528 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
529 * UNW_DEC_REG_REG(fmt,src,dst,arg)
530 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
531 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
532 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
533 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
534 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
535 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
536 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
537 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
538 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
539 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
540 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
541 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
545 unw_decode_uleb128 (const unsigned char **dpp
)
548 unw_word byte
, result
= 0;
549 const unsigned char *bp
= *dpp
;
554 result
|= (byte
& 0x7f) << shift
;
556 if ((byte
& 0x80) == 0)
567 static const unsigned char *
568 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
569 void *arg ATTRIBUTE_UNUSED
)
571 unsigned char byte1
, abreg
;
575 t
= unw_decode_uleb128 (&dp
);
576 off
= unw_decode_uleb128 (&dp
);
577 abreg
= (byte1
& 0x7f);
579 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
581 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
585 static const unsigned char *
586 unw_decode_x2 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
587 void *arg ATTRIBUTE_UNUSED
)
589 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
594 t
= unw_decode_uleb128 (&dp
);
595 abreg
= (byte1
& 0x7f);
597 x
= (byte1
>> 7) & 1;
598 if ((byte1
& 0x80) == 0 && ytreg
== 0)
599 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
601 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
605 static const unsigned char *
606 unw_decode_x3 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
607 void *arg ATTRIBUTE_UNUSED
)
609 unsigned char byte1
, byte2
, abreg
, qp
;
614 t
= unw_decode_uleb128 (&dp
);
615 off
= unw_decode_uleb128 (&dp
);
618 abreg
= (byte2
& 0x7f);
621 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
623 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
627 static const unsigned char *
628 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
629 void *arg ATTRIBUTE_UNUSED
)
631 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
637 t
= unw_decode_uleb128 (&dp
);
640 abreg
= (byte2
& 0x7f);
641 x
= (byte2
>> 7) & 1;
644 if ((byte2
& 0x80) == 0 && byte3
== 0)
645 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
647 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
651 static const unsigned char *
652 unw_decode_r1 (const unsigned char *dp
, unsigned int code
, void *arg
,
653 const unsigned char * end ATTRIBUTE_UNUSED
)
655 int body
= (code
& 0x20) != 0;
658 rlen
= (code
& 0x1f);
659 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
663 static const unsigned char *
664 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
,
665 const unsigned char * end ATTRIBUTE_UNUSED
)
667 unsigned char byte1
, mask
, grsave
;
672 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
673 grsave
= (byte1
& 0x7f);
674 rlen
= unw_decode_uleb128 (& dp
);
675 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
679 static const unsigned char *
680 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
,
681 const unsigned char * end ATTRIBUTE_UNUSED
)
685 rlen
= unw_decode_uleb128 (& dp
);
686 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
690 static const unsigned char *
691 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
692 void *arg ATTRIBUTE_UNUSED
,
693 const unsigned char * end ATTRIBUTE_UNUSED
)
695 unsigned char brmask
= (code
& 0x1f);
697 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
701 static const unsigned char *
702 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
703 void *arg ATTRIBUTE_UNUSED
,
704 const unsigned char * end
)
706 if ((code
& 0x10) == 0)
708 unsigned char byte1
= *dp
++;
710 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
711 (byte1
& 0x7f), arg
);
713 else if ((code
& 0x08) == 0)
715 unsigned char byte1
= *dp
++, r
, dst
;
717 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
718 dst
= (byte1
& 0x7f);
722 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
725 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
728 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
731 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
734 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
737 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
740 UNW_DEC_RP_BR ("P3", dst
, arg
);
743 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
746 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
749 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
752 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
755 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
758 UNW_DEC_BAD_CODE (r
);
762 else if ((code
& 0x7) == 0)
763 UNW_DEC_SPILL_MASK ("P4", dp
, arg
, end
);
764 else if ((code
& 0x7) == 1)
766 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
771 grmask
= ((byte1
>> 4) & 0xf);
772 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
773 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
776 UNW_DEC_BAD_CODE (code
);
781 static const unsigned char *
782 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
783 void *arg ATTRIBUTE_UNUSED
,
784 const unsigned char * end ATTRIBUTE_UNUSED
)
786 int gregs
= (code
& 0x10) != 0;
787 unsigned char mask
= (code
& 0x0f);
790 UNW_DEC_GR_MEM ("P6", mask
, arg
);
792 UNW_DEC_FR_MEM ("P6", mask
, arg
);
796 static const unsigned char *
797 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
,
798 const unsigned char * end ATTRIBUTE_UNUSED
)
800 unsigned char r
, byte1
, byte2
;
803 if ((code
& 0x10) == 0)
806 t
= unw_decode_uleb128 (&dp
);
810 size
= unw_decode_uleb128 (&dp
);
811 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
815 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
818 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
821 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
824 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
827 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
830 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
833 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
836 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
839 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
842 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
845 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
848 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
851 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
854 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
857 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
860 UNW_DEC_BAD_CODE (r
);
871 t
= unw_decode_uleb128 (&dp
);
875 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
878 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
881 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
884 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
887 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
890 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
893 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
896 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
899 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
902 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
905 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
908 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
911 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
914 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
917 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
920 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
923 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
926 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
929 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
932 UNW_DEC_BAD_CODE (r
);
941 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
947 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
951 return unw_decode_x1 (dp
, code
, arg
);
954 return unw_decode_x2 (dp
, code
, arg
);
957 return unw_decode_x3 (dp
, code
, arg
);
960 return unw_decode_x4 (dp
, code
, arg
);
963 UNW_DEC_BAD_CODE (code
);
970 static const unsigned char *
971 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
972 void *arg ATTRIBUTE_UNUSED
,
973 const unsigned char * end ATTRIBUTE_UNUSED
)
975 unw_word label
= (code
& 0x1f);
977 if ((code
& 0x20) != 0)
978 UNW_DEC_COPY_STATE ("B1", label
, arg
);
980 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
984 static const unsigned char *
985 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
986 void *arg ATTRIBUTE_UNUSED
,
987 const unsigned char * end ATTRIBUTE_UNUSED
)
991 t
= unw_decode_uleb128 (& dp
);
992 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
996 static const unsigned char *
997 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
,
998 const unsigned char * end ATTRIBUTE_UNUSED
)
1000 unw_word t
, ecount
, label
;
1002 if ((code
& 0x10) == 0)
1004 t
= unw_decode_uleb128 (&dp
);
1005 ecount
= unw_decode_uleb128 (&dp
);
1006 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1008 else if ((code
& 0x07) == 0)
1010 label
= unw_decode_uleb128 (&dp
);
1011 if ((code
& 0x08) != 0)
1012 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1014 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1020 return unw_decode_x1 (dp
, code
, arg
);
1022 return unw_decode_x2 (dp
, code
, arg
);
1024 return unw_decode_x3 (dp
, code
, arg
);
1026 return unw_decode_x4 (dp
, code
, arg
);
1028 UNW_DEC_BAD_CODE (code
);
1034 typedef const unsigned char *(*unw_decoder
)
1035 (const unsigned char *, unsigned int, void *, const unsigned char *);
1037 static const unw_decoder unw_decode_table
[2][8] =
1039 /* prologue table: */
1041 unw_decode_r1
, /* 0 */
1045 unw_decode_p1
, /* 4 */
1051 unw_decode_r1
, /* 0 */
1055 unw_decode_b1
, /* 4 */
1062 /* Decode one descriptor and return address of next descriptor. */
1063 const unsigned char *
1064 unw_decode (const unsigned char *dp
, int inside_body
,
1065 void *ptr_inside_body
, const unsigned char * end
)
1067 unw_decoder decoder
;
1071 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1072 return (*decoder
) (dp
, code
, ptr_inside_body
, end
);