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