ubsan: alpha-vma: timeout
[deliverable/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-2020 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 "sysdep.h"
25 #include "unwind-ia64.h"
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.
30 Only do this if we believe that the compiler can support a 64 bit
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
36 static bfd_vma unw_rlen = 0;
37
38 static void unw_print_brmask (char *, unsigned int);
39 static void unw_print_grmask (char *, unsigned int);
40 static void unw_print_frmask (char *, unsigned int);
41 static void unw_print_abreg (char *, unsigned int);
42 static void unw_print_xyreg (char *, unsigned int, unsigned int);
43
44 static void
45 unw_print_brmask (char *cp, unsigned int mask)
46 {
47 int sep = 0;
48 int i;
49
50 for (i = 0; mask && (i < 5); ++i)
51 {
52 if (mask & 1)
53 {
54 if (sep)
55 *cp++ = ',';
56 *cp++ = 'b';
57 *cp++ = i + 1 + '0';
58 sep = 1;
59 }
60 mask >>= 1;
61 }
62 *cp = '\0';
63 }
64
65 static void
66 unw_print_grmask (char *cp, unsigned int mask)
67 {
68 int sep = 0;
69 int i;
70
71 for (i = 0; i < 4; ++i)
72 {
73 if (mask & 1)
74 {
75 if (sep)
76 *cp++ = ',';
77 *cp++ = 'r';
78 *cp++ = i + 4 + '0';
79 sep = 1;
80 }
81 mask >>= 1;
82 }
83 *cp = '\0';
84 }
85
86 static void
87 unw_print_frmask (char *cp, unsigned int mask)
88 {
89 int sep = 0;
90 int i;
91
92 for (i = 0; i < 20; ++i)
93 {
94 if (mask & 1)
95 {
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;
107 }
108 mask >>= 1;
109 }
110 *cp = '\0';
111 }
112
113 static void
114 unw_print_abreg (char *cp, unsigned int abreg)
115 {
116 static const char * const special_reg[16] =
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
143 static void
144 unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg)
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
173 typedef bfd_vma unw_word;
174
175 #define UNW_DEC_BAD_CODE(code) \
176 printf (_("Unknown code 0x%02x\n"), code)
177
178 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
179 do \
180 { \
181 unw_rlen = rlen; \
182 *(int *)arg = body; \
183 printf (" %s:%s(rlen=%lu)\n", \
184 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
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); \
221 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
222 fmt, maskstr, regname, (unsigned long) rlen); \
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); \
232 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
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); \
242 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
243 } \
244 while (0)
245
246 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
247 do \
248 { \
249 char frstr[200], grstr[20]; \
250 \
251 unw_print_grmask (grstr, grmask); \
252 unw_print_frmask (frstr, frmask); \
253 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
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); \
263 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
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); \
273 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
274 } \
275 while (0)
276
277 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
278 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
279
280 #define UNW_DEC_RP_BR(fmt, dst, arg) \
281 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
282
283 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
284 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
285
286 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
287 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
288 fmt, reg, 4*(unsigned long)spoff)
289
290 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
291 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
292 fmt, reg, 4*(unsigned long)pspoff)
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); \
300 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
301 } \
302 while (0)
303
304 #define UNW_DEC_ABI(fmt, abi, context, arg) \
305 do \
306 { \
307 static const char * const abiname[] = \
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); \
318 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
319 fmt, abistr, context); \
320 } \
321 while (0)
322
323 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
324 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
325
326 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
327 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
328
329 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
330 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
331
332 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
333 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
334 fmt, 4*(unsigned long)pspoff)
335
336 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
337 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
338 fmt, 4*(unsigned long)spoff)
339
340 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
341 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
342 fmt, (unsigned long) t, 16*(unsigned long)size)
343
344 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
345 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
346
347 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
348 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
349 fmt, 4*(unsigned long)pspoff)
350
351 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
352 do \
353 { \
354 static const char *spill_type = "-frb"; \
355 unsigned const char *imaskp = dp; \
356 unsigned char mask = 0; \
357 bfd_vma insn = 0; \
358 \
359 /* PR 18420. */ \
360 if ((dp + (unw_rlen / 4)) > end) \
361 { \
362 printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
363 (long) (unw_rlen / 4), (long)(end - dp)); \
364 /* FIXME: Should we reset unw_rlen ? */ \
365 break; \
366 } \
367 printf ("\t%s:spill_mask(imask=[", fmt); \
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 { \
384 char regname[20]; \
385 \
386 unw_print_abreg (regname, abreg); \
387 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
388 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
389 } \
390 while (0)
391
392 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
393 do \
394 { \
395 char regname[20]; \
396 \
397 unw_print_abreg (regname, abreg); \
398 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
399 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
400 } \
401 while (0)
402
403 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
404 do \
405 { \
406 char regname[20]; \
407 \
408 unw_print_abreg (regname, abreg); \
409 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
410 fmt, (unsigned long) t, regname); \
411 } \
412 while (0)
413
414 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
415 do \
416 { \
417 char abregname[20], tregname[20]; \
418 \
419 unw_print_abreg (abregname, abreg); \
420 unw_print_xyreg (tregname, x, ytreg); \
421 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
422 fmt, (unsigned long) t, abregname, tregname); \
423 } \
424 while (0)
425
426 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
427 do \
428 { \
429 char regname[20]; \
430 \
431 unw_print_abreg (regname, abreg); \
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); \
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); \
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);\
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); \
454 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
455 fmt, qp, (unsigned long) t, regname); \
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); \
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); \
468 } \
469 while (0)
470
471 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
472 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
473
474 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
475 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
476
477 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
478 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
479 fmt, (unsigned long) t, (unsigned long) ecount)
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:
492 * unw_word Unsigned integer type with at least 64 bits
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
543 static unw_word
544 unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end)
545 {
546 unsigned shift = 0;
547 unw_word byte, result = 0;
548 const unsigned char *bp = *dpp;
549
550 while (bp < end)
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
566 static const unsigned char *
567 unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
568 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
569 {
570 unsigned char byte1, abreg;
571 unw_word t, off;
572
573 if ((end - dp) < 3)
574 {
575 printf (_("\t<corrupt X1>\n"));
576 return end;
577 }
578
579 byte1 = *dp++;
580 t = unw_decode_uleb128 (&dp, end);
581 off = unw_decode_uleb128 (&dp, end);
582 abreg = (byte1 & 0x7f);
583 if (byte1 & 0x80)
584 UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
585 else
586 UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
587 return dp;
588 }
589
590 static const unsigned char *
591 unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
592 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
593 {
594 unsigned char byte1, byte2, abreg, x, ytreg;
595 unw_word t;
596
597 if ((end - dp) < 3)
598 {
599 printf (_("\t<corrupt X2>\n"));
600 return end;
601 }
602
603 byte1 = *dp++;
604 byte2 = *dp++;
605 t = unw_decode_uleb128 (&dp, end);
606 abreg = (byte1 & 0x7f);
607 ytreg = byte2;
608 x = (byte1 >> 7) & 1;
609 if ((byte1 & 0x80) == 0 && ytreg == 0)
610 UNW_DEC_RESTORE ("X2", t, abreg, arg);
611 else
612 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
613 return dp;
614 }
615
616 static const unsigned char *
617 unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
618 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
619 {
620 unsigned char byte1, byte2, abreg, qp;
621 unw_word t, off;
622
623 if ((end - dp) < 4)
624 {
625 printf (_("\t<corrupt X3>\n"));
626 return end;
627 }
628
629 byte1 = *dp++;
630 byte2 = *dp++;
631 t = unw_decode_uleb128 (&dp, end);
632 off = unw_decode_uleb128 (&dp, end);
633
634 qp = (byte1 & 0x3f);
635 abreg = (byte2 & 0x7f);
636
637 if (byte1 & 0x80)
638 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
639 else
640 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
641 return dp;
642 }
643
644 static const unsigned char *
645 unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
646 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
647 {
648 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
649 unw_word t;
650
651 if ((end - dp) < 4)
652 {
653 printf (_("\t<corrupt X4>\n"));
654 return end;
655 }
656
657 byte1 = *dp++;
658 byte2 = *dp++;
659 byte3 = *dp++;
660 t = unw_decode_uleb128 (&dp, end);
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 const unsigned char * end ATTRIBUTE_UNUSED)
677 {
678 int body = (code & 0x20) != 0;
679 unw_word rlen;
680
681 rlen = (code & 0x1f);
682 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
683 return dp;
684 }
685
686 static const unsigned char *
687 unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
688 const unsigned char * end)
689 {
690 unsigned char byte1, mask, grsave;
691 unw_word rlen;
692
693 if ((end - dp) < 2)
694 {
695 printf (_("\t<corrupt R2>\n"));
696 return end;
697 }
698
699 byte1 = *dp++;
700
701 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
702 grsave = (byte1 & 0x7f);
703 rlen = unw_decode_uleb128 (& dp, end);
704 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
705 return dp;
706 }
707
708 static const unsigned char *
709 unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
710 const unsigned char * end)
711 {
712 unw_word rlen;
713
714 rlen = unw_decode_uleb128 (& dp, end);
715 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
716 return dp;
717 }
718
719 static const unsigned char *
720 unw_decode_p1 (const unsigned char *dp, unsigned int code,
721 void *arg ATTRIBUTE_UNUSED,
722 const unsigned char * end ATTRIBUTE_UNUSED)
723 {
724 unsigned char brmask = (code & 0x1f);
725
726 UNW_DEC_BR_MEM ("P1", brmask, arg);
727 return dp;
728 }
729
730 static const unsigned char *
731 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
732 void *arg ATTRIBUTE_UNUSED,
733 const unsigned char * end)
734 {
735 if ((code & 0x10) == 0)
736 {
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++;
746
747 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
748 (byte1 & 0x7f), arg);
749 }
750 else if ((code & 0x08) == 0)
751 {
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++;
761
762 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
763 dst = (byte1 & 0x7f);
764 switch (r)
765 {
766 case 0:
767 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
768 break;
769 case 1:
770 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
771 break;
772 case 2:
773 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
774 break;
775 case 3:
776 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
777 break;
778 case 4:
779 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
780 break;
781 case 5:
782 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
783 break;
784 case 6:
785 UNW_DEC_RP_BR ("P3", dst, arg);
786 break;
787 case 7:
788 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
789 break;
790 case 8:
791 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
792 break;
793 case 9:
794 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
795 break;
796 case 10:
797 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
798 break;
799 case 11:
800 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
801 break;
802 default:
803 UNW_DEC_BAD_CODE (r);
804 break;
805 }
806 }
807 else if ((code & 0x7) == 0)
808 UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
809 else if ((code & 0x7) == 1)
810 {
811 unw_word grmask, frmask, byte1, byte2, byte3;
812
813 if ((end - dp) < 3)
814 {
815 printf (_("\t<corrupt P5>\n"));
816 return end;
817 }
818 byte1 = *dp++;
819 byte2 = *dp++;
820 byte3 = *dp++;
821 grmask = ((byte1 >> 4) & 0xf);
822 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
823 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
824 }
825 else
826 UNW_DEC_BAD_CODE (code);
827
828 return dp;
829 }
830
831 static const unsigned char *
832 unw_decode_p6 (const unsigned char *dp, unsigned int code,
833 void *arg ATTRIBUTE_UNUSED,
834 const unsigned char * end ATTRIBUTE_UNUSED)
835 {
836 int gregs = (code & 0x10) != 0;
837 unsigned char mask = (code & 0x0f);
838
839 if (gregs)
840 UNW_DEC_GR_MEM ("P6", mask, arg);
841 else
842 UNW_DEC_FR_MEM ("P6", mask, arg);
843 return dp;
844 }
845
846 static const unsigned char *
847 unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
848 const unsigned char * end)
849 {
850 unsigned char r, byte1, byte2;
851 unw_word t, size;
852
853 if ((code & 0x10) == 0)
854 {
855 r = (code & 0xf);
856 t = unw_decode_uleb128 (&dp, end);
857 switch (r)
858 {
859 case 0:
860 size = unw_decode_uleb128 (&dp, end);
861 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
862 break;
863
864 case 1:
865 UNW_DEC_MEM_STACK_V ("P7", t, arg);
866 break;
867 case 2:
868 UNW_DEC_SPILL_BASE ("P7", t, arg);
869 break;
870 case 3:
871 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
872 break;
873 case 4:
874 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
875 break;
876 case 5:
877 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
878 break;
879 case 6:
880 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
881 break;
882 case 7:
883 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
884 break;
885 case 8:
886 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
887 break;
888 case 9:
889 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
890 break;
891 case 10:
892 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
893 break;
894 case 11:
895 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
896 break;
897 case 12:
898 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
899 break;
900 case 13:
901 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
902 break;
903 case 14:
904 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
905 break;
906 case 15:
907 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
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 {
920 if ((end - dp) < 2)
921 {
922 printf (_("\t<corrupt P8>\n"));
923 return end;
924 }
925
926 r = *dp++;
927 t = unw_decode_uleb128 (&dp, end);
928 switch (r)
929 {
930 case 1:
931 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
932 break;
933 case 2:
934 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
935 break;
936 case 3:
937 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
938 break;
939 case 4:
940 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
941 break;
942 case 5:
943 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
944 break;
945 case 6:
946 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
947 break;
948 case 7:
949 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
950 break;
951 case 8:
952 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
953 break;
954 case 9:
955 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
956 break;
957 case 10:
958 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
959 break;
960 case 11:
961 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
962 break;
963 case 12:
964 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
965 break;
966 case 13:
967 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
968 break;
969 case 14:
970 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
971 break;
972 case 15:
973 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
974 break;
975 case 16:
976 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
977 break;
978 case 17:
979 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
980 break;
981 case 18:
982 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
983 break;
984 case 19:
985 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
986 break;
987 default:
988 UNW_DEC_BAD_CODE (r);
989 break;
990 }
991 }
992 break;
993
994 case 0x1:
995 if ((end - dp) < 2)
996 {
997 printf (_("\t<corrupt P9>\n"));
998 return end;
999 }
1000
1001 byte1 = *dp++;
1002 byte2 = *dp++;
1003 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
1004 break;
1005
1006 case 0xf: /* p10 */
1007 if ((end - dp) < 2)
1008 {
1009 printf (_("\t<corrupt P10>\n"));
1010 return end;
1011 }
1012
1013 byte1 = *dp++;
1014 byte2 = *dp++;
1015 UNW_DEC_ABI ("P10", byte1, byte2, arg);
1016 break;
1017
1018 case 0x9:
1019 return unw_decode_x1 (dp, code, arg, end);
1020
1021 case 0xa:
1022 return unw_decode_x2 (dp, code, arg, end);
1023
1024 case 0xb:
1025 return unw_decode_x3 (dp, code, arg, end);
1026
1027 case 0xc:
1028 return unw_decode_x4 (dp, code, arg, end);
1029
1030 default:
1031 UNW_DEC_BAD_CODE (code);
1032 break;
1033 }
1034 }
1035 return dp;
1036 }
1037
1038 static const unsigned char *
1039 unw_decode_b1 (const unsigned char *dp, unsigned int code,
1040 void *arg ATTRIBUTE_UNUSED,
1041 const unsigned char * end ATTRIBUTE_UNUSED)
1042 {
1043 unw_word label = (code & 0x1f);
1044
1045 if ((code & 0x20) != 0)
1046 UNW_DEC_COPY_STATE ("B1", label, arg);
1047 else
1048 UNW_DEC_LABEL_STATE ("B1", label, arg);
1049 return dp;
1050 }
1051
1052 static const unsigned char *
1053 unw_decode_b2 (const unsigned char *dp, unsigned int code,
1054 void *arg ATTRIBUTE_UNUSED,
1055 const unsigned char * end)
1056 {
1057 unw_word t;
1058
1059 t = unw_decode_uleb128 (& dp, end);
1060 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1061 return dp;
1062 }
1063
1064 static const unsigned char *
1065 unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
1066 const unsigned char * end)
1067 {
1068 unw_word t, ecount, label;
1069
1070 if ((code & 0x10) == 0)
1071 {
1072 t = unw_decode_uleb128 (&dp, end);
1073 ecount = unw_decode_uleb128 (&dp, end);
1074 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1075 }
1076 else if ((code & 0x07) == 0)
1077 {
1078 label = unw_decode_uleb128 (&dp, end);
1079 if ((code & 0x08) != 0)
1080 UNW_DEC_COPY_STATE ("B4", label, arg);
1081 else
1082 UNW_DEC_LABEL_STATE ("B4", label, arg);
1083 }
1084 else
1085 switch (code & 0x7)
1086 {
1087 case 1:
1088 return unw_decode_x1 (dp, code, arg, end);
1089 case 2:
1090 return unw_decode_x2 (dp, code, arg, end);
1091 case 3:
1092 return unw_decode_x3 (dp, code, arg, end);
1093 case 4:
1094 return unw_decode_x4 (dp, code, arg, end);
1095 default:
1096 UNW_DEC_BAD_CODE (code);
1097 break;
1098 }
1099 return dp;
1100 }
1101
1102 typedef const unsigned char *(*unw_decoder)
1103 (const unsigned char *, unsigned int, void *, const unsigned char *);
1104
1105 static const unw_decoder unw_decode_table[2][8] =
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. */
1131 const unsigned char *
1132 unw_decode (const unsigned char *dp, int inside_body,
1133 void *ptr_inside_body, const unsigned char * end)
1134 {
1135 unw_decoder decoder;
1136 unsigned char code;
1137
1138 if ((end - dp) < 1)
1139 {
1140 printf (_("\t<corrupt IA64 descriptor>\n"));
1141 return end;
1142 }
1143
1144 code = *dp++;
1145 decoder = unw_decode_table[inside_body][code >> 5];
1146 return (*decoder) (dp, code, ptr_inside_body, end);
1147 }
This page took 0.05329 seconds and 4 git commands to generate.