• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libunwind - a platform-independent unwind library
2    Copyright (C) 2001-2004 Hewlett-Packard Co
3         Contributed by David Mosberger-Tang <davidm@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
push(struct ia64_state_record * sr)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
pop(struct ia64_state_record * sr)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 *
dup_state_stack(struct ia64_reg_state * rs)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
free_state_stack(struct ia64_reg_state * rs)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
decode_abreg(unsigned char abreg,int memory)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
set_reg(struct ia64_reg_info * reg,enum ia64_where where,int when,unsigned long val)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
alloc_spill_area(unsigned long * offp,unsigned long regsize,struct ia64_reg_info * lo,struct ia64_reg_info * hi)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
spill_next_when(struct ia64_reg_info ** regp,struct ia64_reg_info * lim,unw_word t)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
finish_prologue(struct ia64_state_record * sr)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
desc_prologue(int body,unw_word rlen,unsigned char mask,unsigned char grsave,struct ia64_state_record * sr)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
desc_abi(unsigned char abi,unsigned char context,struct ia64_state_record * sr)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
desc_br_gr(unsigned char brmask,unsigned char gr,struct ia64_state_record * sr)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
desc_br_mem(unsigned char brmask,struct ia64_state_record * sr)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
desc_frgr_mem(unsigned char grmask,unw_word frmask,struct ia64_state_record * sr)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
desc_fr_mem(unsigned char frmask,struct ia64_state_record * sr)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
desc_gr_gr(unsigned char grmask,unsigned char gr,struct ia64_state_record * sr)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
desc_gr_mem(unsigned char grmask,struct ia64_state_record * sr)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
desc_mem_stack_f(unw_word t,unw_word size,struct ia64_state_record * sr)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
desc_mem_stack_v(unw_word t,struct ia64_state_record * sr)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
desc_reg_gr(unsigned char reg,unsigned char dst,struct ia64_state_record * sr)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
desc_reg_psprel(unsigned char reg,unw_word pspoff,struct ia64_state_record * sr)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
desc_reg_sprel(unsigned char reg,unw_word spoff,struct ia64_state_record * sr)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
desc_rp_br(unsigned char dst,struct ia64_state_record * sr)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
desc_reg_when(unsigned char regnum,unw_word t,struct ia64_state_record * sr)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
desc_spill_base(unw_word pspoff,struct ia64_state_record * sr)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 *
desc_spill_mask(unsigned char * imaskp,struct ia64_state_record * sr)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
desc_epilogue(unw_word t,unw_word ecount,struct ia64_state_record * sr)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
desc_copy_state(unw_word label,struct ia64_state_record * sr)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
desc_label_state(unw_word label,struct ia64_state_record * sr)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
desc_is_active(unsigned char qp,unw_word t,struct ia64_state_record * sr)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
desc_restore_p(unsigned char qp,unw_word t,unsigned char abreg,struct ia64_state_record * sr)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
desc_spill_reg_p(unsigned char qp,unw_word t,unsigned char abreg,unsigned char x,unsigned char ytreg,struct ia64_state_record * sr)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
desc_spill_psprel_p(unsigned char qp,unw_word t,unsigned char abreg,unw_word pspoff,struct ia64_state_record * sr)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
desc_spill_sprel_p(unsigned char qp,unw_word t,unsigned char abreg,unw_word spoff,struct ia64_state_record * sr)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
693 
694 /* parse dynamic unwind info */
695 
696 static struct ia64_reg_info *
lookup_preg(int regnum,int memory,struct ia64_state_record * sr)697 lookup_preg (int regnum, int memory, struct ia64_state_record *sr)
698 {
699   int preg;
700 
701   switch (regnum)
702     {
703     case UNW_IA64_AR_BSP:               preg = IA64_REG_BSP; break;
704     case UNW_IA64_AR_BSPSTORE:          preg = IA64_REG_BSPSTORE; break;
705     case UNW_IA64_AR_FPSR:              preg = IA64_REG_FPSR; break;
706     case UNW_IA64_AR_LC:                preg = IA64_REG_LC; break;
707     case UNW_IA64_AR_PFS:               preg = IA64_REG_PFS; break;
708     case UNW_IA64_AR_RNAT:              preg = IA64_REG_RNAT; break;
709     case UNW_IA64_AR_UNAT:              preg = IA64_REG_UNAT; break;
710     case UNW_IA64_BR + 0:               preg = IA64_REG_IP; break;
711     case UNW_IA64_PR:                   preg = IA64_REG_PR; break;
712     case UNW_IA64_SP:                   preg = IA64_REG_PSP; break;
713 
714     case UNW_IA64_NAT:
715       if (memory)
716         preg = IA64_REG_PRI_UNAT_MEM;
717       else
718         preg = IA64_REG_PRI_UNAT_GR;
719       break;
720 
721     case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7:
722       preg = IA64_REG_R4 + (regnum - (UNW_IA64_GR + 4));
723       break;
724 
725     case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5:
726       preg = IA64_REG_B1 + (regnum - UNW_IA64_BR);
727       break;
728 
729     case UNW_IA64_FR + 2 ... UNW_IA64_FR + 5:
730       preg = IA64_REG_F2 + (regnum - (UNW_IA64_FR + 2));
731       break;
732 
733     case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31:
734       preg = IA64_REG_F16 + (regnum - (UNW_IA64_FR + 16));
735       break;
736 
737     default:
738       Dprintf ("%s: invalid register number %d\n", __FUNCTION__, regnum);
739       return NULL;
740     }
741   return sr->curr.reg + preg;
742 }
743 
744 /* An alias directive inside a region of length RLEN is interpreted to
745    mean that the region behaves exactly like the first RLEN
746    instructions at the aliased IP.  RLEN=0 implies that the current
747    state matches exactly that of before the instruction at the aliased
748    IP is executed.  */
749 
750 static int
desc_alias(unw_dyn_op_t * op,struct cursor * c,struct ia64_state_record * sr)751 desc_alias (unw_dyn_op_t *op, struct cursor *c, struct ia64_state_record *sr)
752 {
753   struct ia64_state_record orig_sr = *sr;
754   int i, ret, when, rlen = sr->region_len;
755   unw_word_t new_ip;
756 
757   when = MIN (sr->when_target, rlen);
758   new_ip = op->val + ((when / 3) * 16 + (when % 3));
759 
760   if ((ret = ia64_fetch_proc_info (c, new_ip, 1)) < 0)
761     return ret;
762 
763   if ((ret = create_state_record_for (c, sr, new_ip)) < 0)
764     return ret;
765 
766   sr->first_region = orig_sr.first_region;
767   sr->done = 0;
768   sr->any_spills |= orig_sr.any_spills;
769   sr->in_body = orig_sr.in_body;
770   sr->region_start = orig_sr.region_start;
771   sr->region_len = orig_sr.region_len;
772   if (sr->when_sp_restored != IA64_WHEN_NEVER)
773     sr->when_sp_restored = op->when + MIN (orig_sr.when_sp_restored, rlen);
774   sr->epilogue_count = orig_sr.epilogue_count;
775   sr->when_target = orig_sr.when_target;
776 
777   for (i = 0; i < IA64_NUM_PREGS; ++i)
778     if (sr->curr.reg[i].when != IA64_WHEN_NEVER)
779       sr->curr.reg[i].when = op->when + MIN (sr->curr.reg[i].when, rlen);
780 
781   ia64_free_state_record (sr);
782   sr->labeled_states = orig_sr.labeled_states;
783   sr->curr.next = orig_sr.curr.next;
784   return 0;
785 }
786 
787 static inline int
parse_dynamic(struct cursor * c,struct ia64_state_record * sr)788 parse_dynamic (struct cursor *c, struct ia64_state_record *sr)
789 {
790   unw_dyn_info_t *di = c->pi.unwind_info;
791   unw_dyn_proc_info_t *proc = &di->u.pi;
792   unw_dyn_region_info_t *r;
793   struct ia64_reg_info *ri;
794   enum ia64_where where;
795   int32_t when, len;
796   unw_dyn_op_t *op;
797   unw_word_t val;
798   int memory, ret;
799   int8_t qp;
800 
801   for (r = proc->regions; r; r = r->next)
802     {
803       len = r->insn_count;
804       if (len < 0)
805         {
806           if (r->next)
807             {
808               Debug (1, "negative region length allowed in last region only!");
809               return -UNW_EINVAL;
810             }
811           len = -len;
812           /* hack old region info to set the start where we need it: */
813           sr->region_start = (di->end_ip - di->start_ip) / 0x10 * 3 - len;
814           sr->region_len = 0;
815         }
816       /* all regions are treated as prologue regions: */
817       desc_prologue (0, len, 0, 0, sr);
818 
819       if (sr->done)
820         return 0;
821 
822       for (op = r->op; op < r->op + r->op_count; ++op)
823         {
824           when = op->when;
825           val = op->val;
826           qp = op->qp;
827 
828           if (!desc_is_active (qp, when, sr))
829             continue;
830 
831           when = sr->region_start + MIN ((int) when, sr->region_len - 1);
832 
833           switch (op->tag)
834             {
835             case UNW_DYN_SAVE_REG:
836               memory = 0;
837               if ((unsigned) (val - UNW_IA64_GR) < 128)
838                 where = IA64_WHERE_GR;
839               else if ((unsigned) (val - UNW_IA64_FR) < 128)
840                 where = IA64_WHERE_FR;
841               else if ((unsigned) (val - UNW_IA64_BR) < 8)
842                 where = IA64_WHERE_BR;
843               else
844                 {
845                   Dprintf ("%s: can't save to register number %d\n",
846                            __FUNCTION__, (int) op->reg);
847                   return -UNW_EBADREG;
848                 }
849               /* fall through */
850             update_reg_info:
851               ri = lookup_preg (op->reg, memory, sr);
852               if (!ri)
853                 return -UNW_EBADREG;
854               ri->where = where;
855               ri->when = when;
856               ri->val = val;
857               break;
858 
859             case UNW_DYN_SPILL_FP_REL:
860               memory = 1;
861               where = IA64_WHERE_PSPREL;
862               val = 0x10 - val;
863               goto update_reg_info;
864 
865             case UNW_DYN_SPILL_SP_REL:
866               memory = 1;
867               where = IA64_WHERE_SPREL;
868               goto update_reg_info;
869 
870             case UNW_DYN_ADD:
871               if (op->reg == UNW_IA64_SP)
872                 {
873                   if (val & 0xf)
874                     {
875                       Dprintf ("%s: frame-size %ld not an integer "
876                                "multiple of 16\n",
877                                __FUNCTION__, (long) op->val);
878                       return -UNW_EINVAL;
879                     }
880                   desc_mem_stack_f (when, -((int64_t) val / 16), sr);
881                 }
882               else
883                 {
884                   Dprintf ("%s: can only ADD to stack-pointer\n",
885                            __FUNCTION__);
886                   return -UNW_EBADREG;
887                 }
888               break;
889 
890             case UNW_DYN_POP_FRAMES:
891               sr->when_sp_restored = when;
892               sr->epilogue_count = op->val;
893               break;
894 
895             case UNW_DYN_LABEL_STATE:
896               desc_label_state (op->val, sr);
897               break;
898 
899             case UNW_DYN_COPY_STATE:
900               desc_copy_state (op->val, sr);
901               break;
902 
903             case UNW_DYN_ALIAS:
904               if ((ret = desc_alias (op, c, sr)) < 0)
905                 return ret;
906 
907             case UNW_DYN_STOP:
908               goto end_of_ops;
909             }
910         }
911     end_of_ops:
912       ;
913     }
914   return 0;
915 }
916 #else
917 # define parse_dynamic(c,sr)    (-UNW_EINVAL)
918 #endif /* _U_dyn_op */
919 
920 
921 HIDDEN int
ia64_fetch_proc_info(struct cursor * c,unw_word_t ip,int need_unwind_info)922 ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, int need_unwind_info)
923 {
924   int ret, dynamic = 1;
925 
926   if (c->pi_valid && !need_unwind_info)
927     return 0;
928 
929   /* check dynamic info first --- it overrides everything else */
930   ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info,
931                                      c->as_arg);
932   if (ret == -UNW_ENOINFO)
933     {
934       dynamic = 0;
935       ret = ia64_find_proc_info (c, ip, need_unwind_info);
936     }
937 
938   c->pi_valid = 1;
939   c->pi_is_dynamic = dynamic;
940   return ret;
941 }
942 
943 static inline void
put_unwind_info(struct cursor * c,unw_proc_info_t * pi)944 put_unwind_info (struct cursor *c, unw_proc_info_t *pi)
945 {
946   if (!c->pi_valid)
947     return;
948 
949   if (c->pi_is_dynamic)
950     unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg);
951   else
952     ia64_put_unwind_info (c, pi);
953 }
954 
955 static int
create_state_record_for(struct cursor * c,struct ia64_state_record * sr,unw_word_t ip)956 create_state_record_for (struct cursor *c, struct ia64_state_record *sr,
957                          unw_word_t ip)
958 {
959   unw_word_t predicates = c->pr;
960   struct ia64_reg_info *r;
961   uint8_t *dp, *desc_end;
962   int ret;
963 
964   assert (c->pi_valid);
965 
966   /* build state record */
967   memset (sr, 0, sizeof (*sr));
968   for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r)
969     r->when = IA64_WHEN_NEVER;
970   sr->pr_val = predicates;
971   sr->first_region = 1;
972 
973   if (!c->pi.unwind_info)
974     {
975       /* No info, return default unwinder (leaf proc, no mem stack, no
976          saved regs), rp in b0, pfs in ar.pfs.  */
977       Debug (1, "no unwind info for ip=0x%lx (gp=%lx)\n",
978              (long) ip, (long) c->pi.gp);
979       sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR;
980       sr->curr.reg[IA64_REG_IP].when = -1;
981       sr->curr.reg[IA64_REG_IP].val = 0;
982       goto out;
983     }
984 
985   sr->when_target = (3 * ((ip & ~(unw_word_t) 0xf) - c->pi.start_ip) / 16
986                      + (ip & 0xf));
987 
988   switch (c->pi.format)
989     {
990     case UNW_INFO_FORMAT_TABLE:
991     case UNW_INFO_FORMAT_REMOTE_TABLE:
992       dp = c->pi.unwind_info;
993       desc_end = dp + c->pi.unwind_info_size;
994       while (!sr->done && dp < desc_end)
995         dp = unw_decode (dp, sr->in_body, sr);
996       ret = 0;
997       break;
998 
999     case UNW_INFO_FORMAT_DYNAMIC:
1000       ret = parse_dynamic (c, sr);
1001       break;
1002 
1003     default:
1004       ret = -UNW_EINVAL;
1005     }
1006 
1007   put_unwind_info (c, &c->pi);
1008 
1009   if (ret < 0)
1010     return ret;
1011 
1012   if (sr->when_target > sr->when_sp_restored)
1013     {
1014       /* sp has been restored and all values on the memory stack below
1015          psp also have been restored.  */
1016       sr->curr.reg[IA64_REG_PSP].val = 0;
1017       sr->curr.reg[IA64_REG_PSP].where = IA64_WHERE_NONE;
1018       sr->curr.reg[IA64_REG_PSP].when = IA64_WHEN_NEVER;
1019       for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r)
1020         if ((r->where == IA64_WHERE_PSPREL && r->val <= 0x10)
1021             || r->where == IA64_WHERE_SPREL)
1022           {
1023             r->val = 0;
1024             r->where = IA64_WHERE_NONE;
1025             r->when = IA64_WHEN_NEVER;
1026           }
1027     }
1028 
1029   /* If RP did't get saved, generate entry for the return link
1030      register.  */
1031   if (sr->curr.reg[IA64_REG_IP].when >= sr->when_target)
1032     {
1033       sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR;
1034       sr->curr.reg[IA64_REG_IP].when = -1;
1035       sr->curr.reg[IA64_REG_IP].val = sr->return_link_reg;
1036     }
1037 
1038   if (sr->when_target > sr->curr.reg[IA64_REG_BSP].when
1039       && sr->when_target > sr->curr.reg[IA64_REG_BSPSTORE].when
1040       && sr->when_target > sr->curr.reg[IA64_REG_RNAT].when)
1041     {
1042       Debug (8, "func 0x%lx may switch the register-backing-store\n",
1043              c->pi.start_ip);
1044       c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH;
1045     }
1046  out:
1047 #if UNW_DEBUG
1048   if (unwi_debug_level > 2)
1049     {
1050       Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n",
1051                __FUNCTION__,
1052                (long) c->pi.start_ip, sr->when_target, (long) c->pi.flags);
1053       for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r)
1054         {
1055           if (r->where != IA64_WHERE_NONE || r->when != IA64_WHEN_NEVER)
1056             {
1057               Dprintf ("  %s <- ", unw.preg_name[r - sr->curr.reg]);
1058               switch (r->where)
1059                 {
1060                 case IA64_WHERE_GR:
1061                   Dprintf ("r%lu", (long) r->val);
1062                   break;
1063                 case IA64_WHERE_FR:
1064                   Dprintf ("f%lu", (long) r->val);
1065                   break;
1066                 case IA64_WHERE_BR:
1067                   Dprintf ("b%lu", (long) r->val);
1068                   break;
1069                 case IA64_WHERE_SPREL:
1070                   Dprintf ("[sp+0x%lx]", (long) r->val);
1071                   break;
1072                 case IA64_WHERE_PSPREL:
1073                   Dprintf ("[psp+0x%lx]", (long) r->val);
1074                   break;
1075                 case IA64_WHERE_NONE:
1076                   Dprintf ("%s+0x%lx",
1077                            unw.preg_name[r - sr->curr.reg], (long) r->val);
1078                   break;
1079                 default:
1080                   Dprintf ("BADWHERE(%d)", r->where);
1081                   break;
1082                 }
1083               Dprintf ("\t\t%d\n", r->when);
1084             }
1085         }
1086     }
1087 #endif
1088   return 0;
1089 }
1090 
1091 /* The proc-info must be valid for IP before this routine can be
1092    called.  */
1093 HIDDEN int
ia64_create_state_record(struct cursor * c,struct ia64_state_record * sr)1094 ia64_create_state_record (struct cursor *c, struct ia64_state_record *sr)
1095 {
1096   return create_state_record_for (c, sr, c->ip);
1097 }
1098 
1099 HIDDEN int
ia64_free_state_record(struct ia64_state_record * sr)1100 ia64_free_state_record (struct ia64_state_record *sr)
1101 {
1102   struct ia64_labeled_state *ls, *next;
1103 
1104   /* free labeled register states & stack: */
1105 
1106   for (ls = sr->labeled_states; ls; ls = next)
1107     {
1108       next = ls->next;
1109       free_state_stack (&ls->saved_state);
1110       free_labeled_state (ls);
1111     }
1112   free_state_stack (&sr->curr);
1113 
1114   return 0;
1115 }
1116 
1117 HIDDEN int
ia64_make_proc_info(struct cursor * c)1118 ia64_make_proc_info (struct cursor *c)
1119 {
1120   int ret, caching = c->as->caching_policy != UNW_CACHE_NONE;
1121 
1122   if (!caching || ia64_get_cached_proc_info (c) < 0)
1123     {
1124       /* Lookup it up the slow way... */
1125       if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0)
1126         return ret;
1127       if (caching)
1128         ia64_cache_proc_info (c);
1129     }
1130   return 0;
1131 }
1132