1 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
2    Copyright (C) 2000-2014 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
unw_print_brmask(char * cp,unsigned int mask)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
unw_print_grmask(char * cp,unsigned int mask)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
unw_print_frmask(char * cp,unsigned int mask)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
unw_print_abreg(char * cp,unsigned int abreg)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
unw_print_xyreg(char * cp,unsigned int x,unsigned int ytreg)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)					\
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       printf ("\t%s:spill_mask(imask=[", fmt);					\
361       for (insn = 0; insn < unw_rlen; ++insn)					\
362 	{									\
363 	  if ((insn % 4) == 0)							\
364 	    mask = *imaskp++;							\
365 	  if (insn > 0 && (insn % 3) == 0)					\
366 	    putchar (',');							\
367 	  putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]);	\
368 	}									\
369       printf ("])\n");								\
370       dp = imaskp;								\
371     }										\
372   while (0)
373 
374 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg)				\
375   do										\
376     {										\
377       char regname[20];								\
378 										\
379       unw_print_abreg (regname, abreg);						\
380       printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n",			\
381 	      fmt, regname, (unsigned long) t, 4*(unsigned long)off);		\
382     }										\
383   while (0)
384 
385 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg)			\
386   do										\
387     {										\
388       char regname[20];								\
389 										\
390       unw_print_abreg (regname, abreg);						\
391       printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n",		\
392 	      fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff);	\
393     }										\
394   while (0)
395 
396 #define UNW_DEC_RESTORE(fmt, t, abreg, arg)			\
397   do								\
398     {								\
399       char regname[20];						\
400 								\
401       unw_print_abreg (regname, abreg);				\
402       printf ("\t%s:restore(t=%lu,reg=%s)\n",			\
403 	      fmt, (unsigned long) t, regname);			\
404     }								\
405   while (0)
406 
407 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg)		\
408   do								\
409     {								\
410       char abregname[20], tregname[20];				\
411 								\
412       unw_print_abreg (abregname, abreg);			\
413       unw_print_xyreg (tregname, x, ytreg);			\
414       printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n",		\
415 	      fmt, (unsigned long) t, abregname, tregname);	\
416     }								\
417   while (0)
418 
419 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg)			    \
420   do										    \
421     {										    \
422       char regname[20];								    \
423 										    \
424       unw_print_abreg (regname, abreg);						    \
425       printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n",		    \
426 	      fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff);	    \
427     }										    \
428   while (0)
429 
430 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg)		\
431   do									\
432     {									\
433       char regname[20];							\
434 									\
435       unw_print_abreg (regname, abreg);					\
436       printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
437 	      fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
438     }									\
439   while (0)
440 
441 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg)			\
442   do									\
443     {									\
444       char regname[20];							\
445 									\
446       unw_print_abreg (regname, abreg);					\
447       printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n",			\
448 	      fmt, qp, (unsigned long) t, regname);			\
449     }									\
450   while (0)
451 
452 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg)		\
453   do									\
454     {									\
455       char regname[20], tregname[20];					\
456 									\
457       unw_print_abreg (regname, abreg);					\
458       unw_print_xyreg (tregname, x, ytreg);				\
459       printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n",	\
460 	      fmt, qp, (unsigned long) t, regname, tregname);		\
461     }									\
462   while (0)
463 
464 #define UNW_DEC_LABEL_STATE(fmt, label, arg)				\
465   printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
466 
467 #define UNW_DEC_COPY_STATE(fmt, label, arg)				\
468   printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
469 
470 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg)		\
471   printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n",		\
472 	  fmt, (unsigned long) t, (unsigned long) ecount)
473 
474 /*
475  * Generic IA-64 unwind info decoder.
476  *
477  * This file is used both by the Linux kernel and objdump.  Please
478  * keep the two copies of this file in sync (modulo differences in the
479  * prototypes...).
480  *
481  * You need to customize the decoder by defining the following
482  * macros/constants before including this file:
483  *
484  *  Types:
485  *	unw_word	Unsigned integer type with at least 64 bits
486  *
487  *  Register names:
488  *	UNW_REG_BSP
489  *	UNW_REG_BSPSTORE
490  *	UNW_REG_FPSR
491  *	UNW_REG_LC
492  *	UNW_REG_PFS
493  *	UNW_REG_PR
494  *	UNW_REG_RNAT
495  *	UNW_REG_PSP
496  *	UNW_REG_RP
497  *	UNW_REG_UNAT
498  *
499  *  Decoder action macros:
500  *	UNW_DEC_BAD_CODE(code)
501  *	UNW_DEC_ABI(fmt,abi,context,arg)
502  *	UNW_DEC_BR_GR(fmt,brmask,gr,arg)
503  *	UNW_DEC_BR_MEM(fmt,brmask,arg)
504  *	UNW_DEC_COPY_STATE(fmt,label,arg)
505  *	UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
506  *	UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
507  *	UNW_DEC_FR_MEM(fmt,frmask,arg)
508  *	UNW_DEC_GR_GR(fmt,grmask,gr,arg)
509  *	UNW_DEC_GR_MEM(fmt,grmask,arg)
510  *	UNW_DEC_LABEL_STATE(fmt,label,arg)
511  *	UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
512  *	UNW_DEC_MEM_STACK_V(fmt,t,arg)
513  *	UNW_DEC_PRIUNAT_GR(fmt,r,arg)
514  *	UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
515  *	UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
516  *	UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
517  *	UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
518  *	UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
519  *	UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
520  *	UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
521  *	UNW_DEC_REG_REG(fmt,src,dst,arg)
522  *	UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
523  *	UNW_DEC_REG_WHEN(fmt,reg,t,arg)
524  *	UNW_DEC_RESTORE(fmt,t,abreg,arg)
525  *	UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
526  *	UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
527  *	UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
528  *	UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
529  *	UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
530  *	UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
531  *	UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
532  *	UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
533  *	UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
534  */
535 
536 static unw_word unw_decode_uleb128 (const unsigned char **);
537 static const unsigned char *unw_decode_x1
538   (const unsigned char *, unsigned int, void *);
539 static const unsigned char *unw_decode_x2
540   (const unsigned char *, unsigned int, void *);
541 static const unsigned char *unw_decode_x3
542   (const unsigned char *, unsigned int, void *);
543 static const unsigned char *unw_decode_x4
544   (const unsigned char *, unsigned int, void *);
545 static const unsigned char *unw_decode_r1
546   (const unsigned char *, unsigned int, void *);
547 static const unsigned char *unw_decode_r2
548   (const unsigned char *, unsigned int, void *);
549 static const unsigned char *unw_decode_r3
550   (const unsigned char *, unsigned int, void *);
551 static const unsigned char *unw_decode_p1
552   (const unsigned char *, unsigned int, void *);
553 static const unsigned char *unw_decode_p2_p5
554   (const unsigned char *, unsigned int, void *);
555 static const unsigned char *unw_decode_p6
556   (const unsigned char *, unsigned int, void *);
557 static const unsigned char *unw_decode_p7_p10
558   (const unsigned char *, unsigned int, void *);
559 static const unsigned char *unw_decode_b1
560   (const unsigned char *, unsigned int, void *);
561 static const unsigned char *unw_decode_b2
562   (const unsigned char *, unsigned int, void *);
563 static const unsigned char *unw_decode_b3_x4
564   (const unsigned char *, unsigned int, void *);
565 
566 static unw_word
unw_decode_uleb128(const unsigned char ** dpp)567 unw_decode_uleb128 (const unsigned char **dpp)
568 {
569   unsigned shift = 0;
570   unw_word byte, result = 0;
571   const unsigned char *bp = *dpp;
572 
573   while (1)
574     {
575       byte = *bp++;
576       result |= (byte & 0x7f) << shift;
577 
578       if ((byte & 0x80) == 0)
579 	break;
580 
581       shift += 7;
582     }
583 
584   *dpp = bp;
585 
586   return result;
587 }
588 
589 static const unsigned char *
unw_decode_x1(const unsigned char * dp,unsigned int code ATTRIBUTE_UNUSED,void * arg ATTRIBUTE_UNUSED)590 unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
591 	       void *arg ATTRIBUTE_UNUSED)
592 {
593   unsigned char byte1, abreg;
594   unw_word t, off;
595 
596   byte1 = *dp++;
597   t = unw_decode_uleb128 (&dp);
598   off = unw_decode_uleb128 (&dp);
599   abreg = (byte1 & 0x7f);
600   if (byte1 & 0x80)
601     UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
602   else
603     UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
604   return dp;
605 }
606 
607 static const unsigned char *
unw_decode_x2(const unsigned char * dp,unsigned int code ATTRIBUTE_UNUSED,void * arg ATTRIBUTE_UNUSED)608 unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
609 	       void *arg ATTRIBUTE_UNUSED)
610 {
611   unsigned char byte1, byte2, abreg, x, ytreg;
612   unw_word t;
613 
614   byte1 = *dp++;
615   byte2 = *dp++;
616   t = unw_decode_uleb128 (&dp);
617   abreg = (byte1 & 0x7f);
618   ytreg = byte2;
619   x = (byte1 >> 7) & 1;
620   if ((byte1 & 0x80) == 0 && ytreg == 0)
621     UNW_DEC_RESTORE ("X2", t, abreg, arg);
622   else
623     UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
624   return dp;
625 }
626 
627 static const unsigned char *
unw_decode_x3(const unsigned char * dp,unsigned int code ATTRIBUTE_UNUSED,void * arg ATTRIBUTE_UNUSED)628 unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
629 	       void *arg ATTRIBUTE_UNUSED)
630 {
631   unsigned char byte1, byte2, abreg, qp;
632   unw_word t, off;
633 
634   byte1 = *dp++;
635   byte2 = *dp++;
636   t = unw_decode_uleb128 (&dp);
637   off = unw_decode_uleb128 (&dp);
638 
639   qp = (byte1 & 0x3f);
640   abreg = (byte2 & 0x7f);
641 
642   if (byte1 & 0x80)
643     UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
644   else
645     UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
646   return dp;
647 }
648 
649 static const unsigned char *
unw_decode_x4(const unsigned char * dp,unsigned int code ATTRIBUTE_UNUSED,void * arg ATTRIBUTE_UNUSED)650 unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
651 	       void *arg ATTRIBUTE_UNUSED)
652 {
653   unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
654   unw_word t;
655 
656   byte1 = *dp++;
657   byte2 = *dp++;
658   byte3 = *dp++;
659   t = unw_decode_uleb128 (&dp);
660 
661   qp = (byte1 & 0x3f);
662   abreg = (byte2 & 0x7f);
663   x = (byte2 >> 7) & 1;
664   ytreg = byte3;
665 
666   if ((byte2 & 0x80) == 0 && byte3 == 0)
667     UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
668   else
669     UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
670   return dp;
671 }
672 
673 static const unsigned char *
unw_decode_r1(const unsigned char * dp,unsigned int code,void * arg)674 unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg)
675 {
676   int body = (code & 0x20) != 0;
677   unw_word rlen;
678 
679   rlen = (code & 0x1f);
680   UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
681   return dp;
682 }
683 
684 static const unsigned char *
unw_decode_r2(const unsigned char * dp,unsigned int code,void * arg)685 unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg)
686 {
687   unsigned char byte1, mask, grsave;
688   unw_word rlen;
689 
690   byte1 = *dp++;
691 
692   mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
693   grsave = (byte1 & 0x7f);
694   rlen = unw_decode_uleb128 (& dp);
695   UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
696   return dp;
697 }
698 
699 static const unsigned char *
unw_decode_r3(const unsigned char * dp,unsigned int code,void * arg)700 unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg)
701 {
702   unw_word rlen;
703 
704   rlen = unw_decode_uleb128 (& dp);
705   UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
706   return dp;
707 }
708 
709 static const unsigned char *
unw_decode_p1(const unsigned char * dp,unsigned int code,void * arg ATTRIBUTE_UNUSED)710 unw_decode_p1 (const unsigned char *dp, unsigned int code,
711 	       void *arg ATTRIBUTE_UNUSED)
712 {
713   unsigned char brmask = (code & 0x1f);
714 
715   UNW_DEC_BR_MEM ("P1", brmask, arg);
716   return dp;
717 }
718 
719 static const unsigned char *
unw_decode_p2_p5(const unsigned char * dp,unsigned int code,void * arg ATTRIBUTE_UNUSED)720 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
721 		  void *arg ATTRIBUTE_UNUSED)
722 {
723   if ((code & 0x10) == 0)
724     {
725       unsigned char byte1 = *dp++;
726 
727       UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
728 		     (byte1 & 0x7f), arg);
729     }
730   else if ((code & 0x08) == 0)
731     {
732       unsigned char byte1 = *dp++, r, dst;
733 
734       r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
735       dst = (byte1 & 0x7f);
736       switch (r)
737 	{
738 	case 0:
739 	  UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
740 	  break;
741 	case 1:
742 	  UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
743 	  break;
744 	case 2:
745 	  UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
746 	  break;
747 	case 3:
748 	  UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
749 	  break;
750 	case 4:
751 	  UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
752 	  break;
753 	case 5:
754 	  UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
755 	  break;
756 	case 6:
757 	  UNW_DEC_RP_BR ("P3", dst, arg);
758 	  break;
759 	case 7:
760 	  UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
761 	  break;
762 	case 8:
763 	  UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
764 	  break;
765 	case 9:
766 	  UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
767 	  break;
768 	case 10:
769 	  UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
770 	  break;
771 	case 11:
772 	  UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
773 	  break;
774 	default:
775 	  UNW_DEC_BAD_CODE (r);
776 	  break;
777 	}
778     }
779   else if ((code & 0x7) == 0)
780     UNW_DEC_SPILL_MASK ("P4", dp, arg);
781   else if ((code & 0x7) == 1)
782     {
783       unw_word grmask, frmask, byte1, byte2, byte3;
784 
785       byte1 = *dp++;
786       byte2 = *dp++;
787       byte3 = *dp++;
788       grmask = ((byte1 >> 4) & 0xf);
789       frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
790       UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
791     }
792   else
793     UNW_DEC_BAD_CODE (code);
794 
795   return dp;
796 }
797 
798 static const unsigned char *
unw_decode_p6(const unsigned char * dp,unsigned int code,void * arg ATTRIBUTE_UNUSED)799 unw_decode_p6 (const unsigned char *dp, unsigned int code,
800 	       void *arg ATTRIBUTE_UNUSED)
801 {
802   int gregs = (code & 0x10) != 0;
803   unsigned char mask = (code & 0x0f);
804 
805   if (gregs)
806     UNW_DEC_GR_MEM ("P6", mask, arg);
807   else
808     UNW_DEC_FR_MEM ("P6", mask, arg);
809   return dp;
810 }
811 
812 static const unsigned char *
unw_decode_p7_p10(const unsigned char * dp,unsigned int code,void * arg)813 unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg)
814 {
815   unsigned char r, byte1, byte2;
816   unw_word t, size;
817 
818   if ((code & 0x10) == 0)
819     {
820       r = (code & 0xf);
821       t = unw_decode_uleb128 (&dp);
822       switch (r)
823 	{
824 	case 0:
825 	  size = unw_decode_uleb128 (&dp);
826 	  UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
827 	  break;
828 
829 	case 1:
830 	  UNW_DEC_MEM_STACK_V ("P7", t, arg);
831 	  break;
832 	case 2:
833 	  UNW_DEC_SPILL_BASE ("P7", t, arg);
834 	  break;
835 	case 3:
836 	  UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
837 	  break;
838 	case 4:
839 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
840 	  break;
841 	case 5:
842 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
843 	  break;
844 	case 6:
845 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
846 	  break;
847 	case 7:
848 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
849 	  break;
850 	case 8:
851 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
852 	  break;
853 	case 9:
854 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
855 	  break;
856 	case 10:
857 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
858 	  break;
859 	case 11:
860 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
861 	  break;
862 	case 12:
863 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
864 	  break;
865 	case 13:
866 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
867 	  break;
868 	case 14:
869 	  UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
870 	  break;
871 	case 15:
872 	  UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
873 	  break;
874 	default:
875 	  UNW_DEC_BAD_CODE (r);
876 	  break;
877 	}
878     }
879   else
880     {
881       switch (code & 0xf)
882 	{
883 	case 0x0:		/* p8 */
884 	  {
885 	    r = *dp++;
886 	    t = unw_decode_uleb128 (&dp);
887 	    switch (r)
888 	      {
889 	      case 1:
890 		UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
891 		break;
892 	      case 2:
893 		UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
894 		break;
895 	      case 3:
896 		UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
897 		break;
898 	      case 4:
899 		UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
900 		break;
901 	      case 5:
902 		UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
903 		break;
904 	      case 6:
905 		UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
906 		break;
907 	      case 7:
908 		UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
909 		break;
910 	      case 8:
911 		UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
912 		break;
913 	      case 9:
914 		UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
915 		break;
916 	      case 10:
917 		UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
918 		break;
919 	      case 11:
920 		UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
921 		break;
922 	      case 12:
923 		UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
924 		break;
925 	      case 13:
926 		UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
927 		break;
928 	      case 14:
929 		UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
930 		break;
931 	      case 15:
932 		UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
933 		break;
934 	      case 16:
935 		UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
936 		break;
937 	      case 17:
938 		UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
939 		break;
940 	      case 18:
941 		UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
942 		break;
943 	      case 19:
944 		UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
945 		break;
946 	      default:
947 		UNW_DEC_BAD_CODE (r);
948 		break;
949 	      }
950 	  }
951 	  break;
952 
953 	case 0x1:
954 	  byte1 = *dp++;
955 	  byte2 = *dp++;
956 	  UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
957 	  break;
958 
959 	case 0xf:		/* p10 */
960 	  byte1 = *dp++;
961 	  byte2 = *dp++;
962 	  UNW_DEC_ABI ("P10", byte1, byte2, arg);
963 	  break;
964 
965 	case 0x9:
966 	  return unw_decode_x1 (dp, code, arg);
967 
968 	case 0xa:
969 	  return unw_decode_x2 (dp, code, arg);
970 
971 	case 0xb:
972 	  return unw_decode_x3 (dp, code, arg);
973 
974 	case 0xc:
975 	  return unw_decode_x4 (dp, code, arg);
976 
977 	default:
978 	  UNW_DEC_BAD_CODE (code);
979 	  break;
980 	}
981     }
982   return dp;
983 }
984 
985 static const unsigned char *
unw_decode_b1(const unsigned char * dp,unsigned int code,void * arg ATTRIBUTE_UNUSED)986 unw_decode_b1 (const unsigned char *dp, unsigned int code,
987 	       void *arg ATTRIBUTE_UNUSED)
988 {
989   unw_word label = (code & 0x1f);
990 
991   if ((code & 0x20) != 0)
992     UNW_DEC_COPY_STATE ("B1", label, arg);
993   else
994     UNW_DEC_LABEL_STATE ("B1", label, arg);
995   return dp;
996 }
997 
998 static const unsigned char *
unw_decode_b2(const unsigned char * dp,unsigned int code,void * arg ATTRIBUTE_UNUSED)999 unw_decode_b2 (const unsigned char *dp, unsigned int code,
1000 	       void *arg ATTRIBUTE_UNUSED)
1001 {
1002   unw_word t;
1003 
1004   t = unw_decode_uleb128 (& dp);
1005   UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1006   return dp;
1007 }
1008 
1009 static const unsigned char *
unw_decode_b3_x4(const unsigned char * dp,unsigned int code,void * arg)1010 unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg)
1011 {
1012   unw_word t, ecount, label;
1013 
1014   if ((code & 0x10) == 0)
1015     {
1016       t = unw_decode_uleb128 (&dp);
1017       ecount = unw_decode_uleb128 (&dp);
1018       UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1019     }
1020   else if ((code & 0x07) == 0)
1021     {
1022       label = unw_decode_uleb128 (&dp);
1023       if ((code & 0x08) != 0)
1024 	UNW_DEC_COPY_STATE ("B4", label, arg);
1025       else
1026 	UNW_DEC_LABEL_STATE ("B4", label, arg);
1027     }
1028   else
1029     switch (code & 0x7)
1030       {
1031       case 1:
1032 	return unw_decode_x1 (dp, code, arg);
1033       case 2:
1034 	return unw_decode_x2 (dp, code, arg);
1035       case 3:
1036 	return unw_decode_x3 (dp, code, arg);
1037       case 4:
1038 	return unw_decode_x4 (dp, code, arg);
1039       default:
1040 	UNW_DEC_BAD_CODE (code);
1041 	break;
1042       }
1043   return dp;
1044 }
1045 
1046 typedef const unsigned char *(*unw_decoder)
1047      (const unsigned char *, unsigned int, void *);
1048 
1049 static const unw_decoder unw_decode_table[2][8] =
1050   {
1051     /* prologue table: */
1052     {
1053       unw_decode_r1,		/* 0 */
1054       unw_decode_r1,
1055       unw_decode_r2,
1056       unw_decode_r3,
1057       unw_decode_p1,		/* 4 */
1058       unw_decode_p2_p5,
1059       unw_decode_p6,
1060       unw_decode_p7_p10
1061     },
1062     {
1063       unw_decode_r1,		/* 0 */
1064       unw_decode_r1,
1065       unw_decode_r2,
1066       unw_decode_r3,
1067       unw_decode_b1,		/* 4 */
1068       unw_decode_b1,
1069       unw_decode_b2,
1070       unw_decode_b3_x4
1071     }
1072   };
1073 
1074 /* Decode one descriptor and return address of next descriptor.  */
1075 const unsigned char *
unw_decode(const unsigned char * dp,int inside_body,void * ptr_inside_body)1076 unw_decode (const unsigned char *dp, int inside_body,
1077 	    void *ptr_inside_body)
1078 {
1079   unw_decoder decoder;
1080   unsigned char code;
1081 
1082   code = *dp++;
1083   decoder = unw_decode_table[inside_body][code >> 5];
1084   return (*decoder) (dp, code, ptr_inside_body);
1085 }
1086