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