1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright (C) 2000-2020 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. */
25 #include "unwind-ia64.h"
28 /* Define BFD64 here, even if our default architecture is 32 bit ELF
29 as this will allow us to read in and parse 64bit and 32bit ELF files.
30 Only do this if we believe that the compiler can support a 64 bit
31 data type. For now we only rely on GCC being able to do this. */
36 static bfd_vma unw_rlen
= 0;
38 static void unw_print_brmask (char *, unsigned int);
39 static void unw_print_grmask (char *, unsigned int);
40 static void unw_print_frmask (char *, unsigned int);
41 static void unw_print_abreg (char *, unsigned int);
42 static void unw_print_xyreg (char *, unsigned int, unsigned int);
45 unw_print_brmask (char *cp
, unsigned int mask
)
50 for (i
= 0; mask
&& (i
< 5); ++i
)
66 unw_print_grmask (char *cp
, unsigned int mask
)
71 for (i
= 0; i
< 4; ++i
)
87 unw_print_frmask (char *cp
, unsigned int mask
)
92 for (i
= 0; i
< 20; ++i
)
103 *cp
++ = (i
+ 2) / 10 + 1 + '0';
104 *cp
++ = (i
+ 2) % 10 + '0';
114 unw_print_abreg (char *cp
, unsigned int abreg
)
116 static const char * const special_reg
[16] =
118 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
119 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
120 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
123 switch ((abreg
>> 5) & 0x3)
126 sprintf (cp
, "r%u", (abreg
& 0x1f));
130 sprintf (cp
, "f%u", (abreg
& 0x1f));
134 sprintf (cp
, "b%u", (abreg
& 0x1f));
137 case 3: /* special */
138 strcpy (cp
, special_reg
[abreg
& 0xf]);
144 unw_print_xyreg (char *cp
, unsigned int x
, unsigned int ytreg
)
146 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
149 sprintf (cp
, "r%u", (ytreg
& 0x1f));
153 sprintf (cp
, "f%u", (ytreg
& 0x1f));
157 sprintf (cp
, "b%u", (ytreg
& 0x1f));
162 #define UNW_REG_BSP "bsp"
163 #define UNW_REG_BSPSTORE "bspstore"
164 #define UNW_REG_FPSR "fpsr"
165 #define UNW_REG_LC "lc"
166 #define UNW_REG_PFS "pfs"
167 #define UNW_REG_PR "pr"
168 #define UNW_REG_PSP "psp"
169 #define UNW_REG_RNAT "rnat"
170 #define UNW_REG_RP "rp"
171 #define UNW_REG_UNAT "unat"
173 typedef bfd_vma unw_word
;
175 #define UNW_DEC_BAD_CODE(code) \
176 printf (_("Unknown code 0x%02x\n"), code)
178 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
182 *(int *)arg = body; \
183 printf (" %s:%s(rlen=%lu)\n", \
184 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
188 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
191 char regname[16], maskstr[64], *sep; \
200 strcat (maskstr, "rp"); \
205 strcat (maskstr, sep); \
206 strcat (maskstr, "ar.pfs"); \
211 strcat (maskstr, sep); \
212 strcat (maskstr, "psp"); \
217 strcat (maskstr, sep); \
218 strcat (maskstr, "pr"); \
220 sprintf (regname, "r%u", grsave); \
221 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
222 fmt, maskstr, regname, (unsigned long) rlen); \
226 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
231 unw_print_frmask (frstr, frmask); \
232 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
236 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
241 unw_print_grmask (grstr, grmask); \
242 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
246 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
249 char frstr[200], grstr[20]; \
251 unw_print_grmask (grstr, grmask); \
252 unw_print_frmask (frstr, frmask); \
253 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
257 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
262 unw_print_brmask (brstr, brmask); \
263 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
267 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
272 unw_print_brmask (brstr, brmask); \
273 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
277 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
278 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
280 #define UNW_DEC_RP_BR(fmt, dst, arg) \
281 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
283 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
284 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
286 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
287 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
288 fmt, reg, 4*(unsigned long)spoff)
290 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
291 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
292 fmt, reg, 4*(unsigned long)pspoff)
294 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
299 unw_print_grmask (grstr, grmask); \
300 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
304 #define UNW_DEC_ABI(fmt, abi, context, arg) \
307 static const char * const abiname[] = \
309 "@svr4", "@hpux", "@nt" \
312 const char *abistr = buf; \
315 abistr = abiname[abi]; \
317 sprintf (buf, "0x%x", abi); \
318 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
319 fmt, abistr, context); \
323 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
324 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
326 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
327 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
329 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
330 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
332 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
333 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
334 fmt, 4*(unsigned long)pspoff)
336 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
337 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
338 fmt, 4*(unsigned long)spoff)
340 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
341 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
342 fmt, (unsigned long) t, 16*(unsigned long)size)
344 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
345 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
347 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
348 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
349 fmt, 4*(unsigned long)pspoff)
351 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
354 static const char *spill_type = "-frb"; \
355 unsigned const char *imaskp = dp; \
356 unsigned char mask = 0; \
360 if ((dp + (unw_rlen / 4)) > end) \
362 printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
363 (long) (unw_rlen / 4), (long)(end - dp)); \
364 /* FIXME: Should we reset unw_rlen ? */ \
367 printf ("\t%s:spill_mask(imask=[", fmt); \
368 for (insn = 0; insn < unw_rlen; ++insn) \
370 if ((insn % 4) == 0) \
372 if (insn > 0 && (insn % 3) == 0) \
374 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
381 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
386 unw_print_abreg (regname, abreg); \
387 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
388 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
392 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
397 unw_print_abreg (regname, abreg); \
398 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
399 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
403 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
408 unw_print_abreg (regname, abreg); \
409 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
410 fmt, (unsigned long) t, regname); \
414 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
417 char abregname[20], tregname[20]; \
419 unw_print_abreg (abregname, abreg); \
420 unw_print_xyreg (tregname, x, ytreg); \
421 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
422 fmt, (unsigned long) t, abregname, tregname); \
426 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
431 unw_print_abreg (regname, abreg); \
432 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
433 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
437 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
442 unw_print_abreg (regname, abreg); \
443 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
444 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
448 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
453 unw_print_abreg (regname, abreg); \
454 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
455 fmt, qp, (unsigned long) t, regname); \
459 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
462 char regname[20], tregname[20]; \
464 unw_print_abreg (regname, abreg); \
465 unw_print_xyreg (tregname, x, ytreg); \
466 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
467 fmt, qp, (unsigned long) t, regname, tregname); \
471 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
472 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
474 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
475 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
477 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
478 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
479 fmt, (unsigned long) t, (unsigned long) ecount)
482 * Generic IA-64 unwind info decoder.
484 * This file is used both by the Linux kernel and objdump. Please
485 * keep the two copies of this file in sync (modulo differences in the
488 * You need to customize the decoder by defining the following
489 * macros/constants before including this file:
492 * unw_word Unsigned integer type with at least 64 bits
506 * Decoder action macros:
507 * UNW_DEC_BAD_CODE(code)
508 * UNW_DEC_ABI(fmt,abi,context,arg)
509 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
510 * UNW_DEC_BR_MEM(fmt,brmask,arg)
511 * UNW_DEC_COPY_STATE(fmt,label,arg)
512 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
513 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
514 * UNW_DEC_FR_MEM(fmt,frmask,arg)
515 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
516 * UNW_DEC_GR_MEM(fmt,grmask,arg)
517 * UNW_DEC_LABEL_STATE(fmt,label,arg)
518 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
519 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
520 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
521 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
522 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
523 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
524 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
525 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
526 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
527 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
528 * UNW_DEC_REG_REG(fmt,src,dst,arg)
529 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
530 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
531 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
532 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
533 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
534 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
535 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
536 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
537 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
538 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
539 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
540 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
544 unw_decode_uleb128 (const unsigned char **dpp
, const unsigned char * end
)
548 unw_word byte
, result
= 0;
549 const unsigned char *bp
= *dpp
;
554 if (shift
< sizeof (result
) * 8)
556 result
|= (byte
& 0x7f) << shift
;
557 if ((result
>> shift
) != (byte
& 0x7f))
562 else if ((byte
& 0x7f) != 0)
565 if ((byte
& 0x80) == 0)
574 printf (_("Bad uleb128\n"));
579 static const unsigned char *
580 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
581 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
583 unsigned char byte1
, abreg
;
588 printf (_("\t<corrupt X1>\n"));
593 t
= unw_decode_uleb128 (&dp
, end
);
594 off
= unw_decode_uleb128 (&dp
, end
);
595 abreg
= (byte1
& 0x7f);
597 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
599 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
603 static const unsigned char *
604 unw_decode_x2 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
605 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
607 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
612 printf (_("\t<corrupt X2>\n"));
618 t
= unw_decode_uleb128 (&dp
, end
);
619 abreg
= (byte1
& 0x7f);
621 x
= (byte1
>> 7) & 1;
622 if ((byte1
& 0x80) == 0 && ytreg
== 0)
623 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
625 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
629 static const unsigned char *
630 unw_decode_x3 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
631 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
633 unsigned char byte1
, byte2
, abreg
, qp
;
638 printf (_("\t<corrupt X3>\n"));
644 t
= unw_decode_uleb128 (&dp
, end
);
645 off
= unw_decode_uleb128 (&dp
, end
);
648 abreg
= (byte2
& 0x7f);
651 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
653 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
657 static const unsigned char *
658 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
659 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
661 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
666 printf (_("\t<corrupt X4>\n"));
673 t
= unw_decode_uleb128 (&dp
, end
);
676 abreg
= (byte2
& 0x7f);
677 x
= (byte2
>> 7) & 1;
680 if ((byte2
& 0x80) == 0 && byte3
== 0)
681 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
683 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
687 static const unsigned char *
688 unw_decode_r1 (const unsigned char *dp
, unsigned int code
, void *arg
,
689 const unsigned char * end ATTRIBUTE_UNUSED
)
691 int body
= (code
& 0x20) != 0;
694 rlen
= (code
& 0x1f);
695 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
699 static const unsigned char *
700 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
,
701 const unsigned char * end
)
703 unsigned char byte1
, mask
, grsave
;
708 printf (_("\t<corrupt R2>\n"));
714 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
715 grsave
= (byte1
& 0x7f);
716 rlen
= unw_decode_uleb128 (& dp
, end
);
717 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
721 static const unsigned char *
722 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
,
723 const unsigned char * end
)
727 rlen
= unw_decode_uleb128 (& dp
, end
);
728 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
732 static const unsigned char *
733 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
734 void *arg ATTRIBUTE_UNUSED
,
735 const unsigned char * end ATTRIBUTE_UNUSED
)
737 unsigned char brmask
= (code
& 0x1f);
739 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
743 static const unsigned char *
744 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
745 void *arg ATTRIBUTE_UNUSED
,
746 const unsigned char * end
)
748 if ((code
& 0x10) == 0)
754 printf (_("\t<corrupt P2>\n"));
760 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
761 (byte1
& 0x7f), arg
);
763 else if ((code
& 0x08) == 0)
765 unsigned char byte1
, r
, dst
;
769 printf (_("\t<corrupt P3>\n"));
775 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
776 dst
= (byte1
& 0x7f);
780 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
783 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
786 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
789 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
792 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
795 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
798 UNW_DEC_RP_BR ("P3", dst
, arg
);
801 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
804 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
807 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
810 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
813 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
816 UNW_DEC_BAD_CODE (r
);
820 else if ((code
& 0x7) == 0)
821 UNW_DEC_SPILL_MASK ("P4", dp
, arg
, end
);
822 else if ((code
& 0x7) == 1)
824 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
828 printf (_("\t<corrupt P5>\n"));
834 grmask
= ((byte1
>> 4) & 0xf);
835 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
836 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
839 UNW_DEC_BAD_CODE (code
);
844 static const unsigned char *
845 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
846 void *arg ATTRIBUTE_UNUSED
,
847 const unsigned char * end ATTRIBUTE_UNUSED
)
849 int gregs
= (code
& 0x10) != 0;
850 unsigned char mask
= (code
& 0x0f);
853 UNW_DEC_GR_MEM ("P6", mask
, arg
);
855 UNW_DEC_FR_MEM ("P6", mask
, arg
);
859 static const unsigned char *
860 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
,
861 const unsigned char * end
)
863 unsigned char r
, byte1
, byte2
;
866 if ((code
& 0x10) == 0)
869 t
= unw_decode_uleb128 (&dp
, end
);
873 size
= unw_decode_uleb128 (&dp
, end
);
874 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
878 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
881 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
884 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
887 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
890 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
893 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
896 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
899 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
902 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
905 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
908 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
911 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
914 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
917 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
920 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
923 UNW_DEC_BAD_CODE (r
);
935 printf (_("\t<corrupt P8>\n"));
940 t
= unw_decode_uleb128 (&dp
, end
);
944 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
947 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
950 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
953 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
956 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
959 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
962 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
965 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
968 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
971 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
974 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
977 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
980 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
983 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
986 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
989 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
992 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
995 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
998 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
1001 UNW_DEC_BAD_CODE (r
);
1010 printf (_("\t<corrupt P9>\n"));
1016 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
1022 printf (_("\t<corrupt P10>\n"));
1028 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
1032 return unw_decode_x1 (dp
, code
, arg
, end
);
1035 return unw_decode_x2 (dp
, code
, arg
, end
);
1038 return unw_decode_x3 (dp
, code
, arg
, end
);
1041 return unw_decode_x4 (dp
, code
, arg
, end
);
1044 UNW_DEC_BAD_CODE (code
);
1051 static const unsigned char *
1052 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
1053 void *arg ATTRIBUTE_UNUSED
,
1054 const unsigned char * end ATTRIBUTE_UNUSED
)
1056 unw_word label
= (code
& 0x1f);
1058 if ((code
& 0x20) != 0)
1059 UNW_DEC_COPY_STATE ("B1", label
, arg
);
1061 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
1065 static const unsigned char *
1066 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
1067 void *arg ATTRIBUTE_UNUSED
,
1068 const unsigned char * end
)
1072 t
= unw_decode_uleb128 (& dp
, end
);
1073 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1077 static const unsigned char *
1078 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
,
1079 const unsigned char * end
)
1081 unw_word t
, ecount
, label
;
1083 if ((code
& 0x10) == 0)
1085 t
= unw_decode_uleb128 (&dp
, end
);
1086 ecount
= unw_decode_uleb128 (&dp
, end
);
1087 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1089 else if ((code
& 0x07) == 0)
1091 label
= unw_decode_uleb128 (&dp
, end
);
1092 if ((code
& 0x08) != 0)
1093 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1095 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1101 return unw_decode_x1 (dp
, code
, arg
, end
);
1103 return unw_decode_x2 (dp
, code
, arg
, end
);
1105 return unw_decode_x3 (dp
, code
, arg
, end
);
1107 return unw_decode_x4 (dp
, code
, arg
, end
);
1109 UNW_DEC_BAD_CODE (code
);
1115 typedef const unsigned char *(*unw_decoder
)
1116 (const unsigned char *, unsigned int, void *, const unsigned char *);
1118 static const unw_decoder unw_decode_table
[2][8] =
1120 /* prologue table: */
1122 unw_decode_r1
, /* 0 */
1126 unw_decode_p1
, /* 4 */
1132 unw_decode_r1
, /* 0 */
1136 unw_decode_b1
, /* 4 */
1143 /* Decode one descriptor and return address of next descriptor. */
1144 const unsigned char *
1145 unw_decode (const unsigned char *dp
, int inside_body
,
1146 void *ptr_inside_body
, const unsigned char * end
)
1148 unw_decoder decoder
;
1153 printf (_("\t<corrupt IA64 descriptor>\n"));
1158 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1159 return (*decoder
) (dp
, code
, ptr_inside_body
, end
);