Replace binutils 2.24 with latest binutils 2.27.
[dragonfly.git] / contrib / binutils-2.24 / binutils / unwind-ia64.c
blob249114fffbe0acf85e379d06b144a83e22491d6c
1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright 2000, 2001, 2002, 2003, 2005, 2007, 2012
3 Free Software Foundation, Inc.
5 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
7 This file is part of GNU Binutils.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #include "config.h"
25 #include "unwind-ia64.h"
26 #include <stdio.h>
27 #include <string.h>
29 #if __GNUC__ >= 2
30 /* Define BFD64 here, even if our default architecture is 32 bit ELF
31 as this will allow us to read in and parse 64bit and 32bit ELF files.
32 Only do this if we believe that the compiler can support a 64 bit
33 data type. For now we only rely on GCC being able to do this. */
34 #define BFD64
35 #endif
36 #include "bfd.h"
38 static bfd_vma unw_rlen = 0;
40 static void unw_print_brmask (char *, unsigned int);
41 static void unw_print_grmask (char *, unsigned int);
42 static void unw_print_frmask (char *, unsigned int);
43 static void unw_print_abreg (char *, unsigned int);
44 static void unw_print_xyreg (char *, unsigned int, unsigned int);
46 static void
47 unw_print_brmask (char *cp, unsigned int mask)
49 int sep = 0;
50 int i;
52 for (i = 0; mask && (i < 5); ++i)
54 if (mask & 1)
56 if (sep)
57 *cp++ = ',';
58 *cp++ = 'b';
59 *cp++ = i + 1 + '0';
60 sep = 1;
62 mask >>= 1;
64 *cp = '\0';
67 static void
68 unw_print_grmask (char *cp, 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 (char *cp, unsigned int mask)
91 int sep = 0;
92 int i;
94 for (i = 0; i < 20; ++i)
96 if (mask & 1)
98 if (sep)
99 *cp++ = ',';
100 *cp++ = 'f';
101 if (i < 4)
102 *cp++ = i + 2 + '0';
103 else
105 *cp++ = (i + 2) / 10 + 1 + '0';
106 *cp++ = (i + 2) % 10 + '0';
108 sep = 1;
110 mask >>= 1;
112 *cp = '\0';
115 static void
116 unw_print_abreg (char *cp, unsigned int abreg)
118 static const char * const special_reg[16] =
120 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
121 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
122 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
125 switch ((abreg >> 5) & 0x3)
127 case 0: /* gr */
128 sprintf (cp, "r%u", (abreg & 0x1f));
129 break;
131 case 1: /* fr */
132 sprintf (cp, "f%u", (abreg & 0x1f));
133 break;
135 case 2: /* br */
136 sprintf (cp, "b%u", (abreg & 0x1f));
137 break;
139 case 3: /* special */
140 strcpy (cp, special_reg[abreg & 0xf]);
141 break;
145 static void
146 unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg)
148 switch ((x << 1) | ((ytreg >> 7) & 1))
150 case 0: /* gr */
151 sprintf (cp, "r%u", (ytreg & 0x1f));
152 break;
154 case 1: /* fr */
155 sprintf (cp, "f%u", (ytreg & 0x1f));
156 break;
158 case 2: /* br */
159 sprintf (cp, "b%u", (ytreg & 0x1f));
160 break;
164 #define UNW_REG_BSP "bsp"
165 #define UNW_REG_BSPSTORE "bspstore"
166 #define UNW_REG_FPSR "fpsr"
167 #define UNW_REG_LC "lc"
168 #define UNW_REG_PFS "pfs"
169 #define UNW_REG_PR "pr"
170 #define UNW_REG_PSP "psp"
171 #define UNW_REG_RNAT "rnat"
172 #define UNW_REG_RP "rp"
173 #define UNW_REG_UNAT "unat"
175 typedef bfd_vma unw_word;
177 #define UNW_DEC_BAD_CODE(code) \
178 printf ("Unknown code 0x%02x\n", code)
180 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
181 do \
183 unw_rlen = rlen; \
184 *(int *)arg = body; \
185 printf (" %s:%s(rlen=%lu)\n", \
186 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
188 while (0)
190 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
191 do \
193 char regname[16], maskstr[64], *sep; \
195 unw_rlen = rlen; \
196 *(int *)arg = 0; \
198 maskstr[0] = '\0'; \
199 sep = ""; \
200 if (mask & 0x8) \
202 strcat (maskstr, "rp"); \
203 sep = ","; \
205 if (mask & 0x4) \
207 strcat (maskstr, sep); \
208 strcat (maskstr, "ar.pfs"); \
209 sep = ","; \
211 if (mask & 0x2) \
213 strcat (maskstr, sep); \
214 strcat (maskstr, "psp"); \
215 sep = ","; \
217 if (mask & 0x1) \
219 strcat (maskstr, sep); \
220 strcat (maskstr, "pr"); \
222 sprintf (regname, "r%u", grsave); \
223 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
224 fmt, maskstr, regname, (unsigned long) rlen); \
226 while (0)
228 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
229 do \
231 char frstr[200]; \
233 unw_print_frmask (frstr, frmask); \
234 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
236 while (0)
238 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
239 do \
241 char grstr[200]; \
243 unw_print_grmask (grstr, grmask); \
244 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
246 while (0)
248 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
249 do \
251 char frstr[200], grstr[20]; \
253 unw_print_grmask (grstr, grmask); \
254 unw_print_frmask (frstr, frmask); \
255 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
257 while (0)
259 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
260 do \
262 char brstr[20]; \
264 unw_print_brmask (brstr, brmask); \
265 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
267 while (0)
269 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
270 do \
272 char brstr[20]; \
274 unw_print_brmask (brstr, brmask); \
275 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
277 while (0)
279 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
280 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
282 #define UNW_DEC_RP_BR(fmt, dst, arg) \
283 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
285 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
286 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
288 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
289 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
290 fmt, reg, 4*(unsigned long)spoff)
292 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
293 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
294 fmt, reg, 4*(unsigned long)pspoff)
296 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
297 do \
299 char grstr[20]; \
301 unw_print_grmask (grstr, grmask); \
302 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
304 while (0)
306 #define UNW_DEC_ABI(fmt, abi, context, arg) \
307 do \
309 static const char * const abiname[] = \
311 "@svr4", "@hpux", "@nt" \
312 }; \
313 char buf[20]; \
314 const char *abistr = buf; \
316 if (abi < 3) \
317 abistr = abiname[abi]; \
318 else \
319 sprintf (buf, "0x%x", abi); \
320 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
321 fmt, abistr, context); \
323 while (0)
325 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
326 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
328 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
329 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
331 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
332 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
334 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
335 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
336 fmt, 4*(unsigned long)pspoff)
338 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
339 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
340 fmt, 4*(unsigned long)spoff)
342 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
343 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
344 fmt, (unsigned long) t, 16*(unsigned long)size)
346 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
347 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
349 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
350 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
351 fmt, 4*(unsigned long)pspoff)
353 #define UNW_DEC_SPILL_MASK(fmt, dp, arg) \
354 do \
356 static const char *spill_type = "-frb"; \
357 unsigned const char *imaskp = dp; \
358 unsigned char mask = 0; \
359 bfd_vma insn = 0; \
361 printf ("\t%s:spill_mask(imask=[", fmt); \
362 for (insn = 0; insn < unw_rlen; ++insn) \
364 if ((insn % 4) == 0) \
365 mask = *imaskp++; \
366 if (insn > 0 && (insn % 3) == 0) \
367 putchar (','); \
368 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
370 printf ("])\n"); \
371 dp = imaskp; \
373 while (0)
375 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
376 do \
378 char regname[20]; \
380 unw_print_abreg (regname, abreg); \
381 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
382 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
384 while (0)
386 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
387 do \
389 char regname[20]; \
391 unw_print_abreg (regname, abreg); \
392 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
393 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
395 while (0)
397 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
398 do \
400 char regname[20]; \
402 unw_print_abreg (regname, abreg); \
403 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
404 fmt, (unsigned long) t, regname); \
406 while (0)
408 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
409 do \
411 char abregname[20], tregname[20]; \
413 unw_print_abreg (abregname, abreg); \
414 unw_print_xyreg (tregname, x, ytreg); \
415 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
416 fmt, (unsigned long) t, abregname, tregname); \
418 while (0)
420 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
421 do \
423 char regname[20]; \
425 unw_print_abreg (regname, abreg); \
426 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
427 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
429 while (0)
431 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
432 do \
434 char regname[20]; \
436 unw_print_abreg (regname, abreg); \
437 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
438 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
440 while (0)
442 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
443 do \
445 char regname[20]; \
447 unw_print_abreg (regname, abreg); \
448 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
449 fmt, qp, (unsigned long) t, regname); \
451 while (0)
453 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
454 do \
456 char regname[20], tregname[20]; \
458 unw_print_abreg (regname, abreg); \
459 unw_print_xyreg (tregname, x, ytreg); \
460 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
461 fmt, qp, (unsigned long) t, regname, tregname); \
463 while (0)
465 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
466 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
468 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
469 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
471 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
472 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
473 fmt, (unsigned long) t, (unsigned long) ecount)
476 * Generic IA-64 unwind info decoder.
478 * This file is used both by the Linux kernel and objdump. Please
479 * keep the two copies of this file in sync (modulo differences in the
480 * prototypes...).
482 * You need to customize the decoder by defining the following
483 * macros/constants before including this file:
485 * Types:
486 * unw_word Unsigned integer type with at least 64 bits
488 * Register names:
489 * UNW_REG_BSP
490 * UNW_REG_BSPSTORE
491 * UNW_REG_FPSR
492 * UNW_REG_LC
493 * UNW_REG_PFS
494 * UNW_REG_PR
495 * UNW_REG_RNAT
496 * UNW_REG_PSP
497 * UNW_REG_RP
498 * UNW_REG_UNAT
500 * Decoder action macros:
501 * UNW_DEC_BAD_CODE(code)
502 * UNW_DEC_ABI(fmt,abi,context,arg)
503 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
504 * UNW_DEC_BR_MEM(fmt,brmask,arg)
505 * UNW_DEC_COPY_STATE(fmt,label,arg)
506 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
507 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
508 * UNW_DEC_FR_MEM(fmt,frmask,arg)
509 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
510 * UNW_DEC_GR_MEM(fmt,grmask,arg)
511 * UNW_DEC_LABEL_STATE(fmt,label,arg)
512 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
513 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
514 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
515 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
516 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
517 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
518 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
519 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
520 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
521 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
522 * UNW_DEC_REG_REG(fmt,src,dst,arg)
523 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
524 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
525 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
526 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
527 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
528 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
529 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
530 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
531 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
532 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
533 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
534 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
537 static unw_word unw_decode_uleb128 (const unsigned char **);
538 static const unsigned char *unw_decode_x1
539 (const unsigned char *, unsigned int, void *);
540 static const unsigned char *unw_decode_x2
541 (const unsigned char *, unsigned int, void *);
542 static const unsigned char *unw_decode_x3
543 (const unsigned char *, unsigned int, void *);
544 static const unsigned char *unw_decode_x4
545 (const unsigned char *, unsigned int, void *);
546 static const unsigned char *unw_decode_r1
547 (const unsigned char *, unsigned int, void *);
548 static const unsigned char *unw_decode_r2
549 (const unsigned char *, unsigned int, void *);
550 static const unsigned char *unw_decode_r3
551 (const unsigned char *, unsigned int, void *);
552 static const unsigned char *unw_decode_p1
553 (const unsigned char *, unsigned int, void *);
554 static const unsigned char *unw_decode_p2_p5
555 (const unsigned char *, unsigned int, void *);
556 static const unsigned char *unw_decode_p6
557 (const unsigned char *, unsigned int, void *);
558 static const unsigned char *unw_decode_p7_p10
559 (const unsigned char *, unsigned int, void *);
560 static const unsigned char *unw_decode_b1
561 (const unsigned char *, unsigned int, void *);
562 static const unsigned char *unw_decode_b2
563 (const unsigned char *, unsigned int, void *);
564 static const unsigned char *unw_decode_b3_x4
565 (const unsigned char *, unsigned int, void *);
567 static unw_word
568 unw_decode_uleb128 (const unsigned char **dpp)
570 unsigned shift = 0;
571 unw_word byte, result = 0;
572 const unsigned char *bp = *dpp;
574 while (1)
576 byte = *bp++;
577 result |= (byte & 0x7f) << shift;
579 if ((byte & 0x80) == 0)
580 break;
582 shift += 7;
585 *dpp = bp;
587 return result;
590 static const unsigned char *
591 unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
592 void *arg ATTRIBUTE_UNUSED)
594 unsigned char byte1, abreg;
595 unw_word t, off;
597 byte1 = *dp++;
598 t = unw_decode_uleb128 (&dp);
599 off = unw_decode_uleb128 (&dp);
600 abreg = (byte1 & 0x7f);
601 if (byte1 & 0x80)
602 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
603 else
604 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
605 return dp;
608 static const unsigned char *
609 unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
610 void *arg ATTRIBUTE_UNUSED)
612 unsigned char byte1, byte2, abreg, x, ytreg;
613 unw_word t;
615 byte1 = *dp++;
616 byte2 = *dp++;
617 t = unw_decode_uleb128 (&dp);
618 abreg = (byte1 & 0x7f);
619 ytreg = byte2;
620 x = (byte1 >> 7) & 1;
621 if ((byte1 & 0x80) == 0 && ytreg == 0)
622 UNW_DEC_RESTORE ("X2", t, abreg, arg);
623 else
624 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
625 return dp;
628 static const unsigned char *
629 unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
630 void *arg ATTRIBUTE_UNUSED)
632 unsigned char byte1, byte2, abreg, qp;
633 unw_word t, off;
635 byte1 = *dp++;
636 byte2 = *dp++;
637 t = unw_decode_uleb128 (&dp);
638 off = unw_decode_uleb128 (&dp);
640 qp = (byte1 & 0x3f);
641 abreg = (byte2 & 0x7f);
643 if (byte1 & 0x80)
644 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
645 else
646 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
647 return dp;
650 static const unsigned char *
651 unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
652 void *arg ATTRIBUTE_UNUSED)
654 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
655 unw_word t;
657 byte1 = *dp++;
658 byte2 = *dp++;
659 byte3 = *dp++;
660 t = unw_decode_uleb128 (&dp);
662 qp = (byte1 & 0x3f);
663 abreg = (byte2 & 0x7f);
664 x = (byte2 >> 7) & 1;
665 ytreg = byte3;
667 if ((byte2 & 0x80) == 0 && byte3 == 0)
668 UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
669 else
670 UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
671 return dp;
674 static const unsigned char *
675 unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg)
677 int body = (code & 0x20) != 0;
678 unw_word rlen;
680 rlen = (code & 0x1f);
681 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
682 return dp;
685 static const unsigned char *
686 unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg)
688 unsigned char byte1, mask, grsave;
689 unw_word rlen;
691 byte1 = *dp++;
693 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
694 grsave = (byte1 & 0x7f);
695 rlen = unw_decode_uleb128 (& dp);
696 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
697 return dp;
700 static const unsigned char *
701 unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg)
703 unw_word rlen;
705 rlen = unw_decode_uleb128 (& dp);
706 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
707 return dp;
710 static const unsigned char *
711 unw_decode_p1 (const unsigned char *dp, unsigned int code,
712 void *arg ATTRIBUTE_UNUSED)
714 unsigned char brmask = (code & 0x1f);
716 UNW_DEC_BR_MEM ("P1", brmask, arg);
717 return dp;
720 static const unsigned char *
721 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
722 void *arg ATTRIBUTE_UNUSED)
724 if ((code & 0x10) == 0)
726 unsigned char byte1 = *dp++;
728 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
729 (byte1 & 0x7f), arg);
731 else if ((code & 0x08) == 0)
733 unsigned char byte1 = *dp++, r, dst;
735 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
736 dst = (byte1 & 0x7f);
737 switch (r)
739 case 0:
740 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
741 break;
742 case 1:
743 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
744 break;
745 case 2:
746 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
747 break;
748 case 3:
749 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
750 break;
751 case 4:
752 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
753 break;
754 case 5:
755 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
756 break;
757 case 6:
758 UNW_DEC_RP_BR ("P3", dst, arg);
759 break;
760 case 7:
761 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
762 break;
763 case 8:
764 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
765 break;
766 case 9:
767 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
768 break;
769 case 10:
770 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
771 break;
772 case 11:
773 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
774 break;
775 default:
776 UNW_DEC_BAD_CODE (r);
777 break;
780 else if ((code & 0x7) == 0)
781 UNW_DEC_SPILL_MASK ("P4", dp, arg);
782 else if ((code & 0x7) == 1)
784 unw_word grmask, frmask, byte1, byte2, byte3;
786 byte1 = *dp++;
787 byte2 = *dp++;
788 byte3 = *dp++;
789 grmask = ((byte1 >> 4) & 0xf);
790 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
791 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
793 else
794 UNW_DEC_BAD_CODE (code);
796 return dp;
799 static const unsigned char *
800 unw_decode_p6 (const unsigned char *dp, unsigned int code,
801 void *arg ATTRIBUTE_UNUSED)
803 int gregs = (code & 0x10) != 0;
804 unsigned char mask = (code & 0x0f);
806 if (gregs)
807 UNW_DEC_GR_MEM ("P6", mask, arg);
808 else
809 UNW_DEC_FR_MEM ("P6", mask, arg);
810 return dp;
813 static const unsigned char *
814 unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg)
816 unsigned char r, byte1, byte2;
817 unw_word t, size;
819 if ((code & 0x10) == 0)
821 r = (code & 0xf);
822 t = unw_decode_uleb128 (&dp);
823 switch (r)
825 case 0:
826 size = unw_decode_uleb128 (&dp);
827 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
828 break;
830 case 1:
831 UNW_DEC_MEM_STACK_V ("P7", t, arg);
832 break;
833 case 2:
834 UNW_DEC_SPILL_BASE ("P7", t, arg);
835 break;
836 case 3:
837 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
838 break;
839 case 4:
840 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
841 break;
842 case 5:
843 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
844 break;
845 case 6:
846 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
847 break;
848 case 7:
849 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
850 break;
851 case 8:
852 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
853 break;
854 case 9:
855 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
856 break;
857 case 10:
858 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
859 break;
860 case 11:
861 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
862 break;
863 case 12:
864 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
865 break;
866 case 13:
867 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
868 break;
869 case 14:
870 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
871 break;
872 case 15:
873 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
874 break;
875 default:
876 UNW_DEC_BAD_CODE (r);
877 break;
880 else
882 switch (code & 0xf)
884 case 0x0: /* p8 */
886 r = *dp++;
887 t = unw_decode_uleb128 (&dp);
888 switch (r)
890 case 1:
891 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
892 break;
893 case 2:
894 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
895 break;
896 case 3:
897 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
898 break;
899 case 4:
900 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
901 break;
902 case 5:
903 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
904 break;
905 case 6:
906 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
907 break;
908 case 7:
909 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
910 break;
911 case 8:
912 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
913 break;
914 case 9:
915 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
916 break;
917 case 10:
918 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
919 break;
920 case 11:
921 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
922 break;
923 case 12:
924 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
925 break;
926 case 13:
927 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
928 break;
929 case 14:
930 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
931 break;
932 case 15:
933 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
934 break;
935 case 16:
936 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
937 break;
938 case 17:
939 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
940 break;
941 case 18:
942 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
943 break;
944 case 19:
945 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
946 break;
947 default:
948 UNW_DEC_BAD_CODE (r);
949 break;
952 break;
954 case 0x1:
955 byte1 = *dp++;
956 byte2 = *dp++;
957 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
958 break;
960 case 0xf: /* p10 */
961 byte1 = *dp++;
962 byte2 = *dp++;
963 UNW_DEC_ABI ("P10", byte1, byte2, arg);
964 break;
966 case 0x9:
967 return unw_decode_x1 (dp, code, arg);
969 case 0xa:
970 return unw_decode_x2 (dp, code, arg);
972 case 0xb:
973 return unw_decode_x3 (dp, code, arg);
975 case 0xc:
976 return unw_decode_x4 (dp, code, arg);
978 default:
979 UNW_DEC_BAD_CODE (code);
980 break;
983 return dp;
986 static const unsigned char *
987 unw_decode_b1 (const unsigned char *dp, unsigned int code,
988 void *arg ATTRIBUTE_UNUSED)
990 unw_word label = (code & 0x1f);
992 if ((code & 0x20) != 0)
993 UNW_DEC_COPY_STATE ("B1", label, arg);
994 else
995 UNW_DEC_LABEL_STATE ("B1", label, arg);
996 return dp;
999 static const unsigned char *
1000 unw_decode_b2 (const unsigned char *dp, unsigned int code,
1001 void *arg ATTRIBUTE_UNUSED)
1003 unw_word t;
1005 t = unw_decode_uleb128 (& dp);
1006 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1007 return dp;
1010 static const unsigned char *
1011 unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg)
1013 unw_word t, ecount, label;
1015 if ((code & 0x10) == 0)
1017 t = unw_decode_uleb128 (&dp);
1018 ecount = unw_decode_uleb128 (&dp);
1019 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1021 else if ((code & 0x07) == 0)
1023 label = unw_decode_uleb128 (&dp);
1024 if ((code & 0x08) != 0)
1025 UNW_DEC_COPY_STATE ("B4", label, arg);
1026 else
1027 UNW_DEC_LABEL_STATE ("B4", label, arg);
1029 else
1030 switch (code & 0x7)
1032 case 1:
1033 return unw_decode_x1 (dp, code, arg);
1034 case 2:
1035 return unw_decode_x2 (dp, code, arg);
1036 case 3:
1037 return unw_decode_x3 (dp, code, arg);
1038 case 4:
1039 return unw_decode_x4 (dp, code, arg);
1040 default:
1041 UNW_DEC_BAD_CODE (code);
1042 break;
1044 return dp;
1047 typedef const unsigned char *(*unw_decoder)
1048 (const unsigned char *, unsigned int, void *);
1050 static const unw_decoder unw_decode_table[2][8] =
1052 /* prologue table: */
1054 unw_decode_r1, /* 0 */
1055 unw_decode_r1,
1056 unw_decode_r2,
1057 unw_decode_r3,
1058 unw_decode_p1, /* 4 */
1059 unw_decode_p2_p5,
1060 unw_decode_p6,
1061 unw_decode_p7_p10
1064 unw_decode_r1, /* 0 */
1065 unw_decode_r1,
1066 unw_decode_r2,
1067 unw_decode_r3,
1068 unw_decode_b1, /* 4 */
1069 unw_decode_b1,
1070 unw_decode_b2,
1071 unw_decode_b3_x4
1075 /* Decode one descriptor and return address of next descriptor. */
1076 const unsigned char *
1077 unw_decode (const unsigned char *dp, int inside_body,
1078 void *ptr_inside_body)
1080 unw_decoder decoder;
1081 unsigned char code;
1083 code = *dp++;
1084 decoder = unw_decode_table[inside_body][code >> 5];
1085 return (*decoder) (dp, code, ptr_inside_body);