1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright 2000, 2001, 2002, 2003 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 believe 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 (char *, unsigned int);
37 static void unw_print_grmask (char *, unsigned int);
38 static void unw_print_frmask (char *, unsigned int);
39 static void unw_print_abreg (char *, unsigned int);
40 static void unw_print_xyreg (char *, unsigned int, unsigned int);
43 unw_print_brmask (char *cp
, unsigned int mask
)
48 for (i
= 0; mask
&& (i
< 5); ++i
)
64 unw_print_grmask (char *cp
, unsigned int mask
)
69 for (i
= 0; i
< 4; ++i
)
85 unw_print_frmask (char *cp
, unsigned int mask
)
90 for (i
= 0; i
< 20; ++i
)
101 *cp
++ = (i
+ 2) / 10 + 1 + '0';
102 *cp
++ = (i
+ 2) % 10 + '0';
112 unw_print_abreg (char *cp
, unsigned int abreg
)
114 static const char *special_reg
[16] =
116 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
117 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
118 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
121 switch ((abreg
>> 5) & 0x3)
124 sprintf (cp
, "r%u", (abreg
& 0x1f));
128 sprintf (cp
, "f%u", (abreg
& 0x1f));
132 sprintf (cp
, "b%u", (abreg
& 0x1f));
135 case 3: /* special */
136 strcpy (cp
, special_reg
[abreg
& 0xf]);
142 unw_print_xyreg (char *cp
, unsigned int x
, unsigned int ytreg
)
144 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
147 sprintf (cp
, "r%u", (ytreg
& 0x1f));
151 sprintf (cp
, "f%u", (ytreg
& 0x1f));
155 sprintf (cp
, "b%u", (ytreg
& 0x1f));
160 #define UNW_REG_BSP "bsp"
161 #define UNW_REG_BSPSTORE "bspstore"
162 #define UNW_REG_FPSR "fpsr"
163 #define UNW_REG_LC "lc"
164 #define UNW_REG_PFS "pfs"
165 #define UNW_REG_PR "pr"
166 #define UNW_REG_PSP "psp"
167 #define UNW_REG_RNAT "rnat"
168 #define UNW_REG_RP "rp"
169 #define UNW_REG_UNAT "unat"
171 typedef bfd_vma unw_word
;
173 #define UNW_DEC_BAD_CODE(code) \
174 printf ("Unknown code 0x%02x\n", code)
176 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
180 *(int *)arg = body; \
181 printf (" %s:%s(rlen=%lu)\n", \
182 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
186 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
189 char regname[16], maskstr[64], *sep; \
198 strcat (maskstr, "rp"); \
203 strcat (maskstr, sep); \
204 strcat (maskstr, "ar.pfs"); \
209 strcat (maskstr, sep); \
210 strcat (maskstr, "psp"); \
215 strcat (maskstr, sep); \
216 strcat (maskstr, "pr"); \
218 sprintf (regname, "r%u", grsave); \
219 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
220 fmt, maskstr, regname, (unsigned long) rlen); \
224 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
229 unw_print_frmask (frstr, frmask); \
230 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
234 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
239 unw_print_grmask (grstr, grmask); \
240 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
244 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
247 char frstr[200], grstr[20]; \
249 unw_print_grmask (grstr, grmask); \
250 unw_print_frmask (frstr, frmask); \
251 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
255 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
260 unw_print_brmask (brstr, brmask); \
261 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
265 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
270 unw_print_brmask (brstr, brmask); \
271 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
275 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
276 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
278 #define UNW_DEC_RP_BR(fmt, dst, arg) \
279 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
281 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
282 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
284 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
285 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
286 fmt, reg, 4*(unsigned long)spoff)
288 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
289 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
290 fmt, reg, 4*(unsigned long)pspoff)
292 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
297 unw_print_grmask (grstr, grmask); \
298 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
302 #define UNW_DEC_ABI(fmt, abi, context, arg) \
305 static const char *abiname[] = \
307 "@svr4", "@hpux", "@nt" \
310 const char *abistr = buf; \
313 abistr = abiname[abi]; \
315 sprintf (buf, "0x%x", abi); \
316 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
317 fmt, abistr, context); \
321 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
322 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
324 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
325 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
327 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
328 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
330 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
331 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
332 fmt, 4*(unsigned long)pspoff)
334 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
335 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
336 fmt, 4*(unsigned long)spoff)
338 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
339 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
340 fmt, (unsigned long) t, 16*(unsigned long)size)
342 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
343 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
345 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
346 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
347 fmt, 4*(unsigned long)pspoff)
349 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
352 static const char *spill_type = "-frb"; \
353 unsigned const char *imaskp = dp; \
354 unsigned char mask = 0; \
357 printf ("\t%s:spill_mask(imask=[", fmt); \
358 for (insn = 0; insn < unw_rlen; ++insn) \
360 if ((insn % 4) == 0) \
362 if (insn > 0 && (insn % 3) == 0) \
364 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
371 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
376 unw_print_abreg (regname, abreg); \
377 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
378 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
382 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
387 unw_print_abreg (regname, abreg); \
388 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
389 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
393 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
398 unw_print_abreg (regname, abreg); \
399 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
400 fmt, (unsigned long) t, regname); \
404 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
407 char abregname[10], tregname[10]; \
409 unw_print_abreg (abregname, abreg); \
410 unw_print_xyreg (tregname, x, ytreg); \
411 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
412 fmt, (unsigned long) t, abregname, tregname); \
416 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
421 unw_print_abreg (regname, abreg); \
422 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
423 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
427 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
432 unw_print_abreg (regname, abreg); \
433 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
434 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
438 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
443 unw_print_abreg (regname, abreg); \
444 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
445 fmt, qp, (unsigned long) t, regname); \
449 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
452 char regname[20], tregname[20]; \
454 unw_print_abreg (regname, abreg); \
455 unw_print_xyreg (tregname, x, ytreg); \
456 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
457 fmt, qp, (unsigned long) t, regname, tregname); \
461 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
462 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
464 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
465 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
467 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
468 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
469 fmt, (unsigned long) t, (unsigned long) ecount)
472 * Generic IA-64 unwind info decoder.
474 * This file is used both by the Linux kernel and objdump. Please
475 * keep the two copies of this file in sync (modulo differences in the
478 * You need to customize the decoder by defining the following
479 * macros/constants before including this file:
482 * unw_word Unsigned integer type with at least 64 bits
496 * Decoder action macros:
497 * UNW_DEC_BAD_CODE(code)
498 * UNW_DEC_ABI(fmt,abi,context,arg)
499 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
500 * UNW_DEC_BR_MEM(fmt,brmask,arg)
501 * UNW_DEC_COPY_STATE(fmt,label,arg)
502 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
503 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
504 * UNW_DEC_FR_MEM(fmt,frmask,arg)
505 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
506 * UNW_DEC_GR_MEM(fmt,grmask,arg)
507 * UNW_DEC_LABEL_STATE(fmt,label,arg)
508 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
509 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
510 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
511 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
512 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
513 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
514 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
515 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
516 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
517 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
518 * UNW_DEC_REG_REG(fmt,src,dst,arg)
519 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
520 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
521 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
522 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
523 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
524 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
525 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
526 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
527 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
528 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
529 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
530 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
533 static unw_word
unw_decode_uleb128 (const unsigned char **);
534 static const unsigned char *unw_decode_x1
535 (const unsigned char *, unsigned int, void *);
536 static const unsigned char *unw_decode_x2
537 (const unsigned char *, unsigned int, void *);
538 static const unsigned char *unw_decode_x3
539 (const unsigned char *, unsigned int, void *);
540 static const unsigned char *unw_decode_x4
541 (const unsigned char *, unsigned int, void *);
542 static const unsigned char *unw_decode_r1
543 (const unsigned char *, unsigned int, void *);
544 static const unsigned char *unw_decode_r2
545 (const unsigned char *, unsigned int, void *);
546 static const unsigned char *unw_decode_r3
547 (const unsigned char *, unsigned int, void *);
548 static const unsigned char *unw_decode_p1
549 (const unsigned char *, unsigned int, void *);
550 static const unsigned char *unw_decode_p2_p5
551 (const unsigned char *, unsigned int, void *);
552 static const unsigned char *unw_decode_p6
553 (const unsigned char *, unsigned int, void *);
554 static const unsigned char *unw_decode_p7_p10
555 (const unsigned char *, unsigned int, void *);
556 static const unsigned char *unw_decode_b1
557 (const unsigned char *, unsigned int, void *);
558 static const unsigned char *unw_decode_b2
559 (const unsigned char *, unsigned int, void *);
560 static const unsigned char *unw_decode_b3_x4
561 (const unsigned char *, unsigned int, void *);
564 unw_decode_uleb128 (const unsigned char **dpp
)
567 unw_word byte
, result
= 0;
568 const unsigned char *bp
= *dpp
;
573 result
|= (byte
& 0x7f) << shift
;
575 if ((byte
& 0x80) == 0)
586 static const unsigned char *
587 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
588 void *arg ATTRIBUTE_UNUSED
)
590 unsigned char byte1
, abreg
;
594 t
= unw_decode_uleb128 (&dp
);
595 off
= unw_decode_uleb128 (&dp
);
596 abreg
= (byte1
& 0x7f);
598 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
600 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
604 static const unsigned char *
605 unw_decode_x2 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
606 void *arg ATTRIBUTE_UNUSED
)
608 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
613 t
= unw_decode_uleb128 (&dp
);
614 abreg
= (byte1
& 0x7f);
616 x
= (byte1
>> 7) & 1;
617 if ((byte1
& 0x80) == 0 && ytreg
== 0)
618 UNW_DEC_RESTORE ("X2", t
, abreg
, arg
);
620 UNW_DEC_SPILL_REG ("X2", t
, abreg
, x
, ytreg
, arg
);
624 static const unsigned char *
625 unw_decode_x3 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
626 void *arg ATTRIBUTE_UNUSED
)
628 unsigned char byte1
, byte2
, abreg
, qp
;
633 t
= unw_decode_uleb128 (&dp
);
634 off
= unw_decode_uleb128 (&dp
);
637 abreg
= (byte2
& 0x7f);
640 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
642 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
646 static const unsigned char *
647 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
648 void *arg ATTRIBUTE_UNUSED
)
650 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
656 t
= unw_decode_uleb128 (&dp
);
659 abreg
= (byte2
& 0x7f);
660 x
= (byte2
>> 7) & 1;
663 if ((byte2
& 0x80) == 0 && byte3
== 0)
664 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
666 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
670 static const unsigned char *
671 unw_decode_r1 (const unsigned char *dp
, unsigned int code
, void *arg
)
673 int body
= (code
& 0x20) != 0;
676 rlen
= (code
& 0x1f);
677 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
681 static const unsigned char *
682 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
)
684 unsigned char byte1
, mask
, grsave
;
689 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
690 grsave
= (byte1
& 0x7f);
691 rlen
= unw_decode_uleb128 (& dp
);
692 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
696 static const unsigned char *
697 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
)
701 rlen
= unw_decode_uleb128 (& dp
);
702 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
706 static const unsigned char *
707 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
708 void *arg ATTRIBUTE_UNUSED
)
710 unsigned char brmask
= (code
& 0x1f);
712 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
716 static const unsigned char *
717 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
718 void *arg ATTRIBUTE_UNUSED
)
720 if ((code
& 0x10) == 0)
722 unsigned char byte1
= *dp
++;
724 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
725 (byte1
& 0x7f), arg
);
727 else if ((code
& 0x08) == 0)
729 unsigned char byte1
= *dp
++, r
, dst
;
731 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
732 dst
= (byte1
& 0x7f);
736 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
739 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
742 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
745 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
748 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
751 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
754 UNW_DEC_RP_BR ("P3", dst
, arg
);
757 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
760 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
763 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
766 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
769 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
772 UNW_DEC_BAD_CODE (r
);
776 else if ((code
& 0x7) == 0)
777 UNW_DEC_SPILL_MASK ("P4", dp
, arg
);
778 else if ((code
& 0x7) == 1)
780 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
785 grmask
= ((byte1
>> 4) & 0xf);
786 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
787 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
790 UNW_DEC_BAD_CODE (code
);
795 static const unsigned char *
796 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
797 void *arg ATTRIBUTE_UNUSED
)
799 int gregs
= (code
& 0x10) != 0;
800 unsigned char mask
= (code
& 0x0f);
803 UNW_DEC_GR_MEM ("P6", mask
, arg
);
805 UNW_DEC_FR_MEM ("P6", mask
, arg
);
809 static const unsigned char *
810 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
)
812 unsigned char r
, byte1
, byte2
;
815 if ((code
& 0x10) == 0)
818 t
= unw_decode_uleb128 (&dp
);
822 size
= unw_decode_uleb128 (&dp
);
823 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
827 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
830 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
833 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
836 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
839 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
842 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
845 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
848 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
851 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
854 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
857 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
860 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
863 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
866 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
869 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
872 UNW_DEC_BAD_CODE (r
);
883 t
= unw_decode_uleb128 (&dp
);
887 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
890 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
893 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
896 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
899 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
902 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
905 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
908 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
911 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
914 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
917 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
920 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
923 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
926 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
929 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
932 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
935 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
938 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
941 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
944 UNW_DEC_BAD_CODE (r
);
953 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
959 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
963 return unw_decode_x1 (dp
, code
, arg
);
966 return unw_decode_x2 (dp
, code
, arg
);
969 return unw_decode_x3 (dp
, code
, arg
);
972 return unw_decode_x4 (dp
, code
, arg
);
975 UNW_DEC_BAD_CODE (code
);
982 static const unsigned char *
983 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
984 void *arg ATTRIBUTE_UNUSED
)
986 unw_word label
= (code
& 0x1f);
988 if ((code
& 0x20) != 0)
989 UNW_DEC_COPY_STATE ("B1", label
, arg
);
991 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
995 static const unsigned char *
996 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
997 void *arg ATTRIBUTE_UNUSED
)
1001 t
= unw_decode_uleb128 (& dp
);
1002 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1006 static const unsigned char *
1007 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
)
1009 unw_word t
, ecount
, label
;
1011 if ((code
& 0x10) == 0)
1013 t
= unw_decode_uleb128 (&dp
);
1014 ecount
= unw_decode_uleb128 (&dp
);
1015 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1017 else if ((code
& 0x07) == 0)
1019 label
= unw_decode_uleb128 (&dp
);
1020 if ((code
& 0x08) != 0)
1021 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1023 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1029 return unw_decode_x1 (dp
, code
, arg
);
1031 return unw_decode_x2 (dp
, code
, arg
);
1033 return unw_decode_x3 (dp
, code
, arg
);
1035 return unw_decode_x4 (dp
, code
, arg
);
1037 UNW_DEC_BAD_CODE (code
);
1043 typedef const unsigned char *(*unw_decoder
)
1044 (const unsigned char *, unsigned int, void *);
1046 static unw_decoder unw_decode_table
[2][8] =
1048 /* prologue table: */
1050 unw_decode_r1
, /* 0 */
1054 unw_decode_p1
, /* 4 */
1060 unw_decode_r1
, /* 0 */
1064 unw_decode_b1
, /* 4 */
1071 /* Decode one descriptor and return address of next descriptor. */
1072 const unsigned char *
1073 unw_decode (const unsigned char *dp
, int inside_body
,
1074 void *ptr_inside_body
)
1076 unw_decoder decoder
;
1080 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1081 return (*decoder
) (dp
, code
, ptr_inside_body
);