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