Home | History | Annotate | Download | only in ia64
      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 (&regs[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