1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2    Copyright (C) 2000-2016 Free Software Foundation, Inc.
3 
4    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 
6    This file is part of GNU Binutils.
7 
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.
12 
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.
17 
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.  */
22 
23 #include "config.h"
24 #include "unwind-ia64.h"
25 #include <stdio.h>
26 #include <string.h>
27 
28 #if __GNUC__ >= 2
29 /* Define BFD64 here, even if our default architecture is 32 bit ELF
30    as this will allow us to read in and parse 64bit and 32bit ELF files.
31    Only do this if we believe that the compiler can support a 64 bit
32    data type.  For now we only rely on GCC being able to do this.  */
33 #define BFD64
34 #endif
35 #include "bfd.h"
36 
37 static bfd_vma unw_rlen = 0;
38 
39 static void unw_print_brmask (char *, unsigned int);
40 static void unw_print_grmask (char *, unsigned int);
41 static void unw_print_frmask (char *, unsigned int);
42 static void unw_print_abreg (char *, unsigned int);
43 static void unw_print_xyreg (char *, unsigned int, unsigned int);
44 
45 static void
46 unw_print_brmask (char *cp, unsigned int mask)
47 {
48   int sep = 0;
49   int i;
50 
51   for (i = 0; mask && (i < 5); ++i)
52     {
53       if (mask & 1)
54 	{
55 	  if (sep)
56 	    *cp++ = ',';
57 	  *cp++ = 'b';
58 	  *cp++ = i + 1 + '0';
59 	  sep = 1;
60 	}
61       mask >>= 1;
62     }
63   *cp = '\0';
64 }
65 
66 static void
67 unw_print_grmask (char *cp, unsigned int mask)
68 {
69   int sep = 0;
70   int i;
71 
72   for (i = 0; i < 4; ++i)
73     {
74       if (mask & 1)
75 	{
76 	  if (sep)
77 	    *cp++ = ',';
78 	  *cp++ = 'r';
79 	  *cp++ = i + 4 + '0';
80 	  sep = 1;
81 	}
82       mask >>= 1;
83     }
84   *cp = '\0';
85 }
86 
87 static void
88 unw_print_frmask (char *cp, unsigned int mask)
89 {
90   int sep = 0;
91   int i;
92 
93   for (i = 0; i < 20; ++i)
94     {
95       if (mask & 1)
96 	{
97 	  if (sep)
98 	    *cp++ = ',';
99 	  *cp++ = 'f';
100 	  if (i < 4)
101 	    *cp++ = i + 2 + '0';
102 	  else
103 	    {
104 	      *cp++ = (i + 2) / 10 + 1 + '0';
105 	      *cp++ = (i + 2) % 10 + '0';
106 	    }
107 	  sep = 1;
108 	}
109       mask >>= 1;
110     }
111   *cp = '\0';
112 }
113 
114 static void
115 unw_print_abreg (char *cp, unsigned int abreg)
116 {
117   static const char * const special_reg[16] =
118   {
119     "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
120     "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
121     "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
122   };
123 
124   switch ((abreg >> 5) & 0x3)
125     {
126     case 0: /* gr */
127       sprintf (cp, "r%u", (abreg & 0x1f));
128       break;
129 
130     case 1: /* fr */
131       sprintf (cp, "f%u", (abreg & 0x1f));
132       break;
133 
134     case 2: /* br */
135       sprintf (cp, "b%u", (abreg & 0x1f));
136       break;
137 
138     case 3: /* special */
139       strcpy (cp, special_reg[abreg & 0xf]);
140       break;
141     }
142 }
143 
144 static void
145 unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg)
146 {
147   switch ((x << 1) | ((ytreg >> 7) & 1))
148     {
149     case 0: /* gr */
150       sprintf (cp, "r%u", (ytreg & 0x1f));
151       break;
152 
153     case 1: /* fr */
154       sprintf (cp, "f%u", (ytreg & 0x1f));
155       break;
156 
157     case 2: /* br */
158       sprintf (cp, "b%u", (ytreg & 0x1f));
159       break;
160     }
161 }
162 
163 #define UNW_REG_BSP		"bsp"
164 #define UNW_REG_BSPSTORE	"bspstore"
165 #define UNW_REG_FPSR		"fpsr"
166 #define UNW_REG_LC		"lc"
167 #define UNW_REG_PFS		"pfs"
168 #define UNW_REG_PR		"pr"
169 #define UNW_REG_PSP		"psp"
170 #define UNW_REG_RNAT		"rnat"
171 #define UNW_REG_RP		"rp"
172 #define UNW_REG_UNAT		"unat"
173 
174 typedef bfd_vma unw_word;
175 
176 #define UNW_DEC_BAD_CODE(code)			\
177     printf ("Unknown code 0x%02x\n", code)
178 
179 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg)					\
180   do										\
181     {										\
182       unw_rlen = rlen;								\
183       *(int *)arg = body;							\
184       printf ("    %s:%s(rlen=%lu)\n",						\
185 	      fmt, body ? "body" : "prologue", (unsigned long) rlen);		\
186     }										\
187   while (0)
188 
189 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg)			\
190   do										\
191     {										\
192       char regname[16], maskstr[64], *sep;					\
193 										\
194       unw_rlen = rlen;								\
195       *(int *)arg = 0;								\
196 										\
197       maskstr[0] = '\0';							\
198       sep = "";									\
199       if (mask & 0x8)								\
200 	{									\
201 	  strcat (maskstr, "rp");						\
202 	  sep = ",";								\
203 	}									\
204       if (mask & 0x4)								\
205 	{									\
206 	  strcat (maskstr, sep);						\
207 	  strcat (maskstr, "ar.pfs");						\
208 	  sep = ",";								\
209 	}									\
210       if (mask & 0x2)								\
211 	{									\
212 	  strcat (maskstr, sep);						\
213 	  strcat (maskstr, "psp");						\
214 	  sep = ",";								\
215 	}									\
216       if (mask & 0x1)								\
217 	{									\
218 	  strcat (maskstr, sep);						\
219 	  strcat (maskstr, "pr");						\
220 	}									\
221       sprintf (regname, "r%u", grsave);						\
222       printf ("    %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n",		\
223 	      fmt, maskstr, regname, (unsigned long) rlen);			\
224     }										\
225   while (0)
226 
227 #define UNW_DEC_FR_MEM(fmt, frmask, arg)			\
228   do								\
229     {								\
230       char frstr[200];						\
231 								\
232       unw_print_frmask (frstr, frmask);				\
233       printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr);	\
234     }								\
235   while (0)
236 
237 #define UNW_DEC_GR_MEM(fmt, grmask, arg)			\
238   do								\
239     {								\
240       char grstr[200];						\
241 								\
242       unw_print_grmask (grstr, grmask);				\
243       printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr);	\
244     }								\
245   while (0)
246 
247 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg)				\
248   do										\
249     {										\
250       char frstr[200], grstr[20];						\
251 										\
252       unw_print_grmask (grstr, grmask);						\
253       unw_print_frmask (frstr, frmask);						\
254       printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr);	\
255     }										\
256   while (0)
257 
258 #define UNW_DEC_BR_MEM(fmt, brmask, arg)				\
259   do									\
260     {									\
261       char brstr[20];							\
262 									\
263       unw_print_brmask (brstr, brmask);					\
264       printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr);		\
265     }									\
266   while (0)
267 
268 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg)				\
269   do									\
270     {									\
271       char brstr[20];							\
272 									\
273       unw_print_brmask (brstr, brmask);					\
274       printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr);	\
275     }									\
276   while (0)
277 
278 #define UNW_DEC_REG_GR(fmt, src, dst, arg)		\
279   printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
280 
281 #define UNW_DEC_RP_BR(fmt, dst, arg)		\
282   printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
283 
284 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg)				\
285   printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
286 
287 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg)		\
288   printf ("\t%s:%s_sprel(spoff=0x%lx)\n",		\
289 	  fmt, reg, 4*(unsigned long)spoff)
290 
291 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg)		\
292   printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n",		\
293 	  fmt, reg, 4*(unsigned long)pspoff)
294 
295 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg)				\
296   do									\
297     {									\
298       char grstr[20];							\
299 									\
300       unw_print_grmask (grstr, grmask);					\
301       printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr);		\
302     }									\
303   while (0)
304 
305 #define UNW_DEC_ABI(fmt, abi, context, arg)			\
306   do								\
307     {								\
308       static const char * const abiname[] =			\
309       {								\
310 	"@svr4", "@hpux", "@nt"					\
311       };							\
312       char buf[20];						\
313       const char *abistr = buf;					\
314 								\
315       if (abi < 3)						\
316 	abistr = abiname[abi];					\
317       else							\
318 	sprintf (buf, "0x%x", abi);				\
319       printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n",		\
320 	      fmt, abistr, context);				\
321     }								\
322   while (0)
323 
324 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg)		\
325   printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
326 
327 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg)				\
328   printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
329 
330 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg)				\
331   printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
332 
333 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg)		\
334   printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n",		\
335 	  fmt, 4*(unsigned long)pspoff)
336 
337 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg)		\
338   printf ("\t%s:priunat_sprel(spoff=0x%lx)\n",		\
339 	  fmt, 4*(unsigned long)spoff)
340 
341 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg)		\
342   printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n",		\
343 	  fmt, (unsigned long) t, 16*(unsigned long)size)
344 
345 #define UNW_DEC_MEM_STACK_V(fmt, t, arg)				\
346   printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
347 
348 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg)			\
349   printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n",		\
350 	  fmt, 4*(unsigned long)pspoff)
351 
352 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end)				\
353   do									\
354     {									\
355       static const char *spill_type = "-frb";				\
356       unsigned const char *imaskp = dp;					\
357       unsigned char mask = 0;						\
358       bfd_vma insn = 0;							\
359       									\
360       /* PR 18420.  */							\
361       if ((dp + (unw_rlen / 4)) > end)					\
362 	{								\
363 	  printf ("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n",\
364 		  (long) (unw_rlen / 4), (long)(end - dp));		\
365 	  /* FIXME: Should we reset unw_rlen ?  */			\
366 	  break;							\
367 	}								\
368       printf ("\t%s:spill_mask(imask=[", fmt);					\
369       for (insn = 0; insn < unw_rlen; ++insn)					\
370 	{									\
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]);	\
376 	}									\
377       printf ("])\n");								\
378       dp = imaskp;								\
379     }										\
380   while (0)
381 
382 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg)				\
383   do										\
384     {										\
385       char regname[20];								\
386 										\
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);		\
390     }										\
391   while (0)
392 
393 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg)			\
394   do										\
395     {										\
396       char regname[20];								\
397 										\
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);	\
401     }										\
402   while (0)
403 
404 #define UNW_DEC_RESTORE(fmt, t, abreg, arg)			\
405   do								\
406     {								\
407       char regname[20];						\
408 								\
409       unw_print_abreg (regname, abreg);				\
410       printf ("\t%s:restore(t=%lu,reg=%s)\n",			\
411 	      fmt, (unsigned long) t, regname);			\
412     }								\
413   while (0)
414 
415 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg)		\
416   do								\
417     {								\
418       char abregname[20], tregname[20];				\
419 								\
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);	\
424     }								\
425   while (0)
426 
427 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg)			    \
428   do										    \
429     {										    \
430       char regname[20];								    \
431 										    \
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);	    \
435     }										    \
436   while (0)
437 
438 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg)		\
439   do									\
440     {									\
441       char regname[20];							\
442 									\
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);\
446     }									\
447   while (0)
448 
449 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg)			\
450   do									\
451     {									\
452       char regname[20];							\
453 									\
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);			\
457     }									\
458   while (0)
459 
460 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg)		\
461   do									\
462     {									\
463       char regname[20], tregname[20];					\
464 									\
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);		\
469     }									\
470   while (0)
471 
472 #define UNW_DEC_LABEL_STATE(fmt, label, arg)				\
473   printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
474 
475 #define UNW_DEC_COPY_STATE(fmt, label, arg)				\
476   printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
477 
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)
481 
482 /*
483  * Generic IA-64 unwind info decoder.
484  *
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...).
488  *
489  * You need to customize the decoder by defining the following
490  * macros/constants before including this file:
491  *
492  *  Types:
493  *	unw_word	Unsigned integer type with at least 64 bits
494  *
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
506  *
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)
542  */
543 
544 static unw_word
545 unw_decode_uleb128 (const unsigned char **dpp)
546 {
547   unsigned shift = 0;
548   unw_word byte, result = 0;
549   const unsigned char *bp = *dpp;
550 
551   while (1)
552     {
553       byte = *bp++;
554       result |= (byte & 0x7f) << shift;
555 
556       if ((byte & 0x80) == 0)
557 	break;
558 
559       shift += 7;
560     }
561 
562   *dpp = bp;
563 
564   return result;
565 }
566 
567 static const unsigned char *
568 unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
569 	       void *arg ATTRIBUTE_UNUSED)
570 {
571   unsigned char byte1, abreg;
572   unw_word t, off;
573 
574   byte1 = *dp++;
575   t = unw_decode_uleb128 (&dp);
576   off = unw_decode_uleb128 (&dp);
577   abreg = (byte1 & 0x7f);
578   if (byte1 & 0x80)
579     UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
580   else
581     UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
582   return dp;
583 }
584 
585 static const unsigned char *
586 unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
587 	       void *arg ATTRIBUTE_UNUSED)
588 {
589   unsigned char byte1, byte2, abreg, x, ytreg;
590   unw_word t;
591 
592   byte1 = *dp++;
593   byte2 = *dp++;
594   t = unw_decode_uleb128 (&dp);
595   abreg = (byte1 & 0x7f);
596   ytreg = byte2;
597   x = (byte1 >> 7) & 1;
598   if ((byte1 & 0x80) == 0 && ytreg == 0)
599     UNW_DEC_RESTORE ("X2", t, abreg, arg);
600   else
601     UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
602   return dp;
603 }
604 
605 static const unsigned char *
606 unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
607 	       void *arg ATTRIBUTE_UNUSED)
608 {
609   unsigned char byte1, byte2, abreg, qp;
610   unw_word t, off;
611 
612   byte1 = *dp++;
613   byte2 = *dp++;
614   t = unw_decode_uleb128 (&dp);
615   off = unw_decode_uleb128 (&dp);
616 
617   qp = (byte1 & 0x3f);
618   abreg = (byte2 & 0x7f);
619 
620   if (byte1 & 0x80)
621     UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
622   else
623     UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
624   return dp;
625 }
626 
627 static const unsigned char *
628 unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
629 	       void *arg ATTRIBUTE_UNUSED)
630 {
631   unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
632   unw_word t;
633 
634   byte1 = *dp++;
635   byte2 = *dp++;
636   byte3 = *dp++;
637   t = unw_decode_uleb128 (&dp);
638 
639   qp = (byte1 & 0x3f);
640   abreg = (byte2 & 0x7f);
641   x = (byte2 >> 7) & 1;
642   ytreg = byte3;
643 
644   if ((byte2 & 0x80) == 0 && byte3 == 0)
645     UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
646   else
647     UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
648   return dp;
649 }
650 
651 static const unsigned char *
652 unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg,
653 	       const unsigned char * end ATTRIBUTE_UNUSED)
654 {
655   int body = (code & 0x20) != 0;
656   unw_word rlen;
657 
658   rlen = (code & 0x1f);
659   UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
660   return dp;
661 }
662 
663 static const unsigned char *
664 unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
665 	       const unsigned char * end ATTRIBUTE_UNUSED)
666 {
667   unsigned char byte1, mask, grsave;
668   unw_word rlen;
669 
670   byte1 = *dp++;
671 
672   mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
673   grsave = (byte1 & 0x7f);
674   rlen = unw_decode_uleb128 (& dp);
675   UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
676   return dp;
677 }
678 
679 static const unsigned char *
680 unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
681 	       const unsigned char * end ATTRIBUTE_UNUSED)
682 {
683   unw_word rlen;
684 
685   rlen = unw_decode_uleb128 (& dp);
686   UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
687   return dp;
688 }
689 
690 static const unsigned char *
691 unw_decode_p1 (const unsigned char *dp, unsigned int code,
692 	       void *arg ATTRIBUTE_UNUSED,
693 	       const unsigned char * end ATTRIBUTE_UNUSED)
694 {
695   unsigned char brmask = (code & 0x1f);
696 
697   UNW_DEC_BR_MEM ("P1", brmask, arg);
698   return dp;
699 }
700 
701 static const unsigned char *
702 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
703 		  void *arg ATTRIBUTE_UNUSED,
704 		  const unsigned char * end)
705 {
706   if ((code & 0x10) == 0)
707     {
708       unsigned char byte1 = *dp++;
709 
710       UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
711 		     (byte1 & 0x7f), arg);
712     }
713   else if ((code & 0x08) == 0)
714     {
715       unsigned char byte1 = *dp++, r, dst;
716 
717       r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
718       dst = (byte1 & 0x7f);
719       switch (r)
720 	{
721 	case 0:
722 	  UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
723 	  break;
724 	case 1:
725 	  UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
726 	  break;
727 	case 2:
728 	  UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
729 	  break;
730 	case 3:
731 	  UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
732 	  break;
733 	case 4:
734 	  UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
735 	  break;
736 	case 5:
737 	  UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
738 	  break;
739 	case 6:
740 	  UNW_DEC_RP_BR ("P3", dst, arg);
741 	  break;
742 	case 7:
743 	  UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
744 	  break;
745 	case 8:
746 	  UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
747 	  break;
748 	case 9:
749 	  UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
750 	  break;
751 	case 10:
752 	  UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
753 	  break;
754 	case 11:
755 	  UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
756 	  break;
757 	default:
758 	  UNW_DEC_BAD_CODE (r);
759 	  break;
760 	}
761     }
762   else if ((code & 0x7) == 0)
763     UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
764   else if ((code & 0x7) == 1)
765     {
766       unw_word grmask, frmask, byte1, byte2, byte3;
767 
768       byte1 = *dp++;
769       byte2 = *dp++;
770       byte3 = *dp++;
771       grmask = ((byte1 >> 4) & 0xf);
772       frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
773       UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
774     }
775   else
776     UNW_DEC_BAD_CODE (code);
777 
778   return dp;
779 }
780 
781 static const unsigned char *
782 unw_decode_p6 (const unsigned char *dp, unsigned int code,
783 	       void *arg ATTRIBUTE_UNUSED,
784 	       const unsigned char * end ATTRIBUTE_UNUSED)
785 {
786   int gregs = (code & 0x10) != 0;
787   unsigned char mask = (code & 0x0f);
788 
789   if (gregs)
790     UNW_DEC_GR_MEM ("P6", mask, arg);
791   else
792     UNW_DEC_FR_MEM ("P6", mask, arg);
793   return dp;
794 }
795 
796 static const unsigned char *
797 unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
798 		   const unsigned char * end ATTRIBUTE_UNUSED)
799 {
800   unsigned char r, byte1, byte2;
801   unw_word t, size;
802 
803   if ((code & 0x10) == 0)
804     {
805       r = (code & 0xf);
806       t = unw_decode_uleb128 (&dp);
807       switch (r)
808 	{
809 	case 0:
810 	  size = unw_decode_uleb128 (&dp);
811 	  UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
812 	  break;
813 
814 	case 1:
815 	  UNW_DEC_MEM_STACK_V ("P7", t, arg);
816 	  break;
817 	case 2:
818 	  UNW_DEC_SPILL_BASE ("P7", t, arg);
819 	  break;
820 	case 3:
821 	  UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
822 	  break;
823 	case 4:
824 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
825 	  break;
826 	case 5:
827 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
828 	  break;
829 	case 6:
830 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
831 	  break;
832 	case 7:
833 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
834 	  break;
835 	case 8:
836 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
837 	  break;
838 	case 9:
839 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
840 	  break;
841 	case 10:
842 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
843 	  break;
844 	case 11:
845 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
846 	  break;
847 	case 12:
848 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
849 	  break;
850 	case 13:
851 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
852 	  break;
853 	case 14:
854 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
855 	  break;
856 	case 15:
857 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
858 	  break;
859 	default:
860 	  UNW_DEC_BAD_CODE (r);
861 	  break;
862 	}
863     }
864   else
865     {
866       switch (code & 0xf)
867 	{
868 	case 0x0:		/* p8 */
869 	  {
870 	    r = *dp++;
871 	    t = unw_decode_uleb128 (&dp);
872 	    switch (r)
873 	      {
874 	      case 1:
875 		UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
876 		break;
877 	      case 2:
878 		UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
879 		break;
880 	      case 3:
881 		UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
882 		break;
883 	      case 4:
884 		UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
885 		break;
886 	      case 5:
887 		UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
888 		break;
889 	      case 6:
890 		UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
891 		break;
892 	      case 7:
893 		UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
894 		break;
895 	      case 8:
896 		UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
897 		break;
898 	      case 9:
899 		UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
900 		break;
901 	      case 10:
902 		UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
903 		break;
904 	      case 11:
905 		UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
906 		break;
907 	      case 12:
908 		UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
909 		break;
910 	      case 13:
911 		UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
912 		break;
913 	      case 14:
914 		UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
915 		break;
916 	      case 15:
917 		UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
918 		break;
919 	      case 16:
920 		UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
921 		break;
922 	      case 17:
923 		UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
924 		break;
925 	      case 18:
926 		UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
927 		break;
928 	      case 19:
929 		UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
930 		break;
931 	      default:
932 		UNW_DEC_BAD_CODE (r);
933 		break;
934 	      }
935 	  }
936 	  break;
937 
938 	case 0x1:
939 	  byte1 = *dp++;
940 	  byte2 = *dp++;
941 	  UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
942 	  break;
943 
944 	case 0xf:		/* p10 */
945 	  byte1 = *dp++;
946 	  byte2 = *dp++;
947 	  UNW_DEC_ABI ("P10", byte1, byte2, arg);
948 	  break;
949 
950 	case 0x9:
951 	  return unw_decode_x1 (dp, code, arg);
952 
953 	case 0xa:
954 	  return unw_decode_x2 (dp, code, arg);
955 
956 	case 0xb:
957 	  return unw_decode_x3 (dp, code, arg);
958 
959 	case 0xc:
960 	  return unw_decode_x4 (dp, code, arg);
961 
962 	default:
963 	  UNW_DEC_BAD_CODE (code);
964 	  break;
965 	}
966     }
967   return dp;
968 }
969 
970 static const unsigned char *
971 unw_decode_b1 (const unsigned char *dp, unsigned int code,
972 	       void *arg ATTRIBUTE_UNUSED,
973 	       const unsigned char * end ATTRIBUTE_UNUSED)
974 {
975   unw_word label = (code & 0x1f);
976 
977   if ((code & 0x20) != 0)
978     UNW_DEC_COPY_STATE ("B1", label, arg);
979   else
980     UNW_DEC_LABEL_STATE ("B1", label, arg);
981   return dp;
982 }
983 
984 static const unsigned char *
985 unw_decode_b2 (const unsigned char *dp, unsigned int code,
986 	       void *arg ATTRIBUTE_UNUSED,
987 	       const unsigned char * end ATTRIBUTE_UNUSED)
988 {
989   unw_word t;
990 
991   t = unw_decode_uleb128 (& dp);
992   UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
993   return dp;
994 }
995 
996 static const unsigned char *
997 unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
998 		  const unsigned char * end ATTRIBUTE_UNUSED)
999 {
1000   unw_word t, ecount, label;
1001 
1002   if ((code & 0x10) == 0)
1003     {
1004       t = unw_decode_uleb128 (&dp);
1005       ecount = unw_decode_uleb128 (&dp);
1006       UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1007     }
1008   else if ((code & 0x07) == 0)
1009     {
1010       label = unw_decode_uleb128 (&dp);
1011       if ((code & 0x08) != 0)
1012 	UNW_DEC_COPY_STATE ("B4", label, arg);
1013       else
1014 	UNW_DEC_LABEL_STATE ("B4", label, arg);
1015     }
1016   else
1017     switch (code & 0x7)
1018       {
1019       case 1:
1020 	return unw_decode_x1 (dp, code, arg);
1021       case 2:
1022 	return unw_decode_x2 (dp, code, arg);
1023       case 3:
1024 	return unw_decode_x3 (dp, code, arg);
1025       case 4:
1026 	return unw_decode_x4 (dp, code, arg);
1027       default:
1028 	UNW_DEC_BAD_CODE (code);
1029 	break;
1030       }
1031   return dp;
1032 }
1033 
1034 typedef const unsigned char *(*unw_decoder)
1035   (const unsigned char *, unsigned int, void *, const unsigned char *);
1036 
1037 static const unw_decoder unw_decode_table[2][8] =
1038   {
1039     /* prologue table: */
1040     {
1041       unw_decode_r1,		/* 0 */
1042       unw_decode_r1,
1043       unw_decode_r2,
1044       unw_decode_r3,
1045       unw_decode_p1,		/* 4 */
1046       unw_decode_p2_p5,
1047       unw_decode_p6,
1048       unw_decode_p7_p10
1049     },
1050     {
1051       unw_decode_r1,		/* 0 */
1052       unw_decode_r1,
1053       unw_decode_r2,
1054       unw_decode_r3,
1055       unw_decode_b1,		/* 4 */
1056       unw_decode_b1,
1057       unw_decode_b2,
1058       unw_decode_b3_x4
1059     }
1060   };
1061 
1062 /* Decode one descriptor and return address of next descriptor.  */
1063 const unsigned char *
1064 unw_decode (const unsigned char *dp, int inside_body,
1065 	    void *ptr_inside_body, const unsigned char * end)
1066 {
1067   unw_decoder decoder;
1068   unsigned char code;
1069 
1070   code = *dp++;
1071   decoder = unw_decode_table[inside_body][code >> 5];
1072   return (*decoder) (dp, code, ptr_inside_body, end);
1073 }
1074