1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright 2000, 2001 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "unwind-ia64.h"
26 /* Define BFD64 here, even if our default architecture is 32 bit ELF
27 as this will allow us to read in and parse 64bit and 32bit ELF files.
28 Only do this if we belive that the compiler can support a 64 bit
29 data type. For now we only rely on GCC being able to do this. */
34 static bfd_vma unw_rlen
= 0;
36 static void unw_print_brmask
PARAMS ((char *, unsigned int));
37 static void unw_print_grmask
PARAMS ((char *, unsigned int));
38 static void unw_print_frmask
PARAMS ((char *, unsigned int));
39 static void unw_print_abreg
PARAMS ((char *, unsigned int));
40 static void unw_print_xyreg
PARAMS ((char *, unsigned int, unsigned int));
43 unw_print_brmask (cp
, mask
)
50 for (i
= 0; mask
&& (i
< 5); ++i
)
66 unw_print_grmask (cp
, mask
)
73 for (i
= 0; i
< 4; ++i
)
89 unw_print_frmask (cp
, mask
)
96 for (i
= 0; i
< 20; ++i
)
107 *cp
++ = (i
+ 2) / 10 + 1 + '0';
108 *cp
++ = (i
+ 2) % 10 + '0';
118 unw_print_abreg (cp
, abreg
)
122 static const char *special_reg
[16] =
124 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
125 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
126 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
129 switch ((abreg
>> 5) & 0x3)
132 sprintf (cp
, "r%u", (abreg
& 0x1f));
136 sprintf (cp
, "f%u", (abreg
& 0x1f));
140 sprintf (cp
, "b%u", (abreg
& 0x1f));
143 case 3: /* special */
144 strcpy (cp
, special_reg
[abreg
& 0xf]);
150 unw_print_xyreg (cp
, x
, ytreg
)
155 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
158 sprintf (cp
, "r%u", (ytreg
& 0x1f));
162 sprintf (cp
, "f%u", (ytreg
& 0x1f));
166 sprintf (cp
, "b%u", (ytreg
& 0x1f));
171 #define UNW_REG_BSP "bsp"
172 #define UNW_REG_BSPSTORE "bspstore"
173 #define UNW_REG_FPSR "fpsr"
174 #define UNW_REG_LC "lc"
175 #define UNW_REG_PFS "pfs"
176 #define UNW_REG_PR "pr"
177 #define UNW_REG_PSP "psp"
178 #define UNW_REG_RNAT "rnat"
179 #define UNW_REG_RP "rp"
180 #define UNW_REG_UNAT "unat"
182 typedef bfd_vma unw_word
;
184 #define UNW_DEC_BAD_CODE(code) \
185 printf ("Unknown code 0x%02x\n", code)
187 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
191 *(int *)arg = body; \
192 printf (" %s:%s(rlen=%lu)\n", \
193 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
197 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
200 char regname[16], maskstr[64], *sep; \
209 strcat (maskstr, "rp"); \
214 strcat (maskstr, sep); \
215 strcat (maskstr, "ar.pfs"); \
220 strcat (maskstr, sep); \
221 strcat (maskstr, "psp"); \
226 strcat (maskstr, sep); \
227 strcat (maskstr, "pr"); \
229 sprintf (regname, "r%u", grsave); \
230 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
231 fmt, maskstr, regname, (unsigned long) rlen); \
235 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
240 unw_print_frmask (frstr, frmask); \
241 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
245 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
250 unw_print_grmask (grstr, grmask); \
251 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
255 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
258 char frstr[200], grstr[20]; \
260 unw_print_grmask (grstr, grmask); \
261 unw_print_frmask (frstr, frmask); \
262 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
266 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
271 unw_print_brmask (brstr, brmask); \
272 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
276 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
281 unw_print_brmask (brstr, brmask); \
282 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
286 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
287 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
289 #define UNW_DEC_RP_BR(fmt, dst, arg) \
290 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
292 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
293 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
295 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
296 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
297 fmt, reg, 4*(unsigned long)spoff)
299 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
300 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
301 fmt, reg, 4*(unsigned long)pspoff)
303 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
308 unw_print_grmask (grstr, grmask); \
309 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
313 #define UNW_DEC_ABI(fmt, abi, context, arg) \
316 static const char *abiname[] = \
318 "@svr4", "@hpux", "@nt" \
321 const char *abistr = buf; \
324 abistr = abiname[abi]; \
326 sprintf (buf, "0x%x", abi); \
327 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
328 fmt, abistr, context); \
332 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
333 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
335 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
336 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
338 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
339 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
341 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
342 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
343 fmt, 4*(unsigned long)pspoff)
345 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
346 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
347 fmt, 4*(unsigned long)spoff)
349 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
350 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
351 fmt, (unsigned long) t, 16*(unsigned long)size)
353 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
354 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
356 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
357 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
358 fmt, 4*(unsigned long)pspoff)
360 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
363 static const char * spill_type = "-frb"; \
364 unsigned const char * imaskp = dp; \
365 unsigned char mask = 0; \
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[10], tregname[10]; \
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)
544 static unw_word unw_decode_uleb128
PARAMS ((const unsigned char **));
545 static const unsigned char *unw_decode_x1
PARAMS ((const unsigned char *,
546 unsigned int, void *));
547 static const unsigned char *unw_decode_x2
PARAMS ((const unsigned char *,
548 unsigned int, void *));
549 static const unsigned char *unw_decode_x3
PARAMS ((const unsigned char *,
550 unsigned int, void *));
551 static const unsigned char *unw_decode_x4
PARAMS ((const unsigned char *,
552 unsigned int, void *));
553 static const unsigned char *unw_decode_r1
PARAMS ((const unsigned char *,
554 unsigned int, void *));
555 static const unsigned char *unw_decode_r2
PARAMS ((const unsigned char *,
556 unsigned int, void *));
557 static const unsigned char *unw_decode_r3
PARAMS ((const unsigned char *,
558 unsigned int, void *));
559 static const unsigned char *unw_decode_p1
PARAMS ((const unsigned char *,
560 unsigned int, void *));
561 static const unsigned char *unw_decode_p2_p5
PARAMS ((const unsigned char *,
562 unsigned int, void *));
563 static const unsigned char *unw_decode_p6
PARAMS ((const unsigned char *,
564 unsigned int, void *));
565 static const unsigned char *unw_decode_p7_p10
PARAMS ((const unsigned char *,
566 unsigned int, void *));
567 static const unsigned char *unw_decode_b1
PARAMS ((const unsigned char *,
568 unsigned int, void *));
569 static const unsigned char *unw_decode_b2
PARAMS ((const unsigned char *,
570 unsigned int, void *));
571 static const unsigned char *unw_decode_b3_x4
PARAMS ((const unsigned char *,
572 unsigned int, void *));
575 unw_decode_uleb128 (dpp
)
576 const unsigned char **dpp
;
579 unw_word byte
, result
= 0;
580 const unsigned char *bp
= *dpp
;
585 result
|= (byte
& 0x7f) << shift
;
587 if ((byte
& 0x80) == 0)
598 static const unsigned char *
599 unw_decode_x1 (dp
, code
, arg
)
600 const unsigned char * dp
;
601 unsigned int code ATTRIBUTE_UNUSED
;
602 void * arg ATTRIBUTE_UNUSED
;
604 unsigned char byte1
, abreg
;
608 t
= unw_decode_uleb128 (&dp
);
609 off
= unw_decode_uleb128 (&dp
);
610 abreg
= (byte1
& 0x7f);
612 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
614 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
618 static const unsigned char *
619 unw_decode_x2 (dp
, code
, arg
)
620 const unsigned char * dp
;
621 unsigned int code ATTRIBUTE_UNUSED
;
622 void * arg ATTRIBUTE_UNUSED
;
624 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
629 t
= unw_decode_uleb128 (&dp
);
630 abreg
= (byte1
& 0x7f);
632 x
= (byte1
>> 7) & 1;
633 if ((byte1
& 0x80) == 0 && ytreg
== 0)
634 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
636 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
640 static const unsigned char *
641 unw_decode_x3 (dp
, code
, arg
)
642 const unsigned char * dp
;
643 unsigned int code ATTRIBUTE_UNUSED
;
644 void * arg ATTRIBUTE_UNUSED
;
646 unsigned char byte1
, byte2
, abreg
, qp
;
651 t
= unw_decode_uleb128 (&dp
);
652 off
= unw_decode_uleb128 (&dp
);
655 abreg
= (byte2
& 0x7f);
658 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
660 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
664 static const unsigned char *
665 unw_decode_x4 (dp
, code
, arg
)
666 const unsigned char * dp
;
667 unsigned int code ATTRIBUTE_UNUSED
;
668 void * arg ATTRIBUTE_UNUSED
;
670 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
676 t
= unw_decode_uleb128 (&dp
);
679 abreg
= (byte2
& 0x7f);
680 x
= (byte2
>> 7) & 1;
683 if ((byte2
& 0x80) == 0 && byte3
== 0)
684 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
686 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
690 static const unsigned char *
691 unw_decode_r1 (dp
, code
, arg
)
692 const unsigned char *dp
;
696 int body
= (code
& 0x20) != 0;
699 rlen
= (code
& 0x1f);
700 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
704 static const unsigned char *
705 unw_decode_r2 (dp
, code
, arg
)
706 const unsigned char *dp
;
710 unsigned char byte1
, mask
, grsave
;
715 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
716 grsave
= (byte1
& 0x7f);
717 rlen
= unw_decode_uleb128 (& dp
);
718 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
722 static const unsigned char *
723 unw_decode_r3 (dp
, code
, arg
)
724 const unsigned char *dp
;
730 rlen
= unw_decode_uleb128 (& dp
);
731 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
735 static const unsigned char *
736 unw_decode_p1 (dp
, code
, arg
)
737 const unsigned char * dp
;
739 void * arg 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 (dp
, code
, arg
)
749 const unsigned char * dp
;
751 void * arg ATTRIBUTE_UNUSED
;
753 if ((code
& 0x10) == 0)
755 unsigned char byte1
= *dp
++;
757 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
758 (byte1
& 0x7f), arg
);
760 else if ((code
& 0x08) == 0)
762 unsigned char byte1
= *dp
++, r
, dst
;
764 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
765 dst
= (byte1
& 0x7f);
769 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
772 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
775 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
778 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
781 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
784 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
787 UNW_DEC_RP_BR ("P3", dst
, arg
);
790 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
793 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
796 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
799 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
802 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
805 UNW_DEC_BAD_CODE (r
);
809 else if ((code
& 0x7) == 0)
810 UNW_DEC_SPILL_MASK ("P4", dp
, arg
);
811 else if ((code
& 0x7) == 1)
813 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
818 grmask
= ((byte1
>> 4) & 0xf);
819 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
820 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
823 UNW_DEC_BAD_CODE (code
);
828 static const unsigned char *
829 unw_decode_p6 (dp
, code
, arg
)
830 const unsigned char * dp
;
832 void * arg ATTRIBUTE_UNUSED
;
834 int gregs
= (code
& 0x10) != 0;
835 unsigned char mask
= (code
& 0x0f);
838 UNW_DEC_GR_MEM ("P6", mask
, arg
);
840 UNW_DEC_FR_MEM ("P6", mask
, arg
);
844 static const unsigned char *
845 unw_decode_p7_p10 (dp
, code
, arg
)
846 const unsigned char *dp
;
850 unsigned char r
, byte1
, byte2
;
853 if ((code
& 0x10) == 0)
856 t
= unw_decode_uleb128 (&dp
);
860 size
= unw_decode_uleb128 (&dp
);
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
);
921 t
= unw_decode_uleb128 (&dp
);
925 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
928 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
931 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
937 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
940 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
943 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
946 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
949 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
952 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
955 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
958 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
961 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
964 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
967 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
970 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
973 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
976 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
979 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
982 UNW_DEC_BAD_CODE (r
);
991 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
997 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
1001 return unw_decode_x1 (dp
, code
, arg
);
1004 return unw_decode_x2 (dp
, code
, arg
);
1007 return unw_decode_x3 (dp
, code
, arg
);
1010 return unw_decode_x4 (dp
, code
, arg
);
1013 UNW_DEC_BAD_CODE (code
);
1020 static const unsigned char *
1021 unw_decode_b1 (dp
, code
, arg
)
1022 const unsigned char * dp
;
1024 void * arg ATTRIBUTE_UNUSED
;
1026 unw_word label
= (code
& 0x1f);
1028 if ((code
& 0x20) != 0)
1029 UNW_DEC_COPY_STATE ("B1", label
, arg
);
1031 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
1035 static const unsigned char *
1036 unw_decode_b2 (dp
, code
, arg
)
1037 const unsigned char * dp
;
1039 void * arg ATTRIBUTE_UNUSED
;
1043 t
= unw_decode_uleb128 (& dp
);
1044 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1048 static const unsigned char *
1049 unw_decode_b3_x4 (dp
, code
, arg
)
1050 const unsigned char *dp
;
1054 unw_word t
, ecount
, label
;
1056 if ((code
& 0x10) == 0)
1058 t
= unw_decode_uleb128 (&dp
);
1059 ecount
= unw_decode_uleb128 (&dp
);
1060 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1062 else if ((code
& 0x07) == 0)
1064 label
= unw_decode_uleb128 (&dp
);
1065 if ((code
& 0x08) != 0)
1066 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1068 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1074 return unw_decode_x1 (dp
, code
, arg
);
1076 return unw_decode_x2 (dp
, code
, arg
);
1078 return unw_decode_x3 (dp
, code
, arg
);
1080 return unw_decode_x4 (dp
, code
, arg
);
1082 UNW_DEC_BAD_CODE (code
);
1088 typedef const unsigned char *(*unw_decoder
)
1089 PARAMS ((const unsigned char *, unsigned int, void *));
1091 static unw_decoder unw_decode_table
[2][8] =
1093 /* prologue table: */
1095 unw_decode_r1
, /* 0 */
1099 unw_decode_p1
, /* 4 */
1105 unw_decode_r1
, /* 0 */
1109 unw_decode_b1
, /* 4 */
1116 /* Decode one descriptor and return address of next descriptor. */
1117 const unsigned char *
1118 unw_decode (dp
, inside_body
, ptr_inside_body
)
1119 const unsigned char * dp
;
1121 void * ptr_inside_body
;
1123 unw_decoder decoder
;
1127 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1128 return (*decoder
) (dp
, code
, ptr_inside_body
);