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