OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [unwind-ia64.c] - Blame information for rev 58

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.