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
)
547 unw_word byte
, result
= 0;
548 const unsigned char *bp
= *dpp
;
553 result
|= (byte
& 0x7f) << shift
;
555 if ((byte
& 0x80) == 0)
566 static const unsigned char *
567 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
568 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
570 unsigned char byte1
, abreg
;
575 printf (_("\t<corrupt X1>\n"));
580 t
= unw_decode_uleb128 (&dp
, end
);
581 off
= unw_decode_uleb128 (&dp
, end
);
582 abreg
= (byte1
& 0x7f);
584 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
586 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
590 static const unsigned char *
591 unw_decode_x2 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
592 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
594 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
599 printf (_("\t<corrupt X2>\n"));
605 t
= unw_decode_uleb128 (&dp
, end
);
606 abreg
= (byte1
& 0x7f);
608 x
= (byte1
>> 7) & 1;
609 if ((byte1
& 0x80) == 0 && ytreg
== 0)
610 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
612 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
616 static const unsigned char *
617 unw_decode_x3 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
618 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
620 unsigned char byte1
, byte2
, abreg
, qp
;
625 printf (_("\t<corrupt X3>\n"));
631 t
= unw_decode_uleb128 (&dp
, end
);
632 off
= unw_decode_uleb128 (&dp
, end
);
635 abreg
= (byte2
& 0x7f);
638 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
640 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
644 static const unsigned char *
645 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
646 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
648 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
653 printf (_("\t<corrupt X4>\n"));
660 t
= unw_decode_uleb128 (&dp
, end
);
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
,
676 const unsigned char * end ATTRIBUTE_UNUSED
)
678 int body
= (code
& 0x20) != 0;
681 rlen
= (code
& 0x1f);
682 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
686 static const unsigned char *
687 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
,
688 const unsigned char * end
)
690 unsigned char byte1
, mask
, grsave
;
695 printf (_("\t<corrupt R2>\n"));
701 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
702 grsave
= (byte1
& 0x7f);
703 rlen
= unw_decode_uleb128 (& dp
, end
);
704 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
708 static const unsigned char *
709 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
,
710 const unsigned char * end
)
714 rlen
= unw_decode_uleb128 (& dp
, end
);
715 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
719 static const unsigned char *
720 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
721 void *arg ATTRIBUTE_UNUSED
,
722 const unsigned char * end ATTRIBUTE_UNUSED
)
724 unsigned char brmask
= (code
& 0x1f);
726 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
730 static const unsigned char *
731 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
732 void *arg ATTRIBUTE_UNUSED
,
733 const unsigned char * end
)
735 if ((code
& 0x10) == 0)
741 printf (_("\t<corrupt P2>\n"));
747 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
748 (byte1
& 0x7f), arg
);
750 else if ((code
& 0x08) == 0)
752 unsigned char byte1
, r
, dst
;
756 printf (_("\t<corrupt P3>\n"));
762 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
763 dst
= (byte1
& 0x7f);
767 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
770 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
773 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
776 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
779 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
782 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
785 UNW_DEC_RP_BR ("P3", dst
, arg
);
788 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
791 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
794 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
797 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
800 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
803 UNW_DEC_BAD_CODE (r
);
807 else if ((code
& 0x7) == 0)
808 UNW_DEC_SPILL_MASK ("P4", dp
, arg
, end
);
809 else if ((code
& 0x7) == 1)
811 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
815 printf (_("\t<corrupt P5>\n"));
821 grmask
= ((byte1
>> 4) & 0xf);
822 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
823 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
826 UNW_DEC_BAD_CODE (code
);
831 static const unsigned char *
832 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
833 void *arg ATTRIBUTE_UNUSED
,
834 const unsigned char * end ATTRIBUTE_UNUSED
)
836 int gregs
= (code
& 0x10) != 0;
837 unsigned char mask
= (code
& 0x0f);
840 UNW_DEC_GR_MEM ("P6", mask
, arg
);
842 UNW_DEC_FR_MEM ("P6", mask
, arg
);
846 static const unsigned char *
847 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
,
848 const unsigned char * end
)
850 unsigned char r
, byte1
, byte2
;
853 if ((code
& 0x10) == 0)
856 t
= unw_decode_uleb128 (&dp
, end
);
860 size
= unw_decode_uleb128 (&dp
, end
);
861 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
865 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
868 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
871 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
874 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
877 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
880 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
883 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
886 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
889 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
892 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
895 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
898 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
901 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
904 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
907 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
910 UNW_DEC_BAD_CODE (r
);
922 printf (_("\t<corrupt P8>\n"));
927 t
= unw_decode_uleb128 (&dp
, end
);
931 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
937 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
940 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
943 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
946 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
949 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
952 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
955 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
958 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
961 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
964 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
967 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
970 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
973 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
976 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
979 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
982 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
985 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
988 UNW_DEC_BAD_CODE (r
);
997 printf (_("\t<corrupt P9>\n"));
1003 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
1009 printf (_("\t<corrupt P10>\n"));
1015 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
1019 return unw_decode_x1 (dp
, code
, arg
, end
);
1022 return unw_decode_x2 (dp
, code
, arg
, end
);
1025 return unw_decode_x3 (dp
, code
, arg
, end
);
1028 return unw_decode_x4 (dp
, code
, arg
, end
);
1031 UNW_DEC_BAD_CODE (code
);
1038 static const unsigned char *
1039 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
1040 void *arg ATTRIBUTE_UNUSED
,
1041 const unsigned char * end ATTRIBUTE_UNUSED
)
1043 unw_word label
= (code
& 0x1f);
1045 if ((code
& 0x20) != 0)
1046 UNW_DEC_COPY_STATE ("B1", label
, arg
);
1048 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
1052 static const unsigned char *
1053 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
1054 void *arg ATTRIBUTE_UNUSED
,
1055 const unsigned char * end
)
1059 t
= unw_decode_uleb128 (& dp
, end
);
1060 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1064 static const unsigned char *
1065 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
,
1066 const unsigned char * end
)
1068 unw_word t
, ecount
, label
;
1070 if ((code
& 0x10) == 0)
1072 t
= unw_decode_uleb128 (&dp
, end
);
1073 ecount
= unw_decode_uleb128 (&dp
, end
);
1074 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1076 else if ((code
& 0x07) == 0)
1078 label
= unw_decode_uleb128 (&dp
, end
);
1079 if ((code
& 0x08) != 0)
1080 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1082 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1088 return unw_decode_x1 (dp
, code
, arg
, end
);
1090 return unw_decode_x2 (dp
, code
, arg
, end
);
1092 return unw_decode_x3 (dp
, code
, arg
, end
);
1094 return unw_decode_x4 (dp
, code
, arg
, end
);
1096 UNW_DEC_BAD_CODE (code
);
1102 typedef const unsigned char *(*unw_decoder
)
1103 (const unsigned char *, unsigned int, void *, const unsigned char *);
1105 static const unw_decoder unw_decode_table
[2][8] =
1107 /* prologue table: */
1109 unw_decode_r1
, /* 0 */
1113 unw_decode_p1
, /* 4 */
1119 unw_decode_r1
, /* 0 */
1123 unw_decode_b1
, /* 4 */
1130 /* Decode one descriptor and return address of next descriptor. */
1131 const unsigned char *
1132 unw_decode (const unsigned char *dp
, int inside_body
,
1133 void *ptr_inside_body
, const unsigned char * end
)
1135 unw_decoder decoder
;
1140 printf (_("\t<corrupt IA64 descriptor>\n"));
1145 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1146 return (*decoder
) (dp
, code
, ptr_inside_body
, end
);