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