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>
5 This file is part of libunwind.
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:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
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. */
28 /* forward declaration: */
29 static int create_state_record_for (struct cursor
*c
,
30 struct ia64_state_record
*sr
,
33 typedef unsigned long unw_word
;
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))
40 /* Routines to manipulate the state stack. */
43 push (struct ia64_state_record
*sr
)
45 struct ia64_reg_state
*rs
;
47 rs
= alloc_reg_state ();
50 print_error ("libunwind: cannot stack reg state!\n");
53 memcpy (rs
, &sr
->curr
, sizeof (*rs
));
58 pop (struct ia64_state_record
*sr
)
60 struct ia64_reg_state
*rs
= sr
->curr
.next
;
64 print_error ("libunwind: stack underflow!\n");
67 memcpy (&sr
->curr
, rs
, sizeof (*rs
));
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
)
75 struct ia64_reg_state
*copy
, *prev
= NULL
, *first
= NULL
;
79 copy
= alloc_reg_state ();
82 print_error ("unwind.dup_state_stack: out of memory\n");
85 memcpy (copy
, rs
, sizeof (*copy
));
96 /* Free all stacked register states (but not RS itself). */
98 free_state_stack (struct ia64_reg_state
*rs
)
100 struct ia64_reg_state
*p
, *next
;
102 for (p
= rs
->next
; p
!= NULL
; p
= next
)
110 /* Unwind decoder routines */
112 static enum ia64_pregnum CONST_ATTR
113 decode_abreg (unsigned char abreg
, int memory
)
118 return IA64_REG_R4
+ (abreg
- 0x04);
120 return IA64_REG_F2
+ (abreg
- 0x22);
122 return IA64_REG_F16
+ (abreg
- 0x30);
124 return IA64_REG_B1
+ (abreg
- 0x41);
130 return memory
? IA64_REG_PRI_UNAT_MEM
: IA64_REG_PRI_UNAT_GR
;
136 return IA64_REG_BSPSTORE
;
138 return IA64_REG_RNAT
;
140 return IA64_REG_UNAT
;
142 return IA64_REG_FPSR
;
150 Dprintf ("libunwind: bad abreg=0x%x\n", abreg
);
155 set_reg (struct ia64_reg_info
*reg
, enum ia64_where where
, int when
,
160 if (reg
->when
== IA64_WHEN_NEVER
)
165 alloc_spill_area (unsigned long *offp
, unsigned long regsize
,
166 struct ia64_reg_info
*lo
, struct ia64_reg_info
*hi
)
168 struct ia64_reg_info
*reg
;
170 for (reg
= hi
; reg
>= lo
; --reg
)
172 if (reg
->where
== IA64_WHERE_SPILL_HOME
)
174 reg
->where
= IA64_WHERE_PSPREL
;
182 spill_next_when (struct ia64_reg_info
**regp
, struct ia64_reg_info
*lim
,
185 struct ia64_reg_info
*reg
;
187 for (reg
= *regp
; reg
<= lim
; ++reg
)
189 if (reg
->where
== IA64_WHERE_SPILL_HOME
)
196 Dprintf ("libunwind: excess spill!\n");
200 finish_prologue (struct ia64_state_record
*sr
)
202 struct ia64_reg_info
*reg
;
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
)
210 reg
= sr
->curr
.reg
+ unw
.save_order
[i
];
211 if (reg
->where
== IA64_WHERE_GR_SAVE
)
213 reg
->where
= IA64_WHERE_GR
;
214 reg
->val
= sr
->gr_save_loc
++;
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. */
224 unsigned char kind
, mask
= 0, *cp
= sr
->imask
;
226 static const unsigned char limit
[3] =
228 IA64_REG_F31
, IA64_REG_R7
, IA64_REG_B5
230 struct ia64_reg_info
*(regs
[3]);
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
;
236 for (t
= 0; (int) t
< sr
->region_len
; ++t
)
240 kind
= (mask
>> 2 * (3 - (t
& 3))) & 3;
242 spill_next_when (®s
[kind
- 1], sr
->curr
.reg
+ limit
[kind
- 1],
243 sr
->region_start
+ t
);
247 /* Next, lay out the memory stack spill area. */
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
);
261 /* Region header descriptors. */
264 desc_prologue (int body
, unw_word rlen
, unsigned char mask
,
265 unsigned char grsave
, struct ia64_state_record
*sr
)
269 if (!(sr
->in_body
|| sr
->first_region
))
270 finish_prologue (sr
);
271 sr
->first_region
= 0;
273 /* check if we're done: */
274 if (sr
->when_target
< sr
->region_start
+ sr
->region_len
)
280 region_start
= sr
->region_start
+ sr
->region_len
;
282 for (i
= 0; i
< sr
->epilogue_count
; ++i
)
284 sr
->epilogue_count
= 0;
285 sr
->when_sp_restored
= IA64_WHEN_NEVER
;
287 sr
->region_start
= region_start
;
288 sr
->region_len
= rlen
;
296 for (i
= 0; i
< 4; ++i
)
299 set_reg (sr
->curr
.reg
+ unw
.save_order
[i
], IA64_WHERE_GR
,
300 sr
->region_start
+ sr
->region_len
- 1, grsave
++);
303 sr
->gr_save_loc
= grsave
;
306 sr
->spill_offset
= 0x10; /* default to psp+16 */
310 /* Prologue descriptors. */
313 desc_abi (unsigned char abi
, unsigned char context
,
314 struct ia64_state_record
*sr
)
316 sr
->abi_marker
= (abi
<< 8) | context
;
320 desc_br_gr (unsigned char brmask
, unsigned char gr
,
321 struct ia64_state_record
*sr
)
325 for (i
= 0; i
< 5; ++i
)
328 set_reg (sr
->curr
.reg
+ IA64_REG_B1
+ i
, IA64_WHERE_GR
,
329 sr
->region_start
+ sr
->region_len
- 1, gr
++);
335 desc_br_mem (unsigned char brmask
, struct ia64_state_record
*sr
)
339 for (i
= 0; i
< 5; ++i
)
343 set_reg (sr
->curr
.reg
+ IA64_REG_B1
+ i
, IA64_WHERE_SPILL_HOME
,
344 sr
->region_start
+ sr
->region_len
- 1, 0);
352 desc_frgr_mem (unsigned char grmask
, unw_word frmask
,
353 struct ia64_state_record
*sr
)
357 for (i
= 0; i
< 4; ++i
)
359 if ((grmask
& 1) != 0)
361 set_reg (sr
->curr
.reg
+ IA64_REG_R4
+ i
, IA64_WHERE_SPILL_HOME
,
362 sr
->region_start
+ sr
->region_len
- 1, 0);
367 for (i
= 0; i
< 20; ++i
)
369 if ((frmask
& 1) != 0)
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);
381 desc_fr_mem (unsigned char frmask
, struct ia64_state_record
*sr
)
385 for (i
= 0; i
< 4; ++i
)
387 if ((frmask
& 1) != 0)
389 set_reg (sr
->curr
.reg
+ IA64_REG_F2
+ i
, IA64_WHERE_SPILL_HOME
,
390 sr
->region_start
+ sr
->region_len
- 1, 0);
398 desc_gr_gr (unsigned char grmask
, unsigned char gr
,
399 struct ia64_state_record
*sr
)
403 for (i
= 0; i
< 4; ++i
)
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
++);
413 desc_gr_mem (unsigned char grmask
, struct ia64_state_record
*sr
)
417 for (i
= 0; i
< 4; ++i
)
419 if ((grmask
& 1) != 0)
421 set_reg (sr
->curr
.reg
+ IA64_REG_R4
+ i
, IA64_WHERE_SPILL_HOME
,
422 sr
->region_start
+ sr
->region_len
- 1, 0);
430 desc_mem_stack_f (unw_word t
, unw_word size
, struct ia64_state_record
*sr
)
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
);
437 desc_mem_stack_v (unw_word t
, struct ia64_state_record
*sr
)
439 sr
->curr
.reg
[IA64_REG_PSP
].when
=
440 sr
->region_start
+ MIN ((int) t
, sr
->region_len
- 1);
444 desc_reg_gr (unsigned char reg
, unsigned char dst
,
445 struct ia64_state_record
*sr
)
447 set_reg (sr
->curr
.reg
+ reg
, IA64_WHERE_GR
,
448 sr
->region_start
+ sr
->region_len
- 1, dst
);
452 desc_reg_psprel (unsigned char reg
, unw_word pspoff
,
453 struct ia64_state_record
*sr
)
455 set_reg (sr
->curr
.reg
+ reg
, IA64_WHERE_PSPREL
,
456 sr
->region_start
+ sr
->region_len
- 1, 0x10 - 4 * pspoff
);
460 desc_reg_sprel (unsigned char reg
, unw_word spoff
,
461 struct ia64_state_record
*sr
)
463 set_reg (sr
->curr
.reg
+ reg
, IA64_WHERE_SPREL
,
464 sr
->region_start
+ sr
->region_len
- 1, 4 * spoff
);
468 desc_rp_br (unsigned char dst
, struct ia64_state_record
*sr
)
470 sr
->return_link_reg
= dst
;
474 desc_reg_when (unsigned char regnum
, unw_word t
, struct ia64_state_record
*sr
)
476 struct ia64_reg_info
*reg
= sr
->curr
.reg
+ regnum
;
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);
484 desc_spill_base (unw_word pspoff
, struct ia64_state_record
*sr
)
486 sr
->spill_offset
= 0x10 - 4 * pspoff
;
489 static inline unsigned char *
490 desc_spill_mask (unsigned char *imaskp
, struct ia64_state_record
*sr
)
493 return imaskp
+ (2 * sr
->region_len
+ 7) / 8;
496 /* Body descriptors. */
499 desc_epilogue (unw_word t
, unw_word ecount
, struct ia64_state_record
*sr
)
501 sr
->when_sp_restored
= sr
->region_start
+ sr
->region_len
- 1 - t
;
502 sr
->epilogue_count
= ecount
+ 1;
506 desc_copy_state (unw_word label
, struct ia64_state_record
*sr
)
508 struct ia64_labeled_state
*ls
;
510 for (ls
= sr
->labeled_states
; ls
; ls
= ls
->next
)
512 if (ls
->label
== label
)
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
);
520 print_error ("libunwind: failed to find labeled state\n");
524 desc_label_state (unw_word label
, struct ia64_state_record
*sr
)
526 struct ia64_labeled_state
*ls
;
528 ls
= alloc_labeled_state ();
531 print_error ("unwind.desc_label_state(): out of memory\n");
535 memcpy (&ls
->saved_state
, &sr
->curr
, sizeof (ls
->saved_state
));
536 ls
->saved_state
.next
= dup_state_stack (sr
->curr
.next
);
538 /* insert into list of labeled states: */
539 ls
->next
= sr
->labeled_states
;
540 sr
->labeled_states
= ls
;
543 /* General descriptors. */
546 desc_is_active (unsigned char qp
, unw_word t
, struct ia64_state_record
*sr
)
548 if (sr
->when_target
<= sr
->region_start
+ MIN ((int) t
, sr
->region_len
- 1))
552 if ((sr
->pr_val
& ((unw_word_t
) 1 << qp
)) == 0)
554 sr
->pr_mask
|= ((unw_word_t
) 1 << qp
);
560 desc_restore_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
561 struct ia64_state_record
*sr
)
563 struct ia64_reg_info
*r
;
565 if (!desc_is_active (qp
, t
, sr
))
568 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
569 r
->where
= IA64_WHERE_NONE
;
570 r
->when
= IA64_WHEN_NEVER
;
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
)
579 enum ia64_where where
= IA64_WHERE_GR
;
580 struct ia64_reg_info
*r
;
582 if (!desc_is_active (qp
, t
, sr
))
586 where
= IA64_WHERE_BR
;
587 else if (ytreg
& 0x80)
588 where
= IA64_WHERE_FR
;
590 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
592 r
->when
= sr
->region_start
+ MIN ((int) t
, sr
->region_len
- 1);
593 r
->val
= (ytreg
& 0x7f);
597 desc_spill_psprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
598 unw_word pspoff
, struct ia64_state_record
*sr
)
600 struct ia64_reg_info
*r
;
602 if (!desc_is_active (qp
, t
, sr
))
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
;
612 desc_spill_sprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
613 unw_word spoff
, struct ia64_state_record
*sr
)
615 struct ia64_reg_info
*r
;
617 if (!desc_is_active (qp
, t
, sr
))
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);
626 #define UNW_DEC_BAD_CODE(code) \
627 print_error ("libunwind: unknown code encountered\n")
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
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)
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))
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)
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)
690 #include "unwind_decoder.h"
694 /* parse dynamic unwind info */
696 static struct ia64_reg_info
*
697 lookup_preg (int regnum
, int memory
, struct ia64_state_record
*sr
)
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;
716 preg
= IA64_REG_PRI_UNAT_MEM
;
718 preg
= IA64_REG_PRI_UNAT_GR
;
721 case UNW_IA64_GR
+ 4 ... UNW_IA64_GR
+ 7:
722 preg
= IA64_REG_R4
+ (regnum
- (UNW_IA64_GR
+ 4));
725 case UNW_IA64_BR
+ 1 ... UNW_IA64_BR
+ 5:
726 preg
= IA64_REG_B1
+ (regnum
- UNW_IA64_BR
);
729 case UNW_IA64_FR
+ 2 ... UNW_IA64_FR
+ 5:
730 preg
= IA64_REG_F2
+ (regnum
- (UNW_IA64_FR
+ 2));
733 case UNW_IA64_FR
+ 16 ... UNW_IA64_FR
+ 31:
734 preg
= IA64_REG_F16
+ (regnum
- (UNW_IA64_FR
+ 16));
738 Dprintf ("%s: invalid register number %d\n", __FUNCTION__
, regnum
);
741 return sr
->curr
.reg
+ preg
;
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
751 desc_alias (unw_dyn_op_t
*op
, struct cursor
*c
, struct ia64_state_record
*sr
)
753 struct ia64_state_record orig_sr
= *sr
;
754 int i
, ret
, when
, rlen
= sr
->region_len
;
757 when
= MIN (sr
->when_target
, rlen
);
758 new_ip
= op
->val
+ ((when
/ 3) * 16 + (when
% 3));
760 if ((ret
= ia64_fetch_proc_info (c
, new_ip
, 1)) < 0)
763 if ((ret
= create_state_record_for (c
, sr
, new_ip
)) < 0)
766 sr
->first_region
= orig_sr
.first_region
;
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
;
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
);
781 ia64_free_state_record (sr
);
782 sr
->labeled_states
= orig_sr
.labeled_states
;
783 sr
->curr
.next
= orig_sr
.curr
.next
;
788 parse_dynamic (struct cursor
*c
, struct ia64_state_record
*sr
)
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
;
801 for (r
= proc
->regions
; r
; r
= r
->next
)
808 Debug (1, "negative region length allowed in last region only!");
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
;
816 /* all regions are treated as prologue regions: */
817 desc_prologue (0, len
, 0, 0, sr
);
822 for (op
= r
->op
; op
< r
->op
+ r
->op_count
; ++op
)
828 if (!desc_is_active (qp
, when
, sr
))
831 when
= sr
->region_start
+ MIN ((int) when
, sr
->region_len
- 1);
835 case UNW_DYN_SAVE_REG
:
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
;
845 Dprintf ("%s: can't save to register number %d\n",
846 __FUNCTION__
, (int) op
->reg
);
851 ri
= lookup_preg (op
->reg
, memory
, sr
);
859 case UNW_DYN_SPILL_FP_REL
:
861 where
= IA64_WHERE_PSPREL
;
863 goto update_reg_info
;
865 case UNW_DYN_SPILL_SP_REL
:
867 where
= IA64_WHERE_SPREL
;
868 goto update_reg_info
;
871 if (op
->reg
== UNW_IA64_SP
)
875 Dprintf ("%s: frame-size %ld not an integer "
877 __FUNCTION__
, (long) op
->val
);
880 desc_mem_stack_f (when
, -((int64_t) val
/ 16), sr
);
884 Dprintf ("%s: can only ADD to stack-pointer\n",
890 case UNW_DYN_POP_FRAMES
:
891 sr
->when_sp_restored
= when
;
892 sr
->epilogue_count
= op
->val
;
895 case UNW_DYN_LABEL_STATE
:
896 desc_label_state (op
->val
, sr
);
899 case UNW_DYN_COPY_STATE
:
900 desc_copy_state (op
->val
, sr
);
904 if ((ret
= desc_alias (op
, c
, sr
)) < 0)
917 # define parse_dynamic(c,sr) (-UNW_EINVAL)
918 #endif /* _U_dyn_op */
922 ia64_fetch_proc_info (struct cursor
*c
, unw_word_t ip
, int need_unwind_info
)
924 int ret
, dynamic
= 1;
926 if (c
->pi_valid
&& !need_unwind_info
)
929 /* check dynamic info first --- it overrides everything else */
930 ret
= unwi_find_dynamic_proc_info (c
->as
, ip
, &c
->pi
, need_unwind_info
,
932 if (ret
== -UNW_ENOINFO
)
935 ret
= ia64_find_proc_info (c
, ip
, need_unwind_info
);
939 c
->pi_is_dynamic
= dynamic
;
944 put_unwind_info (struct cursor
*c
, unw_proc_info_t
*pi
)
949 if (c
->pi_is_dynamic
)
950 unwi_put_dynamic_unwind_info (c
->as
, pi
, c
->as_arg
);
952 ia64_put_unwind_info (c
, pi
);
956 create_state_record_for (struct cursor
*c
, struct ia64_state_record
*sr
,
959 unw_word_t predicates
= c
->pr
;
960 struct ia64_reg_info
*r
;
961 uint8_t *dp
, *desc_end
;
964 assert (c
->pi_valid
);
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;
973 if (!c
->pi
.unwind_info
)
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;
985 sr
->when_target
= (3 * ((ip
& ~(unw_word_t
) 0xf) - c
->pi
.start_ip
) / 16
988 switch (c
->pi
.format
)
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
);
999 case UNW_INFO_FORMAT_DYNAMIC
:
1000 ret
= parse_dynamic (c
, sr
);
1007 put_unwind_info (c
, &c
->pi
);
1012 if (sr
->when_target
> sr
->when_sp_restored
)
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
)
1024 r
->where
= IA64_WHERE_NONE
;
1025 r
->when
= IA64_WHEN_NEVER
;
1029 /* If RP did't get saved, generate entry for the return link
1031 if (sr
->curr
.reg
[IA64_REG_IP
].when
>= sr
->when_target
)
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
;
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
)
1042 Debug (8, "func 0x%lx may switch the register-backing-store\n",
1044 c
->pi
.flags
|= UNW_PI_FLAG_IA64_RBS_SWITCH
;
1048 if (unwi_debug_level
> 2)
1050 Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n",
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
)
1055 if (r
->where
!= IA64_WHERE_NONE
|| r
->when
!= IA64_WHEN_NEVER
)
1057 Dprintf (" %s <- ", unw
.preg_name
[r
- sr
->curr
.reg
]);
1061 Dprintf ("r%lu", (long) r
->val
);
1064 Dprintf ("f%lu", (long) r
->val
);
1067 Dprintf ("b%lu", (long) r
->val
);
1069 case IA64_WHERE_SPREL
:
1070 Dprintf ("[sp+0x%lx]", (long) r
->val
);
1072 case IA64_WHERE_PSPREL
:
1073 Dprintf ("[psp+0x%lx]", (long) r
->val
);
1075 case IA64_WHERE_NONE
:
1076 Dprintf ("%s+0x%lx",
1077 unw
.preg_name
[r
- sr
->curr
.reg
], (long) r
->val
);
1080 Dprintf ("BADWHERE(%d)", r
->where
);
1083 Dprintf ("\t\t%d\n", r
->when
);
1091 /* The proc-info must be valid for IP before this routine can be
1094 ia64_create_state_record (struct cursor
*c
, struct ia64_state_record
*sr
)
1096 return create_state_record_for (c
, sr
, c
->ip
);
1100 ia64_free_state_record (struct ia64_state_record
*sr
)
1102 struct ia64_labeled_state
*ls
, *next
;
1104 /* free labeled register states & stack: */
1106 for (ls
= sr
->labeled_states
; ls
; ls
= next
)
1109 free_state_stack (&ls
->saved_state
);
1110 free_labeled_state (ls
);
1112 free_state_stack (&sr
->curr
);
1118 ia64_make_proc_info (struct cursor
*c
)
1120 int ret
, caching
= c
->as
->caching_policy
!= UNW_CACHE_NONE
;
1122 if (!caching
|| ia64_get_cached_proc_info (c
) < 0)
1124 /* Lookup it up the slow way... */
1125 if ((ret
= ia64_fetch_proc_info (c
, c
->ip
, 0)) < 0)
1128 ia64_cache_proc_info (c
);