1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright (C) 2000-2022 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));
161 strcpy (cp
, "invalid");
166 #define UNW_REG_BSP "bsp"
167 #define UNW_REG_BSPSTORE "bspstore"
168 #define UNW_REG_FPSR "fpsr"
169 #define UNW_REG_LC "lc"
170 #define UNW_REG_PFS "pfs"
171 #define UNW_REG_PR "pr"
172 #define UNW_REG_PSP "psp"
173 #define UNW_REG_RNAT "rnat"
174 #define UNW_REG_RP "rp"
175 #define UNW_REG_UNAT "unat"
177 typedef bfd_vma unw_word
;
179 #define UNW_DEC_BAD_CODE(code) \
180 printf (_("Unknown code 0x%02x\n"), code)
182 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
186 *(int *)arg = body; \
187 printf (" %s:%s(rlen=%lu)\n", \
188 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
192 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
195 char regname[16], maskstr[64], *sep; \
204 strcat (maskstr, "rp"); \
209 strcat (maskstr, sep); \
210 strcat (maskstr, "ar.pfs"); \
215 strcat (maskstr, sep); \
216 strcat (maskstr, "psp"); \
221 strcat (maskstr, sep); \
222 strcat (maskstr, "pr"); \
224 sprintf (regname, "r%u", grsave); \
225 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
226 fmt, maskstr, regname, (unsigned long) rlen); \
230 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
235 unw_print_frmask (frstr, frmask); \
236 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
240 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
245 unw_print_grmask (grstr, grmask); \
246 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
250 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
253 char frstr[200], grstr[20]; \
255 unw_print_grmask (grstr, grmask); \
256 unw_print_frmask (frstr, frmask); \
257 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
261 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
266 unw_print_brmask (brstr, brmask); \
267 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
271 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
276 unw_print_brmask (brstr, brmask); \
277 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
281 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
282 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
284 #define UNW_DEC_RP_BR(fmt, dst, arg) \
285 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
287 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
288 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
290 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
291 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
292 fmt, reg, 4*(unsigned long)spoff)
294 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
295 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
296 fmt, reg, 4*(unsigned long)pspoff)
298 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
303 unw_print_grmask (grstr, grmask); \
304 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
308 #define UNW_DEC_ABI(fmt, abi, context, arg) \
311 static const char * const abiname[] = \
313 "@svr4", "@hpux", "@nt" \
316 const char *abistr = buf; \
319 abistr = abiname[abi]; \
321 sprintf (buf, "0x%x", abi); \
322 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
323 fmt, abistr, context); \
327 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
328 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
330 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
331 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
333 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
334 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
336 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
337 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
338 fmt, 4*(unsigned long)pspoff)
340 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
341 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
342 fmt, 4*(unsigned long)spoff)
344 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
345 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
346 fmt, (unsigned long) t, 16*(unsigned long)size)
348 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
349 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
351 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
352 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
353 fmt, 4*(unsigned long)pspoff)
355 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
358 static const char *spill_type = "-frb"; \
359 unsigned const char *imaskp = dp; \
360 unsigned char mask = 0; \
364 if ((dp + (unw_rlen / 4)) > end) \
366 printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
367 (long) (unw_rlen / 4), (long)(end - dp)); \
368 /* FIXME: Should we reset unw_rlen ? */ \
371 printf ("\t%s:spill_mask(imask=[", fmt); \
372 for (insn = 0; insn < unw_rlen; ++insn) \
374 if ((insn % 4) == 0) \
376 if (insn > 0 && (insn % 3) == 0) \
378 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
385 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
390 unw_print_abreg (regname, abreg); \
391 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
392 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
396 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
401 unw_print_abreg (regname, abreg); \
402 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
403 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
407 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
412 unw_print_abreg (regname, abreg); \
413 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
414 fmt, (unsigned long) t, regname); \
418 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
421 char abregname[20], tregname[20]; \
423 unw_print_abreg (abregname, abreg); \
424 unw_print_xyreg (tregname, x, ytreg); \
425 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
426 fmt, (unsigned long) t, abregname, tregname); \
430 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
435 unw_print_abreg (regname, abreg); \
436 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
437 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
441 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
446 unw_print_abreg (regname, abreg); \
447 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
448 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
452 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
457 unw_print_abreg (regname, abreg); \
458 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
459 fmt, qp, (unsigned long) t, regname); \
463 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
466 char regname[20], tregname[20]; \
468 unw_print_abreg (regname, abreg); \
469 unw_print_xyreg (tregname, x, ytreg); \
470 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
471 fmt, qp, (unsigned long) t, regname, tregname); \
475 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
476 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
478 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
479 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
481 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
482 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
483 fmt, (unsigned long) t, (unsigned long) ecount)
486 * Generic IA-64 unwind info decoder.
488 * This file is used both by the Linux kernel and objdump. Please
489 * keep the two copies of this file in sync (modulo differences in the
492 * You need to customize the decoder by defining the following
493 * macros/constants before including this file:
496 * unw_word Unsigned integer type with at least 64 bits
510 * Decoder action macros:
511 * UNW_DEC_BAD_CODE(code)
512 * UNW_DEC_ABI(fmt,abi,context,arg)
513 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
514 * UNW_DEC_BR_MEM(fmt,brmask,arg)
515 * UNW_DEC_COPY_STATE(fmt,label,arg)
516 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
517 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
518 * UNW_DEC_FR_MEM(fmt,frmask,arg)
519 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
520 * UNW_DEC_GR_MEM(fmt,grmask,arg)
521 * UNW_DEC_LABEL_STATE(fmt,label,arg)
522 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
523 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
524 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
525 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
526 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
527 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
528 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
529 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
530 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
531 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
532 * UNW_DEC_REG_REG(fmt,src,dst,arg)
533 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
534 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
535 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
536 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
537 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
538 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
539 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
540 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
541 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
542 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
543 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
544 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
548 unw_decode_uleb128 (const unsigned char **dpp
, const unsigned char * end
)
552 unw_word byte
, result
= 0;
553 const unsigned char *bp
= *dpp
;
558 if (shift
< sizeof (result
) * 8)
560 result
|= (byte
& 0x7f) << shift
;
561 if ((result
>> shift
) != (byte
& 0x7f))
566 else if ((byte
& 0x7f) != 0)
569 if ((byte
& 0x80) == 0)
578 printf (_("Bad uleb128\n"));
583 static const unsigned char *
584 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
585 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
587 unsigned char byte1
, abreg
;
592 printf (_("\t<corrupt X1>\n"));
597 t
= unw_decode_uleb128 (&dp
, end
);
598 off
= unw_decode_uleb128 (&dp
, end
);
599 abreg
= (byte1
& 0x7f);
601 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
603 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
607 static const unsigned char *
608 unw_decode_x2 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
609 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
611 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
616 printf (_("\t<corrupt X2>\n"));
622 t
= unw_decode_uleb128 (&dp
, end
);
623 abreg
= (byte1
& 0x7f);
625 x
= (byte1
>> 7) & 1;
626 if ((byte1
& 0x80) == 0 && ytreg
== 0)
627 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
629 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
633 static const unsigned char *
634 unw_decode_x3 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
635 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
637 unsigned char byte1
, byte2
, abreg
, qp
;
642 printf (_("\t<corrupt X3>\n"));
648 t
= unw_decode_uleb128 (&dp
, end
);
649 off
= unw_decode_uleb128 (&dp
, end
);
652 abreg
= (byte2
& 0x7f);
655 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
657 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
661 static const unsigned char *
662 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
663 void *arg ATTRIBUTE_UNUSED
, const unsigned char * end
)
665 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
670 printf (_("\t<corrupt X4>\n"));
677 t
= unw_decode_uleb128 (&dp
, end
);
680 abreg
= (byte2
& 0x7f);
681 x
= (byte2
>> 7) & 1;
684 if ((byte2
& 0x80) == 0 && byte3
== 0)
685 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
687 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
691 static const unsigned char *
692 unw_decode_r1 (const unsigned char *dp
, unsigned int code
, void *arg
,
693 const unsigned char * end ATTRIBUTE_UNUSED
)
695 int body
= (code
& 0x20) != 0;
698 rlen
= (code
& 0x1f);
699 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
703 static const unsigned char *
704 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
,
705 const unsigned char * end
)
707 unsigned char byte1
, mask
, grsave
;
712 printf (_("\t<corrupt R2>\n"));
718 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
719 grsave
= (byte1
& 0x7f);
720 rlen
= unw_decode_uleb128 (& dp
, end
);
721 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
725 static const unsigned char *
726 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
,
727 const unsigned char * end
)
731 rlen
= unw_decode_uleb128 (& dp
, end
);
732 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
736 static const unsigned char *
737 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
738 void *arg ATTRIBUTE_UNUSED
,
739 const unsigned char * end ATTRIBUTE_UNUSED
)
741 unsigned char brmask
= (code
& 0x1f);
743 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
747 static const unsigned char *
748 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
749 void *arg ATTRIBUTE_UNUSED
,
750 const unsigned char * end
)
752 if ((code
& 0x10) == 0)
758 printf (_("\t<corrupt P2>\n"));
764 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
765 (byte1
& 0x7f), arg
);
767 else if ((code
& 0x08) == 0)
769 unsigned char byte1
, r
, dst
;
773 printf (_("\t<corrupt P3>\n"));
779 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
780 dst
= (byte1
& 0x7f);
784 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
787 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
790 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
793 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
796 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
799 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
802 UNW_DEC_RP_BR ("P3", dst
, arg
);
805 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
808 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
811 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
814 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
817 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
820 UNW_DEC_BAD_CODE (r
);
824 else if ((code
& 0x7) == 0)
825 UNW_DEC_SPILL_MASK ("P4", dp
, arg
, end
);
826 else if ((code
& 0x7) == 1)
828 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
832 printf (_("\t<corrupt P5>\n"));
838 grmask
= ((byte1
>> 4) & 0xf);
839 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
840 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
843 UNW_DEC_BAD_CODE (code
);
848 static const unsigned char *
849 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
850 void *arg ATTRIBUTE_UNUSED
,
851 const unsigned char * end ATTRIBUTE_UNUSED
)
853 int gregs
= (code
& 0x10) != 0;
854 unsigned char mask
= (code
& 0x0f);
857 UNW_DEC_GR_MEM ("P6", mask
, arg
);
859 UNW_DEC_FR_MEM ("P6", mask
, arg
);
863 static const unsigned char *
864 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
,
865 const unsigned char * end
)
867 unsigned char r
, byte1
, byte2
;
870 if ((code
& 0x10) == 0)
873 t
= unw_decode_uleb128 (&dp
, end
);
877 size
= unw_decode_uleb128 (&dp
, end
);
878 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
882 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
885 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
888 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
891 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
894 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
897 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
900 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
903 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
906 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
909 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
912 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
915 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
918 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
921 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
924 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
927 UNW_DEC_BAD_CODE (r
);
939 printf (_("\t<corrupt P8>\n"));
944 t
= unw_decode_uleb128 (&dp
, end
);
948 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
951 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
954 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
957 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
960 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
963 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
966 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
969 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
972 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
975 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
978 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
981 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
984 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
987 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
990 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
993 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
996 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
999 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
1002 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
1005 UNW_DEC_BAD_CODE (r
);
1014 printf (_("\t<corrupt P9>\n"));
1020 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
1026 printf (_("\t<corrupt P10>\n"));
1032 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
1036 return unw_decode_x1 (dp
, code
, arg
, end
);
1039 return unw_decode_x2 (dp
, code
, arg
, end
);
1042 return unw_decode_x3 (dp
, code
, arg
, end
);
1045 return unw_decode_x4 (dp
, code
, arg
, end
);
1048 UNW_DEC_BAD_CODE (code
);
1055 static const unsigned char *
1056 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
1057 void *arg ATTRIBUTE_UNUSED
,
1058 const unsigned char * end ATTRIBUTE_UNUSED
)
1060 unw_word label
= (code
& 0x1f);
1062 if ((code
& 0x20) != 0)
1063 UNW_DEC_COPY_STATE ("B1", label
, arg
);
1065 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
1069 static const unsigned char *
1070 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
1071 void *arg ATTRIBUTE_UNUSED
,
1072 const unsigned char * end
)
1076 t
= unw_decode_uleb128 (& dp
, end
);
1077 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1081 static const unsigned char *
1082 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
,
1083 const unsigned char * end
)
1085 unw_word t
, ecount
, label
;
1087 if ((code
& 0x10) == 0)
1089 t
= unw_decode_uleb128 (&dp
, end
);
1090 ecount
= unw_decode_uleb128 (&dp
, end
);
1091 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1093 else if ((code
& 0x07) == 0)
1095 label
= unw_decode_uleb128 (&dp
, end
);
1096 if ((code
& 0x08) != 0)
1097 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1099 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1105 return unw_decode_x1 (dp
, code
, arg
, end
);
1107 return unw_decode_x2 (dp
, code
, arg
, end
);
1109 return unw_decode_x3 (dp
, code
, arg
, end
);
1111 return unw_decode_x4 (dp
, code
, arg
, end
);
1113 UNW_DEC_BAD_CODE (code
);
1119 typedef const unsigned char *(*unw_decoder
)
1120 (const unsigned char *, unsigned int, void *, const unsigned char *);
1122 static const unw_decoder unw_decode_table
[2][8] =
1124 /* prologue table: */
1126 unw_decode_r1
, /* 0 */
1130 unw_decode_p1
, /* 4 */
1136 unw_decode_r1
, /* 0 */
1140 unw_decode_b1
, /* 4 */
1147 /* Decode one descriptor and return address of next descriptor. */
1148 const unsigned char *
1149 unw_decode (const unsigned char *dp
, int inside_body
,
1150 void *ptr_inside_body
, const unsigned char * end
)
1152 unw_decoder decoder
;
1157 printf (_("\t<corrupt IA64 descriptor>\n"));
1162 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1163 return (*decoder
) (dp
, code
, ptr_inside_body
, end
);