gdb: fix vfork with multiple threads
[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-2021 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 default:
161 strcpy (cp, "invalid");
162 break;
163 }
164 }
165
166 #define UNW_REG_BSP "bsp"
167 #define UNW_REG_BSPSTORE "bspstore"
168 #define UNW_REG_FPSR "fpsr"
169 #define UNW_REG_LC "lc"
170 #define UNW_REG_PFS "pfs"
171 #define UNW_REG_PR "pr"
172 #define UNW_REG_PSP "psp"
173 #define UNW_REG_RNAT "rnat"
174 #define UNW_REG_RP "rp"
175 #define UNW_REG_UNAT "unat"
176
177 typedef bfd_vma unw_word;
178
179 #define UNW_DEC_BAD_CODE(code) \
180 printf (_("Unknown code 0x%02x\n"), code)
181
182 #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
183 do \
184 { \
185 unw_rlen = rlen; \
186 *(int *)arg = body; \
187 printf (" %s:%s(rlen=%lu)\n", \
188 fmt, body ? "body" : "prologue", (unsigned long) rlen); \
189 } \
190 while (0)
191
192 #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
193 do \
194 { \
195 char regname[16], maskstr[64], *sep; \
196 \
197 unw_rlen = rlen; \
198 *(int *)arg = 0; \
199 \
200 maskstr[0] = '\0'; \
201 sep = ""; \
202 if (mask & 0x8) \
203 { \
204 strcat (maskstr, "rp"); \
205 sep = ","; \
206 } \
207 if (mask & 0x4) \
208 { \
209 strcat (maskstr, sep); \
210 strcat (maskstr, "ar.pfs"); \
211 sep = ","; \
212 } \
213 if (mask & 0x2) \
214 { \
215 strcat (maskstr, sep); \
216 strcat (maskstr, "psp"); \
217 sep = ","; \
218 } \
219 if (mask & 0x1) \
220 { \
221 strcat (maskstr, sep); \
222 strcat (maskstr, "pr"); \
223 } \
224 sprintf (regname, "r%u", grsave); \
225 printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
226 fmt, maskstr, regname, (unsigned long) rlen); \
227 } \
228 while (0)
229
230 #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
231 do \
232 { \
233 char frstr[200]; \
234 \
235 unw_print_frmask (frstr, frmask); \
236 printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
237 } \
238 while (0)
239
240 #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
241 do \
242 { \
243 char grstr[200]; \
244 \
245 unw_print_grmask (grstr, grmask); \
246 printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
247 } \
248 while (0)
249
250 #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
251 do \
252 { \
253 char frstr[200], grstr[20]; \
254 \
255 unw_print_grmask (grstr, grmask); \
256 unw_print_frmask (frstr, frmask); \
257 printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
258 } \
259 while (0)
260
261 #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
262 do \
263 { \
264 char brstr[20]; \
265 \
266 unw_print_brmask (brstr, brmask); \
267 printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
268 } \
269 while (0)
270
271 #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
272 do \
273 { \
274 char brstr[20]; \
275 \
276 unw_print_brmask (brstr, brmask); \
277 printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
278 } \
279 while (0)
280
281 #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
282 printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
283
284 #define UNW_DEC_RP_BR(fmt, dst, arg) \
285 printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
286
287 #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
288 printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
289
290 #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
291 printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
292 fmt, reg, 4*(unsigned long)spoff)
293
294 #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
295 printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
296 fmt, reg, 4*(unsigned long)pspoff)
297
298 #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
299 do \
300 { \
301 char grstr[20]; \
302 \
303 unw_print_grmask (grstr, grmask); \
304 printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
305 } \
306 while (0)
307
308 #define UNW_DEC_ABI(fmt, abi, context, arg) \
309 do \
310 { \
311 static const char * const abiname[] = \
312 { \
313 "@svr4", "@hpux", "@nt" \
314 }; \
315 char buf[20]; \
316 const char *abistr = buf; \
317 \
318 if (abi < 3) \
319 abistr = abiname[abi]; \
320 else \
321 sprintf (buf, "0x%x", abi); \
322 printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
323 fmt, abistr, context); \
324 } \
325 while (0)
326
327 #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
328 printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
329
330 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
331 printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
332
333 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
334 printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
335
336 #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
337 printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
338 fmt, 4*(unsigned long)pspoff)
339
340 #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
341 printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
342 fmt, 4*(unsigned long)spoff)
343
344 #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
345 printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
346 fmt, (unsigned long) t, 16*(unsigned long)size)
347
348 #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
349 printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
350
351 #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
352 printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
353 fmt, 4*(unsigned long)pspoff)
354
355 #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
356 do \
357 { \
358 static const char *spill_type = "-frb"; \
359 unsigned const char *imaskp = dp; \
360 unsigned char mask = 0; \
361 bfd_vma insn = 0; \
362 \
363 /* PR 18420. */ \
364 if ((dp + (unw_rlen / 4)) > end) \
365 { \
366 printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
367 (long) (unw_rlen / 4), (long)(end - dp)); \
368 /* FIXME: Should we reset unw_rlen ? */ \
369 break; \
370 } \
371 printf ("\t%s:spill_mask(imask=[", fmt); \
372 for (insn = 0; insn < unw_rlen; ++insn) \
373 { \
374 if ((insn % 4) == 0) \
375 mask = *imaskp++; \
376 if (insn > 0 && (insn % 3) == 0) \
377 putchar (','); \
378 putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
379 } \
380 printf ("])\n"); \
381 dp = imaskp; \
382 } \
383 while (0)
384
385 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
386 do \
387 { \
388 char regname[20]; \
389 \
390 unw_print_abreg (regname, abreg); \
391 printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
392 fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
393 } \
394 while (0)
395
396 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
397 do \
398 { \
399 char regname[20]; \
400 \
401 unw_print_abreg (regname, abreg); \
402 printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
403 fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
404 } \
405 while (0)
406
407 #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
408 do \
409 { \
410 char regname[20]; \
411 \
412 unw_print_abreg (regname, abreg); \
413 printf ("\t%s:restore(t=%lu,reg=%s)\n", \
414 fmt, (unsigned long) t, regname); \
415 } \
416 while (0)
417
418 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
419 do \
420 { \
421 char abregname[20], tregname[20]; \
422 \
423 unw_print_abreg (abregname, abreg); \
424 unw_print_xyreg (tregname, x, ytreg); \
425 printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
426 fmt, (unsigned long) t, abregname, tregname); \
427 } \
428 while (0)
429
430 #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
431 do \
432 { \
433 char regname[20]; \
434 \
435 unw_print_abreg (regname, abreg); \
436 printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
437 fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
438 } \
439 while (0)
440
441 #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
442 do \
443 { \
444 char regname[20]; \
445 \
446 unw_print_abreg (regname, abreg); \
447 printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
448 fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
449 } \
450 while (0)
451
452 #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
453 do \
454 { \
455 char regname[20]; \
456 \
457 unw_print_abreg (regname, abreg); \
458 printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
459 fmt, qp, (unsigned long) t, regname); \
460 } \
461 while (0)
462
463 #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
464 do \
465 { \
466 char regname[20], tregname[20]; \
467 \
468 unw_print_abreg (regname, abreg); \
469 unw_print_xyreg (tregname, x, ytreg); \
470 printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
471 fmt, qp, (unsigned long) t, regname, tregname); \
472 } \
473 while (0)
474
475 #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
476 printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
477
478 #define UNW_DEC_COPY_STATE(fmt, label, arg) \
479 printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
480
481 #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
482 printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
483 fmt, (unsigned long) t, (unsigned long) ecount)
484
485 /*
486 * Generic IA-64 unwind info decoder.
487 *
488 * This file is used both by the Linux kernel and objdump. Please
489 * keep the two copies of this file in sync (modulo differences in the
490 * prototypes...).
491 *
492 * You need to customize the decoder by defining the following
493 * macros/constants before including this file:
494 *
495 * Types:
496 * unw_word Unsigned integer type with at least 64 bits
497 *
498 * Register names:
499 * UNW_REG_BSP
500 * UNW_REG_BSPSTORE
501 * UNW_REG_FPSR
502 * UNW_REG_LC
503 * UNW_REG_PFS
504 * UNW_REG_PR
505 * UNW_REG_RNAT
506 * UNW_REG_PSP
507 * UNW_REG_RP
508 * UNW_REG_UNAT
509 *
510 * Decoder action macros:
511 * UNW_DEC_BAD_CODE(code)
512 * UNW_DEC_ABI(fmt,abi,context,arg)
513 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
514 * UNW_DEC_BR_MEM(fmt,brmask,arg)
515 * UNW_DEC_COPY_STATE(fmt,label,arg)
516 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
517 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
518 * UNW_DEC_FR_MEM(fmt,frmask,arg)
519 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
520 * UNW_DEC_GR_MEM(fmt,grmask,arg)
521 * UNW_DEC_LABEL_STATE(fmt,label,arg)
522 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
523 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
524 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
525 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
526 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
527 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
528 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
529 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
530 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
531 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
532 * UNW_DEC_REG_REG(fmt,src,dst,arg)
533 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
534 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
535 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
536 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
537 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
538 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
539 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
540 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
541 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
542 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
543 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
544 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
545 */
546
547 static unw_word
548 unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end)
549 {
550 unsigned shift = 0;
551 int status = 1;
552 unw_word byte, result = 0;
553 const unsigned char *bp = *dpp;
554
555 while (bp < end)
556 {
557 byte = *bp++;
558 if (shift < sizeof (result) * 8)
559 {
560 result |= (byte & 0x7f) << shift;
561 if ((result >> shift) != (byte & 0x7f))
562 /* Overflow. */
563 status |= 2;
564 shift += 7;
565 }
566 else if ((byte & 0x7f) != 0)
567 status |= 2;
568
569 if ((byte & 0x80) == 0)
570 {
571 status &= ~1;
572 break;
573 }
574 }
575
576 *dpp = bp;
577 if (status != 0)
578 printf (_("Bad uleb128\n"));
579
580 return result;
581 }
582
583 static const unsigned char *
584 unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
585 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
586 {
587 unsigned char byte1, abreg;
588 unw_word t, off;
589
590 if ((end - dp) < 3)
591 {
592 printf (_("\t<corrupt X1>\n"));
593 return end;
594 }
595
596 byte1 = *dp++;
597 t = unw_decode_uleb128 (&dp, end);
598 off = unw_decode_uleb128 (&dp, end);
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, const unsigned char * end)
610 {
611 unsigned char byte1, byte2, abreg, x, ytreg;
612 unw_word t;
613
614 if ((end - dp) < 3)
615 {
616 printf (_("\t<corrupt X2>\n"));
617 return end;
618 }
619
620 byte1 = *dp++;
621 byte2 = *dp++;
622 t = unw_decode_uleb128 (&dp, end);
623 abreg = (byte1 & 0x7f);
624 ytreg = byte2;
625 x = (byte1 >> 7) & 1;
626 if ((byte1 & 0x80) == 0 && ytreg == 0)
627 UNW_DEC_RESTORE ("X2", t, abreg, arg);
628 else
629 UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
630 return dp;
631 }
632
633 static const unsigned char *
634 unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
635 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
636 {
637 unsigned char byte1, byte2, abreg, qp;
638 unw_word t, off;
639
640 if ((end - dp) < 4)
641 {
642 printf (_("\t<corrupt X3>\n"));
643 return end;
644 }
645
646 byte1 = *dp++;
647 byte2 = *dp++;
648 t = unw_decode_uleb128 (&dp, end);
649 off = unw_decode_uleb128 (&dp, end);
650
651 qp = (byte1 & 0x3f);
652 abreg = (byte2 & 0x7f);
653
654 if (byte1 & 0x80)
655 UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
656 else
657 UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
658 return dp;
659 }
660
661 static const unsigned char *
662 unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
663 void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
664 {
665 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
666 unw_word t;
667
668 if ((end - dp) < 4)
669 {
670 printf (_("\t<corrupt X4>\n"));
671 return end;
672 }
673
674 byte1 = *dp++;
675 byte2 = *dp++;
676 byte3 = *dp++;
677 t = unw_decode_uleb128 (&dp, end);
678
679 qp = (byte1 & 0x3f);
680 abreg = (byte2 & 0x7f);
681 x = (byte2 >> 7) & 1;
682 ytreg = byte3;
683
684 if ((byte2 & 0x80) == 0 && byte3 == 0)
685 UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
686 else
687 UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
688 return dp;
689 }
690
691 static const unsigned char *
692 unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg,
693 const unsigned char * end ATTRIBUTE_UNUSED)
694 {
695 int body = (code & 0x20) != 0;
696 unw_word rlen;
697
698 rlen = (code & 0x1f);
699 UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
700 return dp;
701 }
702
703 static const unsigned char *
704 unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
705 const unsigned char * end)
706 {
707 unsigned char byte1, mask, grsave;
708 unw_word rlen;
709
710 if ((end - dp) < 2)
711 {
712 printf (_("\t<corrupt R2>\n"));
713 return end;
714 }
715
716 byte1 = *dp++;
717
718 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
719 grsave = (byte1 & 0x7f);
720 rlen = unw_decode_uleb128 (& dp, end);
721 UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
722 return dp;
723 }
724
725 static const unsigned char *
726 unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
727 const unsigned char * end)
728 {
729 unw_word rlen;
730
731 rlen = unw_decode_uleb128 (& dp, end);
732 UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
733 return dp;
734 }
735
736 static const unsigned char *
737 unw_decode_p1 (const unsigned char *dp, unsigned int code,
738 void *arg ATTRIBUTE_UNUSED,
739 const unsigned char * end ATTRIBUTE_UNUSED)
740 {
741 unsigned char brmask = (code & 0x1f);
742
743 UNW_DEC_BR_MEM ("P1", brmask, arg);
744 return dp;
745 }
746
747 static const unsigned char *
748 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
749 void *arg ATTRIBUTE_UNUSED,
750 const unsigned char * end)
751 {
752 if ((code & 0x10) == 0)
753 {
754 unsigned char byte1;
755
756 if ((end - dp) < 1)
757 {
758 printf (_("\t<corrupt P2>\n"));
759 return end;
760 }
761
762 byte1 = *dp++;
763
764 UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
765 (byte1 & 0x7f), arg);
766 }
767 else if ((code & 0x08) == 0)
768 {
769 unsigned char byte1, r, dst;
770
771 if ((end - dp) < 1)
772 {
773 printf (_("\t<corrupt P3>\n"));
774 return end;
775 }
776
777 byte1 = *dp++;
778
779 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
780 dst = (byte1 & 0x7f);
781 switch (r)
782 {
783 case 0:
784 UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
785 break;
786 case 1:
787 UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
788 break;
789 case 2:
790 UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
791 break;
792 case 3:
793 UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
794 break;
795 case 4:
796 UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
797 break;
798 case 5:
799 UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
800 break;
801 case 6:
802 UNW_DEC_RP_BR ("P3", dst, arg);
803 break;
804 case 7:
805 UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
806 break;
807 case 8:
808 UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
809 break;
810 case 9:
811 UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
812 break;
813 case 10:
814 UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
815 break;
816 case 11:
817 UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
818 break;
819 default:
820 UNW_DEC_BAD_CODE (r);
821 break;
822 }
823 }
824 else if ((code & 0x7) == 0)
825 UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
826 else if ((code & 0x7) == 1)
827 {
828 unw_word grmask, frmask, byte1, byte2, byte3;
829
830 if ((end - dp) < 3)
831 {
832 printf (_("\t<corrupt P5>\n"));
833 return end;
834 }
835 byte1 = *dp++;
836 byte2 = *dp++;
837 byte3 = *dp++;
838 grmask = ((byte1 >> 4) & 0xf);
839 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
840 UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
841 }
842 else
843 UNW_DEC_BAD_CODE (code);
844
845 return dp;
846 }
847
848 static const unsigned char *
849 unw_decode_p6 (const unsigned char *dp, unsigned int code,
850 void *arg ATTRIBUTE_UNUSED,
851 const unsigned char * end ATTRIBUTE_UNUSED)
852 {
853 int gregs = (code & 0x10) != 0;
854 unsigned char mask = (code & 0x0f);
855
856 if (gregs)
857 UNW_DEC_GR_MEM ("P6", mask, arg);
858 else
859 UNW_DEC_FR_MEM ("P6", mask, arg);
860 return dp;
861 }
862
863 static const unsigned char *
864 unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
865 const unsigned char * end)
866 {
867 unsigned char r, byte1, byte2;
868 unw_word t, size;
869
870 if ((code & 0x10) == 0)
871 {
872 r = (code & 0xf);
873 t = unw_decode_uleb128 (&dp, end);
874 switch (r)
875 {
876 case 0:
877 size = unw_decode_uleb128 (&dp, end);
878 UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
879 break;
880
881 case 1:
882 UNW_DEC_MEM_STACK_V ("P7", t, arg);
883 break;
884 case 2:
885 UNW_DEC_SPILL_BASE ("P7", t, arg);
886 break;
887 case 3:
888 UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
889 break;
890 case 4:
891 UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
892 break;
893 case 5:
894 UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
895 break;
896 case 6:
897 UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
898 break;
899 case 7:
900 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
901 break;
902 case 8:
903 UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
904 break;
905 case 9:
906 UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
907 break;
908 case 10:
909 UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
910 break;
911 case 11:
912 UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
913 break;
914 case 12:
915 UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
916 break;
917 case 13:
918 UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
919 break;
920 case 14:
921 UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
922 break;
923 case 15:
924 UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
925 break;
926 default:
927 UNW_DEC_BAD_CODE (r);
928 break;
929 }
930 }
931 else
932 {
933 switch (code & 0xf)
934 {
935 case 0x0: /* p8 */
936 {
937 if ((end - dp) < 2)
938 {
939 printf (_("\t<corrupt P8>\n"));
940 return end;
941 }
942
943 r = *dp++;
944 t = unw_decode_uleb128 (&dp, end);
945 switch (r)
946 {
947 case 1:
948 UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
949 break;
950 case 2:
951 UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
952 break;
953 case 3:
954 UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
955 break;
956 case 4:
957 UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
958 break;
959 case 5:
960 UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
961 break;
962 case 6:
963 UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
964 break;
965 case 7:
966 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
967 break;
968 case 8:
969 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
970 break;
971 case 9:
972 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
973 break;
974 case 10:
975 UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
976 break;
977 case 11:
978 UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
979 break;
980 case 12:
981 UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
982 break;
983 case 13:
984 UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
985 break;
986 case 14:
987 UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
988 break;
989 case 15:
990 UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
991 break;
992 case 16:
993 UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
994 break;
995 case 17:
996 UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
997 break;
998 case 18:
999 UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
1000 break;
1001 case 19:
1002 UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
1003 break;
1004 default:
1005 UNW_DEC_BAD_CODE (r);
1006 break;
1007 }
1008 }
1009 break;
1010
1011 case 0x1:
1012 if ((end - dp) < 2)
1013 {
1014 printf (_("\t<corrupt P9>\n"));
1015 return end;
1016 }
1017
1018 byte1 = *dp++;
1019 byte2 = *dp++;
1020 UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
1021 break;
1022
1023 case 0xf: /* p10 */
1024 if ((end - dp) < 2)
1025 {
1026 printf (_("\t<corrupt P10>\n"));
1027 return end;
1028 }
1029
1030 byte1 = *dp++;
1031 byte2 = *dp++;
1032 UNW_DEC_ABI ("P10", byte1, byte2, arg);
1033 break;
1034
1035 case 0x9:
1036 return unw_decode_x1 (dp, code, arg, end);
1037
1038 case 0xa:
1039 return unw_decode_x2 (dp, code, arg, end);
1040
1041 case 0xb:
1042 return unw_decode_x3 (dp, code, arg, end);
1043
1044 case 0xc:
1045 return unw_decode_x4 (dp, code, arg, end);
1046
1047 default:
1048 UNW_DEC_BAD_CODE (code);
1049 break;
1050 }
1051 }
1052 return dp;
1053 }
1054
1055 static const unsigned char *
1056 unw_decode_b1 (const unsigned char *dp, unsigned int code,
1057 void *arg ATTRIBUTE_UNUSED,
1058 const unsigned char * end ATTRIBUTE_UNUSED)
1059 {
1060 unw_word label = (code & 0x1f);
1061
1062 if ((code & 0x20) != 0)
1063 UNW_DEC_COPY_STATE ("B1", label, arg);
1064 else
1065 UNW_DEC_LABEL_STATE ("B1", label, arg);
1066 return dp;
1067 }
1068
1069 static const unsigned char *
1070 unw_decode_b2 (const unsigned char *dp, unsigned int code,
1071 void *arg ATTRIBUTE_UNUSED,
1072 const unsigned char * end)
1073 {
1074 unw_word t;
1075
1076 t = unw_decode_uleb128 (& dp, end);
1077 UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
1078 return dp;
1079 }
1080
1081 static const unsigned char *
1082 unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
1083 const unsigned char * end)
1084 {
1085 unw_word t, ecount, label;
1086
1087 if ((code & 0x10) == 0)
1088 {
1089 t = unw_decode_uleb128 (&dp, end);
1090 ecount = unw_decode_uleb128 (&dp, end);
1091 UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
1092 }
1093 else if ((code & 0x07) == 0)
1094 {
1095 label = unw_decode_uleb128 (&dp, end);
1096 if ((code & 0x08) != 0)
1097 UNW_DEC_COPY_STATE ("B4", label, arg);
1098 else
1099 UNW_DEC_LABEL_STATE ("B4", label, arg);
1100 }
1101 else
1102 switch (code & 0x7)
1103 {
1104 case 1:
1105 return unw_decode_x1 (dp, code, arg, end);
1106 case 2:
1107 return unw_decode_x2 (dp, code, arg, end);
1108 case 3:
1109 return unw_decode_x3 (dp, code, arg, end);
1110 case 4:
1111 return unw_decode_x4 (dp, code, arg, end);
1112 default:
1113 UNW_DEC_BAD_CODE (code);
1114 break;
1115 }
1116 return dp;
1117 }
1118
1119 typedef const unsigned char *(*unw_decoder)
1120 (const unsigned char *, unsigned int, void *, const unsigned char *);
1121
1122 static const unw_decoder unw_decode_table[2][8] =
1123 {
1124 /* prologue table: */
1125 {
1126 unw_decode_r1, /* 0 */
1127 unw_decode_r1,
1128 unw_decode_r2,
1129 unw_decode_r3,
1130 unw_decode_p1, /* 4 */
1131 unw_decode_p2_p5,
1132 unw_decode_p6,
1133 unw_decode_p7_p10
1134 },
1135 {
1136 unw_decode_r1, /* 0 */
1137 unw_decode_r1,
1138 unw_decode_r2,
1139 unw_decode_r3,
1140 unw_decode_b1, /* 4 */
1141 unw_decode_b1,
1142 unw_decode_b2,
1143 unw_decode_b3_x4
1144 }
1145 };
1146
1147 /* Decode one descriptor and return address of next descriptor. */
1148 const unsigned char *
1149 unw_decode (const unsigned char *dp, int inside_body,
1150 void *ptr_inside_body, const unsigned char * end)
1151 {
1152 unw_decoder decoder;
1153 unsigned char code;
1154
1155 if ((end - dp) < 1)
1156 {
1157 printf (_("\t<corrupt IA64 descriptor>\n"));
1158 return end;
1159 }
1160
1161 code = *dp++;
1162 decoder = unw_decode_table[inside_body][code >> 5];
1163 return (*decoder) (dp, code, ptr_inside_body, end);
1164 }
This page took 0.053207 seconds and 4 git commands to generate.