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