1 /* Subroutines needed for unwinding IA-64 standard format stack frame
2 info for exception handling.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 Contributed by Andrew MacLeod <amacleod@cygnus.com>
5 Andrew Haley <aph@cygnus.com>
6 David Mosberger-Tang <davidm@hpl.hp.com>
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* As a special exception, if you link this library with other files,
26 some of which are compiled with GCC, to produce an executable,
27 this library does not by itself cause the resulting executable
28 to be covered by the GNU General Public License.
29 This exception does not however invalidate any other reasons why
30 the executable file might be covered by the GNU General Public License. */
36 #include "unwind-ia64.h"
38 #if !USING_SJLJ_EXCEPTIONS
39 #define UNW_VER(x) ((x) >> 48)
40 #define UNW_FLAG_MASK 0x0000ffff00000000
41 #define UNW_FLAG_OSMASK 0x0000f00000000000
42 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
43 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
44 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
46 enum unw_application_register
60 enum unw_register_index
67 UNW_REG_PSP
, /* previous memory stack pointer */
70 UNW_REG_BSP
, /* register stack pointer */
72 UNW_REG_PFS
, /* previous function state */
77 /* Special preserved registers. */
78 UNW_REG_UNAT
, UNW_REG_PR
, UNW_REG_LC
, UNW_REG_FPSR
,
80 /* Non-stacked general registers. */
82 UNW_REG_R4
= UNW_REG_R2
+ 2,
83 UNW_REG_R7
= UNW_REG_R2
+ 5,
84 UNW_REG_R31
= UNW_REG_R2
+ 29,
86 /* Non-stacked floating point registers. */
88 UNW_REG_F5
= UNW_REG_F2
+ 3,
89 UNW_REG_F16
= UNW_REG_F2
+ 14,
90 UNW_REG_F31
= UNW_REG_F2
+ 29,
92 /* Branch registers. */
93 UNW_REG_B0
, UNW_REG_B1
,
94 UNW_REG_B5
= UNW_REG_B1
+ 4,
101 UNW_WHERE_NONE
, /* register isn't saved at all */
102 UNW_WHERE_GR
, /* register is saved in a general register */
103 UNW_WHERE_FR
, /* register is saved in a floating-point register */
104 UNW_WHERE_BR
, /* register is saved in a branch register */
105 UNW_WHERE_SPREL
, /* register is saved on memstack (sp-relative) */
106 UNW_WHERE_PSPREL
, /* register is saved on memstack (psp-relative) */
108 /* At the end of each prologue these locations get resolved to
109 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
110 UNW_WHERE_SPILL_HOME
, /* register is saved in its spill home */
111 UNW_WHERE_GR_SAVE
/* register is saved in next general register */
114 #define UNW_WHEN_NEVER 0x7fffffff
118 unsigned long val
; /* save location: register number or offset */
119 enum unw_where where
; /* where the register gets saved */
120 int when
; /* when the register gets saved */
123 typedef struct unw_state_record
125 unsigned int first_region
: 1; /* is this the first region? */
126 unsigned int done
: 1; /* are we done scanning descriptors? */
127 unsigned int any_spills
: 1; /* got any register spills? */
128 unsigned int in_body
: 1; /* are we inside a body? */
130 unsigned char *imask
; /* imask of of spill_mask record or NULL */
131 unsigned long pr_val
; /* predicate values */
132 unsigned long pr_mask
; /* predicate mask */
133 long spill_offset
; /* psp-relative offset for spill base */
140 unsigned char gr_save_loc
; /* next general register to use for saving */
141 unsigned char return_link_reg
; /* branch register for return link */
143 struct unw_reg_state
{
144 struct unw_reg_state
*next
;
145 unsigned long label
; /* label of this state record */
146 struct unw_reg_info reg
[UNW_NUM_REGS
];
147 } curr
, *stack
, *reg_state_list
;
149 _Unwind_Personality_Fn personality
;
151 } _Unwind_FrameState
;
155 UNW_NAT_NONE
, /* NaT not represented */
156 UNW_NAT_VAL
, /* NaT represented by NaT value (fp reg) */
157 UNW_NAT_MEMSTK
, /* NaT value is in unat word at offset OFF */
158 UNW_NAT_REGSTK
/* NaT is in rnat */
167 struct _Unwind_Context
169 /* Initial frame info. */
170 unsigned long rnat
; /* rse nat collection */
171 unsigned long regstk_top
; /* bsp for first frame */
173 /* Current frame info. */
174 unsigned long bsp
; /* backing store pointer value
175 corresponding to psp. */
176 unsigned long sp
; /* stack pointer value */
177 unsigned long psp
; /* previous sp value */
178 unsigned long rp
; /* return pointer */
179 unsigned long pr
; /* predicate collection */
181 unsigned long region_start
; /* start of unwind region */
182 unsigned long gp
; /* global pointer value */
183 void *lsda
; /* language specific data area */
185 /* Preserved state. */
186 unsigned long *bsp_loc
; /* previous bsp save location */
187 unsigned long *bspstore_loc
;
188 unsigned long *pfs_loc
;
189 unsigned long *pri_unat_loc
;
190 unsigned long *unat_loc
;
191 unsigned long *lc_loc
;
192 unsigned long *fpsr_loc
;
194 unsigned long eh_data
[4];
201 enum unw_nat_type type
: 3;
202 signed long off
: 61; /* NaT word is at loc+nat.off */
204 } ireg
[32 - 2]; /* Indexed by <register number> - 2 */
206 unsigned long *br_loc
[7];
207 void *fr_loc
[32 - 2];
209 /* ??? We initially point pri_unat_loc here. The entire NAT bit
211 unsigned long initial_unat
;
214 typedef unsigned long unw_word
;
216 /* Implicit register save order. See section 11.4.2.3 Rules for Using
217 Unwind Descriptors, rule 3. */
219 static unsigned char const save_order
[] =
221 UNW_REG_RP
, UNW_REG_PFS
, UNW_REG_PSP
, UNW_REG_PR
,
222 UNW_REG_UNAT
, UNW_REG_LC
, UNW_REG_FPSR
, UNW_REG_PRI_UNAT_GR
226 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
228 /* Unwind decoder routines */
231 push (struct unw_state_record
*sr
)
233 struct unw_reg_state
*rs
;
235 rs
= malloc (sizeof (struct unw_reg_state
));
236 memcpy (rs
, &sr
->curr
, sizeof (*rs
));
237 rs
->next
= sr
->stack
;
242 pop (struct unw_state_record
*sr
)
244 struct unw_reg_state
*rs
;
247 sr
->stack
= rs
->next
;
251 static enum unw_register_index
__attribute__((const))
252 decode_abreg (unsigned char abreg
, int memory
)
256 case 0x04 ... 0x07: return UNW_REG_R4
+ (abreg
- 0x04);
257 case 0x22 ... 0x25: return UNW_REG_F2
+ (abreg
- 0x22);
258 case 0x30 ... 0x3f: return UNW_REG_F16
+ (abreg
- 0x30);
259 case 0x41 ... 0x45: return UNW_REG_B1
+ (abreg
- 0x41);
260 case 0x60: return UNW_REG_PR
;
261 case 0x61: return UNW_REG_PSP
;
262 case 0x62: return memory
? UNW_REG_PRI_UNAT_MEM
: UNW_REG_PRI_UNAT_GR
;
263 case 0x63: return UNW_REG_RP
;
264 case 0x64: return UNW_REG_BSP
;
265 case 0x65: return UNW_REG_BSPSTORE
;
266 case 0x66: return UNW_REG_RNAT
;
267 case 0x67: return UNW_REG_UNAT
;
268 case 0x68: return UNW_REG_FPSR
;
269 case 0x69: return UNW_REG_PFS
;
270 case 0x6a: return UNW_REG_LC
;
277 set_reg (struct unw_reg_info
*reg
, enum unw_where where
,
278 int when
, unsigned long val
)
282 if (reg
->when
== UNW_WHEN_NEVER
)
287 alloc_spill_area (unsigned long *offp
, unsigned long regsize
,
288 struct unw_reg_info
*lo
, struct unw_reg_info
*hi
)
290 struct unw_reg_info
*reg
;
292 for (reg
= hi
; reg
>= lo
; --reg
)
294 if (reg
->where
== UNW_WHERE_SPILL_HOME
)
296 reg
->where
= UNW_WHERE_PSPREL
;
297 reg
->val
= 0x10 - *offp
;
304 spill_next_when (struct unw_reg_info
**regp
, struct unw_reg_info
*lim
,
307 struct unw_reg_info
*reg
;
309 for (reg
= *regp
; reg
<= lim
; ++reg
)
311 if (reg
->where
== UNW_WHERE_SPILL_HOME
)
323 finish_prologue (struct unw_state_record
*sr
)
325 struct unw_reg_info
*reg
;
329 /* First, resolve implicit register save locations
330 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
332 for (i
= 0; i
< (int) sizeof(save_order
); ++i
)
334 reg
= sr
->curr
.reg
+ save_order
[i
];
335 if (reg
->where
== UNW_WHERE_GR_SAVE
)
337 reg
->where
= UNW_WHERE_GR
;
338 reg
->val
= sr
->gr_save_loc
++;
342 /* Next, compute when the fp, general, and branch registers get saved.
343 This must come before alloc_spill_area() because we need to know
344 which registers are spilled to their home locations. */
347 static unsigned char const limit
[3] = {
348 UNW_REG_F31
, UNW_REG_R7
, UNW_REG_B5
351 unsigned char kind
, mask
= 0, *cp
= sr
->imask
;
353 struct unw_reg_info
*(regs
[3]);
355 regs
[0] = sr
->curr
.reg
+ UNW_REG_F2
;
356 regs
[1] = sr
->curr
.reg
+ UNW_REG_R4
;
357 regs
[2] = sr
->curr
.reg
+ UNW_REG_B1
;
359 for (t
= 0; t
< sr
->region_len
; ++t
)
363 kind
= (mask
>> 2*(3-(t
& 3))) & 3;
365 spill_next_when(®s
[kind
- 1], sr
->curr
.reg
+ limit
[kind
- 1],
366 sr
->region_start
+ t
);
370 /* Next, lay out the memory stack spill area. */
373 off
= sr
->spill_offset
;
374 alloc_spill_area(&off
, 16, sr
->curr
.reg
+ UNW_REG_F2
,
375 sr
->curr
.reg
+ UNW_REG_F31
);
376 alloc_spill_area(&off
, 8, sr
->curr
.reg
+ UNW_REG_B1
,
377 sr
->curr
.reg
+ UNW_REG_B5
);
378 alloc_spill_area(&off
, 8, sr
->curr
.reg
+ UNW_REG_R4
,
379 sr
->curr
.reg
+ UNW_REG_R7
);
384 * Region header descriptors.
388 desc_prologue (int body
, unw_word rlen
, unsigned char mask
,
389 unsigned char grsave
, struct unw_state_record
*sr
)
393 if (!(sr
->in_body
|| sr
->first_region
))
395 sr
->first_region
= 0;
397 /* Check if we're done. */
398 if (body
&& sr
->when_target
< sr
->region_start
+ sr
->region_len
)
404 for (i
= 0; i
< sr
->epilogue_count
; ++i
)
406 sr
->epilogue_count
= 0;
407 sr
->epilogue_start
= UNW_WHEN_NEVER
;
412 sr
->region_start
+= sr
->region_len
;
413 sr
->region_len
= rlen
;
418 for (i
= 0; i
< 4; ++i
)
421 set_reg (sr
->curr
.reg
+ save_order
[i
], UNW_WHERE_GR
,
422 sr
->region_start
+ sr
->region_len
- 1, grsave
++);
425 sr
->gr_save_loc
= grsave
;
428 sr
->spill_offset
= 0x10; /* default to psp+16 */
433 * Prologue descriptors.
437 desc_abi (unsigned char abi
__attribute__((unused
)),
438 unsigned char context
__attribute__((unused
)),
439 struct unw_state_record
*sr
__attribute__((unused
)))
441 /* Anything to do? */
445 desc_br_gr (unsigned char brmask
, unsigned char gr
,
446 struct unw_state_record
*sr
)
450 for (i
= 0; i
< 5; ++i
)
453 set_reg (sr
->curr
.reg
+ UNW_REG_B1
+ i
, UNW_WHERE_GR
,
454 sr
->region_start
+ sr
->region_len
- 1, gr
++);
460 desc_br_mem (unsigned char brmask
, struct unw_state_record
*sr
)
464 for (i
= 0; i
< 5; ++i
)
468 set_reg (sr
->curr
.reg
+ UNW_REG_B1
+ i
, UNW_WHERE_SPILL_HOME
,
469 sr
->region_start
+ sr
->region_len
- 1, 0);
477 desc_frgr_mem (unsigned char grmask
, unw_word frmask
,
478 struct unw_state_record
*sr
)
482 for (i
= 0; i
< 4; ++i
)
484 if ((grmask
& 1) != 0)
486 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_SPILL_HOME
,
487 sr
->region_start
+ sr
->region_len
- 1, 0);
492 for (i
= 0; i
< 20; ++i
)
494 if ((frmask
& 1) != 0)
496 set_reg (sr
->curr
.reg
+ UNW_REG_F2
+ i
, UNW_WHERE_SPILL_HOME
,
497 sr
->region_start
+ sr
->region_len
- 1, 0);
505 desc_fr_mem (unsigned char frmask
, struct unw_state_record
*sr
)
509 for (i
= 0; i
< 4; ++i
)
511 if ((frmask
& 1) != 0)
513 set_reg (sr
->curr
.reg
+ UNW_REG_F2
+ i
, UNW_WHERE_SPILL_HOME
,
514 sr
->region_start
+ sr
->region_len
- 1, 0);
522 desc_gr_gr (unsigned char grmask
, unsigned char gr
,
523 struct unw_state_record
*sr
)
527 for (i
= 0; i
< 4; ++i
)
529 if ((grmask
& 1) != 0)
530 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_GR
,
531 sr
->region_start
+ sr
->region_len
- 1, gr
++);
537 desc_gr_mem (unsigned char grmask
, struct unw_state_record
*sr
)
541 for (i
= 0; i
< 4; ++i
)
543 if ((grmask
& 1) != 0)
545 set_reg (sr
->curr
.reg
+ UNW_REG_R4
+ i
, UNW_WHERE_SPILL_HOME
,
546 sr
->region_start
+ sr
->region_len
- 1, 0);
554 desc_mem_stack_f (unw_word t
, unw_word size
, struct unw_state_record
*sr
)
556 set_reg (sr
->curr
.reg
+ UNW_REG_PSP
, UNW_WHERE_NONE
,
557 sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1), 16*size
);
561 desc_mem_stack_v (unw_word t
, struct unw_state_record
*sr
)
563 sr
->curr
.reg
[UNW_REG_PSP
].when
564 = sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
568 desc_reg_gr (unsigned char reg
, unsigned char dst
, struct unw_state_record
*sr
)
570 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_GR
,
571 sr
->region_start
+ sr
->region_len
- 1, dst
);
575 desc_reg_psprel (unsigned char reg
, unw_word pspoff
,
576 struct unw_state_record
*sr
)
578 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_PSPREL
,
579 sr
->region_start
+ sr
->region_len
- 1,
584 desc_reg_sprel (unsigned char reg
, unw_word spoff
, struct unw_state_record
*sr
)
586 set_reg (sr
->curr
.reg
+ reg
, UNW_WHERE_SPREL
,
587 sr
->region_start
+ sr
->region_len
- 1,
592 desc_rp_br (unsigned char dst
, struct unw_state_record
*sr
)
594 sr
->return_link_reg
= dst
;
598 desc_reg_when (unsigned char regnum
, unw_word t
, struct unw_state_record
*sr
)
600 struct unw_reg_info
*reg
= sr
->curr
.reg
+ regnum
;
602 if (reg
->where
== UNW_WHERE_NONE
)
603 reg
->where
= UNW_WHERE_GR_SAVE
;
604 reg
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
608 desc_spill_base (unw_word pspoff
, struct unw_state_record
*sr
)
610 sr
->spill_offset
= 0x10 - 4*pspoff
;
613 static inline unsigned char *
614 desc_spill_mask (unsigned char *imaskp
, struct unw_state_record
*sr
)
617 return imaskp
+ (2*sr
->region_len
+ 7)/8;
624 desc_epilogue (unw_word t
, unw_word ecount
, struct unw_state_record
*sr
)
626 sr
->epilogue_start
= sr
->region_start
+ sr
->region_len
- 1 - t
;
627 sr
->epilogue_count
= ecount
+ 1;
631 desc_copy_state (unw_word label
, struct unw_state_record
*sr
)
633 struct unw_reg_state
*rs
;
635 for (rs
= sr
->reg_state_list
; rs
; rs
= rs
->next
)
637 if (rs
->label
== label
)
639 memcpy (&sr
->curr
, rs
, sizeof(sr
->curr
));
647 desc_label_state (unw_word label
, struct unw_state_record
*sr
)
649 struct unw_reg_state
*rs
;
651 rs
= malloc (sizeof (struct unw_reg_state
));
652 memcpy (rs
, &sr
->curr
, sizeof (*rs
));
654 rs
->next
= sr
->reg_state_list
;
655 sr
->reg_state_list
= rs
;
659 * General descriptors.
663 desc_is_active (unsigned char qp
, unw_word t
, struct unw_state_record
*sr
)
665 if (sr
->when_target
<= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1))
669 if ((sr
->pr_val
& (1UL << qp
)) == 0)
671 sr
->pr_mask
|= (1UL << qp
);
677 desc_restore_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
678 struct unw_state_record
*sr
)
680 struct unw_reg_info
*r
;
682 if (! desc_is_active (qp
, t
, sr
))
685 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
686 r
->where
= UNW_WHERE_NONE
;
687 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
692 desc_spill_reg_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
693 unsigned char x
, unsigned char ytreg
,
694 struct unw_state_record
*sr
)
696 enum unw_where where
= UNW_WHERE_GR
;
697 struct unw_reg_info
*r
;
699 if (! desc_is_active (qp
, t
, sr
))
703 where
= UNW_WHERE_BR
;
704 else if (ytreg
& 0x80)
705 where
= UNW_WHERE_FR
;
707 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 0);
709 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
710 r
->val
= ytreg
& 0x7f;
714 desc_spill_psprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
715 unw_word pspoff
, struct unw_state_record
*sr
)
717 struct unw_reg_info
*r
;
719 if (! desc_is_active (qp
, t
, sr
))
722 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 1);
723 r
->where
= UNW_WHERE_PSPREL
;
724 r
->when
= sr
->region_start
+ MIN((int)t
, sr
->region_len
- 1);
725 r
->val
= 0x10 - 4*pspoff
;
729 desc_spill_sprel_p (unsigned char qp
, unw_word t
, unsigned char abreg
,
730 unw_word spoff
, struct unw_state_record
*sr
)
732 struct unw_reg_info
*r
;
734 if (! desc_is_active (qp
, t
, sr
))
737 r
= sr
->curr
.reg
+ decode_abreg (abreg
, 1);
738 r
->where
= UNW_WHERE_SPREL
;
739 r
->when
= sr
->region_start
+ MIN ((int)t
, sr
->region_len
- 1);
744 #define UNW_DEC_BAD_CODE(code) abort ();
746 /* Region headers. */
747 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
748 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
750 /* Prologue descriptors. */
751 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
752 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
753 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
754 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
755 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
756 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
757 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
758 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
759 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
760 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
761 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
762 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
763 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
764 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
765 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
766 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
767 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
768 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
769 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
770 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
771 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
773 /* Body descriptors. */
774 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
775 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
776 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
778 /* General unwind descriptors. */
779 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
780 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
781 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
782 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
783 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
784 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
785 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
786 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
790 * Generic IA-64 unwind info decoder.
792 * This file is used both by the Linux kernel and objdump. Please keep
793 * the copies of this file in sync.
795 * You need to customize the decoder by defining the following
796 * macros/constants before including this file:
799 * unw_word Unsigned integer type with at least 64 bits
813 * Decoder action macros:
814 * UNW_DEC_BAD_CODE(code)
815 * UNW_DEC_ABI(fmt,abi,context,arg)
816 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
817 * UNW_DEC_BR_MEM(fmt,brmask,arg)
818 * UNW_DEC_COPY_STATE(fmt,label,arg)
819 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
820 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
821 * UNW_DEC_FR_MEM(fmt,frmask,arg)
822 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
823 * UNW_DEC_GR_MEM(fmt,grmask,arg)
824 * UNW_DEC_LABEL_STATE(fmt,label,arg)
825 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
826 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
827 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
828 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
829 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
830 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
831 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
832 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
833 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
834 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
835 * UNW_DEC_REG_REG(fmt,src,dst,arg)
836 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
837 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
838 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
839 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
840 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
841 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
842 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
843 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
844 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
845 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
846 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
847 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
851 unw_decode_uleb128 (unsigned char **dpp
)
854 unw_word byte
, result
= 0;
855 unsigned char *bp
= *dpp
;
860 result
|= (byte
& 0x7f) << shift
;
861 if ((byte
& 0x80) == 0)
869 static unsigned char *
870 unw_decode_x1 (unsigned char *dp
,
871 unsigned char code
__attribute__((unused
)),
874 unsigned char byte1
, abreg
;
878 t
= unw_decode_uleb128 (&dp
);
879 off
= unw_decode_uleb128 (&dp
);
880 abreg
= (byte1
& 0x7f);
882 UNW_DEC_SPILL_SPREL(X1
, t
, abreg
, off
, arg
);
884 UNW_DEC_SPILL_PSPREL(X1
, t
, abreg
, off
, arg
);
888 static unsigned char *
889 unw_decode_x2 (unsigned char *dp
,
890 unsigned char code
__attribute__((unused
)),
893 unsigned char byte1
, byte2
, abreg
, x
, ytreg
;
896 byte1
= *dp
++; byte2
= *dp
++;
897 t
= unw_decode_uleb128 (&dp
);
898 abreg
= (byte1
& 0x7f);
900 x
= (byte1
>> 7) & 1;
901 if ((byte1
& 0x80) == 0 && ytreg
== 0)
902 UNW_DEC_RESTORE(X2
, t
, abreg
, arg
);
904 UNW_DEC_SPILL_REG(X2
, t
, abreg
, x
, ytreg
, arg
);
908 static unsigned char *
909 unw_decode_x3 (unsigned char *dp
,
910 unsigned char code
__attribute__((unused
)),
913 unsigned char byte1
, byte2
, abreg
, qp
;
916 byte1
= *dp
++; byte2
= *dp
++;
917 t
= unw_decode_uleb128 (&dp
);
918 off
= unw_decode_uleb128 (&dp
);
921 abreg
= (byte2
& 0x7f);
924 UNW_DEC_SPILL_SPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
926 UNW_DEC_SPILL_PSPREL_P(X3
, qp
, t
, abreg
, off
, arg
);
930 static unsigned char *
931 unw_decode_x4 (unsigned char *dp
,
932 unsigned char code
__attribute__((unused
)),
935 unsigned char byte1
, byte2
, byte3
, qp
, abreg
, x
, ytreg
;
938 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
939 t
= unw_decode_uleb128 (&dp
);
942 abreg
= (byte2
& 0x7f);
943 x
= (byte2
>> 7) & 1;
946 if ((byte2
& 0x80) == 0 && byte3
== 0)
947 UNW_DEC_RESTORE_P(X4
, qp
, t
, abreg
, arg
);
949 UNW_DEC_SPILL_REG_P(X4
, qp
, t
, abreg
, x
, ytreg
, arg
);
953 static unsigned char *
954 unw_decode_r1 (unsigned char *dp
, unsigned char code
, void *arg
)
956 int body
= (code
& 0x20) != 0;
959 rlen
= (code
& 0x1f);
960 UNW_DEC_PROLOGUE(R1
, body
, rlen
, arg
);
964 static unsigned char *
965 unw_decode_r2 (unsigned char *dp
, unsigned char code
, void *arg
)
967 unsigned char byte1
, mask
, grsave
;
972 mask
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
973 grsave
= (byte1
& 0x7f);
974 rlen
= unw_decode_uleb128 (&dp
);
975 UNW_DEC_PROLOGUE_GR(R2
, rlen
, mask
, grsave
, arg
);
979 static unsigned char *
980 unw_decode_r3 (unsigned char *dp
, unsigned char code
, void *arg
)
984 rlen
= unw_decode_uleb128 (&dp
);
985 UNW_DEC_PROLOGUE(R3
, ((code
& 0x3) == 1), rlen
, arg
);
989 static unsigned char *
990 unw_decode_p1 (unsigned char *dp
, unsigned char code
, void *arg
)
992 unsigned char brmask
= (code
& 0x1f);
994 UNW_DEC_BR_MEM(P1
, brmask
, arg
);
998 static unsigned char *
999 unw_decode_p2_p5 (unsigned char *dp
, unsigned char code
, void *arg
)
1001 if ((code
& 0x10) == 0)
1003 unsigned char byte1
= *dp
++;
1005 UNW_DEC_BR_GR(P2
, ((code
& 0xf) << 1) | ((byte1
>> 7) & 1),
1006 (byte1
& 0x7f), arg
);
1008 else if ((code
& 0x08) == 0)
1010 unsigned char byte1
= *dp
++, r
, dst
;
1012 r
= ((code
& 0x7) << 1) | ((byte1
>> 7) & 1);
1013 dst
= (byte1
& 0x7f);
1016 case 0: UNW_DEC_REG_GR(P3
, UNW_REG_PSP
, dst
, arg
); break;
1017 case 1: UNW_DEC_REG_GR(P3
, UNW_REG_RP
, dst
, arg
); break;
1018 case 2: UNW_DEC_REG_GR(P3
, UNW_REG_PFS
, dst
, arg
); break;
1019 case 3: UNW_DEC_REG_GR(P3
, UNW_REG_PR
, dst
, arg
); break;
1020 case 4: UNW_DEC_REG_GR(P3
, UNW_REG_UNAT
, dst
, arg
); break;
1021 case 5: UNW_DEC_REG_GR(P3
, UNW_REG_LC
, dst
, arg
); break;
1022 case 6: UNW_DEC_RP_BR(P3
, dst
, arg
); break;
1023 case 7: UNW_DEC_REG_GR(P3
, UNW_REG_RNAT
, dst
, arg
); break;
1024 case 8: UNW_DEC_REG_GR(P3
, UNW_REG_BSP
, dst
, arg
); break;
1025 case 9: UNW_DEC_REG_GR(P3
, UNW_REG_BSPSTORE
, dst
, arg
); break;
1026 case 10: UNW_DEC_REG_GR(P3
, UNW_REG_FPSR
, dst
, arg
); break;
1027 case 11: UNW_DEC_PRIUNAT_GR(P3
, dst
, arg
); break;
1028 default: UNW_DEC_BAD_CODE(r
); break;
1031 else if ((code
& 0x7) == 0)
1032 UNW_DEC_SPILL_MASK(P4
, dp
, arg
);
1033 else if ((code
& 0x7) == 1)
1035 unw_word grmask
, frmask
, byte1
, byte2
, byte3
;
1037 byte1
= *dp
++; byte2
= *dp
++; byte3
= *dp
++;
1038 grmask
= ((byte1
>> 4) & 0xf);
1039 frmask
= ((byte1
& 0xf) << 16) | (byte2
<< 8) | byte3
;
1040 UNW_DEC_FRGR_MEM(P5
, grmask
, frmask
, arg
);
1043 UNW_DEC_BAD_CODE(code
);
1047 static unsigned char *
1048 unw_decode_p6 (unsigned char *dp
, unsigned char code
, void *arg
)
1050 int gregs
= (code
& 0x10) != 0;
1051 unsigned char mask
= (code
& 0x0f);
1054 UNW_DEC_GR_MEM(P6
, mask
, arg
);
1056 UNW_DEC_FR_MEM(P6
, mask
, arg
);
1060 static unsigned char *
1061 unw_decode_p7_p10 (unsigned char *dp
, unsigned char code
, void *arg
)
1063 unsigned char r
, byte1
, byte2
;
1066 if ((code
& 0x10) == 0)
1069 t
= unw_decode_uleb128 (&dp
);
1073 size
= unw_decode_uleb128 (&dp
);
1074 UNW_DEC_MEM_STACK_F(P7
, t
, size
, arg
);
1077 case 1: UNW_DEC_MEM_STACK_V(P7
, t
, arg
); break;
1078 case 2: UNW_DEC_SPILL_BASE(P7
, t
, arg
); break;
1079 case 3: UNW_DEC_REG_SPREL(P7
, UNW_REG_PSP
, t
, arg
); break;
1080 case 4: UNW_DEC_REG_WHEN(P7
, UNW_REG_RP
, t
, arg
); break;
1081 case 5: UNW_DEC_REG_PSPREL(P7
, UNW_REG_RP
, t
, arg
); break;
1082 case 6: UNW_DEC_REG_WHEN(P7
, UNW_REG_PFS
, t
, arg
); break;
1083 case 7: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PFS
, t
, arg
); break;
1084 case 8: UNW_DEC_REG_WHEN(P7
, UNW_REG_PR
, t
, arg
); break;
1085 case 9: UNW_DEC_REG_PSPREL(P7
, UNW_REG_PR
, t
, arg
); break;
1086 case 10: UNW_DEC_REG_WHEN(P7
, UNW_REG_LC
, t
, arg
); break;
1087 case 11: UNW_DEC_REG_PSPREL(P7
, UNW_REG_LC
, t
, arg
); break;
1088 case 12: UNW_DEC_REG_WHEN(P7
, UNW_REG_UNAT
, t
, arg
); break;
1089 case 13: UNW_DEC_REG_PSPREL(P7
, UNW_REG_UNAT
, t
, arg
); break;
1090 case 14: UNW_DEC_REG_WHEN(P7
, UNW_REG_FPSR
, t
, arg
); break;
1091 case 15: UNW_DEC_REG_PSPREL(P7
, UNW_REG_FPSR
, t
, arg
); break;
1092 default: UNW_DEC_BAD_CODE(r
); break;
1102 t
= unw_decode_uleb128 (&dp
);
1105 case 1: UNW_DEC_REG_SPREL(P8
, UNW_REG_RP
, t
, arg
); break;
1106 case 2: UNW_DEC_REG_SPREL(P8
, UNW_REG_PFS
, t
, arg
); break;
1107 case 3: UNW_DEC_REG_SPREL(P8
, UNW_REG_PR
, t
, arg
); break;
1108 case 4: UNW_DEC_REG_SPREL(P8
, UNW_REG_LC
, t
, arg
); break;
1109 case 5: UNW_DEC_REG_SPREL(P8
, UNW_REG_UNAT
, t
, arg
); break;
1110 case 6: UNW_DEC_REG_SPREL(P8
, UNW_REG_FPSR
, t
, arg
); break;
1111 case 7: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSP
, t
, arg
); break;
1112 case 8: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
1113 case 9: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSP
, t
, arg
); break;
1114 case 10: UNW_DEC_REG_WHEN(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1115 case 11: UNW_DEC_REG_PSPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1116 case 12: UNW_DEC_REG_SPREL(P8
, UNW_REG_BSPSTORE
, t
, arg
); break;
1117 case 13: UNW_DEC_REG_WHEN(P8
, UNW_REG_RNAT
, t
, arg
); break;
1118 case 14: UNW_DEC_REG_PSPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
1119 case 15: UNW_DEC_REG_SPREL(P8
, UNW_REG_RNAT
, t
, arg
); break;
1120 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8
, t
, arg
); break;
1121 case 17: UNW_DEC_PRIUNAT_PSPREL(P8
, t
, arg
); break;
1122 case 18: UNW_DEC_PRIUNAT_SPREL(P8
, t
, arg
); break;
1123 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8
, t
, arg
); break;
1124 default: UNW_DEC_BAD_CODE(r
); break;
1130 byte1
= *dp
++; byte2
= *dp
++;
1131 UNW_DEC_GR_GR(P9
, (byte1
& 0xf), (byte2
& 0x7f), arg
);
1135 byte1
= *dp
++; byte2
= *dp
++;
1136 UNW_DEC_ABI(P10
, byte1
, byte2
, arg
);
1140 return unw_decode_x1 (dp
, code
, arg
);
1143 return unw_decode_x2 (dp
, code
, arg
);
1146 return unw_decode_x3 (dp
, code
, arg
);
1149 return unw_decode_x4 (dp
, code
, arg
);
1152 UNW_DEC_BAD_CODE(code
);
1159 static unsigned char *
1160 unw_decode_b1 (unsigned char *dp
, unsigned char code
, void *arg
)
1162 unw_word label
= (code
& 0x1f);
1164 if ((code
& 0x20) != 0)
1165 UNW_DEC_COPY_STATE(B1
, label
, arg
);
1167 UNW_DEC_LABEL_STATE(B1
, label
, arg
);
1171 static unsigned char *
1172 unw_decode_b2 (unsigned char *dp
, unsigned char code
, void *arg
)
1176 t
= unw_decode_uleb128 (&dp
);
1177 UNW_DEC_EPILOGUE(B2
, t
, (code
& 0x1f), arg
);
1181 static unsigned char *
1182 unw_decode_b3_x4 (unsigned char *dp
, unsigned char code
, void *arg
)
1184 unw_word t
, ecount
, label
;
1186 if ((code
& 0x10) == 0)
1188 t
= unw_decode_uleb128 (&dp
);
1189 ecount
= unw_decode_uleb128 (&dp
);
1190 UNW_DEC_EPILOGUE(B3
, t
, ecount
, arg
);
1192 else if ((code
& 0x07) == 0)
1194 label
= unw_decode_uleb128 (&dp
);
1195 if ((code
& 0x08) != 0)
1196 UNW_DEC_COPY_STATE(B4
, label
, arg
);
1198 UNW_DEC_LABEL_STATE(B4
, label
, arg
);
1203 case 1: return unw_decode_x1 (dp
, code
, arg
);
1204 case 2: return unw_decode_x2 (dp
, code
, arg
);
1205 case 3: return unw_decode_x3 (dp
, code
, arg
);
1206 case 4: return unw_decode_x4 (dp
, code
, arg
);
1207 default: UNW_DEC_BAD_CODE(code
); break;
1212 typedef unsigned char *(*unw_decoder
) (unsigned char *, unsigned char, void *);
1214 static unw_decoder unw_decode_table
[2][8] =
1216 /* prologue table: */
1218 unw_decode_r1
, /* 0 */
1222 unw_decode_p1
, /* 4 */
1228 unw_decode_r1
, /* 0 */
1232 unw_decode_b1
, /* 4 */
1240 * Decode one descriptor and return address of next descriptor.
1242 static inline unsigned char *
1243 unw_decode (unsigned char *dp
, int inside_body
, void *arg
)
1245 unw_decoder decoder
;
1249 decoder
= unw_decode_table
[inside_body
][code
>> 5];
1250 dp
= (*decoder
) (dp
, code
, arg
);
1255 /* RSE helper functions. */
1257 static inline unsigned long
1258 ia64_rse_slot_num (unsigned long *addr
)
1260 return (((unsigned long) addr
) >> 3) & 0x3f;
1263 /* Return TRUE if ADDR is the address of an RNAT slot. */
1264 static inline unsigned long
1265 ia64_rse_is_rnat_slot (unsigned long *addr
)
1267 return ia64_rse_slot_num (addr
) == 0x3f;
1270 /* Returns the address of the RNAT slot that covers the slot at
1271 address SLOT_ADDR. */
1272 static inline unsigned long *
1273 ia64_rse_rnat_addr (unsigned long *slot_addr
)
1275 return (unsigned long *) ((unsigned long) slot_addr
| (0x3f << 3));
1278 /* Calcuate the number of registers in the dirty partition starting at
1279 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1280 divided by eight because the 64th slot is used to store ar.rnat. */
1281 static inline unsigned long
1282 ia64_rse_num_regs (unsigned long *bspstore
, unsigned long *bsp
)
1284 unsigned long slots
= (bsp
- bspstore
);
1286 return slots
- (ia64_rse_slot_num (bspstore
) + slots
)/0x40;
1289 /* The inverse of the above: given bspstore and the number of
1290 registers, calculate ar.bsp. */
1291 static inline unsigned long *
1292 ia64_rse_skip_regs (unsigned long *addr
, long num_regs
)
1294 long delta
= ia64_rse_slot_num (addr
) + num_regs
;
1298 return addr
+ num_regs
+ delta
/0x3f;
1302 /* Unwind accessors. */
1305 unw_access_gr (struct _Unwind_Context
*info
, int regnum
,
1306 unsigned long *val
, char *nat
, int write
)
1308 unsigned long *addr
, *nat_addr
= 0, nat_mask
= 0, dummy_nat
;
1309 struct unw_ireg
*ireg
;
1311 if ((unsigned) regnum
- 1 >= 127)
1316 nat_addr
= addr
= &dummy_nat
;
1319 else if (regnum
< 32)
1321 /* Access a non-stacked register. */
1322 ireg
= &info
->ireg
[regnum
- 2];
1326 nat_addr
= addr
+ ireg
->nat
.off
;
1327 switch (ireg
->nat
.type
)
1330 /* Simulate getf.sig/setf.sig. */
1335 /* Write NaTVal and be done with it. */
1342 else if (addr
[0] == 0 && addr
[1] == 0x1ffe)
1344 /* Return NaT and be done with it. */
1353 nat_addr
= &dummy_nat
;
1356 case UNW_NAT_MEMSTK
:
1357 nat_mask
= 1UL << ((long) addr
& 0x1f8)/8;
1360 case UNW_NAT_REGSTK
:
1361 nat_addr
= ia64_rse_rnat_addr (addr
);
1362 if ((unsigned long) nat_addr
>= info
->regstk_top
)
1363 nat_addr
= &info
->rnat
;
1364 nat_mask
= 1UL << ia64_rse_slot_num (addr
);
1371 /* Access a stacked register. */
1372 addr
= ia64_rse_skip_regs ((unsigned long *) info
->bsp
, regnum
- 32);
1373 nat_addr
= ia64_rse_rnat_addr (addr
);
1374 if ((unsigned long) nat_addr
>= info
->regstk_top
)
1375 nat_addr
= &info
->rnat
;
1376 nat_mask
= 1UL << ia64_rse_slot_num (addr
);
1383 *nat_addr
|= nat_mask
;
1385 *nat_addr
&= ~nat_mask
;
1390 *nat
= (*nat_addr
& nat_mask
) != 0;
1394 /* Get the value of register REG as saved in CONTEXT. */
1397 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
1404 else if (index
>= 15 && index
<= 18)
1405 return context
->eh_data
[index
- 15];
1407 unw_access_gr (context
, index
, &ret
, &nat
, 0);
1412 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1415 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
1421 else if (index
>= 15 && index
<= 18)
1422 context
->eh_data
[index
- 15] = val
;
1424 unw_access_gr (context
, index
, &val
, &nat
, 1);
1427 /* Retrieve the return address for CONTEXT. */
1430 _Unwind_GetIP (struct _Unwind_Context
*context
)
1435 /* Overwrite the return address for CONTEXT with VAL. */
1438 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
1444 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
1446 return context
->lsda
;
1450 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
1452 return context
->region_start
;
1456 static _Unwind_Reason_Code
1457 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1459 struct unw_table_entry
*ent
;
1460 unsigned long *unw
, header
, length
;
1461 unsigned char *insn
, *insn_end
;
1462 unsigned long segment_base
;
1464 memset (fs
, 0, sizeof (*fs
));
1467 ent
= _Unwind_FindTableEntry ((void *) context
->rp
,
1468 &segment_base
, &context
->gp
);
1471 /* Couldn't find unwind info for this function. Try an
1472 os-specific fallback mechanism. This will necessarily
1473 not provide a personality routine or LSDA. */
1474 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1475 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
1477 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1478 handlers, and which keeps the return value in B0 does not need
1479 an unwind table entry.
1481 This can only happen in the frame after unwinding through a signal
1482 handler. Avoid infinite looping by requiring that B0 != RP. */
1483 if (context
->br_loc
[0] && *context
->br_loc
[0] != context
->rp
)
1485 fs
->curr
.reg
[UNW_REG_RP
].where
= UNW_WHERE_BR
;
1486 fs
->curr
.reg
[UNW_REG_RP
].when
= -1;
1487 fs
->curr
.reg
[UNW_REG_RP
].val
= 0;
1491 return _URC_END_OF_STACK
;
1493 return _URC_NO_REASON
;
1495 return _URC_END_OF_STACK
;
1499 context
->region_start
= ent
->start_offset
+ segment_base
;
1500 fs
->when_target
= (context
->rp
- context
->region_start
) / 16 * 3;
1502 unw
= (unsigned long *) (ent
->info_offset
+ segment_base
);
1504 length
= UNW_LENGTH (header
);
1506 /* ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK. */
1508 if (UNW_FLAG_EHANDLER (header
) | UNW_FLAG_UHANDLER (header
))
1511 *(_Unwind_Personality_Fn
*) (unw
[length
+ 1] + context
->gp
);
1512 context
->lsda
= unw
+ length
+ 2;
1515 insn
= (unsigned char *) (unw
+ 1);
1516 insn_end
= (unsigned char *) (unw
+ 1 + length
);
1517 while (!fs
->done
&& insn
< insn_end
)
1518 insn
= unw_decode (insn
, fs
->in_body
, fs
);
1520 /* If we're in the epilogue, sp has been restored and all values
1521 on the memory stack below psp also have been restored. */
1522 if (fs
->when_target
> fs
->epilogue_start
)
1524 struct unw_reg_info
*r
;
1526 fs
->curr
.reg
[UNW_REG_PSP
].where
= UNW_WHERE_NONE
;
1527 fs
->curr
.reg
[UNW_REG_PSP
].val
= 0;
1528 for (r
= fs
->curr
.reg
; r
< fs
->curr
.reg
+ UNW_NUM_REGS
; ++r
)
1529 if ((r
->where
== UNW_WHERE_PSPREL
&& r
->val
<= 0x10)
1530 || r
->where
== UNW_WHERE_SPREL
)
1531 r
->where
= UNW_WHERE_NONE
;
1534 /* If RP did't get saved, generate entry for the return link register. */
1535 if (fs
->curr
.reg
[UNW_REG_RP
].when
>= fs
->when_target
)
1537 fs
->curr
.reg
[UNW_REG_RP
].where
= UNW_WHERE_BR
;
1538 fs
->curr
.reg
[UNW_REG_RP
].when
= -1;
1539 fs
->curr
.reg
[UNW_REG_RP
].val
= fs
->return_link_reg
;
1542 return _URC_NO_REASON
;
1546 uw_update_reg_address (struct _Unwind_Context
*context
,
1547 _Unwind_FrameState
*fs
,
1548 enum unw_register_index regno
)
1550 struct unw_reg_info
*r
= fs
->curr
.reg
+ regno
;
1554 if (r
->where
== UNW_WHERE_NONE
|| r
->when
>= fs
->when_target
)
1562 addr
= ia64_rse_skip_regs ((unsigned long *) context
->bsp
, rval
- 32);
1564 addr
= context
->ireg
[rval
- 2].loc
;
1570 if (rval
>= 2 && rval
< 32)
1571 addr
= context
->fr_loc
[rval
- 2];
1577 /* Note that while RVAL can only be 1-5 from normal descriptors,
1578 we can want to look at B0 due to having manually unwound a
1580 if (rval
>= 0 && rval
<= 5)
1581 addr
= context
->br_loc
[rval
];
1586 case UNW_WHERE_SPREL
:
1587 addr
= (void *)(context
->sp
+ rval
);
1590 case UNW_WHERE_PSPREL
:
1591 addr
= (void *)(context
->psp
+ rval
);
1600 case UNW_REG_R2
... UNW_REG_R31
:
1601 context
->ireg
[regno
- UNW_REG_R2
].loc
= addr
;
1607 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_MEMSTK
;
1608 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
1609 = context
->pri_unat_loc
- (unsigned long *) addr
;
1613 context
->ireg
[regno
- UNW_REG_R2
].nat
1614 = context
->ireg
[rval
- 2].nat
;
1621 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_VAL
;
1622 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
= 0;
1626 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_NONE
;
1627 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
= 0;
1630 case UNW_WHERE_PSPREL
:
1631 case UNW_WHERE_SPREL
:
1632 context
->ireg
[regno
- UNW_REG_R2
].nat
.type
= UNW_NAT_MEMSTK
;
1633 context
->ireg
[regno
- UNW_REG_R2
].nat
.off
1634 = context
->pri_unat_loc
- (unsigned long *) addr
;
1642 case UNW_REG_F2
... UNW_REG_F31
:
1643 context
->fr_loc
[regno
- UNW_REG_F2
] = addr
;
1646 case UNW_REG_B1
... UNW_REG_B5
:
1647 context
->br_loc
[regno
- UNW_REG_B0
] = addr
;
1651 context
->bsp_loc
= addr
;
1653 case UNW_REG_BSPSTORE
:
1654 context
->bspstore_loc
= addr
;
1657 context
->pfs_loc
= addr
;
1660 context
->rp
= *(unsigned long *)addr
;
1663 context
->unat_loc
= addr
;
1666 context
->pr
= *(unsigned long *) addr
;
1669 context
->lc_loc
= addr
;
1672 context
->fpsr_loc
= addr
;
1676 context
->psp
= *(unsigned long *)addr
;
1686 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1690 context
->sp
= context
->psp
;
1692 /* First, set PSP. Subsequent instructions may depend on this value. */
1693 if (fs
->when_target
> fs
->curr
.reg
[UNW_REG_PSP
].when
)
1695 if (fs
->curr
.reg
[UNW_REG_PSP
].where
== UNW_WHERE_NONE
)
1696 context
->psp
= context
->psp
+ fs
->curr
.reg
[UNW_REG_PSP
].val
;
1698 uw_update_reg_address (context
, fs
, UNW_REG_PSP
);
1701 /* Determine the location of the primary UNaT. */
1704 if (fs
->when_target
< fs
->curr
.reg
[UNW_REG_PRI_UNAT_GR
].when
)
1705 i
= UNW_REG_PRI_UNAT_MEM
;
1706 else if (fs
->when_target
< fs
->curr
.reg
[UNW_REG_PRI_UNAT_MEM
].when
)
1707 i
= UNW_REG_PRI_UNAT_GR
;
1708 else if (fs
->curr
.reg
[UNW_REG_PRI_UNAT_MEM
].when
1709 > fs
->curr
.reg
[UNW_REG_PRI_UNAT_GR
].when
)
1710 i
= UNW_REG_PRI_UNAT_MEM
;
1712 i
= UNW_REG_PRI_UNAT_GR
;
1713 uw_update_reg_address (context
, fs
, i
);
1716 /* Compute the addresses of all registers saved in this frame. */
1717 for (i
= UNW_REG_BSP
; i
< UNW_NUM_REGS
; ++i
)
1718 uw_update_reg_address (context
, fs
, i
);
1720 /* Unwind BSP for the local registers allocated this frame. */
1721 /* ??? What to do with stored BSP or BSPSTORE registers. */
1722 if (fs
->when_target
> fs
->curr
.reg
[UNW_REG_PFS
].when
)
1724 unsigned long pfs
= *context
->pfs_loc
;
1725 unsigned long sol
= (pfs
>> 7) & 0x7f;
1726 context
->bsp
= (unsigned long)
1727 ia64_rse_skip_regs ((unsigned long *) context
->bsp
, -sol
);
1731 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1732 level will be the return address and the CFA. Note that CFA = SP+16. */
1734 #define uw_init_context(CONTEXT) \
1736 /* ??? There is a whole lot o code in uw_install_context that \
1737 tries to avoid spilling the entire machine state here. We \
1738 should try to make that work again. */ \
1739 __builtin_unwind_init(); \
1740 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
1744 uw_init_context_1 (struct _Unwind_Context
*context
, void *bsp
)
1746 void *rp
= __builtin_extract_return_addr (__builtin_return_address (0));
1747 /* Set psp to the caller's stack pointer. */
1748 void *psp
= __builtin_dwarf_cfa () - 16;
1749 _Unwind_FrameState fs
;
1751 /* Flush the register stack to memory so that we can access it. */
1752 __builtin_ia64_flushrs ();
1754 memset (context
, 0, sizeof (struct _Unwind_Context
));
1755 context
->bsp
= context
->regstk_top
= (unsigned long) bsp
;
1756 context
->psp
= (unsigned long) psp
;
1757 context
->rp
= (unsigned long) rp
;
1758 asm ("mov %0 = sp" : "=r" (context
->sp
));
1759 asm ("mov %0 = pr" : "=r" (context
->pr
));
1760 context
->pri_unat_loc
= &context
->initial_unat
; /* ??? */
1761 /* ??? Get rnat. Don't we have to turn off the rse for that? */
1763 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1766 uw_update_context (context
, &fs
);
1769 /* Install (ie longjmp to) the contents of TARGET. */
1771 static void __attribute__((noreturn
))
1772 uw_install_context (struct _Unwind_Context
*current
__attribute__((unused
)),
1773 struct _Unwind_Context
*target
)
1775 unsigned long ireg_buf
[4], ireg_nat
= 0, ireg_pr
= 0;
1778 /* Copy integer register data from the target context to a
1779 temporary buffer. Do this so that we can frob AR.UNAT
1780 to get the NaT bits for these registers set properly. */
1781 for (i
= 4; i
<= 7; ++i
)
1784 void *t
= target
->ireg
[i
- 2].loc
;
1787 unw_access_gr (target
, i
, &ireg_buf
[i
- 4], &nat
, 0);
1788 ireg_nat
|= (long)nat
<< (((size_t)&ireg_buf
[i
- 4] >> 3) & 0x3f);
1794 /* The value in uc_bsp that we've computed is that for the
1795 target function. The value that we install below will be
1796 adjusted by the BR.RET instruction based on the contents
1797 of AR.PFS. So we must unadjust that here. */
1798 target
->bsp
= (unsigned long)
1799 ia64_rse_skip_regs ((unsigned long *)target
->bsp
,
1800 (*target
->pfs_loc
>> 7) & 0x7f);
1802 /* Provide assembly with the offsets into the _Unwind_Context. */
1803 asm volatile ("uc_rnat = %0"
1804 : : "i"(offsetof (struct _Unwind_Context
, rnat
)));
1805 asm volatile ("uc_bsp = %0"
1806 : : "i"(offsetof (struct _Unwind_Context
, bsp
)));
1807 asm volatile ("uc_psp = %0"
1808 : : "i"(offsetof (struct _Unwind_Context
, psp
)));
1809 asm volatile ("uc_rp = %0"
1810 : : "i"(offsetof (struct _Unwind_Context
, rp
)));
1811 asm volatile ("uc_pr = %0"
1812 : : "i"(offsetof (struct _Unwind_Context
, pr
)));
1813 asm volatile ("uc_gp = %0"
1814 : : "i"(offsetof (struct _Unwind_Context
, gp
)));
1815 asm volatile ("uc_pfs_loc = %0"
1816 : : "i"(offsetof (struct _Unwind_Context
, pfs_loc
)));
1817 asm volatile ("uc_unat_loc = %0"
1818 : : "i"(offsetof (struct _Unwind_Context
, unat_loc
)));
1819 asm volatile ("uc_lc_loc = %0"
1820 : : "i"(offsetof (struct _Unwind_Context
, lc_loc
)));
1821 asm volatile ("uc_fpsr_loc = %0"
1822 : : "i"(offsetof (struct _Unwind_Context
, fpsr_loc
)));
1823 asm volatile ("uc_eh_data = %0"
1824 : : "i"(offsetof (struct _Unwind_Context
, eh_data
)));
1825 asm volatile ("uc_br_loc = %0"
1826 : : "i"(offsetof (struct _Unwind_Context
, br_loc
)));
1827 asm volatile ("uc_fr_loc = %0"
1828 : : "i"(offsetof (struct _Unwind_Context
, fr_loc
)));
1831 /* Load up call-saved non-window integer registers from ireg_buf. */
1832 "add r20 = 8, %1 \n\t"
1833 "mov ar.unat = %2 \n\t"
1834 "mov pr = %3, 0x3c0 \n\t"
1836 "(p6) ld8.fill r4 = [%1] \n\t"
1837 "(p7) ld8.fill r5 = [r20] \n\t"
1838 "add r21 = uc_br_loc + 8, %0 \n\t"
1839 "adds %1 = 16, %1 \n\t"
1840 "adds r20 = 16, r20 \n\t"
1842 "(p8) ld8.fill r6 = [%1] \n\t"
1843 "(p9) ld8.fill r7 = [r20] \n\t"
1844 "add r20 = uc_br_loc, %0 \n\t"
1846 /* Load up call-saved branch registers. */
1847 "ld8 r22 = [r20], 16 \n\t"
1848 "ld8 r23 = [r21], 16 \n\t"
1850 "ld8 r24 = [r20], 16 \n\t"
1851 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 24)\n\t"
1853 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 32)\n\t"
1854 "ld8 r27 = [r21], 24 \n\t"
1855 "cmp.ne p6, p0 = r0, r22 \n\t"
1857 "ld8 r28 = [r20], 8 \n\t"
1858 "(p6) ld8 r22 = [r22] \n\t"
1859 "cmp.ne p7, p0 = r0, r23 \n\t"
1861 "(p7) ld8 r23 = [r23] \n\t"
1862 "cmp.ne p8, p0 = r0, r24 \n\t"
1864 "(p8) ld8 r24 = [r24] \n\t"
1865 "(p6) mov b1 = r22 \n\t"
1866 "cmp.ne p9, p0 = r0, r25 \n\t"
1868 "(p9) ld8 r25 = [r25] \n\t"
1869 "(p7) mov b2 = r23 \n\t"
1870 "cmp.ne p6, p0 = r0, r26 \n\t"
1872 "(p6) ld8 r26 = [r26] \n\t"
1873 "(p8) mov b3 = r24 \n\t"
1874 "cmp.ne p7, p0 = r0, r27 \n\t"
1876 /* Load up call-saved fp registers. */
1877 "(p7) ldf.fill f2 = [r27] \n\t"
1878 "(p9) mov b4 = r25 \n\t"
1879 "cmp.ne p8, p0 = r0, r28 \n\t"
1881 "(p8) ldf.fill f3 = [r28] \n\t"
1882 "(p6) mov b5 = r26 \n\t"
1884 "ld8 r29 = [r20], 16*8 - 4*8 \n\t"
1885 "ld8 r30 = [r21], 17*8 - 5*8 \n\t"
1887 "ld8 r22 = [r20], 16 \n\t"
1888 "ld8 r23 = [r21], 16 \n\t"
1890 "ld8 r24 = [r20], 16 \n\t"
1891 "ld8 r25 = [r21] \n\t"
1892 "cmp.ne p6, p0 = r0, r29 \n\t"
1894 "ld8 r26 = [r20], 8 \n\t"
1895 "(p6) ldf.fill f4 = [r29] \n\t"
1896 "cmp.ne p7, p0 = r0, r30 \n\t"
1898 "ld8 r27 = [r20], 8 \n\t"
1899 "(p7) ldf.fill f5 = [r30] \n\t"
1900 "cmp.ne p6, p0 = r0, r22 \n\t"
1902 "ld8 r28 = [r20], 8 \n\t"
1903 "(p6) ldf.fill f16 = [r22] \n\t"
1904 "cmp.ne p7, p0 = r0, r23 \n\t"
1906 "ld8 r29 = [r20], 8 \n\t"
1907 "(p7) ldf.fill f17 = [r23] \n\t"
1908 "cmp.ne p6, p0 = r0, r24 \n\t"
1910 "ld8 r22 = [r20], 8 \n\t"
1911 "(p6) ldf.fill f18 = [r24] \n\t"
1912 "cmp.ne p7, p0 = r0, r25 \n\t"
1914 "ld8 r23 = [r20], 8 \n\t"
1915 "(p7) ldf.fill f19 = [r25] \n\t"
1916 "cmp.ne p6, p0 = r0, r26 \n\t"
1918 "ld8 r24 = [r20], 8 \n\t"
1919 "(p6) ldf.fill f20 = [r26] \n\t"
1920 "cmp.ne p7, p0 = r0, r27 \n\t"
1922 "ld8 r25 = [r20], 8 \n\t"
1923 "(p7) ldf.fill f21 = [r27] \n\t"
1924 "cmp.ne p6, p0 = r0, r28 \n\t"
1926 "ld8 r26 = [r20], 8 \n\t"
1927 "(p6) ldf.fill f22 = [r28] \n\t"
1928 "cmp.ne p7, p0 = r0, r29 \n\t"
1930 "ld8 r28 = [r20], 8 \n\t"
1931 "(p7) ldf.fill f23 = [r29] \n\t"
1932 "cmp.ne p6, p0 = r0, r22 \n\t"
1934 "ld8 r29 = [r20], 8 \n\t"
1935 "(p6) ldf.fill f24 = [r22] \n\t"
1936 "cmp.ne p7, p0 = r0, r23 \n\t"
1938 "(p7) ldf.fill f25 = [r23] \n\t"
1939 "cmp.ne p6, p0 = r0, r24 \n\t"
1940 "cmp.ne p7, p0 = r0, r25 \n\t"
1942 "(p6) ldf.fill f26 = [r24] \n\t"
1943 "(p7) ldf.fill f27 = [r25] \n\t"
1944 "cmp.ne p6, p0 = r0, r26 \n\t"
1946 "(p6) ldf.fill f28 = [r26] \n\t"
1947 "cmp.ne p7, p0 = r0, r27 \n\t"
1948 "cmp.ne p6, p0 = r0, r28 \n\t"
1950 "(p7) ldf.fill f29 = [r27] \n\t"
1951 "(p6) ldf.fill f30 = [r28] \n\t"
1952 "cmp.ne p7, p0 = r0, r29 \n\t"
1954 "(p7) ldf.fill f31 = [r29] \n\t"
1955 "add r20 = uc_rnat, %0 \n\t"
1956 "add r21 = uc_bsp, %0 \n\t"
1958 /* Load the balance of the thread state from the context. */
1959 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
1960 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
1962 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
1963 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
1965 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
1966 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
1968 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
1969 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
1971 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
1972 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
1974 /* Load data for the exception handler. */
1975 "ld8 r15 = [r20], 16 \n\t"
1976 "ld8 r16 = [r21], 16 \n\t"
1978 "ld8 r17 = [r20] \n\t"
1979 "ld8 r18 = [r21] \n\t"
1981 /* Install the balance of the thread state loaded above. */
1982 "cmp.ne p6, p0 = r0, r25 \n\t"
1983 "cmp.ne p7, p0 = r0, r27 \n\t"
1985 "(p6) ld8 r25 = [r25] \n\t"
1986 "(p7) ld8 r27 = [r27] \n\t"
1988 "(p7) mov.m ar.unat = r27 \n\t"
1989 "(p6) mov.i ar.pfs = r25 \n\t"
1990 "cmp.ne p9, p0 = r0, r29 \n\t"
1992 "(p9) ld8 r29 = [r29] \n\t"
1993 "cmp.ne p6, p0 = r0, r30 \n\t"
1995 "(p6) ld8 r30 = [r30] \n\t"
1996 /* Don't clobber p6-p9, which are in use at present. */
1997 "mov pr = r28, ~0x3c0 \n\t"
1998 "(p9) mov.i ar.lc = r29 \n\t"
2000 "mov.m r25 = ar.rsc \n\t"
2001 "(p6) mov.i ar.fpsr = r30 \n\t"
2003 "and r25 = 0x1c, r25 \n\t"
2006 "mov.m ar.rsc = r25 \n\t"
2008 /* This must be done before setting AR.BSPSTORE, otherwise
2009 AR.BSP will be initialized with a random displacement
2010 below the value we want, based on the current number of
2011 dirty stacked registers. */
2015 "mov.m ar.bspstore = r23 \n\t"
2017 "or r25 = 0x3, r25 \n\t"
2018 "mov.m ar.rnat = r22 \n\t"
2020 "mov.m ar.rsc = r25 \n\t"
2022 "br.ret.sptk.few b0"
2023 : : "r"(target
), "r"(ireg_buf
), "r"(ireg_nat
), "r"(ireg_pr
)
2024 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2025 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2031 static inline _Unwind_Ptr
2032 uw_identify_context (struct _Unwind_Context
*context
)
2034 return _Unwind_GetIP (context
);
2037 #include "unwind.inc"