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