unwind-ia64.c revision 78844
1139823Simp/* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf. 2133578Sharti Copyright 2000, 2001 Free Software Foundation, Inc. 3133578Sharti Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4133578Sharti 5133578ShartiThis file is part of GNU Binutils. 6133578Sharti 7133578ShartiThis program is free software; you can redistribute it and/or modify 8133578Shartiit under the terms of the GNU General Public License as published by 9133578Shartithe Free Software Foundation; either version 2, or (at your option) 10133578Shartiany later version. 11133578Sharti 12133578ShartiThis program is distributed in the hope that it will be useful, 13133578Shartibut WITHOUT ANY WARRANTY; without even the implied warranty of 14133578ShartiMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15133578ShartiGNU General Public License for more details. 16133578Sharti 17133578ShartiYou should have received a copy of the GNU General Public License 18133578Shartialong with this program; if not, write to the Free Software 19133578ShartiFoundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20133578Sharti 21133578Sharti#include "unwind-ia64.h" 22133578Sharti#include <stdio.h> 23133578Sharti#include <string.h> 24133578Sharti 25133578Sharti#if __GNUC__ >= 2 26133578Sharti/* Define BFD64 here, even if our default architecture is 32 bit ELF 27133578Sharti as this will allow us to read in and parse 64bit and 32bit ELF files. 28133578Sharti Only do this if we belive that the compiler can support a 64 bit 29133578Sharti data type. For now we only rely on GCC being able to do this. */ 30133578Sharti#define BFD64 31133578Sharti#endif 32133578Sharti#include "bfd.h" 33133578Sharti 34139823Simpstatic bfd_vma unw_rlen = 0; 35139823Simp 36139823Simpstatic void 37133578Shartiunw_print_brmask (cp, mask) 38133578Sharti char * cp; 39133578Sharti unsigned char mask; 40133578Sharti{ 41133578Sharti char *sep = ""; 42133578Sharti int i; 43133578Sharti 44133578Sharti for (i = 0; mask && (i < 5); ++i) 45133578Sharti { 46133578Sharti if (mask & 1) 47133578Sharti { 48133578Sharti cp += sprintf (cp, "%sb%u", sep, i + 1); 49133578Sharti sep = ","; 50133578Sharti } 51133578Sharti mask >>= 1; 52133578Sharti } 53133578Sharti *cp = '\0'; 54133578Sharti} 55133578Sharti 56133578Shartistatic void 57133578Shartiunw_print_grmask (cp, mask) 58133578Sharti char * cp; 59133578Sharti unsigned char mask; 60133578Sharti{ 61133578Sharti char *sep = ""; 62133578Sharti int i; 63133578Sharti 64133578Sharti *cp = '\0'; 65133578Sharti for (i = 0; i < 4; ++i) 66133578Sharti { 67133578Sharti if (mask & 1) 68133578Sharti { 69133578Sharti cp += sprintf (cp, "%sr%u", sep, i + 4); 70133578Sharti sep = ","; 71133578Sharti } 72133578Sharti mask >>= 1; 73133578Sharti } 74133578Sharti} 75133578Sharti 76133578Shartistatic void 77133578Shartiunw_print_frmask (cp, mask) 78133578Sharti char * cp; 79133578Sharti unsigned long mask; 80133578Sharti{ 81133578Sharti char *sep = ""; 82133578Sharti int i; 83133578Sharti 84133578Sharti *cp = '\0'; 85133578Sharti for (i = 0; i < 20; ++i) 86133578Sharti { 87133578Sharti if (mask & 1) 88133578Sharti { 89133578Sharti cp += sprintf (cp, "%sf%u", sep, (i < 4) ? (i + 2) : (i + 12)); 90133578Sharti sep = ","; 91133578Sharti } 92133578Sharti mask >>= 1; 93133578Sharti } 94133578Sharti} 95133578Sharti 96133578Shartistatic void 97133578Shartiunw_print_abreg (cp, abreg) 98133578Sharti char * cp; 99133578Sharti unsigned char abreg; 100133578Sharti{ 101133578Sharti static const char *special_reg[16] = 102133578Sharti { 103133578Sharti "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat", 104133578Sharti "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc", 105133578Sharti "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15" 106133578Sharti }; 107133578Sharti 108133578Sharti switch ((abreg >> 5) & 0x3) 109133578Sharti { 110133578Sharti case 0: /* gr */ 111133578Sharti sprintf (cp, "r%u", (abreg & 0x1f)); 112133578Sharti break; 113133578Sharti 114133578Sharti case 1: /* fr */ 115133578Sharti sprintf (cp, "f%u", (abreg & 0x1f)); 116133578Sharti break; 117133578Sharti 118133578Sharti case 2: /* br */ 119133578Sharti sprintf (cp, "b%u", (abreg & 0x1f)); 120133578Sharti break; 121133578Sharti 122133578Sharti case 3: /* special */ 123133578Sharti strcpy (cp, special_reg[abreg & 0xf]); 124133578Sharti break; 125133578Sharti } 126133578Sharti} 127133578Sharti 128133578Shartistatic void 129133578Shartiunw_print_xyreg (cp, x, ytreg) 130133578Sharti char * cp; 131133578Sharti unsigned char x; 132133578Sharti unsigned char ytreg; 133133578Sharti{ 134133578Sharti switch ((x << 1) | ((ytreg >> 7) & 1)) 135133578Sharti { 136133578Sharti case 0: /* gr */ 137133578Sharti sprintf (cp, "r%u", (ytreg & 0x1f)); 138133578Sharti break; 139133578Sharti 140133578Sharti case 1: /* fr */ 141133578Sharti sprintf (cp, "f%u", (ytreg & 0x1f)); 142133578Sharti break; 143133578Sharti 144133578Sharti case 2: /* br */ 145133578Sharti sprintf (cp, "b%u", (ytreg & 0x1f)); 146133578Sharti break; 147133578Sharti } 148133578Sharti} 149133578Sharti 150133578Sharti#define UNW_REG_BSP "bsp" 151133578Sharti#define UNW_REG_BSPSTORE "bspstore" 152133578Sharti#define UNW_REG_FPSR "fpsr" 153133578Sharti#define UNW_REG_LC "lc" 154133578Sharti#define UNW_REG_PFS "pfs" 155133578Sharti#define UNW_REG_PR "pr" 156133578Sharti#define UNW_REG_PSP "psp" 157133578Sharti#define UNW_REG_RNAT "rnat" 158133578Sharti#define UNW_REG_RP "rp" 159133578Sharti#define UNW_REG_UNAT "unat" 160133578Sharti 161133578Shartitypedef bfd_vma unw_word; 162133578Sharti 163133578Sharti#define UNW_DEC_BAD_CODE(code) \ 164133578Sharti printf ("Unknown code 0x%02x\n", code) 165133578Sharti 166133578Sharti#define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \ 167133578Sharti do \ 168133578Sharti { \ 169133578Sharti unw_rlen = rlen; \ 170133578Sharti *(int *)arg = body; \ 171133578Sharti 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 523static unw_word unw_decode_uleb128 PARAMS ((const unsigned char **)); 524static const unsigned char *unw_decode_x1 PARAMS ((const unsigned char *, 525 unsigned char, void *)); 526static const unsigned char *unw_decode_x2 PARAMS ((const unsigned char *, 527 unsigned char, void *)); 528static const unsigned char *unw_decode_x3 PARAMS ((const unsigned char *, 529 unsigned char, void *)); 530static const unsigned char *unw_decode_x4 PARAMS ((const unsigned char *, 531 unsigned char, void *)); 532static const unsigned char *unw_decode_r1 PARAMS ((const unsigned char *, 533 unsigned char, void *)); 534static const unsigned char *unw_decode_r2 PARAMS ((const unsigned char *, 535 unsigned char, void *)); 536static const unsigned char *unw_decode_r3 PARAMS ((const unsigned char *, 537 unsigned char, void *)); 538static const unsigned char *unw_decode_p1 PARAMS ((const unsigned char *, 539 unsigned char, void *)); 540static const unsigned char *unw_decode_p2_p5 PARAMS ((const unsigned char *, 541 unsigned char, void *)); 542static const unsigned char *unw_decode_p6 PARAMS ((const unsigned char *, 543 unsigned char, void *)); 544static const unsigned char *unw_decode_p7_p10 PARAMS ((const unsigned char *, 545 unsigned char, void *)); 546static const unsigned char *unw_decode_b1 PARAMS ((const unsigned char *, 547 unsigned char, void *)); 548static const unsigned char *unw_decode_b2 PARAMS ((const unsigned char *, 549 unsigned char, void *)); 550static const unsigned char *unw_decode_b3_x4 PARAMS ((const unsigned char *, 551 unsigned char, void *)); 552 553static unw_word 554unw_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 577static const unsigned char * 578unw_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 597static const unsigned char * 598unw_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 619static const unsigned char * 620unw_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 643static const unsigned char * 644unw_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 669static const unsigned char * 670unw_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 683static const unsigned char * 684unw_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 701static const unsigned char * 702unw_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 714static const unsigned char * 715unw_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 726static const unsigned char * 727unw_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 807static const unsigned char * 808unw_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 823static const unsigned char * 824unw_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 999static const unsigned char * 1000unw_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 1014static const unsigned char * 1015unw_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 1027static const unsigned char * 1028unw_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 1067typedef const unsigned char *(*unw_decoder) 1068 PARAMS ((const unsigned char *, unsigned char, void *)); 1069 1070static 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. */ 1096const unsigned char * 1097unw_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} 1109