2002-09-20 Nathanael Nerode <neroden@gcc.gnu.org>
[binutils.git] / binutils / unwind-ia64.c
blob803a5fa5415ee6b49e0ec3b78ace821e4b6f4f0f
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)
10 any later version.
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"
22 #include <stdio.h>
23 #include <string.h>
25 #if __GNUC__ >= 2
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. */
30 #define BFD64
31 #endif
32 #include "bfd.h"
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));
42 static void
43 unw_print_brmask (cp, mask)
44 char * cp;
45 unsigned int mask;
47 int sep = 0;
48 int i;
50 for (i = 0; mask && (i < 5); ++i)
52 if (mask & 1)
54 if (sep)
55 *cp++ = ',';
56 *cp++ = 'b';
57 *cp++ = i + 1 + '0';
58 sep = 1;
60 mask >>= 1;
62 *cp = '\0';
65 static void
66 unw_print_grmask (cp, mask)
67 char * cp;
68 unsigned int mask;
70 int sep = 0;
71 int i;
73 for (i = 0; i < 4; ++i)
75 if (mask & 1)
77 if (sep)
78 *cp++ = ',';
79 *cp++ = 'r';
80 *cp++ = i + 4 + '0';
81 sep = 1;
83 mask >>= 1;
85 *cp = '\0';
88 static void
89 unw_print_frmask (cp, mask)
90 char * cp;
91 unsigned int mask;
93 int sep = 0;
94 int i;
96 for (i = 0; i < 20; ++i)
98 if (mask & 1)
100 if (sep)
101 *cp++ = ',';
102 *cp++ = 'f';
103 if (i < 4)
104 *cp++ = i + 2 + '0';
105 else
107 *cp++ = (i + 2) / 10 + 1 + '0';
108 *cp++ = (i + 2) % 10 + '0';
110 sep = 1;
112 mask >>= 1;
114 *cp = '\0';
117 static void
118 unw_print_abreg (cp, abreg)
119 char * cp;
120 unsigned int 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)
131 case 0: /* gr */
132 sprintf (cp, "r%u", (abreg & 0x1f));
133 break;
135 case 1: /* fr */
136 sprintf (cp, "f%u", (abreg & 0x1f));
137 break;
139 case 2: /* br */
140 sprintf (cp, "b%u", (abreg & 0x1f));
141 break;
143 case 3: /* special */
144 strcpy (cp, special_reg[abreg & 0xf]);
145 break;
149 static void
150 unw_print_xyreg (cp, x, ytreg)
151 char * cp;
152 unsigned int x;
153 unsigned int ytreg;
155 switch ((x << 1) | ((ytreg >> 7) & 1))
157 case 0: /* gr */
158 sprintf (cp, "r%u", (ytreg & 0x1f));
159 break;
161 case 1: /* fr */
162 sprintf (cp, "f%u", (ytreg & 0x1f));
163 break;
165 case 2: /* br */
166 sprintf (cp, "b%u", (ytreg & 0x1f));
167 break;
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) \
188 do \
190 unw_rlen = rlen; \
191 *(int *)arg = body; \
192 printf (" %s:%s(rlen=%lu)\n", \
193 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
195 while (0)
197 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
198 do \
200 char regname[16], maskstr[64], *sep; \
202 unw_rlen = rlen; \
203 *(int *)arg = 0; \
205 maskstr[0] = '\0'; \
206 sep = ""; \
207 if (mask & 0x8) \
209 strcat (maskstr, "rp"); \
210 sep = ","; \
212 if (mask & 0x4) \
214 strcat (maskstr, sep); \
215 strcat (maskstr, "ar.pfs"); \
216 sep = ","; \
218 if (mask & 0x2) \
220 strcat (maskstr, sep); \
221 strcat (maskstr, "psp"); \
222 sep = ","; \
224 if (mask & 0x1) \
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); \
233 while (0)
235 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
236 do \
238 char frstr[200]; \
240 unw_print_frmask (frstr, frmask); \
241 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
243 while (0)
245 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
246 do \
248 char grstr[200]; \
250 unw_print_grmask (grstr, grmask); \
251 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
253 while (0)
255 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
256 do \
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); \
264 while (0)
266 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
267 do \
269 char brstr[20]; \
271 unw_print_brmask (brstr, brmask); \
272 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
274 while (0)
276 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
277 do \
279 char brstr[20]; \
281 unw_print_brmask (brstr, brmask); \
282 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
284 while (0)
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) \
304 do \
306 char grstr[20]; \
308 unw_print_grmask (grstr, grmask); \
309 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
311 while (0)
313 #define UNW_DEC_ABI(fmt, abi, context, arg) \
314 do \
316 static const char *abiname[] = \
318 "@svr4", "@hpux", "@nt" \
319 }; \
320 char buf[20]; \
321 const char *abistr = buf; \
323 if (abi < 3) \
324 abistr = abiname[abi]; \
325 else \
326 sprintf (buf, "0x%x", abi); \
327 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
328 fmt, abistr, context); \
330 while (0)
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) \
361 do \
363 static const char * spill_type = "-frb"; \
364 unsigned const char * imaskp = dp; \
365 unsigned char mask = 0; \
366 bfd_vma insn = 0; \
368 printf ("\t%s:spill_mask(imask=[", fmt); \
369 for (insn = 0; insn < unw_rlen; ++insn) \
371 if ((insn % 4) == 0) \
372 mask = *imaskp++; \
373 if (insn > 0 && (insn % 3) == 0) \
374 putchar (','); \
375 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
377 printf ("])\n"); \
378 dp = imaskp; \
380 while (0)
382 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
383 do \
385 char regname[10]; \
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); \
391 while (0)
393 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
394 do \
396 char regname[10]; \
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); \
402 while (0)
404 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
405 do \
407 char regname[10]; \
409 unw_print_abreg (regname, abreg); \
410 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
411 fmt, (unsigned long) t, regname); \
413 while (0)
415 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
416 do \
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); \
425 while (0)
427 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
428 do \
430 char regname[20]; \
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); \
436 while (0)
438 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
439 do \
441 char regname[20]; \
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);\
447 while (0)
449 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
450 do \
452 char regname[20]; \
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); \
458 while (0)
460 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
461 do \
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); \
470 while (0)
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
487 * prototypes...).
489 * You need to customize the decoder by defining the following
490 * macros/constants before including this file:
492 * Types:
493 * unw_word Unsigned integer type with at least 64 bits
495 * Register names:
496 * UNW_REG_BSP
497 * UNW_REG_BSPSTORE
498 * UNW_REG_FPSR
499 * UNW_REG_LC
500 * UNW_REG_PFS
501 * UNW_REG_PR
502 * UNW_REG_RNAT
503 * UNW_REG_PSP
504 * UNW_REG_RP
505 * UNW_REG_UNAT
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 *));
574 static unw_word
575 unw_decode_uleb128 (dpp)
576 const unsigned char **dpp;
578 unsigned shift = 0;
579 unw_word byte, result = 0;
580 const unsigned char *bp = *dpp;
582 while (1)
584 byte = *bp++;
585 result |= (byte & 0x7f) << shift;
587 if ((byte & 0x80) == 0)
588 break;
590 shift += 7;
593 *dpp = bp;
595 return result;
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;
605 unw_word t, off;
607 byte1 = *dp++;
608 t = unw_decode_uleb128 (&dp);
609 off = unw_decode_uleb128 (&dp);
610 abreg = (byte1 & 0x7f);
611 if (byte1 & 0x80)
612 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
613 else
614 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
615 return dp;
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;
625 unw_word t;
627 byte1 = *dp++;
628 byte2 = *dp++;
629 t = unw_decode_uleb128 (&dp);
630 abreg = (byte1 & 0x7f);
631 ytreg = byte2;
632 x = (byte1 >> 7) & 1;
633 if ((byte1 & 0x80) == 0 && ytreg == 0)
634 UNW_DEC_RESTORE ("X2", t, abreg, arg);
635 else
636 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
637 return dp;
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;
647 unw_word t, off;
649 byte1 = *dp++;
650 byte2 = *dp++;
651 t = unw_decode_uleb128 (&dp);
652 off = unw_decode_uleb128 (&dp);
654 qp = (byte1 & 0x3f);
655 abreg = (byte2 & 0x7f);
657 if (byte1 & 0x80)
658 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
659 else
660 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
661 return dp;
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;
671 unw_word t;
673 byte1 = *dp++;
674 byte2 = *dp++;
675 byte3 = *dp++;
676 t = unw_decode_uleb128 (&dp);
678 qp = (byte1 & 0x3f);
679 abreg = (byte2 & 0x7f);
680 x = (byte2 >> 7) & 1;
681 ytreg = byte3;
683 if ((byte2 & 0x80) == 0 && byte3 == 0)
684 UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
685 else
686 UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
687 return dp;
690 static const unsigned char *
691 unw_decode_r1 (dp, code, arg)
692 const unsigned char *dp;
693 unsigned int code;
694 void *arg;
696 int body = (code & 0x20) != 0;
697 unw_word rlen;
699 rlen = (code & 0x1f);
700 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
701 return dp;
704 static const unsigned char *
705 unw_decode_r2 (dp, code, arg)
706 const unsigned char *dp;
707 unsigned int code;
708 void *arg;
710 unsigned char byte1, mask, grsave;
711 unw_word rlen;
713 byte1 = *dp++;
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);
719 return dp;
722 static const unsigned char *
723 unw_decode_r3 (dp, code, arg)
724 const unsigned char *dp;
725 unsigned int code;
726 void *arg;
728 unw_word rlen;
730 rlen = unw_decode_uleb128 (& dp);
731 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
732 return dp;
735 static const unsigned char *
736 unw_decode_p1 (dp, code, arg)
737 const unsigned char * dp;
738 unsigned int code;
739 void * arg ATTRIBUTE_UNUSED;
741 unsigned char brmask = (code & 0x1f);
743 UNW_DEC_BR_MEM ("P1", brmask, arg);
744 return dp;
747 static const unsigned char *
748 unw_decode_p2_p5 (dp, code, arg)
749 const unsigned char * dp;
750 unsigned int code;
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);
766 switch (r)
768 case 0:
769 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
770 break;
771 case 1:
772 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
773 break;
774 case 2:
775 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
776 break;
777 case 3:
778 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
779 break;
780 case 4:
781 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
782 break;
783 case 5:
784 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
785 break;
786 case 6:
787 UNW_DEC_RP_BR ("P3", dst, arg);
788 break;
789 case 7:
790 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
791 break;
792 case 8:
793 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
794 break;
795 case 9:
796 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
797 break;
798 case 10:
799 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
800 break;
801 case 11:
802 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
803 break;
804 default:
805 UNW_DEC_BAD_CODE (r);
806 break;
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;
815 byte1 = *dp++;
816 byte2 = *dp++;
817 byte3 = *dp++;
818 grmask = ((byte1 >> 4) & 0xf);
819 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
820 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
822 else
823 UNW_DEC_BAD_CODE (code);
825 return dp;
828 static const unsigned char *
829 unw_decode_p6 (dp, code, arg)
830 const unsigned char * dp;
831 unsigned int code;
832 void * arg ATTRIBUTE_UNUSED;
834 int gregs = (code & 0x10) != 0;
835 unsigned char mask = (code & 0x0f);
837 if (gregs)
838 UNW_DEC_GR_MEM ("P6", mask, arg);
839 else
840 UNW_DEC_FR_MEM ("P6", mask, arg);
841 return dp;
844 static const unsigned char *
845 unw_decode_p7_p10 (dp, code, arg)
846 const unsigned char *dp;
847 unsigned int code;
848 void *arg;
850 unsigned char r, byte1, byte2;
851 unw_word t, size;
853 if ((code & 0x10) == 0)
855 r = (code & 0xf);
856 t = unw_decode_uleb128 (&dp);
857 switch (r)
859 case 0:
860 size = unw_decode_uleb128 (&dp);
861 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
862 break;
864 case 1:
865 UNW_DEC_MEM_STACK_V ("P7", t, arg);
866 break;
867 case 2:
868 UNW_DEC_SPILL_BASE ("P7", t, arg);
869 break;
870 case 3:
871 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
872 break;
873 case 4:
874 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
875 break;
876 case 5:
877 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
878 break;
879 case 6:
880 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
881 break;
882 case 7:
883 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
884 break;
885 case 8:
886 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
887 break;
888 case 9:
889 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
890 break;
891 case 10:
892 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
893 break;
894 case 11:
895 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
896 break;
897 case 12:
898 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
899 break;
900 case 13:
901 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
902 break;
903 case 14:
904 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
905 break;
906 case 15:
907 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
908 break;
909 default:
910 UNW_DEC_BAD_CODE (r);
911 break;
914 else
916 switch (code & 0xf)
918 case 0x0: /* p8 */
920 r = *dp++;
921 t = unw_decode_uleb128 (&dp);
922 switch (r)
924 case 1:
925 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
926 break;
927 case 2:
928 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
929 break;
930 case 3:
931 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
932 break;
933 case 4:
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
935 break;
936 case 5:
937 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
938 break;
939 case 6:
940 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
941 break;
942 case 7:
943 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
944 break;
945 case 8:
946 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
947 break;
948 case 9:
949 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
950 break;
951 case 10:
952 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
953 break;
954 case 11:
955 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
956 break;
957 case 12:
958 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
959 break;
960 case 13:
961 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
962 break;
963 case 14:
964 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
965 break;
966 case 15:
967 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
968 break;
969 case 16:
970 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
971 break;
972 case 17:
973 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
974 break;
975 case 18:
976 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
977 break;
978 case 19:
979 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
980 break;
981 default:
982 UNW_DEC_BAD_CODE (r);
983 break;
986 break;
988 case 0x1:
989 byte1 = *dp++;
990 byte2 = *dp++;
991 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
992 break;
994 case 0xf: /* p10 */
995 byte1 = *dp++;
996 byte2 = *dp++;
997 UNW_DEC_ABI ("P10", byte1, byte2, arg);
998 break;
1000 case 0x9:
1001 return unw_decode_x1 (dp, code, arg);
1003 case 0xa:
1004 return unw_decode_x2 (dp, code, arg);
1006 case 0xb:
1007 return unw_decode_x3 (dp, code, arg);
1009 case 0xc:
1010 return unw_decode_x4 (dp, code, arg);
1012 default:
1013 UNW_DEC_BAD_CODE (code);
1014 break;
1017 return dp;
1020 static const unsigned char *
1021 unw_decode_b1 (dp, code, arg)
1022 const unsigned char * dp;
1023 unsigned int code;
1024 void * arg ATTRIBUTE_UNUSED;
1026 unw_word label = (code & 0x1f);
1028 if ((code & 0x20) != 0)
1029 UNW_DEC_COPY_STATE ("B1", label, arg);
1030 else
1031 UNW_DEC_LABEL_STATE ("B1", label, arg);
1032 return dp;
1035 static const unsigned char *
1036 unw_decode_b2 (dp, code, arg)
1037 const unsigned char * dp;
1038 unsigned int code;
1039 void * arg ATTRIBUTE_UNUSED;
1041 unw_word t;
1043 t = unw_decode_uleb128 (& dp);
1044 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1045 return dp;
1048 static const unsigned char *
1049 unw_decode_b3_x4 (dp, code, arg)
1050 const unsigned char *dp;
1051 unsigned int code;
1052 void *arg;
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);
1067 else
1068 UNW_DEC_LABEL_STATE ("B4", label, arg);
1070 else
1071 switch (code & 0x7)
1073 case 1:
1074 return unw_decode_x1 (dp, code, arg);
1075 case 2:
1076 return unw_decode_x2 (dp, code, arg);
1077 case 3:
1078 return unw_decode_x3 (dp, code, arg);
1079 case 4:
1080 return unw_decode_x4 (dp, code, arg);
1081 default:
1082 UNW_DEC_BAD_CODE (code);
1083 break;
1085 return dp;
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 */
1096 unw_decode_r1,
1097 unw_decode_r2,
1098 unw_decode_r3,
1099 unw_decode_p1, /* 4 */
1100 unw_decode_p2_p5,
1101 unw_decode_p6,
1102 unw_decode_p7_p10
1105 unw_decode_r1, /* 0 */
1106 unw_decode_r1,
1107 unw_decode_r2,
1108 unw_decode_r3,
1109 unw_decode_b1, /* 4 */
1110 unw_decode_b1,
1111 unw_decode_b2,
1112 unw_decode_b3_x4
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;
1120 int inside_body;
1121 void * ptr_inside_body;
1123 unw_decoder decoder;
1124 unsigned char code;
1126 code = *dp++;
1127 decoder = unw_decode_table[inside_body][code >> 5];
1128 return (*decoder) (dp, code, ptr_inside_body);