gdb: add target_ops::supports_displaced_step
[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;
60e63c3e 547 int status = 1;
4d6ed7c8
NC
548 unw_word byte, result = 0;
549 const unsigned char *bp = *dpp;
550
171375c6 551 while (bp < end)
4d6ed7c8
NC
552 {
553 byte = *bp++;
60e63c3e
AM
554 if (shift < sizeof (result) * 8)
555 {
556 result |= (byte & 0x7f) << shift;
557 if ((result >> shift) != (byte & 0x7f))
558 /* Overflow. */
559 status |= 2;
560 shift += 7;
561 }
562 else if ((byte & 0x7f) != 0)
563 status |= 2;
4d6ed7c8
NC
564
565 if ((byte & 0x80) == 0)
60e63c3e
AM
566 {
567 status &= ~1;
568 break;
569 }
4d6ed7c8
NC
570 }
571
572 *dpp = bp;
60e63c3e
AM
573 if (status != 0)
574 printf (_("Bad uleb128\n"));
4d6ed7c8
NC
575
576 return result;
577}
578
579static const unsigned char *
2da42df6 580unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
171375c6 581 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
4d6ed7c8
NC
582{
583 unsigned char byte1, abreg;
584 unw_word t, off;
585
5cacf1c8
NC
586 if ((end - dp) < 3)
587 {
588 printf (_("\t<corrupt X1>\n"));
589 return end;
590 }
591
4d6ed7c8 592 byte1 = *dp++;
171375c6
NC
593 t = unw_decode_uleb128 (&dp, end);
594 off = unw_decode_uleb128 (&dp, end);
4d6ed7c8
NC
595 abreg = (byte1 & 0x7f);
596 if (byte1 & 0x80)
3c44da9a 597 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
4d6ed7c8 598 else
3c44da9a 599 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
4d6ed7c8
NC
600 return dp;
601}
602
603static const unsigned char *
2da42df6 604unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
171375c6 605 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
4d6ed7c8
NC
606{
607 unsigned char byte1, byte2, abreg, x, ytreg;
608 unw_word t;
609
5cacf1c8
NC
610 if ((end - dp) < 3)
611 {
612 printf (_("\t<corrupt X2>\n"));
613 return end;
614 }
615
4d6ed7c8
NC
616 byte1 = *dp++;
617 byte2 = *dp++;
171375c6 618 t = unw_decode_uleb128 (&dp, end);
4d6ed7c8
NC
619 abreg = (byte1 & 0x7f);
620 ytreg = byte2;
621 x = (byte1 >> 7) & 1;
622 if ((byte1 & 0x80) == 0 && ytreg == 0)
3c44da9a 623 UNW_DEC_RESTORE ("X2", t, abreg, arg);
4d6ed7c8 624 else
3c44da9a 625 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
4d6ed7c8
NC
626 return dp;
627}
628
629static const unsigned char *
2da42df6 630unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
171375c6 631 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
4d6ed7c8
NC
632{
633 unsigned char byte1, byte2, abreg, qp;
634 unw_word t, off;
635
5cacf1c8
NC
636 if ((end - dp) < 4)
637 {
638 printf (_("\t<corrupt X3>\n"));
639 return end;
640 }
641
4d6ed7c8
NC
642 byte1 = *dp++;
643 byte2 = *dp++;
171375c6
NC
644 t = unw_decode_uleb128 (&dp, end);
645 off = unw_decode_uleb128 (&dp, end);
4d6ed7c8
NC
646
647 qp = (byte1 & 0x3f);
648 abreg = (byte2 & 0x7f);
649
650 if (byte1 & 0x80)
3c44da9a 651 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
4d6ed7c8 652 else
3c44da9a 653 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
4d6ed7c8
NC
654 return dp;
655}
656
657static const unsigned char *
2da42df6 658unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
171375c6 659 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
4d6ed7c8
NC
660{
661 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
662 unw_word t;
663
5cacf1c8
NC
664 if ((end - dp) < 4)
665 {
666 printf (_("\t<corrupt X4>\n"));
667 return end;
668 }
669
4d6ed7c8
NC
670 byte1 = *dp++;
671 byte2 = *dp++;
672 byte3 = *dp++;
171375c6 673 t = unw_decode_uleb128 (&dp, end);
4d6ed7c8
NC
674
675 qp = (byte1 & 0x3f);
676 abreg = (byte2 & 0x7f);
677 x = (byte2 >> 7) & 1;
678 ytreg = byte3;
679
680 if ((byte2 & 0x80) == 0 && byte3 == 0)
3c44da9a 681 UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
4d6ed7c8 682 else
3c44da9a 683 UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
4d6ed7c8
NC
684 return dp;
685}
686
687static const unsigned char *
b4477bc8
NC
688unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg,
689 const unsigned char * end ATTRIBUTE_UNUSED)
4d6ed7c8
NC
690{
691 int body = (code & 0x20) != 0;
692 unw_word rlen;
693
694 rlen = (code & 0x1f);
3c44da9a 695 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
4d6ed7c8
NC
696 return dp;
697}
698
699static const unsigned char *
b4477bc8 700unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
171375c6 701 const unsigned char * end)
4d6ed7c8
NC
702{
703 unsigned char byte1, mask, grsave;
704 unw_word rlen;
705
5cacf1c8
NC
706 if ((end - dp) < 2)
707 {
708 printf (_("\t<corrupt R2>\n"));
709 return end;
710 }
711
4d6ed7c8
NC
712 byte1 = *dp++;
713
714 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
715 grsave = (byte1 & 0x7f);
171375c6 716 rlen = unw_decode_uleb128 (& dp, end);
3c44da9a 717 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
4d6ed7c8
NC
718 return dp;
719}
720
721static const unsigned char *
b4477bc8 722unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
171375c6 723 const unsigned char * end)
4d6ed7c8
NC
724{
725 unw_word rlen;
726
171375c6 727 rlen = unw_decode_uleb128 (& dp, end);
3c44da9a 728 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
4d6ed7c8
NC
729 return dp;
730}
731
732static const unsigned char *
2da42df6 733unw_decode_p1 (const unsigned char *dp, unsigned int code,
b4477bc8
NC
734 void *arg ATTRIBUTE_UNUSED,
735 const unsigned char * end ATTRIBUTE_UNUSED)
4d6ed7c8
NC
736{
737 unsigned char brmask = (code & 0x1f);
738
3c44da9a 739 UNW_DEC_BR_MEM ("P1", brmask, arg);
4d6ed7c8
NC
740 return dp;
741}
742
743static const unsigned char *
2da42df6 744unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
b4477bc8
NC
745 void *arg ATTRIBUTE_UNUSED,
746 const unsigned char * end)
4d6ed7c8
NC
747{
748 if ((code & 0x10) == 0)
749 {
5cacf1c8
NC
750 unsigned char byte1;
751
752 if ((end - dp) < 1)
753 {
754 printf (_("\t<corrupt P2>\n"));
755 return end;
756 }
757
758 byte1 = *dp++;
4d6ed7c8 759
3c44da9a 760 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
4d6ed7c8
NC
761 (byte1 & 0x7f), arg);
762 }
763 else if ((code & 0x08) == 0)
764 {
5cacf1c8
NC
765 unsigned char byte1, r, dst;
766
767 if ((end - dp) < 1)
768 {
769 printf (_("\t<corrupt P3>\n"));
770 return end;
771 }
772
773 byte1 = *dp++;
4d6ed7c8
NC
774
775 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
776 dst = (byte1 & 0x7f);
777 switch (r)
778 {
779 case 0:
3c44da9a 780 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
4d6ed7c8
NC
781 break;
782 case 1:
3c44da9a 783 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
4d6ed7c8
NC
784 break;
785 case 2:
3c44da9a 786 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
4d6ed7c8
NC
787 break;
788 case 3:
3c44da9a 789 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
4d6ed7c8
NC
790 break;
791 case 4:
3c44da9a 792 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
4d6ed7c8
NC
793 break;
794 case 5:
3c44da9a 795 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
4d6ed7c8
NC
796 break;
797 case 6:
3c44da9a 798 UNW_DEC_RP_BR ("P3", dst, arg);
4d6ed7c8
NC
799 break;
800 case 7:
3c44da9a 801 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
4d6ed7c8
NC
802 break;
803 case 8:
3c44da9a 804 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
4d6ed7c8
NC
805 break;
806 case 9:
3c44da9a 807 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
4d6ed7c8
NC
808 break;
809 case 10:
3c44da9a 810 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
4d6ed7c8
NC
811 break;
812 case 11:
3c44da9a 813 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
4d6ed7c8
NC
814 break;
815 default:
816 UNW_DEC_BAD_CODE (r);
817 break;
818 }
819 }
820 else if ((code & 0x7) == 0)
b4477bc8 821 UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
4d6ed7c8
NC
822 else if ((code & 0x7) == 1)
823 {
824 unw_word grmask, frmask, byte1, byte2, byte3;
825
5cacf1c8
NC
826 if ((end - dp) < 3)
827 {
828 printf (_("\t<corrupt P5>\n"));
829 return end;
830 }
4d6ed7c8
NC
831 byte1 = *dp++;
832 byte2 = *dp++;
833 byte3 = *dp++;
834 grmask = ((byte1 >> 4) & 0xf);
835 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
3c44da9a 836 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
4d6ed7c8
NC
837 }
838 else
839 UNW_DEC_BAD_CODE (code);
840
841 return dp;
842}
843
844static const unsigned char *
2da42df6 845unw_decode_p6 (const unsigned char *dp, unsigned int code,
b4477bc8
NC
846 void *arg ATTRIBUTE_UNUSED,
847 const unsigned char * end ATTRIBUTE_UNUSED)
4d6ed7c8
NC
848{
849 int gregs = (code & 0x10) != 0;
850 unsigned char mask = (code & 0x0f);
851
852 if (gregs)
3c44da9a 853 UNW_DEC_GR_MEM ("P6", mask, arg);
4d6ed7c8 854 else
3c44da9a 855 UNW_DEC_FR_MEM ("P6", mask, arg);
4d6ed7c8
NC
856 return dp;
857}
858
859static const unsigned char *
b4477bc8 860unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
171375c6 861 const unsigned char * end)
4d6ed7c8
NC
862{
863 unsigned char r, byte1, byte2;
864 unw_word t, size;
865
866 if ((code & 0x10) == 0)
867 {
868 r = (code & 0xf);
171375c6 869 t = unw_decode_uleb128 (&dp, end);
4d6ed7c8
NC
870 switch (r)
871 {
872 case 0:
171375c6 873 size = unw_decode_uleb128 (&dp, end);
3c44da9a 874 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
4d6ed7c8
NC
875 break;
876
877 case 1:
3c44da9a 878 UNW_DEC_MEM_STACK_V ("P7", t, arg);
4d6ed7c8
NC
879 break;
880 case 2:
3c44da9a 881 UNW_DEC_SPILL_BASE ("P7", t, arg);
4d6ed7c8
NC
882 break;
883 case 3:
3c44da9a 884 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
4d6ed7c8
NC
885 break;
886 case 4:
3c44da9a 887 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
4d6ed7c8
NC
888 break;
889 case 5:
3c44da9a 890 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
4d6ed7c8
NC
891 break;
892 case 6:
3c44da9a 893 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
4d6ed7c8
NC
894 break;
895 case 7:
3c44da9a 896 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
4d6ed7c8
NC
897 break;
898 case 8:
3c44da9a 899 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
4d6ed7c8
NC
900 break;
901 case 9:
3c44da9a 902 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
4d6ed7c8
NC
903 break;
904 case 10:
3c44da9a 905 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
4d6ed7c8
NC
906 break;
907 case 11:
3c44da9a 908 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
4d6ed7c8
NC
909 break;
910 case 12:
3c44da9a 911 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
4d6ed7c8
NC
912 break;
913 case 13:
3c44da9a 914 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
4d6ed7c8
NC
915 break;
916 case 14:
3c44da9a 917 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
4d6ed7c8
NC
918 break;
919 case 15:
3c44da9a 920 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
4d6ed7c8
NC
921 break;
922 default:
923 UNW_DEC_BAD_CODE (r);
924 break;
925 }
926 }
927 else
928 {
929 switch (code & 0xf)
930 {
931 case 0x0: /* p8 */
932 {
5cacf1c8
NC
933 if ((end - dp) < 2)
934 {
935 printf (_("\t<corrupt P8>\n"));
936 return end;
937 }
938
4d6ed7c8 939 r = *dp++;
171375c6 940 t = unw_decode_uleb128 (&dp, end);
4d6ed7c8
NC
941 switch (r)
942 {
943 case 1:
3c44da9a 944 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
4d6ed7c8
NC
945 break;
946 case 2:
3c44da9a 947 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
4d6ed7c8
NC
948 break;
949 case 3:
3c44da9a 950 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
4d6ed7c8
NC
951 break;
952 case 4:
3c44da9a 953 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
4d6ed7c8
NC
954 break;
955 case 5:
3c44da9a 956 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
4d6ed7c8
NC
957 break;
958 case 6:
3c44da9a 959 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
4d6ed7c8
NC
960 break;
961 case 7:
3c44da9a 962 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
4d6ed7c8
NC
963 break;
964 case 8:
3c44da9a 965 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
4d6ed7c8
NC
966 break;
967 case 9:
3c44da9a 968 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
4d6ed7c8
NC
969 break;
970 case 10:
3c44da9a 971 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
4d6ed7c8
NC
972 break;
973 case 11:
3c44da9a 974 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
4d6ed7c8
NC
975 break;
976 case 12:
3c44da9a 977 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
4d6ed7c8
NC
978 break;
979 case 13:
3c44da9a 980 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
4d6ed7c8
NC
981 break;
982 case 14:
3c44da9a 983 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
4d6ed7c8
NC
984 break;
985 case 15:
3c44da9a 986 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
4d6ed7c8
NC
987 break;
988 case 16:
3c44da9a 989 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
4d6ed7c8
NC
990 break;
991 case 17:
3c44da9a 992 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
4d6ed7c8
NC
993 break;
994 case 18:
3c44da9a 995 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
4d6ed7c8
NC
996 break;
997 case 19:
3c44da9a 998 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
4d6ed7c8
NC
999 break;
1000 default:
1001 UNW_DEC_BAD_CODE (r);
1002 break;
1003 }
1004 }
1005 break;
1006
1007 case 0x1:
5cacf1c8
NC
1008 if ((end - dp) < 2)
1009 {
1010 printf (_("\t<corrupt P9>\n"));
1011 return end;
1012 }
1013
4d6ed7c8
NC
1014 byte1 = *dp++;
1015 byte2 = *dp++;
3c44da9a 1016 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
4d6ed7c8
NC
1017 break;
1018
1019 case 0xf: /* p10 */
5cacf1c8
NC
1020 if ((end - dp) < 2)
1021 {
1022 printf (_("\t<corrupt P10>\n"));
1023 return end;
1024 }
1025
4d6ed7c8
NC
1026 byte1 = *dp++;
1027 byte2 = *dp++;
3c44da9a 1028 UNW_DEC_ABI ("P10", byte1, byte2, arg);
4d6ed7c8
NC
1029 break;
1030
1031 case 0x9:
171375c6 1032 return unw_decode_x1 (dp, code, arg, end);
4d6ed7c8
NC
1033
1034 case 0xa:
171375c6 1035 return unw_decode_x2 (dp, code, arg, end);
4d6ed7c8
NC
1036
1037 case 0xb:
171375c6 1038 return unw_decode_x3 (dp, code, arg, end);
4d6ed7c8
NC
1039
1040 case 0xc:
171375c6 1041 return unw_decode_x4 (dp, code, arg, end);
4d6ed7c8
NC
1042
1043 default:
1044 UNW_DEC_BAD_CODE (code);
1045 break;
1046 }
1047 }
1048 return dp;
1049}
1050
1051static const unsigned char *
2da42df6 1052unw_decode_b1 (const unsigned char *dp, unsigned int code,
b4477bc8
NC
1053 void *arg ATTRIBUTE_UNUSED,
1054 const unsigned char * end ATTRIBUTE_UNUSED)
4d6ed7c8
NC
1055{
1056 unw_word label = (code & 0x1f);
1057
1058 if ((code & 0x20) != 0)
3c44da9a 1059 UNW_DEC_COPY_STATE ("B1", label, arg);
4d6ed7c8 1060 else
3c44da9a 1061 UNW_DEC_LABEL_STATE ("B1", label, arg);
4d6ed7c8
NC
1062 return dp;
1063}
1064
1065static const unsigned char *
2da42df6 1066unw_decode_b2 (const unsigned char *dp, unsigned int code,
b4477bc8 1067 void *arg ATTRIBUTE_UNUSED,
171375c6 1068 const unsigned char * end)
4d6ed7c8
NC
1069{
1070 unw_word t;
1071
171375c6 1072 t = unw_decode_uleb128 (& dp, end);
3c44da9a 1073 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
4d6ed7c8
NC
1074 return dp;
1075}
1076
1077static const unsigned char *
b4477bc8 1078unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
171375c6 1079 const unsigned char * end)
4d6ed7c8
NC
1080{
1081 unw_word t, ecount, label;
1082
1083 if ((code & 0x10) == 0)
1084 {
171375c6
NC
1085 t = unw_decode_uleb128 (&dp, end);
1086 ecount = unw_decode_uleb128 (&dp, end);
3c44da9a 1087 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
4d6ed7c8
NC
1088 }
1089 else if ((code & 0x07) == 0)
1090 {
171375c6 1091 label = unw_decode_uleb128 (&dp, end);
4d6ed7c8 1092 if ((code & 0x08) != 0)
3c44da9a 1093 UNW_DEC_COPY_STATE ("B4", label, arg);
4d6ed7c8 1094 else
3c44da9a 1095 UNW_DEC_LABEL_STATE ("B4", label, arg);
4d6ed7c8
NC
1096 }
1097 else
1098 switch (code & 0x7)
1099 {
1100 case 1:
171375c6 1101 return unw_decode_x1 (dp, code, arg, end);
4d6ed7c8 1102 case 2:
171375c6 1103 return unw_decode_x2 (dp, code, arg, end);
4d6ed7c8 1104 case 3:
171375c6 1105 return unw_decode_x3 (dp, code, arg, end);
4d6ed7c8 1106 case 4:
171375c6 1107 return unw_decode_x4 (dp, code, arg, end);
4d6ed7c8
NC
1108 default:
1109 UNW_DEC_BAD_CODE (code);
1110 break;
1111 }
1112 return dp;
1113}
1114
1115typedef const unsigned char *(*unw_decoder)
b4477bc8 1116 (const unsigned char *, unsigned int, void *, const unsigned char *);
4d6ed7c8 1117
9bcd0325 1118static const unw_decoder unw_decode_table[2][8] =
4d6ed7c8
NC
1119 {
1120 /* prologue table: */
1121 {
1122 unw_decode_r1, /* 0 */
1123 unw_decode_r1,
1124 unw_decode_r2,
1125 unw_decode_r3,
1126 unw_decode_p1, /* 4 */
1127 unw_decode_p2_p5,
1128 unw_decode_p6,
1129 unw_decode_p7_p10
1130 },
1131 {
1132 unw_decode_r1, /* 0 */
1133 unw_decode_r1,
1134 unw_decode_r2,
1135 unw_decode_r3,
1136 unw_decode_b1, /* 4 */
1137 unw_decode_b1,
1138 unw_decode_b2,
1139 unw_decode_b3_x4
1140 }
1141 };
1142
1143/* Decode one descriptor and return address of next descriptor. */
1144const unsigned char *
2da42df6 1145unw_decode (const unsigned char *dp, int inside_body,
b4477bc8 1146 void *ptr_inside_body, const unsigned char * end)
4d6ed7c8
NC
1147{
1148 unw_decoder decoder;
1149 unsigned char code;
1150
5cacf1c8
NC
1151 if ((end - dp) < 1)
1152 {
1153 printf (_("\t<corrupt IA64 descriptor>\n"));
1154 return end;
1155 }
1156
4d6ed7c8
NC
1157 code = *dp++;
1158 decoder = unw_decode_table[inside_body][code >> 5];
b4477bc8 1159 return (*decoder) (dp, code, ptr_inside_body, end);
4d6ed7c8 1160}
This page took 0.834589 seconds and 4 git commands to generate.