1/* Subroutines needed for unwinding IA-64 standard format stack frame 2 info for exception handling. 3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 4 Free Software Foundation, Inc. 5 Contributed by Andrew MacLeod <amacleod@cygnus.com> 6 Andrew Haley <aph@cygnus.com> 7 David Mosberger-Tang <davidm@hpl.hp.com> 8 9 This file is part of GCC. 10 11 GCC is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 2, or (at your option) 14 any later version. 15 16 GCC is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with GCC; see the file COPYING. If not, write to 23 the Free Software Foundation, 51 Franklin Street, Fifth Floor, 24 Boston, MA 02110-1301, USA. */ 25 26/* As a special exception, if you link this library with other files, 27 some of which are compiled with GCC, to produce an executable, 28 this library does not by itself cause the resulting executable 29 to be covered by the GNU General Public License. 30 This exception does not however invalidate any other reasons why 31 the executable file might be covered by the GNU General Public License. */ 32 33 34#include "tconfig.h" 35#include "tsystem.h" 36#include "coretypes.h" 37#include "tm.h" 38#include "unwind.h" 39#include "unwind-ia64.h" 40#include "unwind-compat.h" 41#include "ia64intrin.h" 42 43/* This isn't thread safe, but nice for occasional tests. */ 44#undef ENABLE_MALLOC_CHECKING 45 46#ifndef __USING_SJLJ_EXCEPTIONS__ 47 48#define UNW_VER(x) ((x) >> 48) 49#define UNW_FLAG_MASK 0x0000ffff00000000 50#define UNW_FLAG_OSMASK 0x0000f00000000000 51#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L) 52#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L) 53#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL) 54 55enum unw_application_register 56{ 57 UNW_AR_BSP, 58 UNW_AR_BSPSTORE, 59 UNW_AR_PFS, 60 UNW_AR_RNAT, 61 UNW_AR_UNAT, 62 UNW_AR_LC, 63 UNW_AR_EC, 64 UNW_AR_FPSR, 65 UNW_AR_RSC, 66 UNW_AR_CCV 67}; 68 69enum unw_register_index 70{ 71 /* Primary UNAT. */ 72 UNW_REG_PRI_UNAT_GR, 73 UNW_REG_PRI_UNAT_MEM, 74 75 /* Memory Stack. */ 76 UNW_REG_PSP, /* previous memory stack pointer */ 77 78 /* Register Stack. */ 79 UNW_REG_BSP, /* register stack pointer */ 80 UNW_REG_BSPSTORE, 81 UNW_REG_PFS, /* previous function state */ 82 UNW_REG_RNAT, 83 /* Return Pointer. */ 84 UNW_REG_RP, 85 86 /* Special preserved registers. */ 87 UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR, 88 89 /* Non-stacked general registers. */ 90 UNW_REG_R2, 91 UNW_REG_R4 = UNW_REG_R2 + 2, 92 UNW_REG_R7 = UNW_REG_R2 + 5, 93 UNW_REG_R31 = UNW_REG_R2 + 29, 94 95 /* Non-stacked floating point registers. */ 96 UNW_REG_F2, 97 UNW_REG_F5 = UNW_REG_F2 + 3, 98 UNW_REG_F16 = UNW_REG_F2 + 14, 99 UNW_REG_F31 = UNW_REG_F2 + 29, 100 101 /* Branch registers. */ 102 UNW_REG_B0, UNW_REG_B1, 103 UNW_REG_B5 = UNW_REG_B1 + 4, 104 105 UNW_NUM_REGS 106}; 107 108enum unw_where 109{ 110 UNW_WHERE_NONE, /* register isn't saved at all */ 111 UNW_WHERE_GR, /* register is saved in a general register */ 112 UNW_WHERE_FR, /* register is saved in a floating-point register */ 113 UNW_WHERE_BR, /* register is saved in a branch register */ 114 UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */ 115 UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */ 116 117 /* At the end of each prologue these locations get resolved to 118 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */ 119 UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */ 120 UNW_WHERE_GR_SAVE /* register is saved in next general register */ 121}; 122 123#define UNW_WHEN_NEVER 0x7fffffff 124 125struct unw_reg_info 126{ 127 unsigned long val; /* save location: register number or offset */ 128 enum unw_where where; /* where the register gets saved */ 129 int when; /* when the register gets saved */ 130}; 131 132struct unw_reg_state { 133 struct unw_reg_state *next; /* next (outer) element on state stack */ 134 struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */ 135}; 136 137struct unw_labeled_state { 138 struct unw_labeled_state *next; /* next labeled state (or NULL) */ 139 unsigned long label; /* label for this state */ 140 struct unw_reg_state saved_state; 141}; 142 143typedef struct unw_state_record 144{ 145 unsigned int first_region : 1; /* is this the first region? */ 146 unsigned int done : 1; /* are we done scanning descriptors? */ 147 unsigned int any_spills : 1; /* got any register spills? */ 148 unsigned int in_body : 1; /* are we inside a body? */ 149 unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */ 150 unsigned char *imask; /* imask of spill_mask record or NULL */ 151 unsigned long pr_val; /* predicate values */ 152 unsigned long pr_mask; /* predicate mask */ 153 long spill_offset; /* psp-relative offset for spill base */ 154 int region_start; 155 int region_len; 156 int epilogue_start; 157 int epilogue_count; 158 int when_target; 159 160 unsigned char gr_save_loc; /* next general register to use for saving */ 161 unsigned char return_link_reg; /* branch register for return link */ 162 unsigned short unwabi; 163 164 struct unw_labeled_state *labeled_states; /* list of all labeled states */ 165 struct unw_reg_state curr; /* current state */ 166 167 _Unwind_Personality_Fn personality; 168 169} _Unwind_FrameState; 170 171enum unw_nat_type 172{ 173 UNW_NAT_NONE, /* NaT not represented */ 174 UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */ 175 UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */ 176 UNW_NAT_REGSTK /* NaT is in rnat */ 177}; 178 179struct unw_stack 180{ 181 unsigned long limit; 182 unsigned long top; 183}; 184 185struct _Unwind_Context 186{ 187 /* Initial frame info. */ 188 unsigned long rnat; /* rse nat collection */ 189 unsigned long regstk_top; /* lowest address of rbs stored register 190 which uses context->rnat collection */ 191 192 /* Current frame info. */ 193 unsigned long bsp; /* backing store pointer value 194 corresponding to psp. */ 195 unsigned long sp; /* stack pointer value */ 196 unsigned long psp; /* previous sp value */ 197 unsigned long rp; /* return pointer */ 198 unsigned long pr; /* predicate collection */ 199 200 unsigned long region_start; /* start of unwind region */ 201 unsigned long gp; /* global pointer value */ 202 void *lsda; /* language specific data area */ 203 204 /* Preserved state. */ 205 unsigned long *bsp_loc; /* previous bsp save location 206 Appears to be write-only? */ 207 unsigned long *bspstore_loc; 208 unsigned long *pfs_loc; /* Save location for pfs in current 209 (corr. to sp) frame. Target 210 contains cfm for caller. */ 211 unsigned long *pri_unat_loc; 212 unsigned long *unat_loc; 213 unsigned long *lc_loc; 214 unsigned long *fpsr_loc; 215 216 unsigned long eh_data[4]; 217 218 struct unw_ireg 219 { 220 unsigned long *loc; 221 struct unw_ireg_nat 222 { 223 enum unw_nat_type type : 3; 224 signed long off : 61; /* NaT word is at loc+nat.off */ 225 } nat; 226 } ireg[32 - 2]; /* Indexed by <register number> - 2 */ 227 228 unsigned long *br_loc[8]; 229 void *fr_loc[32 - 2]; 230 231 /* ??? We initially point pri_unat_loc here. The entire NAT bit 232 logic needs work. */ 233 unsigned long initial_unat; 234}; 235 236typedef unsigned long unw_word; 237 238/* Implicit register save order. See section 11.4.2.3 Rules for Using 239 Unwind Descriptors, rule 3. */ 240 241static unsigned char const save_order[] = 242{ 243 UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, 244 UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR 245}; 246 247 248#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) 249 250/* MASK is a bitmap describing the allocation state of emergency buffers, 251 with bit set indicating free. Return >= 0 if allocation is successful; 252 < 0 if failure. */ 253 254static inline int 255atomic_alloc (unsigned int *mask) 256{ 257 unsigned int old = *mask, ret, new; 258 259 while (1) 260 { 261 if (old == 0) 262 return -1; 263 ret = old & -old; 264 new = old & ~ret; 265 new = __sync_val_compare_and_swap (mask, old, new); 266 if (old == new) 267 break; 268 old = new; 269 } 270 271 return __builtin_ffs (ret) - 1; 272} 273 274/* Similarly, free an emergency buffer. */ 275 276static inline void 277atomic_free (unsigned int *mask, int bit) 278{ 279 __sync_xor_and_fetch (mask, 1 << bit); 280} 281 282 283#define SIZE(X) (sizeof(X) / sizeof(*(X))) 284#define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1) 285#define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X)) 286 287static struct unw_reg_state emergency_reg_state[32]; 288static unsigned int emergency_reg_state_free = MASK_FOR (emergency_reg_state); 289 290static struct unw_labeled_state emergency_labeled_state[8]; 291static unsigned int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state); 292 293#ifdef ENABLE_MALLOC_CHECKING 294static int reg_state_alloced; 295static int labeled_state_alloced; 296#endif 297 298/* Allocation and deallocation of structures. */ 299 300static struct unw_reg_state * 301alloc_reg_state (void) 302{ 303 struct unw_reg_state *rs; 304 305#ifdef ENABLE_MALLOC_CHECKING 306 reg_state_alloced++; 307#endif 308 309 rs = malloc (sizeof (struct unw_reg_state)); 310 if (!rs) 311 { 312 int n = atomic_alloc (&emergency_reg_state_free); 313 if (n >= 0) 314 rs = &emergency_reg_state[n]; 315 } 316 317 return rs; 318} 319 320static void 321free_reg_state (struct unw_reg_state *rs) 322{ 323#ifdef ENABLE_MALLOC_CHECKING 324 reg_state_alloced--; 325#endif 326 327 if (PTR_IN (emergency_reg_state, rs)) 328 atomic_free (&emergency_reg_state_free, rs - emergency_reg_state); 329 else 330 free (rs); 331} 332 333static struct unw_labeled_state * 334alloc_label_state (void) 335{ 336 struct unw_labeled_state *ls; 337 338#ifdef ENABLE_MALLOC_CHECKING 339 labeled_state_alloced++; 340#endif 341 342 ls = malloc(sizeof(struct unw_labeled_state)); 343 if (!ls) 344 { 345 int n = atomic_alloc (&emergency_labeled_state_free); 346 if (n >= 0) 347 ls = &emergency_labeled_state[n]; 348 } 349 350 return ls; 351} 352 353static void 354free_label_state (struct unw_labeled_state *ls) 355{ 356#ifdef ENABLE_MALLOC_CHECKING 357 labeled_state_alloced--; 358#endif 359 360 if (PTR_IN (emergency_labeled_state, ls)) 361 atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls); 362 else 363 free (ls); 364} 365 366/* Routines to manipulate the state stack. */ 367 368static void 369push (struct unw_state_record *sr) 370{ 371 struct unw_reg_state *rs = alloc_reg_state (); 372 memcpy (rs, &sr->curr, sizeof (*rs)); 373 sr->curr.next = rs; 374} 375 376static void 377pop (struct unw_state_record *sr) 378{ 379 struct unw_reg_state *rs = sr->curr.next; 380 381 if (!rs) 382 abort (); 383 memcpy (&sr->curr, rs, sizeof(*rs)); 384 free_reg_state (rs); 385} 386 387/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ 388 389static struct unw_reg_state * 390dup_state_stack (struct unw_reg_state *rs) 391{ 392 struct unw_reg_state *copy, *prev = NULL, *first = NULL; 393 394 while (rs) 395 { 396 copy = alloc_reg_state (); 397 memcpy (copy, rs, sizeof(*copy)); 398 if (first) 399 prev->next = copy; 400 else 401 first = copy; 402 rs = rs->next; 403 prev = copy; 404 } 405 406 return first; 407} 408 409/* Free all stacked register states (but not RS itself). */ 410static void 411free_state_stack (struct unw_reg_state *rs) 412{ 413 struct unw_reg_state *p, *next; 414 415 for (p = rs->next; p != NULL; p = next) 416 { 417 next = p->next; 418 free_reg_state (p); 419 } 420 rs->next = NULL; 421} 422 423/* Free all labeled states. */ 424 425static void 426free_label_states (struct unw_labeled_state *ls) 427{ 428 struct unw_labeled_state *next; 429 430 for (; ls ; ls = next) 431 { 432 next = ls->next; 433 434 free_state_stack (&ls->saved_state); 435 free_label_state (ls); 436 } 437} 438 439/* Unwind decoder routines */ 440 441static enum unw_register_index __attribute__((const)) 442decode_abreg (unsigned char abreg, int memory) 443{ 444 switch (abreg) 445 { 446 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04); 447 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22); 448 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30); 449 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41); 450 case 0x60: return UNW_REG_PR; 451 case 0x61: return UNW_REG_PSP; 452 case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR; 453 case 0x63: return UNW_REG_RP; 454 case 0x64: return UNW_REG_BSP; 455 case 0x65: return UNW_REG_BSPSTORE; 456 case 0x66: return UNW_REG_RNAT; 457 case 0x67: return UNW_REG_UNAT; 458 case 0x68: return UNW_REG_FPSR; 459 case 0x69: return UNW_REG_PFS; 460 case 0x6a: return UNW_REG_LC; 461 default: 462 abort (); 463 } 464} 465 466static void 467set_reg (struct unw_reg_info *reg, enum unw_where where, 468 int when, unsigned long val) 469{ 470 reg->val = val; 471 reg->where = where; 472 if (reg->when == UNW_WHEN_NEVER) 473 reg->when = when; 474} 475 476static void 477alloc_spill_area (unsigned long *offp, unsigned long regsize, 478 struct unw_reg_info *lo, struct unw_reg_info *hi) 479{ 480 struct unw_reg_info *reg; 481 482 for (reg = hi; reg >= lo; --reg) 483 { 484 if (reg->where == UNW_WHERE_SPILL_HOME) 485 { 486 reg->where = UNW_WHERE_PSPREL; 487 *offp -= regsize; 488 reg->val = *offp; 489 } 490 } 491} 492 493static inline void 494spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, 495 unw_word t) 496{ 497 struct unw_reg_info *reg; 498 499 for (reg = *regp; reg <= lim; ++reg) 500 { 501 if (reg->where == UNW_WHERE_SPILL_HOME) 502 { 503 reg->when = t; 504 *regp = reg + 1; 505 return; 506 } 507 } 508 /* Excess spill. */ 509 abort (); 510} 511 512static void 513finish_prologue (struct unw_state_record *sr) 514{ 515 struct unw_reg_info *reg; 516 unsigned long off; 517 int i; 518 519 /* First, resolve implicit register save locations 520 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */ 521 522 for (i = 0; i < (int) sizeof (save_order); ++i) 523 { 524 reg = sr->curr.reg + save_order[i]; 525 if (reg->where == UNW_WHERE_GR_SAVE) 526 { 527 reg->where = UNW_WHERE_GR; 528 reg->val = sr->gr_save_loc++; 529 } 530 } 531 532 /* Next, compute when the fp, general, and branch registers get saved. 533 This must come before alloc_spill_area() because we need to know 534 which registers are spilled to their home locations. */ 535 if (sr->imask) 536 { 537 static unsigned char const limit[3] = { 538 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5 539 }; 540 541 unsigned char kind, mask = 0, *cp = sr->imask; 542 int t; 543 struct unw_reg_info *(regs[3]); 544 545 regs[0] = sr->curr.reg + UNW_REG_F2; 546 regs[1] = sr->curr.reg + UNW_REG_R4; 547 regs[2] = sr->curr.reg + UNW_REG_B1; 548 549 for (t = 0; t < sr->region_len; ++t) 550 { 551 if ((t & 3) == 0) 552 mask = *cp++; 553 kind = (mask >> 2*(3-(t & 3))) & 3; 554 if (kind > 0) 555 spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1], 556 sr->region_start + t); 557 } 558 } 559 560 /* Next, lay out the memory stack spill area. */ 561 if (sr->any_spills) 562 { 563 off = sr->spill_offset; 564 alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2, 565 sr->curr.reg + UNW_REG_F31); 566 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1, 567 sr->curr.reg + UNW_REG_B5); 568 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4, 569 sr->curr.reg + UNW_REG_R7); 570 } 571} 572 573/* 574 * Region header descriptors. 575 */ 576 577static void 578desc_prologue (int body, unw_word rlen, unsigned char mask, 579 unsigned char grsave, struct unw_state_record *sr) 580{ 581 int i; 582 583 if (!(sr->in_body || sr->first_region)) 584 finish_prologue (sr); 585 sr->first_region = 0; 586 587 /* Check if we're done. */ 588 if (sr->when_target < sr->region_start + sr->region_len) 589 { 590 sr->done = 1; 591 return; 592 } 593 594 for (i = 0; i < sr->epilogue_count; ++i) 595 pop (sr); 596 597 sr->epilogue_count = 0; 598 sr->epilogue_start = UNW_WHEN_NEVER; 599 600 if (!body) 601 push (sr); 602 603 sr->region_start += sr->region_len; 604 sr->region_len = rlen; 605 sr->in_body = body; 606 607 if (!body) 608 { 609 for (i = 0; i < 4; ++i) 610 { 611 if (mask & 0x8) 612 set_reg (sr->curr.reg + save_order[i], UNW_WHERE_GR, 613 sr->region_start + sr->region_len - 1, grsave++); 614 mask <<= 1; 615 } 616 sr->gr_save_loc = grsave; 617 sr->any_spills = 0; 618 sr->imask = 0; 619 sr->spill_offset = 0x10; /* default to psp+16 */ 620 } 621} 622 623/* 624 * Prologue descriptors. 625 */ 626 627static inline void 628desc_abi (unsigned char abi, 629 unsigned char context, 630 struct unw_state_record *sr) 631{ 632 sr->unwabi = (abi << 8) | context; 633} 634 635static inline void 636desc_br_gr (unsigned char brmask, unsigned char gr, 637 struct unw_state_record *sr) 638{ 639 int i; 640 641 for (i = 0; i < 5; ++i) 642 { 643 if (brmask & 1) 644 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR, 645 sr->region_start + sr->region_len - 1, gr++); 646 brmask >>= 1; 647 } 648} 649 650static inline void 651desc_br_mem (unsigned char brmask, struct unw_state_record *sr) 652{ 653 int i; 654 655 for (i = 0; i < 5; ++i) 656 { 657 if (brmask & 1) 658 { 659 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME, 660 sr->region_start + sr->region_len - 1, 0); 661 sr->any_spills = 1; 662 } 663 brmask >>= 1; 664 } 665} 666 667static inline void 668desc_frgr_mem (unsigned char grmask, unw_word frmask, 669 struct unw_state_record *sr) 670{ 671 int i; 672 673 for (i = 0; i < 4; ++i) 674 { 675 if ((grmask & 1) != 0) 676 { 677 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME, 678 sr->region_start + sr->region_len - 1, 0); 679 sr->any_spills = 1; 680 } 681 grmask >>= 1; 682 } 683 for (i = 0; i < 20; ++i) 684 { 685 if ((frmask & 1) != 0) 686 { 687 enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4; 688 set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME, 689 sr->region_start + sr->region_len - 1, 0); 690 sr->any_spills = 1; 691 } 692 frmask >>= 1; 693 } 694} 695 696static inline void 697desc_fr_mem (unsigned char frmask, struct unw_state_record *sr) 698{ 699 int i; 700 701 for (i = 0; i < 4; ++i) 702 { 703 if ((frmask & 1) != 0) 704 { 705 set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME, 706 sr->region_start + sr->region_len - 1, 0); 707 sr->any_spills = 1; 708 } 709 frmask >>= 1; 710 } 711} 712 713static inline void 714desc_gr_gr (unsigned char grmask, unsigned char gr, 715 struct unw_state_record *sr) 716{ 717 int i; 718 719 for (i = 0; i < 4; ++i) 720 { 721 if ((grmask & 1) != 0) 722 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR, 723 sr->region_start + sr->region_len - 1, gr++); 724 grmask >>= 1; 725 } 726} 727 728static inline void 729desc_gr_mem (unsigned char grmask, struct unw_state_record *sr) 730{ 731 int i; 732 733 for (i = 0; i < 4; ++i) 734 { 735 if ((grmask & 1) != 0) 736 { 737 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME, 738 sr->region_start + sr->region_len - 1, 0); 739 sr->any_spills = 1; 740 } 741 grmask >>= 1; 742 } 743} 744 745static inline void 746desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr) 747{ 748 set_reg (sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE, 749 sr->region_start + MIN ((int)t, sr->region_len - 1), 16*size); 750} 751 752static inline void 753desc_mem_stack_v (unw_word t, struct unw_state_record *sr) 754{ 755 sr->curr.reg[UNW_REG_PSP].when 756 = sr->region_start + MIN ((int)t, sr->region_len - 1); 757} 758 759static inline void 760desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr) 761{ 762 set_reg (sr->curr.reg + reg, UNW_WHERE_GR, 763 sr->region_start + sr->region_len - 1, dst); 764} 765 766static inline void 767desc_reg_psprel (unsigned char reg, unw_word pspoff, 768 struct unw_state_record *sr) 769{ 770 set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL, 771 sr->region_start + sr->region_len - 1, 772 0x10 - 4*pspoff); 773} 774 775static inline void 776desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr) 777{ 778 set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL, 779 sr->region_start + sr->region_len - 1, 780 4*spoff); 781} 782 783static inline void 784desc_rp_br (unsigned char dst, struct unw_state_record *sr) 785{ 786 sr->return_link_reg = dst; 787} 788 789static inline void 790desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr) 791{ 792 struct unw_reg_info *reg = sr->curr.reg + regnum; 793 794 if (reg->where == UNW_WHERE_NONE) 795 reg->where = UNW_WHERE_GR_SAVE; 796 reg->when = sr->region_start + MIN ((int)t, sr->region_len - 1); 797} 798 799static inline void 800desc_spill_base (unw_word pspoff, struct unw_state_record *sr) 801{ 802 sr->spill_offset = 0x10 - 4*pspoff; 803} 804 805static inline unsigned char * 806desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr) 807{ 808 sr->imask = imaskp; 809 return imaskp + (2*sr->region_len + 7)/8; 810} 811 812/* 813 * Body descriptors. 814 */ 815static inline void 816desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr) 817{ 818 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t; 819 sr->epilogue_count = ecount + 1; 820} 821 822static inline void 823desc_copy_state (unw_word label, struct unw_state_record *sr) 824{ 825 struct unw_labeled_state *ls; 826 827 for (ls = sr->labeled_states; ls; ls = ls->next) 828 { 829 if (ls->label == label) 830 { 831 free_state_stack (&sr->curr); 832 memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr)); 833 sr->curr.next = dup_state_stack (ls->saved_state.next); 834 return; 835 } 836 } 837 abort (); 838} 839 840static inline void 841desc_label_state (unw_word label, struct unw_state_record *sr) 842{ 843 struct unw_labeled_state *ls = alloc_label_state (); 844 845 ls->label = label; 846 memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state)); 847 ls->saved_state.next = dup_state_stack (sr->curr.next); 848 849 /* Insert into list of labeled states. */ 850 ls->next = sr->labeled_states; 851 sr->labeled_states = ls; 852} 853 854/* 855 * General descriptors. 856 */ 857 858static inline int 859desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr) 860{ 861 if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1)) 862 return 0; 863 if (qp > 0) 864 { 865 if ((sr->pr_val & (1UL << qp)) == 0) 866 return 0; 867 sr->pr_mask |= (1UL << qp); 868 } 869 return 1; 870} 871 872static inline void 873desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, 874 struct unw_state_record *sr) 875{ 876 struct unw_reg_info *r; 877 878 if (! desc_is_active (qp, t, sr)) 879 return; 880 881 r = sr->curr.reg + decode_abreg (abreg, 0); 882 r->where = UNW_WHERE_NONE; 883 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1); 884 r->val = 0; 885} 886 887static inline void 888desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, 889 unsigned char x, unsigned char ytreg, 890 struct unw_state_record *sr) 891{ 892 enum unw_where where = UNW_WHERE_GR; 893 struct unw_reg_info *r; 894 895 if (! desc_is_active (qp, t, sr)) 896 return; 897 898 if (x) 899 where = UNW_WHERE_BR; 900 else if (ytreg & 0x80) 901 where = UNW_WHERE_FR; 902 903 r = sr->curr.reg + decode_abreg (abreg, 0); 904 r->where = where; 905 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1); 906 r->val = ytreg & 0x7f; 907} 908 909static inline void 910desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, 911 unw_word pspoff, struct unw_state_record *sr) 912{ 913 struct unw_reg_info *r; 914 915 if (! desc_is_active (qp, t, sr)) 916 return; 917 918 r = sr->curr.reg + decode_abreg (abreg, 1); 919 r->where = UNW_WHERE_PSPREL; 920 r->when = sr->region_start + MIN((int)t, sr->region_len - 1); 921 r->val = 0x10 - 4*pspoff; 922} 923 924static inline void 925desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, 926 unw_word spoff, struct unw_state_record *sr) 927{ 928 struct unw_reg_info *r; 929 930 if (! desc_is_active (qp, t, sr)) 931 return; 932 933 r = sr->curr.reg + decode_abreg (abreg, 1); 934 r->where = UNW_WHERE_SPREL; 935 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1); 936 r->val = 4*spoff; 937} 938 939 940#define UNW_DEC_BAD_CODE(code) abort (); 941 942/* Region headers. */ 943#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) 944#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) 945 946/* Prologue descriptors. */ 947#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) 948#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) 949#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) 950#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) 951#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) 952#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) 953#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) 954#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) 955#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) 956#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) 957#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) 958#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) 959#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) 960#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg) 961#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg) 962#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg) 963#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg) 964#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg) 965#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) 966#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) 967#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) 968 969/* Body descriptors. */ 970#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) 971#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) 972#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) 973 974/* General unwind descriptors. */ 975#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) 976#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) 977#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg) 978#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg) 979#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) 980#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) 981#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) 982#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) 983 984 985/* 986 * Generic IA-64 unwind info decoder. 987 * 988 * This file is used both by the Linux kernel and objdump. Please keep 989 * the copies of this file in sync. 990 * 991 * You need to customize the decoder by defining the following 992 * macros/constants before including this file: 993 * 994 * Types: 995 * unw_word Unsigned integer type with at least 64 bits 996 * 997 * Register names: 998 * UNW_REG_BSP 999 * UNW_REG_BSPSTORE 1000 * UNW_REG_FPSR 1001 * UNW_REG_LC 1002 * UNW_REG_PFS 1003 * UNW_REG_PR 1004 * UNW_REG_RNAT 1005 * UNW_REG_PSP 1006 * UNW_REG_RP 1007 * UNW_REG_UNAT 1008 * 1009 * Decoder action macros: 1010 * UNW_DEC_BAD_CODE(code) 1011 * UNW_DEC_ABI(fmt,abi,context,arg) 1012 * UNW_DEC_BR_GR(fmt,brmask,gr,arg) 1013 * UNW_DEC_BR_MEM(fmt,brmask,arg) 1014 * UNW_DEC_COPY_STATE(fmt,label,arg) 1015 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) 1016 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) 1017 * UNW_DEC_FR_MEM(fmt,frmask,arg) 1018 * UNW_DEC_GR_GR(fmt,grmask,gr,arg) 1019 * UNW_DEC_GR_MEM(fmt,grmask,arg) 1020 * UNW_DEC_LABEL_STATE(fmt,label,arg) 1021 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) 1022 * UNW_DEC_MEM_STACK_V(fmt,t,arg) 1023 * UNW_DEC_PRIUNAT_GR(fmt,r,arg) 1024 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) 1025 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) 1026 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) 1027 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) 1028 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) 1029 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) 1030 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) 1031 * UNW_DEC_REG_REG(fmt,src,dst,arg) 1032 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) 1033 * UNW_DEC_REG_WHEN(fmt,reg,t,arg) 1034 * UNW_DEC_RESTORE(fmt,t,abreg,arg) 1035 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) 1036 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) 1037 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) 1038 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) 1039 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) 1040 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) 1041 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) 1042 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) 1043 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) 1044 */ 1045 1046static unw_word 1047unw_decode_uleb128 (unsigned char **dpp) 1048{ 1049 unsigned shift = 0; 1050 unw_word byte, result = 0; 1051 unsigned char *bp = *dpp; 1052 1053 while (1) 1054 { 1055 byte = *bp++; 1056 result |= (byte & 0x7f) << shift; 1057 if ((byte & 0x80) == 0) 1058 break; 1059 shift += 7; 1060 } 1061 *dpp = bp; 1062 return result; 1063} 1064 1065static unsigned char * 1066unw_decode_x1 (unsigned char *dp, 1067 unsigned char code __attribute__((unused)), 1068 void *arg) 1069{ 1070 unsigned char byte1, abreg; 1071 unw_word t, off; 1072 1073 byte1 = *dp++; 1074 t = unw_decode_uleb128 (&dp); 1075 off = unw_decode_uleb128 (&dp); 1076 abreg = (byte1 & 0x7f); 1077 if (byte1 & 0x80) 1078 UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg); 1079 else 1080 UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg); 1081 return dp; 1082} 1083 1084static unsigned char * 1085unw_decode_x2 (unsigned char *dp, 1086 unsigned char code __attribute__((unused)), 1087 void *arg) 1088{ 1089 unsigned char byte1, byte2, abreg, x, ytreg; 1090 unw_word t; 1091 1092 byte1 = *dp++; byte2 = *dp++; 1093 t = unw_decode_uleb128 (&dp); 1094 abreg = (byte1 & 0x7f); 1095 ytreg = byte2; 1096 x = (byte1 >> 7) & 1; 1097 if ((byte1 & 0x80) == 0 && ytreg == 0) 1098 UNW_DEC_RESTORE(X2, t, abreg, arg); 1099 else 1100 UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg); 1101 return dp; 1102} 1103 1104static unsigned char * 1105unw_decode_x3 (unsigned char *dp, 1106 unsigned char code __attribute__((unused)), 1107 void *arg) 1108{ 1109 unsigned char byte1, byte2, abreg, qp; 1110 unw_word t, off; 1111 1112 byte1 = *dp++; byte2 = *dp++; 1113 t = unw_decode_uleb128 (&dp); 1114 off = unw_decode_uleb128 (&dp); 1115 1116 qp = (byte1 & 0x3f); 1117 abreg = (byte2 & 0x7f); 1118 1119 if (byte1 & 0x80) 1120 UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg); 1121 else 1122 UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg); 1123 return dp; 1124} 1125 1126static unsigned char * 1127unw_decode_x4 (unsigned char *dp, 1128 unsigned char code __attribute__((unused)), 1129 void *arg) 1130{ 1131 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; 1132 unw_word t; 1133 1134 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; 1135 t = unw_decode_uleb128 (&dp); 1136 1137 qp = (byte1 & 0x3f); 1138 abreg = (byte2 & 0x7f); 1139 x = (byte2 >> 7) & 1; 1140 ytreg = byte3; 1141 1142 if ((byte2 & 0x80) == 0 && byte3 == 0) 1143 UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg); 1144 else 1145 UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg); 1146 return dp; 1147} 1148 1149static unsigned char * 1150unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg) 1151{ 1152 int body = (code & 0x20) != 0; 1153 unw_word rlen; 1154 1155 rlen = (code & 0x1f); 1156 UNW_DEC_PROLOGUE(R1, body, rlen, arg); 1157 return dp; 1158} 1159 1160static unsigned char * 1161unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg) 1162{ 1163 unsigned char byte1, mask, grsave; 1164 unw_word rlen; 1165 1166 byte1 = *dp++; 1167 1168 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); 1169 grsave = (byte1 & 0x7f); 1170 rlen = unw_decode_uleb128 (&dp); 1171 UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg); 1172 return dp; 1173} 1174 1175static unsigned char * 1176unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg) 1177{ 1178 unw_word rlen; 1179 1180 rlen = unw_decode_uleb128 (&dp); 1181 UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg); 1182 return dp; 1183} 1184 1185static unsigned char * 1186unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg) 1187{ 1188 unsigned char brmask = (code & 0x1f); 1189 1190 UNW_DEC_BR_MEM(P1, brmask, arg); 1191 return dp; 1192} 1193 1194static unsigned char * 1195unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg) 1196{ 1197 if ((code & 0x10) == 0) 1198 { 1199 unsigned char byte1 = *dp++; 1200 1201 UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1), 1202 (byte1 & 0x7f), arg); 1203 } 1204 else if ((code & 0x08) == 0) 1205 { 1206 unsigned char byte1 = *dp++, r, dst; 1207 1208 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); 1209 dst = (byte1 & 0x7f); 1210 switch (r) 1211 { 1212 case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break; 1213 case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break; 1214 case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break; 1215 case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break; 1216 case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break; 1217 case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break; 1218 case 6: UNW_DEC_RP_BR(P3, dst, arg); break; 1219 case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break; 1220 case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break; 1221 case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break; 1222 case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break; 1223 case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break; 1224 default: UNW_DEC_BAD_CODE(r); break; 1225 } 1226 } 1227 else if ((code & 0x7) == 0) 1228 UNW_DEC_SPILL_MASK(P4, dp, arg); 1229 else if ((code & 0x7) == 1) 1230 { 1231 unw_word grmask, frmask, byte1, byte2, byte3; 1232 1233 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; 1234 grmask = ((byte1 >> 4) & 0xf); 1235 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; 1236 UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg); 1237 } 1238 else 1239 UNW_DEC_BAD_CODE(code); 1240 return dp; 1241} 1242 1243static unsigned char * 1244unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg) 1245{ 1246 int gregs = (code & 0x10) != 0; 1247 unsigned char mask = (code & 0x0f); 1248 1249 if (gregs) 1250 UNW_DEC_GR_MEM(P6, mask, arg); 1251 else 1252 UNW_DEC_FR_MEM(P6, mask, arg); 1253 return dp; 1254} 1255 1256static unsigned char * 1257unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg) 1258{ 1259 unsigned char r, byte1, byte2; 1260 unw_word t, size; 1261 1262 if ((code & 0x10) == 0) 1263 { 1264 r = (code & 0xf); 1265 t = unw_decode_uleb128 (&dp); 1266 switch (r) 1267 { 1268 case 0: 1269 size = unw_decode_uleb128 (&dp); 1270 UNW_DEC_MEM_STACK_F(P7, t, size, arg); 1271 break; 1272 1273 case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break; 1274 case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break; 1275 case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break; 1276 case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break; 1277 case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break; 1278 case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break; 1279 case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break; 1280 case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break; 1281 case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break; 1282 case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break; 1283 case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break; 1284 case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break; 1285 case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break; 1286 case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break; 1287 case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break; 1288 default: UNW_DEC_BAD_CODE(r); break; 1289 } 1290 } 1291 else 1292 { 1293 switch (code & 0xf) 1294 { 1295 case 0x0: /* p8 */ 1296 { 1297 r = *dp++; 1298 t = unw_decode_uleb128 (&dp); 1299 switch (r) 1300 { 1301 case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break; 1302 case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break; 1303 case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break; 1304 case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break; 1305 case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break; 1306 case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break; 1307 case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break; 1308 case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break; 1309 case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break; 1310 case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break; 1311 case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break; 1312 case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break; 1313 case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break; 1314 case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break; 1315 case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break; 1316 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break; 1317 case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break; 1318 case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break; 1319 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break; 1320 default: UNW_DEC_BAD_CODE(r); break; 1321 } 1322 } 1323 break; 1324 1325 case 0x1: 1326 byte1 = *dp++; byte2 = *dp++; 1327 UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg); 1328 break; 1329 1330 case 0xf: /* p10 */ 1331 byte1 = *dp++; byte2 = *dp++; 1332 UNW_DEC_ABI(P10, byte1, byte2, arg); 1333 break; 1334 1335 case 0x9: 1336 return unw_decode_x1 (dp, code, arg); 1337 1338 case 0xa: 1339 return unw_decode_x2 (dp, code, arg); 1340 1341 case 0xb: 1342 return unw_decode_x3 (dp, code, arg); 1343 1344 case 0xc: 1345 return unw_decode_x4 (dp, code, arg); 1346 1347 default: 1348 UNW_DEC_BAD_CODE(code); 1349 break; 1350 } 1351 } 1352 return dp; 1353} 1354 1355static unsigned char * 1356unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg) 1357{ 1358 unw_word label = (code & 0x1f); 1359 1360 if ((code & 0x20) != 0) 1361 UNW_DEC_COPY_STATE(B1, label, arg); 1362 else 1363 UNW_DEC_LABEL_STATE(B1, label, arg); 1364 return dp; 1365} 1366 1367static unsigned char * 1368unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg) 1369{ 1370 unw_word t; 1371 1372 t = unw_decode_uleb128 (&dp); 1373 UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg); 1374 return dp; 1375} 1376 1377static unsigned char * 1378unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg) 1379{ 1380 unw_word t, ecount, label; 1381 1382 if ((code & 0x10) == 0) 1383 { 1384 t = unw_decode_uleb128 (&dp); 1385 ecount = unw_decode_uleb128 (&dp); 1386 UNW_DEC_EPILOGUE(B3, t, ecount, arg); 1387 } 1388 else if ((code & 0x07) == 0) 1389 { 1390 label = unw_decode_uleb128 (&dp); 1391 if ((code & 0x08) != 0) 1392 UNW_DEC_COPY_STATE(B4, label, arg); 1393 else 1394 UNW_DEC_LABEL_STATE(B4, label, arg); 1395 } 1396 else 1397 switch (code & 0x7) 1398 { 1399 case 1: return unw_decode_x1 (dp, code, arg); 1400 case 2: return unw_decode_x2 (dp, code, arg); 1401 case 3: return unw_decode_x3 (dp, code, arg); 1402 case 4: return unw_decode_x4 (dp, code, arg); 1403 default: UNW_DEC_BAD_CODE(code); break; 1404 } 1405 return dp; 1406} 1407 1408typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *); 1409 1410static const unw_decoder unw_decode_table[2][8] = 1411{ 1412 /* prologue table: */ 1413 { 1414 unw_decode_r1, /* 0 */ 1415 unw_decode_r1, 1416 unw_decode_r2, 1417 unw_decode_r3, 1418 unw_decode_p1, /* 4 */ 1419 unw_decode_p2_p5, 1420 unw_decode_p6, 1421 unw_decode_p7_p10 1422 }, 1423 { 1424 unw_decode_r1, /* 0 */ 1425 unw_decode_r1, 1426 unw_decode_r2, 1427 unw_decode_r3, 1428 unw_decode_b1, /* 4 */ 1429 unw_decode_b1, 1430 unw_decode_b2, 1431 unw_decode_b3_x4 1432 } 1433}; 1434 1435/* 1436 * Decode one descriptor and return address of next descriptor. 1437 */ 1438static inline unsigned char * 1439unw_decode (unsigned char *dp, int inside_body, void *arg) 1440{ 1441 unw_decoder decoder; 1442 unsigned char code; 1443 1444 code = *dp++; 1445 decoder = unw_decode_table[inside_body][code >> 5]; 1446 dp = (*decoder) (dp, code, arg); 1447 return dp; 1448} 1449 1450 1451/* RSE helper functions. */ 1452 1453static inline unsigned long 1454ia64_rse_slot_num (unsigned long *addr) 1455{ 1456 return (((unsigned long) addr) >> 3) & 0x3f; 1457} 1458 1459/* Return TRUE if ADDR is the address of an RNAT slot. */ 1460static inline unsigned long 1461ia64_rse_is_rnat_slot (unsigned long *addr) 1462{ 1463 return ia64_rse_slot_num (addr) == 0x3f; 1464} 1465 1466/* Returns the address of the RNAT slot that covers the slot at 1467 address SLOT_ADDR. */ 1468static inline unsigned long * 1469ia64_rse_rnat_addr (unsigned long *slot_addr) 1470{ 1471 return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3)); 1472} 1473 1474/* Calculate the number of registers in the dirty partition starting at 1475 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY 1476 divided by eight because the 64th slot is used to store ar.rnat. */ 1477static inline unsigned long 1478ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp) 1479{ 1480 unsigned long slots = (bsp - bspstore); 1481 1482 return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40; 1483} 1484 1485/* The inverse of the above: given bspstore and the number of 1486 registers, calculate ar.bsp. */ 1487static inline unsigned long * 1488ia64_rse_skip_regs (unsigned long *addr, long num_regs) 1489{ 1490 long delta = ia64_rse_slot_num (addr) + num_regs; 1491 1492 if (num_regs < 0) 1493 delta -= 0x3e; 1494 return addr + num_regs + delta/0x3f; 1495} 1496 1497 1498/* Copy register backing store from SRC to DST, LEN words 1499 (which include both saved registers and nat collections). 1500 DST_RNAT is a partial nat collection for DST. SRC and DST 1501 don't have to be equal modulo 64 slots, so it cannot be 1502 done with a simple memcpy as the nat collections will be 1503 at different relative offsets and need to be combined together. */ 1504static void 1505ia64_copy_rbs (struct _Unwind_Context *info, unsigned long dst, 1506 unsigned long src, long len, unsigned long dst_rnat) 1507{ 1508 long count; 1509 unsigned long src_rnat; 1510 unsigned long shift1, shift2; 1511 1512 len <<= 3; 1513 dst_rnat &= (1UL << ((dst >> 3) & 0x3f)) - 1; 1514 src_rnat = src >= info->regstk_top 1515 ? info->rnat : *(unsigned long *) (src | 0x1f8); 1516 src_rnat &= ~((1UL << ((src >> 3) & 0x3f)) - 1); 1517 /* Just to make sure. */ 1518 src_rnat &= ~(1UL << 63); 1519 shift1 = ((dst - src) >> 3) & 0x3f; 1520 if ((dst & 0x1f8) < (src & 0x1f8)) 1521 shift1--; 1522 shift2 = 0x3f - shift1; 1523 if ((dst & 0x1f8) >= (src & 0x1f8)) 1524 { 1525 count = ~dst & 0x1f8; 1526 goto first; 1527 } 1528 count = ~src & 0x1f8; 1529 goto second; 1530 while (len > 0) 1531 { 1532 src_rnat = src >= info->regstk_top 1533 ? info->rnat : *(unsigned long *) (src | 0x1f8); 1534 /* Just to make sure. */ 1535 src_rnat &= ~(1UL << 63); 1536 count = shift2 << 3; 1537first: 1538 if (count > len) 1539 count = len; 1540 memcpy ((char *) dst, (char *) src, count); 1541 dst += count; 1542 src += count; 1543 len -= count; 1544 dst_rnat |= (src_rnat << shift1) & ~(1UL << 63); 1545 if (len <= 0) 1546 break; 1547 *(long *) dst = dst_rnat; 1548 dst += 8; 1549 dst_rnat = 0; 1550 count = shift1 << 3; 1551second: 1552 if (count > len) 1553 count = len; 1554 memcpy ((char *) dst, (char *) src, count); 1555 dst += count; 1556 src += count + 8; 1557 len -= count + 8; 1558 dst_rnat |= (src_rnat >> shift2); 1559 } 1560 if ((dst & 0x1f8) == 0x1f8) 1561 { 1562 *(long *) dst = dst_rnat; 1563 dst += 8; 1564 dst_rnat = 0; 1565 } 1566 /* Set info->regstk_top to lowest rbs address which will use 1567 info->rnat collection. */ 1568 info->regstk_top = dst & ~0x1ffUL; 1569 info->rnat = dst_rnat; 1570} 1571 1572/* Unwind accessors. */ 1573 1574static void 1575unw_access_gr (struct _Unwind_Context *info, int regnum, 1576 unsigned long *val, char *nat, int write) 1577{ 1578 unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat; 1579 struct unw_ireg *ireg; 1580 1581 if ((unsigned) regnum - 1 >= 127) 1582 abort (); 1583 1584 if (regnum < 1) 1585 { 1586 nat_addr = addr = &dummy_nat; 1587 dummy_nat = 0; 1588 } 1589 else if (regnum < 32) 1590 { 1591 /* Access a non-stacked register. */ 1592 ireg = &info->ireg[regnum - 2]; 1593 addr = ireg->loc; 1594 if (addr) 1595 { 1596 nat_addr = addr + ireg->nat.off; 1597 switch (ireg->nat.type) 1598 { 1599 case UNW_NAT_VAL: 1600 /* Simulate getf.sig/setf.sig. */ 1601 if (write) 1602 { 1603 if (*nat) 1604 { 1605 /* Write NaTVal and be done with it. */ 1606 addr[0] = 0; 1607 addr[1] = 0x1fffe; 1608 return; 1609 } 1610 addr[1] = 0x1003e; 1611 } 1612 else if (addr[0] == 0 && addr[1] == 0x1ffe) 1613 { 1614 /* Return NaT and be done with it. */ 1615 *val = 0; 1616 *nat = 1; 1617 return; 1618 } 1619 /* FALLTHRU */ 1620 1621 case UNW_NAT_NONE: 1622 dummy_nat = 0; 1623 nat_addr = &dummy_nat; 1624 break; 1625 1626 case UNW_NAT_MEMSTK: 1627 nat_mask = 1UL << ((long) addr & 0x1f8)/8; 1628 break; 1629 1630 case UNW_NAT_REGSTK: 1631 if ((unsigned long) addr >= info->regstk_top) 1632 nat_addr = &info->rnat; 1633 else 1634 nat_addr = ia64_rse_rnat_addr (addr); 1635 nat_mask = 1UL << ia64_rse_slot_num (addr); 1636 break; 1637 } 1638 } 1639 } 1640 else 1641 { 1642 /* Access a stacked register. */ 1643 addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32); 1644 if ((unsigned long) addr >= info->regstk_top) 1645 nat_addr = &info->rnat; 1646 else 1647 nat_addr = ia64_rse_rnat_addr (addr); 1648 nat_mask = 1UL << ia64_rse_slot_num (addr); 1649 } 1650 1651 if (write) 1652 { 1653 *addr = *val; 1654 if (*nat) 1655 *nat_addr |= nat_mask; 1656 else 1657 *nat_addr &= ~nat_mask; 1658 } 1659 else 1660 { 1661 *val = *addr; 1662 *nat = (*nat_addr & nat_mask) != 0; 1663 } 1664} 1665 1666/* Get the value of register REG as saved in CONTEXT. */ 1667 1668_Unwind_Word 1669_Unwind_GetGR (struct _Unwind_Context *context, int index) 1670{ 1671 _Unwind_Word ret; 1672 char nat; 1673 1674 if (index == 1) 1675 return context->gp; 1676 else if (index >= 15 && index <= 18) 1677 return context->eh_data[index - 15]; 1678 else 1679 unw_access_gr (context, index, &ret, &nat, 0); 1680 1681 return ret; 1682} 1683 1684/* Overwrite the saved value for register REG in CONTEXT with VAL. */ 1685 1686void 1687_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) 1688{ 1689 char nat = 0; 1690 1691 if (index == 1) 1692 context->gp = val; 1693 else if (index >= 15 && index <= 18) 1694 context->eh_data[index - 15] = val; 1695 else 1696 unw_access_gr (context, index, &val, &nat, 1); 1697} 1698 1699/* Retrieve the return address for CONTEXT. */ 1700 1701inline _Unwind_Ptr 1702_Unwind_GetIP (struct _Unwind_Context *context) 1703{ 1704 return context->rp; 1705} 1706 1707inline _Unwind_Ptr 1708_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) 1709{ 1710 *ip_before_insn = 0; 1711 return context->rp; 1712} 1713 1714/* Overwrite the return address for CONTEXT with VAL. */ 1715 1716inline void 1717_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val) 1718{ 1719 context->rp = val; 1720} 1721 1722void * 1723_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) 1724{ 1725 return context->lsda; 1726} 1727 1728_Unwind_Ptr 1729_Unwind_GetRegionStart (struct _Unwind_Context *context) 1730{ 1731 return context->region_start; 1732} 1733 1734void * 1735_Unwind_FindEnclosingFunction (void *pc) 1736{ 1737 struct unw_table_entry *ent; 1738 unsigned long segment_base, gp; 1739 1740 ent = _Unwind_FindTableEntry (pc, &segment_base, &gp); 1741 if (ent == NULL) 1742 return NULL; 1743 else 1744 return (void *)(segment_base + ent->start_offset); 1745} 1746 1747/* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance, 1748 the CFA is the value of the stack pointer on entry; In IA-64 unwind 1749 parlance, this is the PSP. */ 1750 1751_Unwind_Word 1752_Unwind_GetCFA (struct _Unwind_Context *context) 1753{ 1754 return (_Unwind_Ptr) context->psp; 1755} 1756 1757/* Get the value of the Backing Store Pointer as saved in CONTEXT. */ 1758 1759_Unwind_Word 1760_Unwind_GetBSP (struct _Unwind_Context *context) 1761{ 1762 return (_Unwind_Ptr) context->bsp; 1763} 1764 1765#ifdef MD_UNWIND_SUPPORT 1766#include MD_UNWIND_SUPPORT 1767#endif 1768 1769static _Unwind_Reason_Code 1770uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) 1771{ 1772 struct unw_table_entry *ent; 1773 unsigned long *unw, header, length; 1774 unsigned char *insn, *insn_end; 1775 unsigned long segment_base; 1776 struct unw_reg_info *r; 1777 1778 memset (fs, 0, sizeof (*fs)); 1779 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r) 1780 r->when = UNW_WHEN_NEVER; 1781 context->lsda = 0; 1782 1783 ent = _Unwind_FindTableEntry ((void *) context->rp, 1784 &segment_base, &context->gp); 1785 if (ent == NULL) 1786 { 1787 /* Couldn't find unwind info for this function. Try an 1788 os-specific fallback mechanism. This will necessarily 1789 not provide a personality routine or LSDA. */ 1790#ifdef MD_FALLBACK_FRAME_STATE_FOR 1791 if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON) 1792 return _URC_NO_REASON; 1793 1794 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception 1795 handlers, and which keeps the return value in B0 does not need 1796 an unwind table entry. 1797 1798 This can only happen in the frame after unwinding through a signal 1799 handler. Avoid infinite looping by requiring that B0 != RP. 1800 RP == 0 terminates the chain. */ 1801 if (context->br_loc[0] && *context->br_loc[0] != context->rp 1802 && context->rp != 0) 1803 { 1804 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; 1805 fs->curr.reg[UNW_REG_RP].when = -1; 1806 fs->curr.reg[UNW_REG_RP].val = 0; 1807 return _URC_NO_REASON; 1808 } 1809#endif 1810 return _URC_END_OF_STACK; 1811 } 1812 1813 context->region_start = ent->start_offset + segment_base; 1814 fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3 1815 + (context->rp & 15); 1816 1817 unw = (unsigned long *) (ent->info_offset + segment_base); 1818 header = *unw; 1819 length = UNW_LENGTH (header); 1820 1821 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */ 1822 1823 if (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header)) 1824 { 1825 fs->personality = 1826 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp); 1827 context->lsda = unw + length + 2; 1828 } 1829 1830 insn = (unsigned char *) (unw + 1); 1831 insn_end = (unsigned char *) (unw + 1 + length); 1832 while (!fs->done && insn < insn_end) 1833 insn = unw_decode (insn, fs->in_body, fs); 1834 1835 free_label_states (fs->labeled_states); 1836 free_state_stack (&fs->curr); 1837 1838#ifdef ENABLE_MALLOC_CHECKING 1839 if (reg_state_alloced || labeled_state_alloced) 1840 abort (); 1841#endif 1842 1843 /* If we're in the epilogue, sp has been restored and all values 1844 on the memory stack below psp also have been restored. */ 1845 if (fs->when_target > fs->epilogue_start) 1846 { 1847 struct unw_reg_info *r; 1848 1849 fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE; 1850 fs->curr.reg[UNW_REG_PSP].val = 0; 1851 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r) 1852 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10) 1853 || r->where == UNW_WHERE_SPREL) 1854 r->where = UNW_WHERE_NONE; 1855 } 1856 1857 /* If RP did't get saved, generate entry for the return link register. */ 1858 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target) 1859 { 1860 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; 1861 fs->curr.reg[UNW_REG_RP].when = -1; 1862 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg; 1863 } 1864 1865 return _URC_NO_REASON; 1866} 1867 1868static void 1869uw_update_reg_address (struct _Unwind_Context *context, 1870 _Unwind_FrameState *fs, 1871 enum unw_register_index regno) 1872{ 1873 struct unw_reg_info *r = fs->curr.reg + regno; 1874 void *addr; 1875 unsigned long rval; 1876 1877 if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target) 1878 return; 1879 1880 rval = r->val; 1881 switch (r->where) 1882 { 1883 case UNW_WHERE_GR: 1884 if (rval >= 32) 1885 addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32); 1886 else if (rval >= 2) 1887 addr = context->ireg[rval - 2].loc; 1888 else if (rval == 0) 1889 { 1890 static const unsigned long dummy; 1891 addr = (void *) &dummy; 1892 } 1893 else 1894 abort (); 1895 break; 1896 1897 case UNW_WHERE_FR: 1898 if (rval >= 2 && rval < 32) 1899 addr = context->fr_loc[rval - 2]; 1900 else 1901 abort (); 1902 break; 1903 1904 case UNW_WHERE_BR: 1905 /* Note that while RVAL can only be 1-5 from normal descriptors, 1906 we can want to look at B0, B6 and B7 due to having manually unwound a 1907 signal frame. */ 1908 if (rval < 8) 1909 addr = context->br_loc[rval]; 1910 else 1911 abort (); 1912 break; 1913 1914 case UNW_WHERE_SPREL: 1915 addr = (void *)(context->sp + rval); 1916 break; 1917 1918 case UNW_WHERE_PSPREL: 1919 addr = (void *)(context->psp + rval); 1920 break; 1921 1922 default: 1923 abort (); 1924 } 1925 1926 switch (regno) 1927 { 1928 case UNW_REG_R2 ... UNW_REG_R31: 1929 context->ireg[regno - UNW_REG_R2].loc = addr; 1930 switch (r->where) 1931 { 1932 case UNW_WHERE_GR: 1933 if (rval >= 32) 1934 { 1935 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK; 1936 context->ireg[regno - UNW_REG_R2].nat.off 1937 = context->pri_unat_loc - (unsigned long *) addr; 1938 } 1939 else if (rval >= 2) 1940 { 1941 context->ireg[regno - UNW_REG_R2].nat 1942 = context->ireg[rval - 2].nat; 1943 } 1944 else if (rval == 0) 1945 { 1946 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE; 1947 context->ireg[regno - UNW_REG_R2].nat.off = 0; 1948 } 1949 else 1950 abort (); 1951 break; 1952 1953 case UNW_WHERE_FR: 1954 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL; 1955 context->ireg[regno - UNW_REG_R2].nat.off = 0; 1956 break; 1957 1958 case UNW_WHERE_BR: 1959 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE; 1960 context->ireg[regno - UNW_REG_R2].nat.off = 0; 1961 break; 1962 1963 case UNW_WHERE_PSPREL: 1964 case UNW_WHERE_SPREL: 1965 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK; 1966 context->ireg[regno - UNW_REG_R2].nat.off 1967 = context->pri_unat_loc - (unsigned long *) addr; 1968 break; 1969 1970 default: 1971 abort (); 1972 } 1973 break; 1974 1975 case UNW_REG_F2 ... UNW_REG_F31: 1976 context->fr_loc[regno - UNW_REG_F2] = addr; 1977 break; 1978 1979 case UNW_REG_B1 ... UNW_REG_B5: 1980 context->br_loc[regno - UNW_REG_B0] = addr; 1981 break; 1982 1983 case UNW_REG_BSP: 1984 context->bsp_loc = addr; 1985 break; 1986 case UNW_REG_BSPSTORE: 1987 context->bspstore_loc = addr; 1988 break; 1989 case UNW_REG_PFS: 1990 context->pfs_loc = addr; 1991 break; 1992 case UNW_REG_RP: 1993 context->rp = *(unsigned long *)addr; 1994 break; 1995 case UNW_REG_UNAT: 1996 context->unat_loc = addr; 1997 break; 1998 case UNW_REG_PR: 1999 context->pr = *(unsigned long *) addr; 2000 break; 2001 case UNW_REG_LC: 2002 context->lc_loc = addr; 2003 break; 2004 case UNW_REG_FPSR: 2005 context->fpsr_loc = addr; 2006 break; 2007 2008 case UNW_REG_PSP: 2009 context->psp = *(unsigned long *)addr; 2010 break; 2011 2012 default: 2013 abort (); 2014 } 2015} 2016 2017static void 2018uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) 2019{ 2020 long i; 2021 2022#ifdef MD_HANDLE_UNWABI 2023 MD_HANDLE_UNWABI (context, fs); 2024#endif 2025 2026 context->sp = context->psp; 2027 2028 /* First, set PSP. Subsequent instructions may depend on this value. */ 2029 if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when) 2030 { 2031 if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE) 2032 context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val; 2033 else 2034 uw_update_reg_address (context, fs, UNW_REG_PSP); 2035 } 2036 2037 /* Determine the location of the primary UNaT. */ 2038 { 2039 int i; 2040 if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when) 2041 i = UNW_REG_PRI_UNAT_MEM; 2042 else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when) 2043 i = UNW_REG_PRI_UNAT_GR; 2044 else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when 2045 > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when) 2046 i = UNW_REG_PRI_UNAT_MEM; 2047 else 2048 i = UNW_REG_PRI_UNAT_GR; 2049 uw_update_reg_address (context, fs, i); 2050 } 2051 2052 /* Compute the addresses of all registers saved in this frame. */ 2053 for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i) 2054 uw_update_reg_address (context, fs, i); 2055 2056 /* Unwind BSP for the local registers allocated this frame. */ 2057 /* ??? What to do with stored BSP or BSPSTORE registers. */ 2058 /* We assert that we are either at a call site, or we have 2059 just unwound through a signal frame. In either case 2060 pfs_loc is valid. */ 2061 if (!(fs -> no_reg_stack_frame)) 2062 { 2063 unsigned long pfs = *context->pfs_loc; 2064 unsigned long sol = (pfs >> 7) & 0x7f; 2065 context->bsp = (unsigned long) 2066 ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol); 2067 } 2068} 2069 2070static void 2071uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) 2072{ 2073 uw_update_context (context, fs); 2074} 2075 2076/* Fill in CONTEXT for top-of-stack. The only valid registers at this 2077 level will be the return address and the CFA. Note that CFA = SP+16. */ 2078 2079#define uw_init_context(CONTEXT) \ 2080 do { \ 2081 /* ??? There is a whole lot o code in uw_install_context that \ 2082 tries to avoid spilling the entire machine state here. We \ 2083 should try to make that work again. */ \ 2084 __builtin_unwind_init(); \ 2085 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \ 2086 } while (0) 2087 2088static void 2089uw_init_context_1 (struct _Unwind_Context *context, void *bsp) 2090{ 2091 void *rp = __builtin_extract_return_addr (__builtin_return_address (0)); 2092 /* Set psp to the caller's stack pointer. */ 2093 void *psp = __builtin_dwarf_cfa () - 16; 2094 _Unwind_FrameState fs; 2095 unsigned long rnat, tmp1, tmp2; 2096 2097 /* Flush the register stack to memory so that we can access it. 2098 Get rse nat collection for the last incomplete rbs chunk of 2099 registers at the same time. For this RSE needs to be turned 2100 into the mandatory only mode. */ 2101 asm ("mov.m %1 = ar.rsc;;\n\t" 2102 "and %2 = 0x1c, %1;;\n\t" 2103 "mov.m ar.rsc = %2;;\n\t" 2104 "flushrs;;\n\t" 2105 "mov.m %0 = ar.rnat;;\n\t" 2106 "mov.m ar.rsc = %1\n\t" 2107 : "=r" (rnat), "=r" (tmp1), "=r" (tmp2)); 2108 2109 memset (context, 0, sizeof (struct _Unwind_Context)); 2110 context->bsp = (unsigned long) bsp; 2111 /* Set context->regstk_top to lowest rbs address which will use 2112 context->rnat collection. */ 2113 context->regstk_top = context->bsp & ~0x1ffULL; 2114 context->rnat = rnat; 2115 context->psp = (unsigned long) psp; 2116 context->rp = (unsigned long) rp; 2117 asm ("mov %0 = sp" : "=r" (context->sp)); 2118 asm ("mov %0 = pr" : "=r" (context->pr)); 2119 context->pri_unat_loc = &context->initial_unat; /* ??? */ 2120 2121 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON) 2122 abort (); 2123 2124 uw_update_context (context, &fs); 2125} 2126 2127/* Install (i.e. longjmp to) the contents of TARGET. */ 2128 2129static void __attribute__((noreturn)) 2130uw_install_context (struct _Unwind_Context *current __attribute__((unused)), 2131 struct _Unwind_Context *target) 2132{ 2133 unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0; 2134 long i; 2135 2136 /* Copy integer register data from the target context to a 2137 temporary buffer. Do this so that we can frob AR.UNAT 2138 to get the NaT bits for these registers set properly. */ 2139 for (i = 4; i <= 7; ++i) 2140 { 2141 char nat; 2142 void *t = target->ireg[i - 2].loc; 2143 if (t) 2144 { 2145 unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0); 2146 ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f); 2147 /* Set p6 - p9. */ 2148 ireg_pr |= 4L << i; 2149 } 2150 } 2151 2152 /* The value in uc_bsp that we've computed is that for the 2153 target function. The value that we install below will be 2154 adjusted by the BR.RET instruction based on the contents 2155 of AR.PFS. So we must unadjust that here. */ 2156 target->bsp = (unsigned long) 2157 ia64_rse_skip_regs ((unsigned long *)target->bsp, 2158 (*target->pfs_loc >> 7) & 0x7f); 2159 2160 if (target->bsp < target->regstk_top) 2161 target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp); 2162 2163 /* Provide assembly with the offsets into the _Unwind_Context. */ 2164 asm volatile ("uc_rnat = %0" 2165 : : "i"(offsetof (struct _Unwind_Context, rnat))); 2166 asm volatile ("uc_bsp = %0" 2167 : : "i"(offsetof (struct _Unwind_Context, bsp))); 2168 asm volatile ("uc_psp = %0" 2169 : : "i"(offsetof (struct _Unwind_Context, psp))); 2170 asm volatile ("uc_rp = %0" 2171 : : "i"(offsetof (struct _Unwind_Context, rp))); 2172 asm volatile ("uc_pr = %0" 2173 : : "i"(offsetof (struct _Unwind_Context, pr))); 2174 asm volatile ("uc_gp = %0" 2175 : : "i"(offsetof (struct _Unwind_Context, gp))); 2176 asm volatile ("uc_pfs_loc = %0" 2177 : : "i"(offsetof (struct _Unwind_Context, pfs_loc))); 2178 asm volatile ("uc_unat_loc = %0" 2179 : : "i"(offsetof (struct _Unwind_Context, unat_loc))); 2180 asm volatile ("uc_lc_loc = %0" 2181 : : "i"(offsetof (struct _Unwind_Context, lc_loc))); 2182 asm volatile ("uc_fpsr_loc = %0" 2183 : : "i"(offsetof (struct _Unwind_Context, fpsr_loc))); 2184 asm volatile ("uc_eh_data = %0" 2185 : : "i"(offsetof (struct _Unwind_Context, eh_data))); 2186 asm volatile ("uc_br_loc = %0" 2187 : : "i"(offsetof (struct _Unwind_Context, br_loc))); 2188 asm volatile ("uc_fr_loc = %0" 2189 : : "i"(offsetof (struct _Unwind_Context, fr_loc))); 2190 2191 asm volatile ( 2192 /* Load up call-saved non-window integer registers from ireg_buf. */ 2193 "add r20 = 8, %1 \n\t" 2194 "mov ar.unat = %2 \n\t" 2195 "mov pr = %3, 0x3c0 \n\t" 2196 ";; \n\t" 2197 "(p6) ld8.fill r4 = [%1] \n\t" 2198 "(p7) ld8.fill r5 = [r20] \n\t" 2199 "add r21 = uc_br_loc + 16, %0 \n\t" 2200 "adds %1 = 16, %1 \n\t" 2201 "adds r20 = 16, r20 \n\t" 2202 ";; \n\t" 2203 "(p8) ld8.fill r6 = [%1] \n\t" 2204 "(p9) ld8.fill r7 = [r20] \n\t" 2205 "add r20 = uc_br_loc + 8, %0 \n\t" 2206 ";; \n\t" 2207 /* Load up call-saved branch registers. */ 2208 "ld8 r22 = [r20], 16 \n\t" 2209 "ld8 r23 = [r21], 16 \n\t" 2210 ";; \n\t" 2211 "ld8 r24 = [r20], 16 \n\t" 2212 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t" 2213 ";; \n\t" 2214 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t" 2215 "ld8 r27 = [r21], 24 \n\t" 2216 "cmp.ne p6, p0 = r0, r22 \n\t" 2217 ";; \n\t" 2218 "ld8 r28 = [r20], 8 \n\t" 2219 "(p6) ld8 r22 = [r22] \n\t" 2220 "cmp.ne p7, p0 = r0, r23 \n\t" 2221 ";; \n\t" 2222 "(p7) ld8 r23 = [r23] \n\t" 2223 "cmp.ne p8, p0 = r0, r24 \n\t" 2224 ";; \n\t" 2225 "(p8) ld8 r24 = [r24] \n\t" 2226 "(p6) mov b1 = r22 \n\t" 2227 "cmp.ne p9, p0 = r0, r25 \n\t" 2228 ";; \n\t" 2229 "(p9) ld8 r25 = [r25] \n\t" 2230 "(p7) mov b2 = r23 \n\t" 2231 "cmp.ne p6, p0 = r0, r26 \n\t" 2232 ";; \n\t" 2233 "(p6) ld8 r26 = [r26] \n\t" 2234 "(p8) mov b3 = r24 \n\t" 2235 "cmp.ne p7, p0 = r0, r27 \n\t" 2236 ";; \n\t" 2237 /* Load up call-saved fp registers. */ 2238 "(p7) ldf.fill f2 = [r27] \n\t" 2239 "(p9) mov b4 = r25 \n\t" 2240 "cmp.ne p8, p0 = r0, r28 \n\t" 2241 ";; \n\t" 2242 "(p8) ldf.fill f3 = [r28] \n\t" 2243 "(p6) mov b5 = r26 \n\t" 2244 ";; \n\t" 2245 "ld8 r29 = [r20], 16*8 - 4*8 \n\t" 2246 "ld8 r30 = [r21], 17*8 - 5*8 \n\t" 2247 ";; \n\t" 2248 "ld8 r22 = [r20], 16 \n\t" 2249 "ld8 r23 = [r21], 16 \n\t" 2250 ";; \n\t" 2251 "ld8 r24 = [r20], 16 \n\t" 2252 "ld8 r25 = [r21] \n\t" 2253 "cmp.ne p6, p0 = r0, r29 \n\t" 2254 ";; \n\t" 2255 "ld8 r26 = [r20], 8 \n\t" 2256 "(p6) ldf.fill f4 = [r29] \n\t" 2257 "cmp.ne p7, p0 = r0, r30 \n\t" 2258 ";; \n\t" 2259 "ld8 r27 = [r20], 8 \n\t" 2260 "(p7) ldf.fill f5 = [r30] \n\t" 2261 "cmp.ne p6, p0 = r0, r22 \n\t" 2262 ";; \n\t" 2263 "ld8 r28 = [r20], 8 \n\t" 2264 "(p6) ldf.fill f16 = [r22] \n\t" 2265 "cmp.ne p7, p0 = r0, r23 \n\t" 2266 ";; \n\t" 2267 "ld8 r29 = [r20], 8 \n\t" 2268 "(p7) ldf.fill f17 = [r23] \n\t" 2269 "cmp.ne p6, p0 = r0, r24 \n\t" 2270 ";; \n\t" 2271 "ld8 r22 = [r20], 8 \n\t" 2272 "(p6) ldf.fill f18 = [r24] \n\t" 2273 "cmp.ne p7, p0 = r0, r25 \n\t" 2274 ";; \n\t" 2275 "ld8 r23 = [r20], 8 \n\t" 2276 "(p7) ldf.fill f19 = [r25] \n\t" 2277 "cmp.ne p6, p0 = r0, r26 \n\t" 2278 ";; \n\t" 2279 "ld8 r24 = [r20], 8 \n\t" 2280 "(p6) ldf.fill f20 = [r26] \n\t" 2281 "cmp.ne p7, p0 = r0, r27 \n\t" 2282 ";; \n\t" 2283 "ld8 r25 = [r20], 8 \n\t" 2284 "(p7) ldf.fill f21 = [r27] \n\t" 2285 "cmp.ne p6, p0 = r0, r28 \n\t" 2286 ";; \n\t" 2287 "ld8 r26 = [r20], 8 \n\t" 2288 "(p6) ldf.fill f22 = [r28] \n\t" 2289 "cmp.ne p7, p0 = r0, r29 \n\t" 2290 ";; \n\t" 2291 "ld8 r27 = [r20], 8 \n\t" 2292 ";; \n\t" 2293 "ld8 r28 = [r20], 8 \n\t" 2294 "(p7) ldf.fill f23 = [r29] \n\t" 2295 "cmp.ne p6, p0 = r0, r22 \n\t" 2296 ";; \n\t" 2297 "ld8 r29 = [r20], 8 \n\t" 2298 "(p6) ldf.fill f24 = [r22] \n\t" 2299 "cmp.ne p7, p0 = r0, r23 \n\t" 2300 ";; \n\t" 2301 "(p7) ldf.fill f25 = [r23] \n\t" 2302 "cmp.ne p6, p0 = r0, r24 \n\t" 2303 "cmp.ne p7, p0 = r0, r25 \n\t" 2304 ";; \n\t" 2305 "(p6) ldf.fill f26 = [r24] \n\t" 2306 "(p7) ldf.fill f27 = [r25] \n\t" 2307 "cmp.ne p6, p0 = r0, r26 \n\t" 2308 ";; \n\t" 2309 "(p6) ldf.fill f28 = [r26] \n\t" 2310 "cmp.ne p7, p0 = r0, r27 \n\t" 2311 "cmp.ne p6, p0 = r0, r28 \n\t" 2312 ";; \n\t" 2313 "(p7) ldf.fill f29 = [r27] \n\t" 2314 "(p6) ldf.fill f30 = [r28] \n\t" 2315 "cmp.ne p7, p0 = r0, r29 \n\t" 2316 ";; \n\t" 2317 "(p7) ldf.fill f31 = [r29] \n\t" 2318 "add r20 = uc_rnat, %0 \n\t" 2319 "add r21 = uc_bsp, %0 \n\t" 2320 ";; \n\t" 2321 /* Load the balance of the thread state from the context. */ 2322 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t" 2323 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t" 2324 ";; \n\t" 2325 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t" 2326 "ld8 r1 = [r21], uc_rp - uc_gp \n\t" 2327 ";; \n\t" 2328 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t" 2329 "ld8 r26 = [r21], uc_pr - uc_rp \n\t" 2330 ";; \n\t" 2331 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t" 2332 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t" 2333 ";; \n\t" 2334 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t" 2335 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t" 2336 ";; \n\t" 2337 /* Load data for the exception handler. */ 2338 "ld8 r15 = [r20], 16 \n\t" 2339 "ld8 r16 = [r21], 16 \n\t" 2340 ";; \n\t" 2341 "ld8 r17 = [r20] \n\t" 2342 "ld8 r18 = [r21] \n\t" 2343 ";; \n\t" 2344 /* Install the balance of the thread state loaded above. */ 2345 "cmp.ne p6, p0 = r0, r25 \n\t" 2346 "cmp.ne p7, p0 = r0, r27 \n\t" 2347 ";; \n\t" 2348 "(p6) ld8 r25 = [r25] \n\t" 2349 "(p7) ld8 r27 = [r27] \n\t" 2350 ";; \n\t" 2351 "(p7) mov.m ar.unat = r27 \n\t" 2352 "(p6) mov.i ar.pfs = r25 \n\t" 2353 "cmp.ne p9, p0 = r0, r29 \n\t" 2354 ";; \n\t" 2355 "(p9) ld8 r29 = [r29] \n\t" 2356 "cmp.ne p6, p0 = r0, r30 \n\t" 2357 ";; \n\t" 2358 "(p6) ld8 r30 = [r30] \n\t" 2359 /* Don't clobber p6-p9, which are in use at present. */ 2360 "mov pr = r28, ~0x3c0 \n\t" 2361 "(p9) mov.i ar.lc = r29 \n\t" 2362 ";; \n\t" 2363 "mov.m r25 = ar.rsc \n\t" 2364 "(p6) mov.m ar.fpsr = r30 \n\t" 2365 ";; \n\t" 2366 "and r29 = 0x1c, r25 \n\t" 2367 "mov b0 = r26 \n\t" 2368 ";; \n\t" 2369 "mov.m ar.rsc = r29 \n\t" 2370 ";; \n\t" 2371 /* This must be done before setting AR.BSPSTORE, otherwise 2372 AR.BSP will be initialized with a random displacement 2373 below the value we want, based on the current number of 2374 dirty stacked registers. */ 2375 "loadrs \n\t" 2376 "invala \n\t" 2377 ";; \n\t" 2378 "mov.m ar.bspstore = r23 \n\t" 2379 ";; \n\t" 2380 "mov.m ar.rnat = r22 \n\t" 2381 ";; \n\t" 2382 "mov.m ar.rsc = r25 \n\t" 2383 "mov sp = r24 \n\t" 2384 "br.ret.sptk.few b0" 2385 : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr) 2386 : "r15", "r16", "r17", "r18", "r20", "r21", "r22", 2387 "r23", "r24", "r25", "r26", "r27", "r28", "r29", 2388 "r30", "r31"); 2389 /* NOTREACHED */ 2390 while (1); 2391} 2392 2393static inline _Unwind_Ptr 2394uw_identify_context (struct _Unwind_Context *context) 2395{ 2396 return _Unwind_GetIP (context); 2397} 2398 2399#include "unwind.inc" 2400 2401#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS) 2402alias (_Unwind_Backtrace); 2403alias (_Unwind_DeleteException); 2404alias (_Unwind_FindEnclosingFunction); 2405alias (_Unwind_ForcedUnwind); 2406alias (_Unwind_GetBSP); 2407alias (_Unwind_GetCFA); 2408alias (_Unwind_GetGR); 2409alias (_Unwind_GetIP); 2410alias (_Unwind_GetLanguageSpecificData); 2411alias (_Unwind_GetRegionStart); 2412alias (_Unwind_RaiseException); 2413alias (_Unwind_Resume); 2414alias (_Unwind_Resume_or_Rethrow); 2415alias (_Unwind_SetGR); 2416alias (_Unwind_SetIP); 2417#endif 2418 2419#endif 2420