[PATCH 40/57][Arm][OBJDUMP] Add support for MVE instructions: vdup, veor, vfma, vfms...
[binutils-gdb.git] / binutils / unwind-ia64.c
blobf6f73ce83ea895fa95a64b9cc0b05e8d7eeb7c53
1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2 Copyright (C) 2000-2019 Free Software Foundation, Inc.
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #include "config.h"
24 #include "sysdep.h"
25 #include "unwind-ia64.h"
27 #if __GNUC__ >= 2
28 /* Define BFD64 here, even if our default architecture is 32 bit ELF
29 as this will allow us to read in and parse 64bit and 32bit ELF files.
30 Only do this if we believe that the compiler can support a 64 bit
31 data type. For now we only rely on GCC being able to do this. */
32 #define BFD64
33 #endif
34 #include "bfd.h"
36 static bfd_vma unw_rlen = 0;
38 static void unw_print_brmask (char *, unsigned int);
39 static void unw_print_grmask (char *, unsigned int);
40 static void unw_print_frmask (char *, unsigned int);
41 static void unw_print_abreg (char *, unsigned int);
42 static void unw_print_xyreg (char *, unsigned int, unsigned int);
44 static void
45 unw_print_brmask (char *cp, 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 (char *cp, unsigned int mask)
68 int sep = 0;
69 int i;
71 for (i = 0; i < 4; ++i)
73 if (mask & 1)
75 if (sep)
76 *cp++ = ',';
77 *cp++ = 'r';
78 *cp++ = i + 4 + '0';
79 sep = 1;
81 mask >>= 1;
83 *cp = '\0';
86 static void
87 unw_print_frmask (char *cp, unsigned int mask)
89 int sep = 0;
90 int i;
92 for (i = 0; i < 20; ++i)
94 if (mask & 1)
96 if (sep)
97 *cp++ = ',';
98 *cp++ = 'f';
99 if (i < 4)
100 *cp++ = i + 2 + '0';
101 else
103 *cp++ = (i + 2) / 10 + 1 + '0';
104 *cp++ = (i + 2) % 10 + '0';
106 sep = 1;
108 mask >>= 1;
110 *cp = '\0';
113 static void
114 unw_print_abreg (char *cp, unsigned int abreg)
116 static const char * const special_reg[16] =
118 "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
119 "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
120 "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
123 switch ((abreg >> 5) & 0x3)
125 case 0: /* gr */
126 sprintf (cp, "r%u", (abreg & 0x1f));
127 break;
129 case 1: /* fr */
130 sprintf (cp, "f%u", (abreg & 0x1f));
131 break;
133 case 2: /* br */
134 sprintf (cp, "b%u", (abreg & 0x1f));
135 break;
137 case 3: /* special */
138 strcpy (cp, special_reg[abreg & 0xf]);
139 break;
143 static void
144 unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg)
146 switch ((x << 1) | ((ytreg >> 7) & 1))
148 case 0: /* gr */
149 sprintf (cp, "r%u", (ytreg & 0x1f));
150 break;
152 case 1: /* fr */
153 sprintf (cp, "f%u", (ytreg & 0x1f));
154 break;
156 case 2: /* br */
157 sprintf (cp, "b%u", (ytreg & 0x1f));
158 break;
162 #define UNW_REG_BSP "bsp"
163 #define UNW_REG_BSPSTORE "bspstore"
164 #define UNW_REG_FPSR "fpsr"
165 #define UNW_REG_LC "lc"
166 #define UNW_REG_PFS "pfs"
167 #define UNW_REG_PR "pr"
168 #define UNW_REG_PSP "psp"
169 #define UNW_REG_RNAT "rnat"
170 #define UNW_REG_RP "rp"
171 #define UNW_REG_UNAT "unat"
173 typedef bfd_vma unw_word;
175 #define UNW_DEC_BAD_CODE(code) \
176 printf (_("Unknown code 0x%02x\n"), code)
178 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
179 do \
181 unw_rlen = rlen; \
182 *(int *)arg = body; \
183 printf (" %s:%s(rlen=%lu)\n", \
184 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
186 while (0)
188 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
189 do \
191 char regname[16], maskstr[64], *sep; \
193 unw_rlen = rlen; \
194 *(int *)arg = 0; \
196 maskstr[0] = '\0'; \
197 sep = ""; \
198 if (mask & 0x8) \
200 strcat (maskstr, "rp"); \
201 sep = ","; \
203 if (mask & 0x4) \
205 strcat (maskstr, sep); \
206 strcat (maskstr, "ar.pfs"); \
207 sep = ","; \
209 if (mask & 0x2) \
211 strcat (maskstr, sep); \
212 strcat (maskstr, "psp"); \
213 sep = ","; \
215 if (mask & 0x1) \
217 strcat (maskstr, sep); \
218 strcat (maskstr, "pr"); \
220 sprintf (regname, "r%u", grsave); \
221 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
222 fmt, maskstr, regname, (unsigned long) rlen); \
224 while (0)
226 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
227 do \
229 char frstr[200]; \
231 unw_print_frmask (frstr, frmask); \
232 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
234 while (0)
236 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
237 do \
239 char grstr[200]; \
241 unw_print_grmask (grstr, grmask); \
242 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
244 while (0)
246 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
247 do \
249 char frstr[200], grstr[20]; \
251 unw_print_grmask (grstr, grmask); \
252 unw_print_frmask (frstr, frmask); \
253 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
255 while (0)
257 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
258 do \
260 char brstr[20]; \
262 unw_print_brmask (brstr, brmask); \
263 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
265 while (0)
267 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
268 do \
270 char brstr[20]; \
272 unw_print_brmask (brstr, brmask); \
273 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
275 while (0)
277 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
278 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
280 #define UNW_DEC_RP_BR(fmt, dst, arg) \
281 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
283 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
284 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
286 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
287 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
288 fmt, reg, 4*(unsigned long)spoff)
290 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
291 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
292 fmt, reg, 4*(unsigned long)pspoff)
294 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
295 do \
297 char grstr[20]; \
299 unw_print_grmask (grstr, grmask); \
300 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
302 while (0)
304 #define UNW_DEC_ABI(fmt, abi, context, arg) \
305 do \
307 static const char * const abiname[] = \
309 "@svr4", "@hpux", "@nt" \
310 }; \
311 char buf[20]; \
312 const char *abistr = buf; \
314 if (abi < 3) \
315 abistr = abiname[abi]; \
316 else \
317 sprintf (buf, "0x%x", abi); \
318 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
319 fmt, abistr, context); \
321 while (0)
323 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
324 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
326 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
327 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
329 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
330 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
332 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
333 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
334 fmt, 4*(unsigned long)pspoff)
336 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
337 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
338 fmt, 4*(unsigned long)spoff)
340 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
341 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
342 fmt, (unsigned long) t, 16*(unsigned long)size)
344 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
345 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
347 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
348 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
349 fmt, 4*(unsigned long)pspoff)
351 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
352 do \
354 static const char *spill_type = "-frb"; \
355 unsigned const char *imaskp = dp; \
356 unsigned char mask = 0; \
357 bfd_vma insn = 0; \
359 /* PR 18420. */ \
360 if ((dp + (unw_rlen / 4)) > end) \
362 printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
363 (long) (unw_rlen / 4), (long)(end - dp)); \
364 /* FIXME: Should we reset unw_rlen ? */ \
365 break; \
367 printf ("\t%s:spill_mask(imask=[", fmt); \
368 for (insn = 0; insn < unw_rlen; ++insn) \
370 if ((insn % 4) == 0) \
371 mask = *imaskp++; \
372 if (insn > 0 && (insn % 3) == 0) \
373 putchar (','); \
374 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
376 printf ("])\n"); \
377 dp = imaskp; \
379 while (0)
381 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
382 do \
384 char regname[20]; \
386 unw_print_abreg (regname, abreg); \
387 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
388 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
390 while (0)
392 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
393 do \
395 char regname[20]; \
397 unw_print_abreg (regname, abreg); \
398 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
399 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
401 while (0)
403 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
404 do \
406 char regname[20]; \
408 unw_print_abreg (regname, abreg); \
409 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
410 fmt, (unsigned long) t, regname); \
412 while (0)
414 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
415 do \
417 char abregname[20], tregname[20]; \
419 unw_print_abreg (abregname, abreg); \
420 unw_print_xyreg (tregname, x, ytreg); \
421 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
422 fmt, (unsigned long) t, abregname, tregname); \
424 while (0)
426 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
427 do \
429 char regname[20]; \
431 unw_print_abreg (regname, abreg); \
432 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
433 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
435 while (0)
437 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
438 do \
440 char regname[20]; \
442 unw_print_abreg (regname, abreg); \
443 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
444 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
446 while (0)
448 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
449 do \
451 char regname[20]; \
453 unw_print_abreg (regname, abreg); \
454 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
455 fmt, qp, (unsigned long) t, regname); \
457 while (0)
459 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
460 do \
462 char regname[20], tregname[20]; \
464 unw_print_abreg (regname, abreg); \
465 unw_print_xyreg (tregname, x, ytreg); \
466 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
467 fmt, qp, (unsigned long) t, regname, tregname); \
469 while (0)
471 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
472 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
474 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
475 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
477 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
478 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
479 fmt, (unsigned long) t, (unsigned long) ecount)
482 * Generic IA-64 unwind info decoder.
484 * This file is used both by the Linux kernel and objdump. Please
485 * keep the two copies of this file in sync (modulo differences in the
486 * prototypes...).
488 * You need to customize the decoder by defining the following
489 * macros/constants before including this file:
491 * Types:
492 * unw_word Unsigned integer type with at least 64 bits
494 * Register names:
495 * UNW_REG_BSP
496 * UNW_REG_BSPSTORE
497 * UNW_REG_FPSR
498 * UNW_REG_LC
499 * UNW_REG_PFS
500 * UNW_REG_PR
501 * UNW_REG_RNAT
502 * UNW_REG_PSP
503 * UNW_REG_RP
504 * UNW_REG_UNAT
506 * Decoder action macros:
507 * UNW_DEC_BAD_CODE(code)
508 * UNW_DEC_ABI(fmt,abi,context,arg)
509 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
510 * UNW_DEC_BR_MEM(fmt,brmask,arg)
511 * UNW_DEC_COPY_STATE(fmt,label,arg)
512 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
513 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
514 * UNW_DEC_FR_MEM(fmt,frmask,arg)
515 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
516 * UNW_DEC_GR_MEM(fmt,grmask,arg)
517 * UNW_DEC_LABEL_STATE(fmt,label,arg)
518 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
519 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
520 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
521 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
522 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
523 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
524 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
525 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
526 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
527 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
528 * UNW_DEC_REG_REG(fmt,src,dst,arg)
529 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
530 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
531 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
532 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
533 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
534 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
535 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
536 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
537 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
538 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
539 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
540 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
543 static unw_word
544 unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end)
546 unsigned shift = 0;
547 unw_word byte, result = 0;
548 const unsigned char *bp = *dpp;
550 while (bp < end)
552 byte = *bp++;
553 result |= (byte & 0x7f) << shift;
555 if ((byte & 0x80) == 0)
556 break;
558 shift += 7;
561 *dpp = bp;
563 return result;
566 static const unsigned char *
567 unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
568 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
570 unsigned char byte1, abreg;
571 unw_word t, off;
573 if ((end - dp) < 3)
575 printf (_("\t<corrupt X1>\n"));
576 return end;
579 byte1 = *dp++;
580 t = unw_decode_uleb128 (&dp, end);
581 off = unw_decode_uleb128 (&dp, end);
582 abreg = (byte1 & 0x7f);
583 if (byte1 & 0x80)
584 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
585 else
586 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
587 return dp;
590 static const unsigned char *
591 unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
592 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
594 unsigned char byte1, byte2, abreg, x, ytreg;
595 unw_word t;
597 if ((end - dp) < 3)
599 printf (_("\t<corrupt X2>\n"));
600 return end;
603 byte1 = *dp++;
604 byte2 = *dp++;
605 t = unw_decode_uleb128 (&dp, end);
606 abreg = (byte1 & 0x7f);
607 ytreg = byte2;
608 x = (byte1 >> 7) & 1;
609 if ((byte1 & 0x80) == 0 && ytreg == 0)
610 UNW_DEC_RESTORE ("X2", t, abreg, arg);
611 else
612 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
613 return dp;
616 static const unsigned char *
617 unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
618 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
620 unsigned char byte1, byte2, abreg, qp;
621 unw_word t, off;
623 if ((end - dp) < 4)
625 printf (_("\t<corrupt X3>\n"));
626 return end;
629 byte1 = *dp++;
630 byte2 = *dp++;
631 t = unw_decode_uleb128 (&dp, end);
632 off = unw_decode_uleb128 (&dp, end);
634 qp = (byte1 & 0x3f);
635 abreg = (byte2 & 0x7f);
637 if (byte1 & 0x80)
638 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
639 else
640 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
641 return dp;
644 static const unsigned char *
645 unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
646 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
648 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
649 unw_word t;
651 if ((end - dp) < 4)
653 printf (_("\t<corrupt X4>\n"));
654 return end;
657 byte1 = *dp++;
658 byte2 = *dp++;
659 byte3 = *dp++;
660 t = unw_decode_uleb128 (&dp, end);
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,
676 const unsigned char * end ATTRIBUTE_UNUSED)
678 int body = (code & 0x20) != 0;
679 unw_word rlen;
681 rlen = (code & 0x1f);
682 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
683 return dp;
686 static const unsigned char *
687 unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
688 const unsigned char * end)
690 unsigned char byte1, mask, grsave;
691 unw_word rlen;
693 if ((end - dp) < 2)
695 printf (_("\t<corrupt R2>\n"));
696 return end;
699 byte1 = *dp++;
701 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
702 grsave = (byte1 & 0x7f);
703 rlen = unw_decode_uleb128 (& dp, end);
704 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
705 return dp;
708 static const unsigned char *
709 unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
710 const unsigned char * end)
712 unw_word rlen;
714 rlen = unw_decode_uleb128 (& dp, end);
715 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
716 return dp;
719 static const unsigned char *
720 unw_decode_p1 (const unsigned char *dp, unsigned int code,
721 void *arg ATTRIBUTE_UNUSED,
722 const unsigned char * end ATTRIBUTE_UNUSED)
724 unsigned char brmask = (code & 0x1f);
726 UNW_DEC_BR_MEM ("P1", brmask, arg);
727 return dp;
730 static const unsigned char *
731 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
732 void *arg ATTRIBUTE_UNUSED,
733 const unsigned char * end)
735 if ((code & 0x10) == 0)
737 unsigned char byte1;
739 if ((end - dp) < 1)
741 printf (_("\t<corrupt P2>\n"));
742 return end;
745 byte1 = *dp++;
747 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
748 (byte1 & 0x7f), arg);
750 else if ((code & 0x08) == 0)
752 unsigned char byte1, r, dst;
754 if ((end - dp) < 1)
756 printf (_("\t<corrupt P3>\n"));
757 return end;
760 byte1 = *dp++;
762 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
763 dst = (byte1 & 0x7f);
764 switch (r)
766 case 0:
767 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
768 break;
769 case 1:
770 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
771 break;
772 case 2:
773 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
774 break;
775 case 3:
776 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
777 break;
778 case 4:
779 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
780 break;
781 case 5:
782 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
783 break;
784 case 6:
785 UNW_DEC_RP_BR ("P3", dst, arg);
786 break;
787 case 7:
788 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
789 break;
790 case 8:
791 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
792 break;
793 case 9:
794 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
795 break;
796 case 10:
797 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
798 break;
799 case 11:
800 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
801 break;
802 default:
803 UNW_DEC_BAD_CODE (r);
804 break;
807 else if ((code & 0x7) == 0)
808 UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
809 else if ((code & 0x7) == 1)
811 unw_word grmask, frmask, byte1, byte2, byte3;
813 if ((end - dp) < 3)
815 printf (_("\t<corrupt P5>\n"));
816 return end;
818 byte1 = *dp++;
819 byte2 = *dp++;
820 byte3 = *dp++;
821 grmask = ((byte1 >> 4) & 0xf);
822 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
823 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
825 else
826 UNW_DEC_BAD_CODE (code);
828 return dp;
831 static const unsigned char *
832 unw_decode_p6 (const unsigned char *dp, unsigned int code,
833 void *arg ATTRIBUTE_UNUSED,
834 const unsigned char * end ATTRIBUTE_UNUSED)
836 int gregs = (code & 0x10) != 0;
837 unsigned char mask = (code & 0x0f);
839 if (gregs)
840 UNW_DEC_GR_MEM ("P6", mask, arg);
841 else
842 UNW_DEC_FR_MEM ("P6", mask, arg);
843 return dp;
846 static const unsigned char *
847 unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
848 const unsigned char * end)
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, end);
857 switch (r)
859 case 0:
860 size = unw_decode_uleb128 (&dp, end);
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 if ((end - dp) < 2)
922 printf (_("\t<corrupt P8>\n"));
923 return end;
926 r = *dp++;
927 t = unw_decode_uleb128 (&dp, end);
928 switch (r)
930 case 1:
931 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
932 break;
933 case 2:
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
935 break;
936 case 3:
937 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
938 break;
939 case 4:
940 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
941 break;
942 case 5:
943 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
944 break;
945 case 6:
946 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
947 break;
948 case 7:
949 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
950 break;
951 case 8:
952 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
953 break;
954 case 9:
955 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
956 break;
957 case 10:
958 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
959 break;
960 case 11:
961 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
962 break;
963 case 12:
964 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
965 break;
966 case 13:
967 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
968 break;
969 case 14:
970 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
971 break;
972 case 15:
973 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
974 break;
975 case 16:
976 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
977 break;
978 case 17:
979 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
980 break;
981 case 18:
982 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
983 break;
984 case 19:
985 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
986 break;
987 default:
988 UNW_DEC_BAD_CODE (r);
989 break;
992 break;
994 case 0x1:
995 if ((end - dp) < 2)
997 printf (_("\t<corrupt P9>\n"));
998 return end;
1001 byte1 = *dp++;
1002 byte2 = *dp++;
1003 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
1004 break;
1006 case 0xf: /* p10 */
1007 if ((end - dp) < 2)
1009 printf (_("\t<corrupt P10>\n"));
1010 return end;
1013 byte1 = *dp++;
1014 byte2 = *dp++;
1015 UNW_DEC_ABI ("P10", byte1, byte2, arg);
1016 break;
1018 case 0x9:
1019 return unw_decode_x1 (dp, code, arg, end);
1021 case 0xa:
1022 return unw_decode_x2 (dp, code, arg, end);
1024 case 0xb:
1025 return unw_decode_x3 (dp, code, arg, end);
1027 case 0xc:
1028 return unw_decode_x4 (dp, code, arg, end);
1030 default:
1031 UNW_DEC_BAD_CODE (code);
1032 break;
1035 return dp;
1038 static const unsigned char *
1039 unw_decode_b1 (const unsigned char *dp, unsigned int code,
1040 void *arg ATTRIBUTE_UNUSED,
1041 const unsigned char * end ATTRIBUTE_UNUSED)
1043 unw_word label = (code & 0x1f);
1045 if ((code & 0x20) != 0)
1046 UNW_DEC_COPY_STATE ("B1", label, arg);
1047 else
1048 UNW_DEC_LABEL_STATE ("B1", label, arg);
1049 return dp;
1052 static const unsigned char *
1053 unw_decode_b2 (const unsigned char *dp, unsigned int code,
1054 void *arg ATTRIBUTE_UNUSED,
1055 const unsigned char * end)
1057 unw_word t;
1059 t = unw_decode_uleb128 (& dp, end);
1060 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1061 return dp;
1064 static const unsigned char *
1065 unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
1066 const unsigned char * end)
1068 unw_word t, ecount, label;
1070 if ((code & 0x10) == 0)
1072 t = unw_decode_uleb128 (&dp, end);
1073 ecount = unw_decode_uleb128 (&dp, end);
1074 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1076 else if ((code & 0x07) == 0)
1078 label = unw_decode_uleb128 (&dp, end);
1079 if ((code & 0x08) != 0)
1080 UNW_DEC_COPY_STATE ("B4", label, arg);
1081 else
1082 UNW_DEC_LABEL_STATE ("B4", label, arg);
1084 else
1085 switch (code & 0x7)
1087 case 1:
1088 return unw_decode_x1 (dp, code, arg, end);
1089 case 2:
1090 return unw_decode_x2 (dp, code, arg, end);
1091 case 3:
1092 return unw_decode_x3 (dp, code, arg, end);
1093 case 4:
1094 return unw_decode_x4 (dp, code, arg, end);
1095 default:
1096 UNW_DEC_BAD_CODE (code);
1097 break;
1099 return dp;
1102 typedef const unsigned char *(*unw_decoder)
1103 (const unsigned char *, unsigned int, void *, const unsigned char *);
1105 static const unw_decoder unw_decode_table[2][8] =
1107 /* prologue table: */
1109 unw_decode_r1, /* 0 */
1110 unw_decode_r1,
1111 unw_decode_r2,
1112 unw_decode_r3,
1113 unw_decode_p1, /* 4 */
1114 unw_decode_p2_p5,
1115 unw_decode_p6,
1116 unw_decode_p7_p10
1119 unw_decode_r1, /* 0 */
1120 unw_decode_r1,
1121 unw_decode_r2,
1122 unw_decode_r3,
1123 unw_decode_b1, /* 4 */
1124 unw_decode_b1,
1125 unw_decode_b2,
1126 unw_decode_b3_x4
1130 /* Decode one descriptor and return address of next descriptor. */
1131 const unsigned char *
1132 unw_decode (const unsigned char *dp, int inside_body,
1133 void *ptr_inside_body, const unsigned char * end)
1135 unw_decoder decoder;
1136 unsigned char code;
1138 if ((end - dp) < 1)
1140 printf (_("\t<corrupt IA64 descriptor>\n"));
1141 return end;
1144 code = *dp++;
1145 decoder = unw_decode_table[inside_body][code >> 5];
1146 return (*decoder) (dp, code, ptr_inside_body, end);