1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright 2000, 2001, 2002, 2003, 2005, 2007 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 3, 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, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "unwind-ia64.h"
27 /* Define BFD64 here, even if our default architecture is 32 bit ELF
28 as this will allow us to read in and parse 64bit and 32bit ELF files.
29 Only do this if we believe that the compiler can support a 64 bit
30 data type. For now we only rely on GCC being able to do this. */
35 static bfd_vma unw_rlen
= 0;
37 static void unw_print_brmask (char *, unsigned int);
38 static void unw_print_grmask (char *, unsigned int);
39 static void unw_print_frmask (char *, unsigned int);
40 static void unw_print_abreg (char *, unsigned int);
41 static void unw_print_xyreg (char *, unsigned int, unsigned int);
44 unw_print_brmask (char *cp
, unsigned int mask
)
49 for (i
= 0; mask
&& (i
< 5); ++i
)
65 unw_print_grmask (char *cp
, unsigned int mask
)
70 for (i
= 0; i
< 4; ++i
)
86 unw_print_frmask (char *cp
, unsigned int mask
)
91 for (i
= 0; i
< 20; ++i
)
102 *cp
++ = (i
+ 2) / 10 + 1 + '0';
103 *cp
++ = (i
+ 2) % 10 + '0';
113 unw_print_abreg (char *cp
, unsigned int abreg
)
115 static const char *special_reg
[16] =
117 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
118 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
119 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
122 switch ((abreg
>> 5) & 0x3)
125 sprintf (cp
, "r%u", (abreg
& 0x1f));
129 sprintf (cp
, "f%u", (abreg
& 0x1f));
133 sprintf (cp
, "b%u", (abreg
& 0x1f));
136 case 3: /* special */
137 strcpy (cp
, special_reg
[abreg
& 0xf]);
143 unw_print_xyreg (char *cp
, unsigned int x
, unsigned int ytreg
)
145 switch ((x
<< 1) | ((ytreg
>> 7) & 1))
148 sprintf (cp
, "r%u", (ytreg
& 0x1f));
152 sprintf (cp
, "f%u", (ytreg
& 0x1f));
156 sprintf (cp
, "b%u", (ytreg
& 0x1f));
161 #define UNW_REG_BSP "bsp"
162 #define UNW_REG_BSPSTORE "bspstore"
163 #define UNW_REG_FPSR "fpsr"
164 #define UNW_REG_LC "lc"
165 #define UNW_REG_PFS "pfs"
166 #define UNW_REG_PR "pr"
167 #define UNW_REG_PSP "psp"
168 #define UNW_REG_RNAT "rnat"
169 #define UNW_REG_RP "rp"
170 #define UNW_REG_UNAT "unat"
172 typedef bfd_vma unw_word
;
174 #define UNW_DEC_BAD_CODE(code) \
175 printf ("Unknown code 0x%02x\n", code)
177 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
181 *(int *)arg = body; \
182 printf (" %s:%s(rlen=%lu)\n", \
183 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
187 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
190 char regname[16], maskstr[64], *sep; \
199 strcat (maskstr, "rp"); \
204 strcat (maskstr, sep); \
205 strcat (maskstr, "ar.pfs"); \
210 strcat (maskstr, sep); \
211 strcat (maskstr, "psp"); \
216 strcat (maskstr, sep); \
217 strcat (maskstr, "pr"); \
219 sprintf (regname, "r%u", grsave); \
220 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
221 fmt, maskstr, regname, (unsigned long) rlen); \
225 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
230 unw_print_frmask (frstr, frmask); \
231 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
235 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
240 unw_print_grmask (grstr, grmask); \
241 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
245 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
248 char frstr[200], grstr[20]; \
250 unw_print_grmask (grstr, grmask); \
251 unw_print_frmask (frstr, frmask); \
252 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
256 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
261 unw_print_brmask (brstr, brmask); \
262 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
266 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
271 unw_print_brmask (brstr, brmask); \
272 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
276 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
277 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
279 #define UNW_DEC_RP_BR(fmt, dst, arg) \
280 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
282 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
283 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
285 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
286 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
287 fmt, reg, 4*(unsigned long)spoff)
289 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
290 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
291 fmt, reg, 4*(unsigned long)pspoff)
293 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
298 unw_print_grmask (grstr, grmask); \
299 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
303 #define UNW_DEC_ABI(fmt, abi, context, arg) \
306 static const char *abiname[] = \
308 "@svr4", "@hpux", "@nt" \
311 const char *abistr = buf; \
314 abistr = abiname[abi]; \
316 sprintf (buf, "0x%x", abi); \
317 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
318 fmt, abistr, context); \
322 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
323 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
325 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
326 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
328 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
329 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
331 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
332 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
333 fmt, 4*(unsigned long)pspoff)
335 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
336 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
337 fmt, 4*(unsigned long)spoff)
339 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
340 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
341 fmt, (unsigned long) t, 16*(unsigned long)size)
343 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
344 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
346 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
347 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
348 fmt, 4*(unsigned long)pspoff)
350 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
353 static const char *spill_type = "-frb"; \
354 unsigned const char *imaskp = dp; \
355 unsigned char mask = 0; \
358 printf ("\t%s:spill_mask(imask=[", fmt); \
359 for (insn = 0; insn < unw_rlen; ++insn) \
361 if ((insn % 4) == 0) \
363 if (insn > 0 && (insn % 3) == 0) \
365 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
372 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
377 unw_print_abreg (regname, abreg); \
378 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
379 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
383 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
388 unw_print_abreg (regname, abreg); \
389 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
390 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
394 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
399 unw_print_abreg (regname, abreg); \
400 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
401 fmt, (unsigned long) t, regname); \
405 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
408 char abregname[20], tregname[20]; \
410 unw_print_abreg (abregname, abreg); \
411 unw_print_xyreg (tregname, x, ytreg); \
412 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
413 fmt, (unsigned long) t, abregname, tregname); \
417 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
422 unw_print_abreg (regname, abreg); \
423 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
424 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
428 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
433 unw_print_abreg (regname, abreg); \
434 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
435 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
439 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
444 unw_print_abreg (regname, abreg); \
445 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
446 fmt, qp, (unsigned long) t, regname); \
450 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
453 char regname[20], tregname[20]; \
455 unw_print_abreg (regname, abreg); \
456 unw_print_xyreg (tregname, x, ytreg); \
457 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
458 fmt, qp, (unsigned long) t, regname, tregname); \
462 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
463 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
465 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
466 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
468 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
469 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
470 fmt, (unsigned long) t, (unsigned long) ecount)
473 * Generic IA-64 unwind info decoder.
475 * This file is used both by the Linux kernel and objdump. Please
476 * keep the two copies of this file in sync (modulo differences in the
479 * You need to customize the decoder by defining the following
480 * macros/constants before including this file:
483 * unw_word Unsigned integer type with at least 64 bits
497 * Decoder action macros:
498 * UNW_DEC_BAD_CODE(code)
499 * UNW_DEC_ABI(fmt,abi,context,arg)
500 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
501 * UNW_DEC_BR_MEM(fmt,brmask,arg)
502 * UNW_DEC_COPY_STATE(fmt,label,arg)
503 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
504 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
505 * UNW_DEC_FR_MEM(fmt,frmask,arg)
506 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
507 * UNW_DEC_GR_MEM(fmt,grmask,arg)
508 * UNW_DEC_LABEL_STATE(fmt,label,arg)
509 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
510 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
511 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
512 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
513 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
514 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
515 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
516 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
517 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
518 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
519 * UNW_DEC_REG_REG(fmt,src,dst,arg)
520 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
521 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
522 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
523 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
524 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
525 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
526 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
527 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
528 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
529 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
530 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
531 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
534 static unw_word
unw_decode_uleb128 (const unsigned char **);
535 static const unsigned char *unw_decode_x1
536 (const unsigned char *, unsigned int, void *);
537 static const unsigned char *unw_decode_x2
538 (const unsigned char *, unsigned int, void *);
539 static const unsigned char *unw_decode_x3
540 (const unsigned char *, unsigned int, void *);
541 static const unsigned char *unw_decode_x4
542 (const unsigned char *, unsigned int, void *);
543 static const unsigned char *unw_decode_r1
544 (const unsigned char *, unsigned int, void *);
545 static const unsigned char *unw_decode_r2
546 (const unsigned char *, unsigned int, void *);
547 static const unsigned char *unw_decode_r3
548 (const unsigned char *, unsigned int, void *);
549 static const unsigned char *unw_decode_p1
550 (const unsigned char *, unsigned int, void *);
551 static const unsigned char *unw_decode_p2_p5
552 (const unsigned char *, unsigned int, void *);
553 static const unsigned char *unw_decode_p6
554 (const unsigned char *, unsigned int, void *);
555 static const unsigned char *unw_decode_p7_p10
556 (const unsigned char *, unsigned int, void *);
557 static const unsigned char *unw_decode_b1
558 (const unsigned char *, unsigned int, void *);
559 static const unsigned char *unw_decode_b2
560 (const unsigned char *, unsigned int, void *);
561 static const unsigned char *unw_decode_b3_x4
562 (const unsigned char *, unsigned int, void *);
565 unw_decode_uleb128 (const unsigned char **dpp
)
568 unw_word byte
, result
= 0;
569 const unsigned char *bp
= *dpp
;
574 result
|= (byte
& 0x7f) << shift
;
576 if ((byte
& 0x80) == 0)
587 static const unsigned char *
588 unw_decode_x1 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
589 void *arg ATTRIBUTE_UNUSED
)
591 unsigned char byte1
, abreg
;
595 t
= unw_decode_uleb128 (&dp
);
596 off
= unw_decode_uleb128 (&dp
);
597 abreg
= (byte1
& 0x7f);
599 UNW_DEC_SPILL_SPREL ("X1", t
, abreg
, off
, arg
);
601 UNW_DEC_SPILL_PSPREL ("X1", t
, abreg
, off
, arg
);
605 static const unsigned char *
606 unw_decode_x2 (const unsigned char *dp
, 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 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
627 void *arg ATTRIBUTE_UNUSED
)
629 unsigned char byte1
, byte2
, abreg
, qp
;
634 t
= unw_decode_uleb128 (&dp
);
635 off
= unw_decode_uleb128 (&dp
);
638 abreg
= (byte2
& 0x7f);
641 UNW_DEC_SPILL_SPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
643 UNW_DEC_SPILL_PSPREL_P ("X3", qp
, t
, abreg
, off
, arg
);
647 static const unsigned char *
648 unw_decode_x4 (const unsigned char *dp
, unsigned int code ATTRIBUTE_UNUSED
,
649 void *arg ATTRIBUTE_UNUSED
)
651 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
657 t
= unw_decode_uleb128 (&dp
);
660 abreg
= (byte2
& 0x7f);
661 x
= (byte2
>> 7) & 1;
664 if ((byte2
& 0x80) == 0 && byte3
== 0)
665 UNW_DEC_RESTORE_P ("X4", qp
, t
, abreg
, arg
);
667 UNW_DEC_SPILL_REG_P ("X4", qp
, t
, abreg
, x
, ytreg
, arg
);
671 static const unsigned char *
672 unw_decode_r1 (const unsigned char *dp
, unsigned int code
, void *arg
)
674 int body
= (code
& 0x20) != 0;
677 rlen
= (code
& 0x1f);
678 UNW_DEC_PROLOGUE ("R1", body
, rlen
, arg
);
682 static const unsigned char *
683 unw_decode_r2 (const unsigned char *dp
, unsigned int code
, void *arg
)
685 unsigned char byte1
, mask
, grsave
;
690 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
691 grsave
= (byte1
& 0x7f);
692 rlen
= unw_decode_uleb128 (& dp
);
693 UNW_DEC_PROLOGUE_GR ("R2", rlen
, mask
, grsave
, arg
);
697 static const unsigned char *
698 unw_decode_r3 (const unsigned char *dp
, unsigned int code
, void *arg
)
702 rlen
= unw_decode_uleb128 (& dp
);
703 UNW_DEC_PROLOGUE ("R3", ((code
& 0x3) == 1), rlen
, arg
);
707 static const unsigned char *
708 unw_decode_p1 (const unsigned char *dp
, unsigned int code
,
709 void *arg ATTRIBUTE_UNUSED
)
711 unsigned char brmask
= (code
& 0x1f);
713 UNW_DEC_BR_MEM ("P1", brmask
, arg
);
717 static const unsigned char *
718 unw_decode_p2_p5 (const unsigned char *dp
, unsigned int code
,
719 void *arg ATTRIBUTE_UNUSED
)
721 if ((code
& 0x10) == 0)
723 unsigned char byte1
= *dp
++;
725 UNW_DEC_BR_GR ("P2", ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
726 (byte1
& 0x7f), arg
);
728 else if ((code
& 0x08) == 0)
730 unsigned char byte1
= *dp
++, r
, dst
;
732 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
733 dst
= (byte1
& 0x7f);
737 UNW_DEC_REG_GR ("P3", UNW_REG_PSP
, dst
, arg
);
740 UNW_DEC_REG_GR ("P3", UNW_REG_RP
, dst
, arg
);
743 UNW_DEC_REG_GR ("P3", UNW_REG_PFS
, dst
, arg
);
746 UNW_DEC_REG_GR ("P3", UNW_REG_PR
, dst
, arg
);
749 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT
, dst
, arg
);
752 UNW_DEC_REG_GR ("P3", UNW_REG_LC
, dst
, arg
);
755 UNW_DEC_RP_BR ("P3", dst
, arg
);
758 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT
, dst
, arg
);
761 UNW_DEC_REG_GR ("P3", UNW_REG_BSP
, dst
, arg
);
764 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE
, dst
, arg
);
767 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR
, dst
, arg
);
770 UNW_DEC_PRIUNAT_GR ("P3", dst
, arg
);
773 UNW_DEC_BAD_CODE (r
);
777 else if ((code
& 0x7) == 0)
778 UNW_DEC_SPILL_MASK ("P4", dp
, arg
);
779 else if ((code
& 0x7) == 1)
781 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
786 grmask
= ((byte1
>> 4) & 0xf);
787 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
788 UNW_DEC_FRGR_MEM ("P5", grmask
, frmask
, arg
);
791 UNW_DEC_BAD_CODE (code
);
796 static const unsigned char *
797 unw_decode_p6 (const unsigned char *dp
, unsigned int code
,
798 void *arg ATTRIBUTE_UNUSED
)
800 int gregs
= (code
& 0x10) != 0;
801 unsigned char mask
= (code
& 0x0f);
804 UNW_DEC_GR_MEM ("P6", mask
, arg
);
806 UNW_DEC_FR_MEM ("P6", mask
, arg
);
810 static const unsigned char *
811 unw_decode_p7_p10 (const unsigned char *dp
, unsigned int code
, void *arg
)
813 unsigned char r
, byte1
, byte2
;
816 if ((code
& 0x10) == 0)
819 t
= unw_decode_uleb128 (&dp
);
823 size
= unw_decode_uleb128 (&dp
);
824 UNW_DEC_MEM_STACK_F ("P7", t
, size
, arg
);
828 UNW_DEC_MEM_STACK_V ("P7", t
, arg
);
831 UNW_DEC_SPILL_BASE ("P7", t
, arg
);
834 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP
, t
, arg
);
837 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP
, t
, arg
);
840 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP
, t
, arg
);
843 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS
, t
, arg
);
846 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS
, t
, arg
);
849 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR
, t
, arg
);
852 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR
, t
, arg
);
855 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC
, t
, arg
);
858 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC
, t
, arg
);
861 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT
, t
, arg
);
864 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT
, t
, arg
);
867 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR
, t
, arg
);
870 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR
, t
, arg
);
873 UNW_DEC_BAD_CODE (r
);
884 t
= unw_decode_uleb128 (&dp
);
888 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP
, t
, arg
);
891 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS
, t
, arg
);
894 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR
, t
, arg
);
897 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC
, t
, arg
);
900 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT
, t
, arg
);
903 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR
, t
, arg
);
906 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP
, t
, arg
);
909 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP
, t
, arg
);
912 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP
, t
, arg
);
915 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE
, t
, arg
);
918 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
921 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE
, t
, arg
);
924 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT
, t
, arg
);
927 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT
, t
, arg
);
930 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT
, t
, arg
);
933 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t
, arg
);
936 UNW_DEC_PRIUNAT_PSPREL ("P8", t
, arg
);
939 UNW_DEC_PRIUNAT_SPREL ("P8", t
, arg
);
942 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t
, arg
);
945 UNW_DEC_BAD_CODE (r
);
954 UNW_DEC_GR_GR ("P9", (byte1
& 0xf), (byte2
& 0x7f), arg
);
960 UNW_DEC_ABI ("P10", byte1
, byte2
, arg
);
964 return unw_decode_x1 (dp
, code
, arg
);
967 return unw_decode_x2 (dp
, code
, arg
);
970 return unw_decode_x3 (dp
, code
, arg
);
973 return unw_decode_x4 (dp
, code
, arg
);
976 UNW_DEC_BAD_CODE (code
);
983 static const unsigned char *
984 unw_decode_b1 (const unsigned char *dp
, unsigned int code
,
985 void *arg ATTRIBUTE_UNUSED
)
987 unw_word label
= (code
& 0x1f);
989 if ((code
& 0x20) != 0)
990 UNW_DEC_COPY_STATE ("B1", label
, arg
);
992 UNW_DEC_LABEL_STATE ("B1", label
, arg
);
996 static const unsigned char *
997 unw_decode_b2 (const unsigned char *dp
, unsigned int code
,
998 void *arg ATTRIBUTE_UNUSED
)
1002 t
= unw_decode_uleb128 (& dp
);
1003 UNW_DEC_EPILOGUE ("B2", t
, (code
& 0x1f), arg
);
1007 static const unsigned char *
1008 unw_decode_b3_x4 (const unsigned char *dp
, unsigned int code
, void *arg
)
1010 unw_word t
, ecount
, label
;
1012 if ((code
& 0x10) == 0)
1014 t
= unw_decode_uleb128 (&dp
);
1015 ecount
= unw_decode_uleb128 (&dp
);
1016 UNW_DEC_EPILOGUE ("B3", t
, ecount
, arg
);
1018 else if ((code
& 0x07) == 0)
1020 label
= unw_decode_uleb128 (&dp
);
1021 if ((code
& 0x08) != 0)
1022 UNW_DEC_COPY_STATE ("B4", label
, arg
);
1024 UNW_DEC_LABEL_STATE ("B4", label
, arg
);
1030 return unw_decode_x1 (dp
, code
, arg
);
1032 return unw_decode_x2 (dp
, code
, arg
);
1034 return unw_decode_x3 (dp
, code
, arg
);
1036 return unw_decode_x4 (dp
, code
, arg
);
1038 UNW_DEC_BAD_CODE (code
);
1044 typedef const unsigned char *(*unw_decoder
)
1045 (const unsigned char *, unsigned int, void *);
1047 static unw_decoder unw_decode_table
[2][8] =
1049 /* prologue table: */
1051 unw_decode_r1
, /* 0 */
1055 unw_decode_p1
, /* 4 */
1061 unw_decode_r1
, /* 0 */
1065 unw_decode_b1
, /* 4 */
1072 /* Decode one descriptor and return address of next descriptor. */
1073 const unsigned char *
1074 unw_decode (const unsigned char *dp
, int inside_body
,
1075 void *ptr_inside_body
)
1077 unw_decoder decoder
;
1081 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1082 return (*decoder
) (dp
, code
, ptr_inside_body
);