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