Imported Upstream version 1.1
[platform/upstream/libunwind.git] / src / ia64 / Gparser.c
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
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 \f
692 #ifdef _U_dyn_op
693
694 /* parse dynamic unwind info */
695
696 static struct ia64_reg_info *
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
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
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 \f
920
921 HIDDEN int
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
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
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
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
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
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 }