Merge branch 'binutils-2_25-branch' of ssh://sourceware.org/git/binutils-gdb into...
[platform/upstream/binutils.git] / binutils / unwind-ia64.c
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
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)                                        \
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
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 }