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
)
54 cp
+= sprintf (cp
, "%sb%u", sep
, i
+ 1);
63 unw_print_grmask (cp
, mask
)
71 for (i
= 0; i
< 4; ++i
)
75 cp
+= sprintf (cp
, "%sr%u", sep
, i
+ 4);
83 unw_print_frmask (cp
, mask
)
91 for (i
= 0; i
< 20; ++i
)
95 cp
+= sprintf (cp
, "%sf%u", sep
, (i
< 4) ? (i
+ 2) : (i
+ 12));
103 unw_print_abreg (cp
, abreg
)
107 static const char *special_reg
[16] =
109 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
110 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
111 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
114 switch ((abreg
>> 5) & 0x3)
117 sprintf (cp
, "r%u", (abreg
& 0x1f));
121 sprintf (cp
, "f%u", (abreg
& 0x1f));
125 sprintf (cp
, "b%u", (abreg
& 0x1f));
128 case 3: /* special */
129 strcpy (cp
, special_reg
[abreg
& 0xf]);
135 unw_print_xyreg (cp
, x
, ytreg
)
140 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
143 sprintf (cp
, "r%u", (ytreg
& 0x1f));
147 sprintf (cp
, "f%u", (ytreg
& 0x1f));
151 sprintf (cp
, "b%u", (ytreg
& 0x1f));
156 #define UNW_REG_BSP "bsp"
157 #define UNW_REG_BSPSTORE "bspstore"
158 #define UNW_REG_FPSR "fpsr"
159 #define UNW_REG_LC "lc"
160 #define UNW_REG_PFS "pfs"
161 #define UNW_REG_PR "pr"
162 #define UNW_REG_PSP "psp"
163 #define UNW_REG_RNAT "rnat"
164 #define UNW_REG_RP "rp"
165 #define UNW_REG_UNAT "unat"
167 typedef bfd_vma unw_word
;
169 #define UNW_DEC_BAD_CODE(code) \
170 printf ("Unknown code 0x%02x\n", code)
172 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
176 *(int *)arg = body; \
177 printf (" %s:%s(rlen=%lu)\n", \
178 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
182 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
185 char regname[16], maskstr[64], *sep; \
194 strcat (maskstr, "rp"); \
199 strcat (maskstr, sep); \
200 strcat (maskstr, "ar.pfs"); \
205 strcat (maskstr, sep); \
206 strcat (maskstr, "psp"); \
211 strcat (maskstr, sep); \
212 strcat (maskstr, "pr"); \
214 sprintf (regname, "r%u", grsave); \
215 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
216 fmt, maskstr, regname, (unsigned long) rlen); \
220 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
225 unw_print_frmask (frstr, frmask); \
226 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
230 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
235 unw_print_grmask (grstr, grmask); \
236 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
240 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
243 char frstr[200], grstr[20]; \
245 unw_print_grmask (grstr, grmask); \
246 unw_print_frmask (frstr, frmask); \
247 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
251 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
256 unw_print_brmask (brstr, brmask); \
257 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
261 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
266 unw_print_brmask (brstr, brmask); \
267 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
271 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
272 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
274 #define UNW_DEC_RP_BR(fmt, dst, arg) \
275 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
277 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
278 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
280 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
281 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
282 fmt, reg, 4*(unsigned long)spoff)
284 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
285 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
286 fmt, reg, 4*(unsigned long)pspoff)
288 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
293 unw_print_grmask (grstr, grmask); \
294 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
298 #define UNW_DEC_ABI(fmt, abi, context, arg) \
301 static const char *abiname[] = \
303 "@svr4", "@hpux", "@nt" \
306 const char *abistr = buf; \
309 abistr = abiname[abi]; \
311 sprintf (buf, "0x%x", abi); \
312 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
313 fmt, abistr, context); \
317 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
318 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
320 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
321 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
323 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
324 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
326 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
327 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
328 fmt, 4*(unsigned long)pspoff)
330 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
331 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
332 fmt, 4*(unsigned long)spoff)
334 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
335 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
336 fmt, (unsigned long) t, 16*(unsigned long)size)
338 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
339 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
341 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
342 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
343 fmt, 4*(unsigned long)pspoff)
345 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
348 static const char * spill_type = "-frb"; \
349 unsigned const char * imaskp = dp; \
350 unsigned char mask = 0; \
353 printf ("\t%s:spill_mask(imask=[", fmt); \
354 for (insn = 0; insn < unw_rlen; ++insn) \
356 if ((insn % 4) == 0) \
358 if (insn > 0 && (insn % 3) == 0) \
360 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
367 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
372 unw_print_abreg (regname, abreg); \
373 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
374 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
378 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
383 unw_print_abreg (regname, abreg); \
384 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
385 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
389 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
394 unw_print_abreg (regname, abreg); \
395 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
396 fmt, (unsigned long) t, regname); \
400 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
403 char abregname[10], tregname[10]; \
405 unw_print_abreg (abregname, abreg); \
406 unw_print_xyreg (tregname, x, ytreg); \
407 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
408 fmt, (unsigned long) t, abregname, tregname); \
412 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
417 unw_print_abreg (regname, abreg); \
418 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
419 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
423 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
428 unw_print_abreg (regname, abreg); \
429 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
430 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
434 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
439 unw_print_abreg (regname, abreg); \
440 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
441 fmt, qp, (unsigned long) t, regname); \
445 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
448 char regname[20], tregname[20]; \
450 unw_print_abreg (regname, abreg); \
451 unw_print_xyreg (tregname, x, ytreg); \
452 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
453 fmt, qp, (unsigned long) t, regname, tregname); \
457 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
458 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
460 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
461 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
463 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
464 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
465 fmt, (unsigned long) t, (unsigned long) ecount)
468 * Generic IA-64 unwind info decoder.
470 * This file is used both by the Linux kernel and objdump. Please
471 * keep the two copies of this file in sync (modulo differences in the
474 * You need to customize the decoder by defining the following
475 * macros/constants before including this file:
478 * unw_word Unsigned integer type with at least 64 bits
492 * Decoder action macros:
493 * UNW_DEC_BAD_CODE(code)
494 * UNW_DEC_ABI(fmt,abi,context,arg)
495 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
496 * UNW_DEC_BR_MEM(fmt,brmask,arg)
497 * UNW_DEC_COPY_STATE(fmt,label,arg)
498 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
499 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
500 * UNW_DEC_FR_MEM(fmt,frmask,arg)
501 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
502 * UNW_DEC_GR_MEM(fmt,grmask,arg)
503 * UNW_DEC_LABEL_STATE(fmt,label,arg)
504 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
505 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
506 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
507 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
508 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
509 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
510 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
511 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
512 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
513 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
514 * UNW_DEC_REG_REG(fmt,src,dst,arg)
515 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
516 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
517 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
518 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
519 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
520 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
521 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
522 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
523 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
524 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
525 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
526 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
529 static unw_word unw_decode_uleb128
PARAMS ((const unsigned char **));
530 static const unsigned char *unw_decode_x1
PARAMS ((const unsigned char *,
531 unsigned int, void *));
532 static const unsigned char *unw_decode_x2
PARAMS ((const unsigned char *,
533 unsigned int, void *));
534 static const unsigned char *unw_decode_x3
PARAMS ((const unsigned char *,
535 unsigned int, void *));
536 static const unsigned char *unw_decode_x4
PARAMS ((const unsigned char *,
537 unsigned int, void *));
538 static const unsigned char *unw_decode_r1
PARAMS ((const unsigned char *,
539 unsigned int, void *));
540 static const unsigned char *unw_decode_r2
PARAMS ((const unsigned char *,
541 unsigned int, void *));
542 static const unsigned char *unw_decode_r3
PARAMS ((const unsigned char *,
543 unsigned int, void *));
544 static const unsigned char *unw_decode_p1
PARAMS ((const unsigned char *,
545 unsigned int, void *));
546 static const unsigned char *unw_decode_p2_p5
PARAMS ((const unsigned char *,
547 unsigned int, void *));
548 static const unsigned char *unw_decode_p6
PARAMS ((const unsigned char *,
549 unsigned int, void *));
550 static const unsigned char *unw_decode_p7_p10
PARAMS ((const unsigned char *,
551 unsigned int, void *));
552 static const unsigned char *unw_decode_b1
PARAMS ((const unsigned char *,
553 unsigned int, void *));
554 static const unsigned char *unw_decode_b2
PARAMS ((const unsigned char *,
555 unsigned int, void *));
556 static const unsigned char *unw_decode_b3_x4
PARAMS ((const unsigned char *,
557 unsigned int, void *));
560 unw_decode_uleb128 (dpp
)
561 const unsigned char **dpp
;
564 unw_word byte
, result
= 0;
565 const unsigned char *bp
= *dpp
;
570 result
|= (byte
& 0x7f) << shift
;
572 if ((byte
& 0x80) == 0)
583 static const unsigned char *
584 unw_decode_x1 (dp
, code
, arg
)
585 const unsigned char * dp
;
586 unsigned int code ATTRIBUTE_UNUSED
;
587 void * arg ATTRIBUTE_UNUSED
;
589 unsigned char byte1
, abreg
;
593 t
= unw_decode_uleb128 (&dp
);
594 off
= unw_decode_uleb128 (&dp
);
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 (dp
, code
, arg
)
605 const unsigned char * dp
;
606 unsigned int code ATTRIBUTE_UNUSED
;
607 void * arg ATTRIBUTE_UNUSED
;
609 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
614 t
= unw_decode_uleb128 (&dp
);
615 abreg
= (byte1
& 0x7f);
617 x
= (byte1
>> 7) & 1;
618 if ((byte1
& 0x80) == 0 && ytreg
== 0)
619 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
621 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
625 static const unsigned char *
626 unw_decode_x3 (dp
, code
, arg
)
627 const unsigned char * dp
;
628 unsigned int code ATTRIBUTE_UNUSED
;
629 void * arg ATTRIBUTE_UNUSED
;
631 unsigned char byte1
, byte2
, abreg
, qp
;
636 t
= unw_decode_uleb128 (&dp
);
637 off
= unw_decode_uleb128 (&dp
);
640 abreg
= (byte2
& 0x7f);
643 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
645 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
649 static const unsigned char *
650 unw_decode_x4 (dp
, code
, arg
)
651 const unsigned char * dp
;
652 unsigned int code ATTRIBUTE_UNUSED
;
653 void * arg ATTRIBUTE_UNUSED
;
655 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
661 t
= unw_decode_uleb128 (&dp
);
664 abreg
= (byte2
& 0x7f);
665 x
= (byte2
>> 7) & 1;
668 if ((byte2
& 0x80) == 0 && byte3
== 0)
669 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
671 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
675 static const unsigned char *
676 unw_decode_r1 (dp
, code
, arg
)
677 const unsigned char *dp
;
681 int body
= (code
& 0x20) != 0;
684 rlen
= (code
& 0x1f);
685 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
689 static const unsigned char *
690 unw_decode_r2 (dp
, code
, arg
)
691 const unsigned char *dp
;
695 unsigned char byte1
, mask
, grsave
;
700 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
701 grsave
= (byte1
& 0x7f);
702 rlen
= unw_decode_uleb128 (& dp
);
703 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
707 static const unsigned char *
708 unw_decode_r3 (dp
, code
, arg
)
709 const unsigned char *dp
;
715 rlen
= unw_decode_uleb128 (& dp
);
716 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
720 static const unsigned char *
721 unw_decode_p1 (dp
, code
, arg
)
722 const unsigned char * dp
;
724 void * arg ATTRIBUTE_UNUSED
;
726 unsigned char brmask
= (code
& 0x1f);
728 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
732 static const unsigned char *
733 unw_decode_p2_p5 (dp
, code
, arg
)
734 const unsigned char * dp
;
736 void * arg ATTRIBUTE_UNUSED
;
738 if ((code
& 0x10) == 0)
740 unsigned char byte1
= *dp
++;
742 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
743 (byte1
& 0x7f), arg
);
745 else if ((code
& 0x08) == 0)
747 unsigned char byte1
= *dp
++, r
, dst
;
749 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
750 dst
= (byte1
& 0x7f);
754 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
757 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
760 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
763 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
766 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
769 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
772 UNW_DEC_RP_BR ("P3", dst
, arg
);
775 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
778 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
781 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
784 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
787 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
790 UNW_DEC_BAD_CODE (r
);
794 else if ((code
& 0x7) == 0)
795 UNW_DEC_SPILL_MASK ("P4", dp
, arg
);
796 else if ((code
& 0x7) == 1)
798 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
803 grmask
= ((byte1
>> 4) & 0xf);
804 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
805 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
808 UNW_DEC_BAD_CODE (code
);
813 static const unsigned char *
814 unw_decode_p6 (dp
, code
, arg
)
815 const unsigned char * dp
;
817 void * arg ATTRIBUTE_UNUSED
;
819 int gregs
= (code
& 0x10) != 0;
820 unsigned char mask
= (code
& 0x0f);
823 UNW_DEC_GR_MEM ("P6", mask
, arg
);
825 UNW_DEC_FR_MEM ("P6", mask
, arg
);
829 static const unsigned char *
830 unw_decode_p7_p10 (dp
, code
, arg
)
831 const unsigned char *dp
;
835 unsigned char r
, byte1
, byte2
;
838 if ((code
& 0x10) == 0)
841 t
= unw_decode_uleb128 (&dp
);
845 size
= unw_decode_uleb128 (&dp
);
846 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
850 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
853 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
856 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
859 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
862 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
865 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
868 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
871 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
874 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
877 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
880 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
883 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
886 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
889 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
892 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
895 UNW_DEC_BAD_CODE (r
);
906 t
= unw_decode_uleb128 (&dp
);
910 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
913 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
916 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
919 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
922 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
925 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
928 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
931 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
937 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
940 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
943 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
946 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
949 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
952 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
955 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
958 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
961 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
964 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
967 UNW_DEC_BAD_CODE (r
);
976 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
982 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
986 return unw_decode_x1 (dp
, code
, arg
);
989 return unw_decode_x2 (dp
, code
, arg
);
992 return unw_decode_x3 (dp
, code
, arg
);
995 return unw_decode_x4 (dp
, code
, arg
);
998 UNW_DEC_BAD_CODE (code
);
1005 static const unsigned char *
1006 unw_decode_b1 (dp
, code
, arg
)
1007 const unsigned char * dp
;
1009 void * arg ATTRIBUTE_UNUSED
;
1011 unw_word label
= (code
& 0x1f);
1013 if ((code
& 0x20) != 0)
1014 UNW_DEC_COPY_STATE ("B1", label
, arg
);
1016 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
1020 static const unsigned char *
1021 unw_decode_b2 (dp
, code
, arg
)
1022 const unsigned char * dp
;
1024 void * arg ATTRIBUTE_UNUSED
;
1028 t
= unw_decode_uleb128 (& dp
);
1029 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1033 static const unsigned char *
1034 unw_decode_b3_x4 (dp
, code
, arg
)
1035 const unsigned char *dp
;
1039 unw_word t
, ecount
, label
;
1041 if ((code
& 0x10) == 0)
1043 t
= unw_decode_uleb128 (&dp
);
1044 ecount
= unw_decode_uleb128 (&dp
);
1045 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1047 else if ((code
& 0x07) == 0)
1049 label
= unw_decode_uleb128 (&dp
);
1050 if ((code
& 0x08) != 0)
1051 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1053 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1059 return unw_decode_x1 (dp
, code
, arg
);
1061 return unw_decode_x2 (dp
, code
, arg
);
1063 return unw_decode_x3 (dp
, code
, arg
);
1065 return unw_decode_x4 (dp
, code
, arg
);
1067 UNW_DEC_BAD_CODE (code
);
1073 typedef const unsigned char *(*unw_decoder
)
1074 PARAMS ((const unsigned char *, unsigned char, void *));
1076 static unw_decoder unw_decode_table
[2][8] =
1078 /* prologue table: */
1080 unw_decode_r1
, /* 0 */
1084 unw_decode_p1
, /* 4 */
1090 unw_decode_r1
, /* 0 */
1094 unw_decode_b1
, /* 4 */
1101 /* Decode one descriptor and return address of next descriptor. */
1102 const unsigned char *
1103 unw_decode (dp
, inside_body
, ptr_inside_body
)
1104 const unsigned char * dp
;
1106 void * ptr_inside_body
;
1108 unw_decoder decoder
;
1112 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1113 return (*decoder
) (dp
, code
, ptr_inside_body
);