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