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