1 /* libunwind - a platform-independent unwind library 2 Copyright (C) 2001-2004 Hewlett-Packard Co 3 Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com> 4 5 This file is part of libunwind. 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 "Software"), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be 16 included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25 26 #include "unwind_i.h" 27 28 /* forward declaration: */ 29 static int create_state_record_for (struct cursor *c, 30 struct ia64_state_record *sr, 31 unw_word_t ip); 32 33 typedef unsigned long unw_word; 34 35 #define alloc_reg_state() (mempool_alloc (&unw.reg_state_pool)) 36 #define free_reg_state(rs) (mempool_free (&unw.reg_state_pool, rs)) 37 #define alloc_labeled_state() (mempool_alloc (&unw.labeled_state_pool)) 38 #define free_labeled_state(s) (mempool_free (&unw.labeled_state_pool, s)) 39 40 /* Routines to manipulate the state stack. */ 41 42 static inline void 43 push (struct ia64_state_record *sr) 44 { 45 struct ia64_reg_state *rs; 46 47 rs = alloc_reg_state (); 48 if (!rs) 49 { 50 print_error ("libunwind: cannot stack reg state!\n"); 51 return; 52 } 53 memcpy (rs, &sr->curr, sizeof (*rs)); 54 sr->curr.next = rs; 55 } 56 57 static void 58 pop (struct ia64_state_record *sr) 59 { 60 struct ia64_reg_state *rs = sr->curr.next; 61 62 if (!rs) 63 { 64 print_error ("libunwind: stack underflow!\n"); 65 return; 66 } 67 memcpy (&sr->curr, rs, sizeof (*rs)); 68 free_reg_state (rs); 69 } 70 71 /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ 72 static struct ia64_reg_state * 73 dup_state_stack (struct ia64_reg_state *rs) 74 { 75 struct ia64_reg_state *copy, *prev = NULL, *first = NULL; 76 77 while (rs) 78 { 79 copy = alloc_reg_state (); 80 if (!copy) 81 { 82 print_error ("unwind.dup_state_stack: out of memory\n"); 83 return NULL; 84 } 85 memcpy (copy, rs, sizeof (*copy)); 86 if (first) 87 prev->next = copy; 88 else 89 first = copy; 90 rs = rs->next; 91 prev = copy; 92 } 93 return first; 94 } 95 96 /* Free all stacked register states (but not RS itself). */ 97 static void 98 free_state_stack (struct ia64_reg_state *rs) 99 { 100 struct ia64_reg_state *p, *next; 101 102 for (p = rs->next; p != NULL; p = next) 103 { 104 next = p->next; 105 free_reg_state (p); 106 } 107 rs->next = NULL; 108 } 109 110 /* Unwind decoder routines */ 111 112 static enum ia64_pregnum CONST_ATTR 113 decode_abreg (unsigned char abreg, int memory) 114 { 115 switch (abreg) 116 { 117 case 0x04 ... 0x07: 118 return IA64_REG_R4 + (abreg - 0x04); 119 case 0x22 ... 0x25: 120 return IA64_REG_F2 + (abreg - 0x22); 121 case 0x30 ... 0x3f: 122 return IA64_REG_F16 + (abreg - 0x30); 123 case 0x41 ... 0x45: 124 return IA64_REG_B1 + (abreg - 0x41); 125 case 0x60: 126 return IA64_REG_PR; 127 case 0x61: 128 return IA64_REG_PSP; 129 case 0x62: 130 return memory ? IA64_REG_PRI_UNAT_MEM : IA64_REG_PRI_UNAT_GR; 131 case 0x63: 132 return IA64_REG_IP; 133 case 0x64: 134 return IA64_REG_BSP; 135 case 0x65: 136 return IA64_REG_BSPSTORE; 137 case 0x66: 138 return IA64_REG_RNAT; 139 case 0x67: 140 return IA64_REG_UNAT; 141 case 0x68: 142 return IA64_REG_FPSR; 143 case 0x69: 144 return IA64_REG_PFS; 145 case 0x6a: 146 return IA64_REG_LC; 147 default: 148 break; 149 } 150 Dprintf ("libunwind: bad abreg=0x%x\n", abreg); 151 return IA64_REG_LC; 152 } 153 154 static void 155 set_reg (struct ia64_reg_info *reg, enum ia64_where where, int when, 156 unsigned long val) 157 { 158 reg->val = val; 159 reg->where = where; 160 if (reg->when == IA64_WHEN_NEVER) 161 reg->when = when; 162 } 163 164 static void 165 alloc_spill_area (unsigned long *offp, unsigned long regsize, 166 struct ia64_reg_info *lo, struct ia64_reg_info *hi) 167 { 168 struct ia64_reg_info *reg; 169 170 for (reg = hi; reg >= lo; --reg) 171 { 172 if (reg->where == IA64_WHERE_SPILL_HOME) 173 { 174 reg->where = IA64_WHERE_PSPREL; 175 *offp -= regsize; 176 reg->val = *offp; 177 } 178 } 179 } 180 181 static inline void 182 spill_next_when (struct ia64_reg_info **regp, struct ia64_reg_info *lim, 183 unw_word t) 184 { 185 struct ia64_reg_info *reg; 186 187 for (reg = *regp; reg <= lim; ++reg) 188 { 189 if (reg->where == IA64_WHERE_SPILL_HOME) 190 { 191 reg->when = t; 192 *regp = reg + 1; 193 return; 194 } 195 } 196 Dprintf ("libunwind: excess spill!\n"); 197 } 198 199 static inline void 200 finish_prologue (struct ia64_state_record *sr) 201 { 202 struct ia64_reg_info *reg; 203 unsigned long off; 204 int i; 205 206 /* First, resolve implicit register save locations (see Section 207 "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */ 208 for (i = 0; i < (int) ARRAY_SIZE (unw.save_order); ++i) 209 { 210 reg = sr->curr.reg + unw.save_order[i]; 211 if (reg->where == IA64_WHERE_GR_SAVE) 212 { 213 reg->where = IA64_WHERE_GR; 214 reg->val = sr->gr_save_loc++; 215 } 216 } 217 218 /* Next, compute when the fp, general, and branch registers get 219 saved. This must come before alloc_spill_area() because we need 220 to know which registers are spilled to their home locations. */ 221 222 if (sr->imask) 223 { 224 unsigned char kind, mask = 0, *cp = sr->imask; 225 unsigned long t; 226 static const unsigned char limit[3] = 227 { 228 IA64_REG_F31, IA64_REG_R7, IA64_REG_B5 229 }; 230 struct ia64_reg_info *(regs[3]); 231 232 regs[0] = sr->curr.reg + IA64_REG_F2; 233 regs[1] = sr->curr.reg + IA64_REG_R4; 234 regs[2] = sr->curr.reg + IA64_REG_B1; 235 236 for (t = 0; (int) t < sr->region_len; ++t) 237 { 238 if ((t & 3) == 0) 239 mask = *cp++; 240 kind = (mask >> 2 * (3 - (t & 3))) & 3; 241 if (kind > 0) 242 spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1], 243 sr->region_start + t); 244 } 245 } 246 247 /* Next, lay out the memory stack spill area. */ 248 249 if (sr->any_spills) 250 { 251 off = sr->spill_offset; 252 alloc_spill_area (&off, 16, sr->curr.reg + IA64_REG_F2, 253 sr->curr.reg + IA64_REG_F31); 254 alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_B1, 255 sr->curr.reg + IA64_REG_B5); 256 alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_R4, 257 sr->curr.reg + IA64_REG_R7); 258 } 259 } 260 261 /* Region header descriptors. */ 262 263 static void 264 desc_prologue (int body, unw_word rlen, unsigned char mask, 265 unsigned char grsave, struct ia64_state_record *sr) 266 { 267 int i, region_start; 268 269 if (!(sr->in_body || sr->first_region)) 270 finish_prologue (sr); 271 sr->first_region = 0; 272 273 /* check if we're done: */ 274 if (sr->when_target < sr->region_start + sr->region_len) 275 { 276 sr->done = 1; 277 return; 278 } 279 280 region_start = sr->region_start + sr->region_len; 281 282 for (i = 0; i < sr->epilogue_count; ++i) 283 pop (sr); 284 sr->epilogue_count = 0; 285 sr->when_sp_restored = IA64_WHEN_NEVER; 286 287 sr->region_start = region_start; 288 sr->region_len = rlen; 289 sr->in_body = body; 290 291 if (!body) 292 { 293 push (sr); 294 295 if (mask) 296 for (i = 0; i < 4; ++i) 297 { 298 if (mask & 0x8) 299 set_reg (sr->curr.reg + unw.save_order[i], IA64_WHERE_GR, 300 sr->region_start + sr->region_len - 1, grsave++); 301 mask <<= 1; 302 } 303 sr->gr_save_loc = grsave; 304 sr->any_spills = 0; 305 sr->imask = 0; 306 sr->spill_offset = 0x10; /* default to psp+16 */ 307 } 308 } 309 310 /* Prologue descriptors. */ 311 312 static inline void 313 desc_abi (unsigned char abi, unsigned char context, 314 struct ia64_state_record *sr) 315 { 316 sr->abi_marker = (abi << 8) | context; 317 } 318 319 static inline void 320 desc_br_gr (unsigned char brmask, unsigned char gr, 321 struct ia64_state_record *sr) 322 { 323 int i; 324 325 for (i = 0; i < 5; ++i) 326 { 327 if (brmask & 1) 328 set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_GR, 329 sr->region_start + sr->region_len - 1, gr++); 330 brmask >>= 1; 331 } 332 } 333 334 static inline void 335 desc_br_mem (unsigned char brmask, struct ia64_state_record *sr) 336 { 337 int i; 338 339 for (i = 0; i < 5; ++i) 340 { 341 if (brmask & 1) 342 { 343 set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_SPILL_HOME, 344 sr->region_start + sr->region_len - 1, 0); 345 sr->any_spills = 1; 346 } 347 brmask >>= 1; 348 } 349 } 350 351 static inline void 352 desc_frgr_mem (unsigned char grmask, unw_word frmask, 353 struct ia64_state_record *sr) 354 { 355 int i; 356 357 for (i = 0; i < 4; ++i) 358 { 359 if ((grmask & 1) != 0) 360 { 361 set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, 362 sr->region_start + sr->region_len - 1, 0); 363 sr->any_spills = 1; 364 } 365 grmask >>= 1; 366 } 367 for (i = 0; i < 20; ++i) 368 { 369 if ((frmask & 1) != 0) 370 { 371 int base = (i < 4) ? IA64_REG_F2 : IA64_REG_F16 - 4; 372 set_reg (sr->curr.reg + base + i, IA64_WHERE_SPILL_HOME, 373 sr->region_start + sr->region_len - 1, 0); 374 sr->any_spills = 1; 375 } 376 frmask >>= 1; 377 } 378 } 379 380 static inline void 381 desc_fr_mem (unsigned char frmask, struct ia64_state_record *sr) 382 { 383 int i; 384 385 for (i = 0; i < 4; ++i) 386 { 387 if ((frmask & 1) != 0) 388 { 389 set_reg (sr->curr.reg + IA64_REG_F2 + i, IA64_WHERE_SPILL_HOME, 390 sr->region_start + sr->region_len - 1, 0); 391 sr->any_spills = 1; 392 } 393 frmask >>= 1; 394 } 395 } 396 397 static inline void 398 desc_gr_gr (unsigned char grmask, unsigned char gr, 399 struct ia64_state_record *sr) 400 { 401 int i; 402 403 for (i = 0; i < 4; ++i) 404 { 405 if ((grmask & 1) != 0) 406 set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_GR, 407 sr->region_start + sr->region_len - 1, gr++); 408 grmask >>= 1; 409 } 410 } 411 412 static inline void 413 desc_gr_mem (unsigned char grmask, struct ia64_state_record *sr) 414 { 415 int i; 416 417 for (i = 0; i < 4; ++i) 418 { 419 if ((grmask & 1) != 0) 420 { 421 set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME, 422 sr->region_start + sr->region_len - 1, 0); 423 sr->any_spills = 1; 424 } 425 grmask >>= 1; 426 } 427 } 428 429 static inline void 430 desc_mem_stack_f (unw_word t, unw_word size, struct ia64_state_record *sr) 431 { 432 set_reg (sr->curr.reg + IA64_REG_PSP, IA64_WHERE_NONE, 433 sr->region_start + MIN ((int) t, sr->region_len - 1), 16 * size); 434 } 435 436 static inline void 437 desc_mem_stack_v (unw_word t, struct ia64_state_record *sr) 438 { 439 sr->curr.reg[IA64_REG_PSP].when = 440 sr->region_start + MIN ((int) t, sr->region_len - 1); 441 } 442 443 static inline void 444 desc_reg_gr (unsigned char reg, unsigned char dst, 445 struct ia64_state_record *sr) 446 { 447 set_reg (sr->curr.reg + reg, IA64_WHERE_GR, 448 sr->region_start + sr->region_len - 1, dst); 449 } 450 451 static inline void 452 desc_reg_psprel (unsigned char reg, unw_word pspoff, 453 struct ia64_state_record *sr) 454 { 455 set_reg (sr->curr.reg + reg, IA64_WHERE_PSPREL, 456 sr->region_start + sr->region_len - 1, 0x10 - 4 * pspoff); 457 } 458 459 static inline void 460 desc_reg_sprel (unsigned char reg, unw_word spoff, 461 struct ia64_state_record *sr) 462 { 463 set_reg (sr->curr.reg + reg, IA64_WHERE_SPREL, 464 sr->region_start + sr->region_len - 1, 4 * spoff); 465 } 466 467 static inline void 468 desc_rp_br (unsigned char dst, struct ia64_state_record *sr) 469 { 470 sr->return_link_reg = dst; 471 } 472 473 static inline void 474 desc_reg_when (unsigned char regnum, unw_word t, struct ia64_state_record *sr) 475 { 476 struct ia64_reg_info *reg = sr->curr.reg + regnum; 477 478 if (reg->where == IA64_WHERE_NONE) 479 reg->where = IA64_WHERE_GR_SAVE; 480 reg->when = sr->region_start + MIN ((int) t, sr->region_len - 1); 481 } 482 483 static inline void 484 desc_spill_base (unw_word pspoff, struct ia64_state_record *sr) 485 { 486 sr->spill_offset = 0x10 - 4 * pspoff; 487 } 488 489 static inline unsigned char * 490 desc_spill_mask (unsigned char *imaskp, struct ia64_state_record *sr) 491 { 492 sr->imask = imaskp; 493 return imaskp + (2 * sr->region_len + 7) / 8; 494 } 495 496 /* Body descriptors. */ 497 498 static inline void 499 desc_epilogue (unw_word t, unw_word ecount, struct ia64_state_record *sr) 500 { 501 sr->when_sp_restored = sr->region_start + sr->region_len - 1 - t; 502 sr->epilogue_count = ecount + 1; 503 } 504 505 static inline void 506 desc_copy_state (unw_word label, struct ia64_state_record *sr) 507 { 508 struct ia64_labeled_state *ls; 509 510 for (ls = sr->labeled_states; ls; ls = ls->next) 511 { 512 if (ls->label == label) 513 { 514 free_state_stack (&sr->curr); 515 memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr)); 516 sr->curr.next = dup_state_stack (ls->saved_state.next); 517 return; 518 } 519 } 520 print_error ("libunwind: failed to find labeled state\n"); 521 } 522 523 static inline void 524 desc_label_state (unw_word label, struct ia64_state_record *sr) 525 { 526 struct ia64_labeled_state *ls; 527 528 ls = alloc_labeled_state (); 529 if (!ls) 530 { 531 print_error ("unwind.desc_label_state(): out of memory\n"); 532 return; 533 } 534 ls->label = label; 535 memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state)); 536 ls->saved_state.next = dup_state_stack (sr->curr.next); 537 538 /* insert into list of labeled states: */ 539 ls->next = sr->labeled_states; 540 sr->labeled_states = ls; 541 } 542 543 /* General descriptors. */ 544 545 static inline int 546 desc_is_active (unsigned char qp, unw_word t, struct ia64_state_record *sr) 547 { 548 if (sr->when_target <= sr->region_start + MIN ((int) t, sr->region_len - 1)) 549 return 0; 550 if (qp > 0) 551 { 552 if ((sr->pr_val & ((unw_word_t) 1 << qp)) == 0) 553 return 0; 554 sr->pr_mask |= ((unw_word_t) 1 << qp); 555 } 556 return 1; 557 } 558 559 static inline void 560 desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, 561 struct ia64_state_record *sr) 562 { 563 struct ia64_reg_info *r; 564 565 if (!desc_is_active (qp, t, sr)) 566 return; 567 568 r = sr->curr.reg + decode_abreg (abreg, 0); 569 r->where = IA64_WHERE_NONE; 570 r->when = IA64_WHEN_NEVER; 571 r->val = 0; 572 } 573 574 static inline void 575 desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, 576 unsigned char x, unsigned char ytreg, 577 struct ia64_state_record *sr) 578 { 579 enum ia64_where where = IA64_WHERE_GR; 580 struct ia64_reg_info *r; 581 582 if (!desc_is_active (qp, t, sr)) 583 return; 584 585 if (x) 586 where = IA64_WHERE_BR; 587 else if (ytreg & 0x80) 588 where = IA64_WHERE_FR; 589 590 r = sr->curr.reg + decode_abreg (abreg, 0); 591 r->where = where; 592 r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); 593 r->val = (ytreg & 0x7f); 594 } 595 596 static inline void 597 desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, 598 unw_word pspoff, struct ia64_state_record *sr) 599 { 600 struct ia64_reg_info *r; 601 602 if (!desc_is_active (qp, t, sr)) 603 return; 604 605 r = sr->curr.reg + decode_abreg (abreg, 1); 606 r->where = IA64_WHERE_PSPREL; 607 r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); 608 r->val = 0x10 - 4 * pspoff; 609 } 610 611 static inline void 612 desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, 613 unw_word spoff, struct ia64_state_record *sr) 614 { 615 struct ia64_reg_info *r; 616 617 if (!desc_is_active (qp, t, sr)) 618 return; 619 620 r = sr->curr.reg + decode_abreg (abreg, 1); 621 r->where = IA64_WHERE_SPREL; 622 r->when = sr->region_start + MIN ((int) t, sr->region_len - 1); 623 r->val = 4 * spoff; 624 } 625 626 #define UNW_DEC_BAD_CODE(code) \ 627 print_error ("libunwind: unknown code encountered\n") 628 629 /* Register names. */ 630 #define UNW_REG_BSP IA64_REG_BSP 631 #define UNW_REG_BSPSTORE IA64_REG_BSPSTORE 632 #define UNW_REG_FPSR IA64_REG_FPSR 633 #define UNW_REG_LC IA64_REG_LC 634 #define UNW_REG_PFS IA64_REG_PFS 635 #define UNW_REG_PR IA64_REG_PR 636 #define UNW_REG_RNAT IA64_REG_RNAT 637 #define UNW_REG_PSP IA64_REG_PSP 638 #define UNW_REG_RP IA64_REG_IP 639 #define UNW_REG_UNAT IA64_REG_UNAT 640 641 /* Region headers. */ 642 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) 643 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) 644 645 /* Prologue descriptors. */ 646 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) 647 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) 648 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) 649 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) 650 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) 651 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) 652 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) 653 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) 654 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) 655 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) 656 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) 657 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) 658 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) 659 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) \ 660 desc_reg_when(IA64_REG_PRI_UNAT_GR,t,arg) 661 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) \ 662 desc_reg_when(IA64_REG_PRI_UNAT_MEM,t,arg) 663 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) \ 664 desc_reg_gr(IA64_REG_PRI_UNAT_GR,r,arg) 665 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) \ 666 desc_reg_psprel(IA64_REG_PRI_UNAT_MEM,o,arg) 667 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) \ 668 desc_reg_sprel(IA64_REG_PRI_UNAT_MEM,o,arg) 669 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) 670 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) 671 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) 672 673 /* Body descriptors. */ 674 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) 675 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) 676 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) 677 678 /* General unwind descriptors. */ 679 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) 680 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) 681 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) \ 682 desc_spill_psprel_p(p,t,a,o,arg) 683 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) \ 684 desc_spill_psprel_p(0,t,a,o,arg) 685 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) 686 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) 687 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) 688 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) 689 690 #include "unwind_decoder.h" 691 692 #ifdef _U_dyn_op 694 695 /* parse dynamic unwind info */ 696 697 static struct ia64_reg_info * 698 lookup_preg (int regnum, int memory, struct ia64_state_record *sr) 699 { 700 int preg; 701 702 switch (regnum) 703 { 704 case UNW_IA64_AR_BSP: preg = IA64_REG_BSP; break; 705 case UNW_IA64_AR_BSPSTORE: preg = IA64_REG_BSPSTORE; break; 706 case UNW_IA64_AR_FPSR: preg = IA64_REG_FPSR; break; 707 case UNW_IA64_AR_LC: preg = IA64_REG_LC; break; 708 case UNW_IA64_AR_PFS: preg = IA64_REG_PFS; break; 709 case UNW_IA64_AR_RNAT: preg = IA64_REG_RNAT; break; 710 case UNW_IA64_AR_UNAT: preg = IA64_REG_UNAT; break; 711 case UNW_IA64_BR + 0: preg = IA64_REG_IP; break; 712 case UNW_IA64_PR: preg = IA64_REG_PR; break; 713 case UNW_IA64_SP: preg = IA64_REG_PSP; break; 714 715 case UNW_IA64_NAT: 716 if (memory) 717 preg = IA64_REG_PRI_UNAT_MEM; 718 else 719 preg = IA64_REG_PRI_UNAT_GR; 720 break; 721 722 case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: 723 preg = IA64_REG_R4 + (regnum - (UNW_IA64_GR + 4)); 724 break; 725 726 case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5: 727 preg = IA64_REG_B1 + (regnum - UNW_IA64_BR); 728 break; 729 730 case UNW_IA64_FR + 2 ... UNW_IA64_FR + 5: 731 preg = IA64_REG_F2 + (regnum - (UNW_IA64_FR + 2)); 732 break; 733 734 case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: 735 preg = IA64_REG_F16 + (regnum - (UNW_IA64_FR + 16)); 736 break; 737 738 default: 739 Dprintf ("%s: invalid register number %d\n", __FUNCTION__, regnum); 740 return NULL; 741 } 742 return sr->curr.reg + preg; 743 } 744 745 /* An alias directive inside a region of length RLEN is interpreted to 746 mean that the region behaves exactly like the first RLEN 747 instructions at the aliased IP. RLEN=0 implies that the current 748 state matches exactly that of before the instruction at the aliased 749 IP is executed. */ 750 751 static int 752 desc_alias (unw_dyn_op_t *op, struct cursor *c, struct ia64_state_record *sr) 753 { 754 struct ia64_state_record orig_sr = *sr; 755 int i, ret, when, rlen = sr->region_len; 756 unw_word_t new_ip; 757 758 when = MIN (sr->when_target, rlen); 759 new_ip = op->val + ((when / 3) * 16 + (when % 3)); 760 761 if ((ret = ia64_fetch_proc_info (c, new_ip, 1)) < 0) 762 return ret; 763 764 if ((ret = create_state_record_for (c, sr, new_ip)) < 0) 765 return ret; 766 767 sr->first_region = orig_sr.first_region; 768 sr->done = 0; 769 sr->any_spills |= orig_sr.any_spills; 770 sr->in_body = orig_sr.in_body; 771 sr->region_start = orig_sr.region_start; 772 sr->region_len = orig_sr.region_len; 773 if (sr->when_sp_restored != IA64_WHEN_NEVER) 774 sr->when_sp_restored = op->when + MIN (orig_sr.when_sp_restored, rlen); 775 sr->epilogue_count = orig_sr.epilogue_count; 776 sr->when_target = orig_sr.when_target; 777 778 for (i = 0; i < IA64_NUM_PREGS; ++i) 779 if (sr->curr.reg[i].when != IA64_WHEN_NEVER) 780 sr->curr.reg[i].when = op->when + MIN (sr->curr.reg[i].when, rlen); 781 782 ia64_free_state_record (sr); 783 sr->labeled_states = orig_sr.labeled_states; 784 sr->curr.next = orig_sr.curr.next; 785 return 0; 786 } 787 788 static inline int 789 parse_dynamic (struct cursor *c, struct ia64_state_record *sr) 790 { 791 unw_dyn_info_t *di = c->pi.unwind_info; 792 unw_dyn_proc_info_t *proc = &di->u.pi; 793 unw_dyn_region_info_t *r; 794 struct ia64_reg_info *ri; 795 enum ia64_where where; 796 int32_t when, len; 797 unw_dyn_op_t *op; 798 unw_word_t val; 799 int memory, ret; 800 int8_t qp; 801 802 for (r = proc->regions; r; r = r->next) 803 { 804 len = r->insn_count; 805 if (len < 0) 806 { 807 if (r->next) 808 { 809 Debug (1, "negative region length allowed in last region only!"); 810 return -UNW_EINVAL; 811 } 812 len = -len; 813 /* hack old region info to set the start where we need it: */ 814 sr->region_start = (di->end_ip - di->start_ip) / 0x10 * 3 - len; 815 sr->region_len = 0; 816 } 817 /* all regions are treated as prologue regions: */ 818 desc_prologue (0, len, 0, 0, sr); 819 820 if (sr->done) 821 return 0; 822 823 for (op = r->op; op < r->op + r->op_count; ++op) 824 { 825 when = op->when; 826 val = op->val; 827 qp = op->qp; 828 829 if (!desc_is_active (qp, when, sr)) 830 continue; 831 832 when = sr->region_start + MIN ((int) when, sr->region_len - 1); 833 834 switch (op->tag) 835 { 836 case UNW_DYN_SAVE_REG: 837 memory = 0; 838 if ((unsigned) (val - UNW_IA64_GR) < 128) 839 where = IA64_WHERE_GR; 840 else if ((unsigned) (val - UNW_IA64_FR) < 128) 841 where = IA64_WHERE_FR; 842 else if ((unsigned) (val - UNW_IA64_BR) < 8) 843 where = IA64_WHERE_BR; 844 else 845 { 846 Dprintf ("%s: can't save to register number %d\n", 847 __FUNCTION__, (int) op->reg); 848 return -UNW_EBADREG; 849 } 850 /* fall through */ 851 update_reg_info: 852 ri = lookup_preg (op->reg, memory, sr); 853 if (!ri) 854 return -UNW_EBADREG; 855 ri->where = where; 856 ri->when = when; 857 ri->val = val; 858 break; 859 860 case UNW_DYN_SPILL_FP_REL: 861 memory = 1; 862 where = IA64_WHERE_PSPREL; 863 val = 0x10 - val; 864 goto update_reg_info; 865 866 case UNW_DYN_SPILL_SP_REL: 867 memory = 1; 868 where = IA64_WHERE_SPREL; 869 goto update_reg_info; 870 871 case UNW_DYN_ADD: 872 if (op->reg == UNW_IA64_SP) 873 { 874 if (val & 0xf) 875 { 876 Dprintf ("%s: frame-size %ld not an integer " 877 "multiple of 16\n", 878 __FUNCTION__, (long) op->val); 879 return -UNW_EINVAL; 880 } 881 desc_mem_stack_f (when, -((int64_t) val / 16), sr); 882 } 883 else 884 { 885 Dprintf ("%s: can only ADD to stack-pointer\n", 886 __FUNCTION__); 887 return -UNW_EBADREG; 888 } 889 break; 890 891 case UNW_DYN_POP_FRAMES: 892 sr->when_sp_restored = when; 893 sr->epilogue_count = op->val; 894 break; 895 896 case UNW_DYN_LABEL_STATE: 897 desc_label_state (op->val, sr); 898 break; 899 900 case UNW_DYN_COPY_STATE: 901 desc_copy_state (op->val, sr); 902 break; 903 904 case UNW_DYN_ALIAS: 905 if ((ret = desc_alias (op, c, sr)) < 0) 906 return ret; 907 908 case UNW_DYN_STOP: 909 goto end_of_ops; 910 } 911 } 912 end_of_ops: 913 ; 914 } 915 return 0; 916 } 917 #else 918 # define parse_dynamic(c,sr) (-UNW_EINVAL) 919 #endif /* _U_dyn_op */ 920 921 923 HIDDEN int 924 ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, int need_unwind_info) 925 { 926 int ret, dynamic = 1; 927 928 if (c->pi_valid && !need_unwind_info) 929 return 0; 930 931 /* check dynamic info first --- it overrides everything else */ 932 ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, 933 c->as_arg); 934 if (ret == -UNW_ENOINFO) 935 { 936 dynamic = 0; 937 ret = ia64_find_proc_info (c, ip, need_unwind_info); 938 } 939 940 c->pi_valid = 1; 941 c->pi_is_dynamic = dynamic; 942 return ret; 943 } 944 945 static inline void 946 put_unwind_info (struct cursor *c, unw_proc_info_t *pi) 947 { 948 if (!c->pi_valid) 949 return; 950 951 if (c->pi_is_dynamic) 952 unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); 953 else 954 ia64_put_unwind_info (c, pi); 955 } 956 957 static int 958 create_state_record_for (struct cursor *c, struct ia64_state_record *sr, 959 unw_word_t ip) 960 { 961 unw_word_t predicates = c->pr; 962 struct ia64_reg_info *r; 963 uint8_t *dp, *desc_end; 964 int ret; 965 966 assert (c->pi_valid); 967 968 /* build state record */ 969 memset (sr, 0, sizeof (*sr)); 970 for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) 971 r->when = IA64_WHEN_NEVER; 972 sr->pr_val = predicates; 973 sr->first_region = 1; 974 975 if (!c->pi.unwind_info) 976 { 977 /* No info, return default unwinder (leaf proc, no mem stack, no 978 saved regs), rp in b0, pfs in ar.pfs. */ 979 Debug (1, "no unwind info for ip=0x%lx (gp=%lx)\n", 980 (long) ip, (long) c->pi.gp); 981 sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; 982 sr->curr.reg[IA64_REG_IP].when = -1; 983 sr->curr.reg[IA64_REG_IP].val = 0; 984 goto out; 985 } 986 987 sr->when_target = (3 * ((ip & ~(unw_word_t) 0xf) - c->pi.start_ip) / 16 988 + (ip & 0xf)); 989 990 switch (c->pi.format) 991 { 992 case UNW_INFO_FORMAT_TABLE: 993 case UNW_INFO_FORMAT_REMOTE_TABLE: 994 dp = c->pi.unwind_info; 995 desc_end = dp + c->pi.unwind_info_size; 996 while (!sr->done && dp < desc_end) 997 dp = unw_decode (dp, sr->in_body, sr); 998 ret = 0; 999 break; 1000 1001 case UNW_INFO_FORMAT_DYNAMIC: 1002 ret = parse_dynamic (c, sr); 1003 break; 1004 1005 default: 1006 ret = -UNW_EINVAL; 1007 } 1008 1009 put_unwind_info (c, &c->pi); 1010 1011 if (ret < 0) 1012 return ret; 1013 1014 if (sr->when_target > sr->when_sp_restored) 1015 { 1016 /* sp has been restored and all values on the memory stack below 1017 psp also have been restored. */ 1018 sr->curr.reg[IA64_REG_PSP].val = 0; 1019 sr->curr.reg[IA64_REG_PSP].where = IA64_WHERE_NONE; 1020 sr->curr.reg[IA64_REG_PSP].when = IA64_WHEN_NEVER; 1021 for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) 1022 if ((r->where == IA64_WHERE_PSPREL && r->val <= 0x10) 1023 || r->where == IA64_WHERE_SPREL) 1024 { 1025 r->val = 0; 1026 r->where = IA64_WHERE_NONE; 1027 r->when = IA64_WHEN_NEVER; 1028 } 1029 } 1030 1031 /* If RP did't get saved, generate entry for the return link 1032 register. */ 1033 if (sr->curr.reg[IA64_REG_IP].when >= sr->when_target) 1034 { 1035 sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR; 1036 sr->curr.reg[IA64_REG_IP].when = -1; 1037 sr->curr.reg[IA64_REG_IP].val = sr->return_link_reg; 1038 } 1039 1040 if (sr->when_target > sr->curr.reg[IA64_REG_BSP].when 1041 && sr->when_target > sr->curr.reg[IA64_REG_BSPSTORE].when 1042 && sr->when_target > sr->curr.reg[IA64_REG_RNAT].when) 1043 { 1044 Debug (8, "func 0x%lx may switch the register-backing-store\n", 1045 c->pi.start_ip); 1046 c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH; 1047 } 1048 out: 1049 #if UNW_DEBUG 1050 if (unwi_debug_level > 2) 1051 { 1052 Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n", 1053 __FUNCTION__, 1054 (long) c->pi.start_ip, sr->when_target, (long) c->pi.flags); 1055 for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r) 1056 { 1057 if (r->where != IA64_WHERE_NONE || r->when != IA64_WHEN_NEVER) 1058 { 1059 Dprintf (" %s <- ", unw.preg_name[r - sr->curr.reg]); 1060 switch (r->where) 1061 { 1062 case IA64_WHERE_GR: 1063 Dprintf ("r%lu", (long) r->val); 1064 break; 1065 case IA64_WHERE_FR: 1066 Dprintf ("f%lu", (long) r->val); 1067 break; 1068 case IA64_WHERE_BR: 1069 Dprintf ("b%lu", (long) r->val); 1070 break; 1071 case IA64_WHERE_SPREL: 1072 Dprintf ("[sp+0x%lx]", (long) r->val); 1073 break; 1074 case IA64_WHERE_PSPREL: 1075 Dprintf ("[psp+0x%lx]", (long) r->val); 1076 break; 1077 case IA64_WHERE_NONE: 1078 Dprintf ("%s+0x%lx", 1079 unw.preg_name[r - sr->curr.reg], (long) r->val); 1080 break; 1081 default: 1082 Dprintf ("BADWHERE(%d)", r->where); 1083 break; 1084 } 1085 Dprintf ("\t\t%d\n", r->when); 1086 } 1087 } 1088 } 1089 #endif 1090 return 0; 1091 } 1092 1093 /* The proc-info must be valid for IP before this routine can be 1094 called. */ 1095 HIDDEN int 1096 ia64_create_state_record (struct cursor *c, struct ia64_state_record *sr) 1097 { 1098 return create_state_record_for (c, sr, c->ip); 1099 } 1100 1101 HIDDEN int 1102 ia64_free_state_record (struct ia64_state_record *sr) 1103 { 1104 struct ia64_labeled_state *ls, *next; 1105 1106 /* free labeled register states & stack: */ 1107 1108 for (ls = sr->labeled_states; ls; ls = next) 1109 { 1110 next = ls->next; 1111 free_state_stack (&ls->saved_state); 1112 free_labeled_state (ls); 1113 } 1114 free_state_stack (&sr->curr); 1115 1116 return 0; 1117 } 1118 1119 HIDDEN int 1120 ia64_make_proc_info (struct cursor *c) 1121 { 1122 int ret, caching = c->as->caching_policy != UNW_CACHE_NONE; 1123 1124 if (!caching || ia64_get_cached_proc_info (c) < 0) 1125 { 1126 /* Lookup it up the slow way... */ 1127 if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0) 1128 return ret; 1129 if (caching) 1130 ia64_cache_proc_info (c); 1131 } 1132 return 0; 1133 } 1134