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