1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combined
21 GCC is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 License for more details.
26 You should have received a copy of the GNU General Public License
27 along with GCC; see the file COPYING. If not, write to the Free
28 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 #include "coretypes.h"
37 #include "unwind-pe.h"
38 #include "unwind-dw2-fde.h"
42 #ifndef __USING_SJLJ_EXCEPTIONS__
44 #ifndef STACK_GROWS_DOWNWARD
45 #define STACK_GROWS_DOWNWARD 0
47 #undef STACK_GROWS_DOWNWARD
48 #define STACK_GROWS_DOWNWARD 1
51 /* A target can override (perhaps for backward compatibility) how
52 many dwarf2 columns are unwound. */
53 #ifndef DWARF_FRAME_REGISTERS
54 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
57 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
58 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
59 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
62 #ifndef DWARF_REG_TO_UNWIND_COLUMN
63 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
66 /* A target can do some update context frobbing. */
67 #ifndef MD_FROB_UPDATE_CONTEXT
68 #define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
71 /* This is the register and unwind state for a particular frame. This
72 provides the information necessary to unwind up past a frame and return
74 struct _Unwind_Context
76 void *reg
[DWARF_FRAME_REGISTERS
+1];
80 struct dwarf_eh_bases bases
;
81 _Unwind_Word args_size
;
84 /* Byte size of every register managed by these routines. */
85 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
88 /* The result of interpreting the frame unwind info for a frame.
89 This is all symbolic at this point, as none of the values can
90 be resolved until the target pc is located. */
93 /* Each register save state can be described in terms of a CFA slot,
94 another register, or a location expression. */
95 struct frame_state_reg_info
100 _Unwind_Sword offset
;
101 const unsigned char *exp
;
109 } reg
[DWARF_FRAME_REGISTERS
+1];
111 /* Used to implement DW_CFA_remember_state. */
112 struct frame_state_reg_info
*prev
;
115 /* The CFA can be described in terms of a reg+offset or a
116 location expression. */
117 _Unwind_Sword cfa_offset
;
118 _Unwind_Word cfa_reg
;
119 const unsigned char *cfa_exp
;
126 /* The PC described by the current frame state. */
129 /* The information we care about from the CIE/FDE. */
130 _Unwind_Personality_Fn personality
;
131 _Unwind_Sword data_align
;
132 _Unwind_Word code_align
;
133 unsigned char retaddr_column
;
134 unsigned char fde_encoding
;
135 unsigned char lsda_encoding
;
138 } _Unwind_FrameState
;
140 /* Read unaligned data from the instruction buffer. */
145 unsigned u2
__attribute__ ((mode (HI
)));
146 unsigned u4
__attribute__ ((mode (SI
)));
147 unsigned u8
__attribute__ ((mode (DI
)));
148 signed s2
__attribute__ ((mode (HI
)));
149 signed s4
__attribute__ ((mode (SI
)));
150 signed s8
__attribute__ ((mode (DI
)));
151 } __attribute__ ((packed
));
154 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
157 read_1u (const void *p
) { return *(const unsigned char *) p
; }
160 read_1s (const void *p
) { return *(const signed char *) p
; }
163 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
166 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
168 static inline unsigned int
169 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
172 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
174 static inline unsigned long
175 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
177 static inline unsigned long
178 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
180 /* Get the value of register REG as saved in CONTEXT. */
183 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
188 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
189 size
= dwarf_reg_size_table
[index
];
190 ptr
= context
->reg
[index
];
192 /* This will segfault if the register hasn't been saved. */
193 if (size
== sizeof(_Unwind_Ptr
))
194 return * (_Unwind_Ptr
*) ptr
;
196 if (size
== sizeof(_Unwind_Word
))
197 return * (_Unwind_Word
*) ptr
;
203 _Unwind_GetPtr (struct _Unwind_Context
*context
, int index
)
205 return (void *)(_Unwind_Ptr
) _Unwind_GetGR (context
, index
);
208 /* Get the value of the CFA as saved in CONTEXT. */
211 _Unwind_GetCFA (struct _Unwind_Context
*context
)
213 return (_Unwind_Ptr
) context
->cfa
;
216 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
219 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
224 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
225 size
= dwarf_reg_size_table
[index
];
226 ptr
= context
->reg
[index
];
228 if (size
== sizeof(_Unwind_Ptr
))
229 * (_Unwind_Ptr
*) ptr
= val
;
230 else if (size
== sizeof(_Unwind_Word
))
231 * (_Unwind_Word
*) ptr
= val
;
236 /* Get the pointer to a register INDEX as saved in CONTEXT. */
239 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
241 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
242 return context
->reg
[index
];
245 /* Set the pointer to a register INDEX as saved in CONTEXT. */
248 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
250 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
251 context
->reg
[index
] = p
;
254 /* Retrieve the return address for CONTEXT. */
257 _Unwind_GetIP (struct _Unwind_Context
*context
)
259 return (_Unwind_Ptr
) context
->ra
;
262 /* Overwrite the return address for CONTEXT with VAL. */
265 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
267 context
->ra
= (void *) val
;
271 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
273 return context
->lsda
;
277 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
279 return (_Unwind_Ptr
) context
->bases
.func
;
283 _Unwind_FindEnclosingFunction (void *pc
)
285 struct dwarf_eh_bases bases
;
286 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
295 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
297 return (_Unwind_Ptr
) context
->bases
.dbase
;
301 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
303 return (_Unwind_Ptr
) context
->bases
.tbase
;
307 /* Extract any interesting information from the CIE for the translation
308 unit F belongs to. Return a pointer to the byte after the augmentation,
309 or NULL if we encountered an undecipherable augmentation. */
311 static const unsigned char *
312 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
313 _Unwind_FrameState
*fs
)
315 const unsigned char *aug
= cie
->augmentation
;
316 const unsigned char *p
= aug
+ strlen (aug
) + 1;
317 const unsigned char *ret
= NULL
;
320 /* g++ v2 "eh" has pointer immediately following augmentation string,
321 so it must be handled first. */
322 if (aug
[0] == 'e' && aug
[1] == 'h')
324 fs
->eh_ptr
= read_pointer (p
);
325 p
+= sizeof (void *);
329 /* Immediately following the augmentation are the code and
330 data alignment and return address column. */
331 p
= read_uleb128 (p
, &fs
->code_align
);
332 p
= read_sleb128 (p
, &fs
->data_align
);
333 fs
->retaddr_column
= *p
++;
334 fs
->lsda_encoding
= DW_EH_PE_omit
;
336 /* If the augmentation starts with 'z', then a uleb128 immediately
337 follows containing the length of the augmentation field following
341 p
= read_uleb128 (p
, &utmp
);
348 /* Iterate over recognized augmentation subsequences. */
351 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
354 fs
->lsda_encoding
= *p
++;
358 /* "R" indicates a byte indicating how FDE addresses are encoded. */
359 else if (aug
[0] == 'R')
361 fs
->fde_encoding
= *p
++;
365 /* "P" indicates a personality routine in the CIE augmentation. */
366 else if (aug
[0] == 'P')
368 p
= read_encoded_value (context
, *p
, p
+ 1,
369 (_Unwind_Ptr
*) &fs
->personality
);
373 /* Otherwise we have an unknown augmentation string.
374 Bail unless we saw a 'z' prefix. */
379 return ret
? ret
: p
;
383 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
384 onto the stack to start. */
387 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
388 struct _Unwind_Context
*context
, _Unwind_Word initial
)
390 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
396 while (op_ptr
< op_end
)
398 enum dwarf_location_atom op
= *op_ptr
++;
399 _Unwind_Word result
, reg
, utmp
;
400 _Unwind_Sword offset
, stmp
;
436 result
= op
- DW_OP_lit0
;
440 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
441 op_ptr
+= sizeof (void *);
445 result
= read_1u (op_ptr
);
449 result
= read_1s (op_ptr
);
453 result
= read_2u (op_ptr
);
457 result
= read_2s (op_ptr
);
461 result
= read_4u (op_ptr
);
465 result
= read_4s (op_ptr
);
469 result
= read_8u (op_ptr
);
473 result
= read_8s (op_ptr
);
477 op_ptr
= read_uleb128 (op_ptr
, &result
);
480 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
516 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
519 op_ptr
= read_uleb128 (op_ptr
, ®
);
520 result
= _Unwind_GetGR (context
, reg
);
555 op_ptr
= read_sleb128 (op_ptr
, &offset
);
556 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
559 op_ptr
= read_uleb128 (op_ptr
, ®
);
560 op_ptr
= read_sleb128 (op_ptr
, &offset
);
561 result
= _Unwind_GetGR (context
, reg
) + offset
;
567 result
= stack
[stack_elt
- 1];
577 if (offset
>= stack_elt
- 1)
579 result
= stack
[stack_elt
- 1 - offset
];
585 result
= stack
[stack_elt
- 2];
590 _Unwind_Word t1
, t2
, t3
;
594 t1
= stack
[stack_elt
- 1];
595 t2
= stack
[stack_elt
- 2];
596 t3
= stack
[stack_elt
- 3];
597 stack
[stack_elt
- 1] = t2
;
598 stack
[stack_elt
- 2] = t3
;
599 stack
[stack_elt
- 3] = t1
;
604 case DW_OP_deref_size
:
608 case DW_OP_plus_uconst
:
609 /* Unary operations. */
612 result
= stack
[stack_elt
];
618 void *ptr
= (void *) (_Unwind_Ptr
) result
;
619 result
= (_Unwind_Ptr
) read_pointer (ptr
);
623 case DW_OP_deref_size
:
625 void *ptr
= (void *) (_Unwind_Ptr
) result
;
629 result
= read_1u (ptr
);
632 result
= read_2u (ptr
);
635 result
= read_4u (ptr
);
638 result
= read_8u (ptr
);
647 if ((_Unwind_Sword
) result
< 0)
656 case DW_OP_plus_uconst
:
657 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
680 /* Binary operations. */
681 _Unwind_Word first
, second
;
682 if ((stack_elt
-= 2) < 0)
684 second
= stack
[stack_elt
];
685 first
= stack
[stack_elt
+ 1];
690 result
= second
& first
;
693 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
696 result
= second
- first
;
699 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
702 result
= second
* first
;
705 result
= second
| first
;
708 result
= second
+ first
;
711 result
= second
<< first
;
714 result
= second
>> first
;
717 result
= (_Unwind_Sword
) second
>> first
;
720 result
= second
^ first
;
723 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
726 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
729 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
732 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
735 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
738 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
748 offset
= read_2s (op_ptr
);
756 offset
= read_2s (op_ptr
);
758 if (stack
[stack_elt
] != 0)
769 /* Most things push a result value. */
770 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
772 stack
[stack_elt
++] = result
;
776 /* We were executing this program to get a value. It should be
780 return stack
[stack_elt
];
784 /* Decode DWARF 2 call frame information. Takes pointers the
785 instruction sequence to decode, current register information and
786 CIE info, and the PC range to evaluate. */
789 execute_cfa_program (const unsigned char *insn_ptr
,
790 const unsigned char *insn_end
,
791 struct _Unwind_Context
*context
,
792 _Unwind_FrameState
*fs
)
794 struct frame_state_reg_info
*unused_rs
= NULL
;
796 /* Don't allow remember/restore between CIE and FDE programs. */
797 fs
->regs
.prev
= NULL
;
799 /* The comparison with the return address uses < rather than <= because
800 we are only interested in the effects of code before the call; for a
801 noreturn function, the return address may point to unrelated code with
802 a different stack configuration that we are not interested in. We
803 assume that the call itself is unwind info-neutral; if not, or if
804 there are delay instructions that adjust the stack, these must be
805 reflected at the point immediately before the call insn. */
806 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
808 unsigned char insn
= *insn_ptr
++;
809 _Unwind_Word reg
, utmp
;
810 _Unwind_Sword offset
, stmp
;
812 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
813 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
814 else if ((insn
& 0xc0) == DW_CFA_offset
)
817 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
818 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
819 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
821 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
823 else if ((insn
& 0xc0) == DW_CFA_restore
)
826 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_UNSAVED
;
831 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
832 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
835 case DW_CFA_advance_loc1
:
836 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
839 case DW_CFA_advance_loc2
:
840 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
843 case DW_CFA_advance_loc4
:
844 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
848 case DW_CFA_offset_extended
:
849 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
850 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
851 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
852 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
854 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
857 case DW_CFA_restore_extended
:
858 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
859 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
862 case DW_CFA_undefined
:
863 case DW_CFA_same_value
:
864 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
870 case DW_CFA_register
:
873 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
874 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
875 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_REG
;
876 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.reg
= reg2
;
880 case DW_CFA_remember_state
:
882 struct frame_state_reg_info
*new_rs
;
886 unused_rs
= unused_rs
->prev
;
889 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
892 fs
->regs
.prev
= new_rs
;
896 case DW_CFA_restore_state
:
898 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
900 old_rs
->prev
= unused_rs
;
906 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
907 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
908 fs
->cfa_offset
= utmp
;
909 fs
->cfa_how
= CFA_REG_OFFSET
;
912 case DW_CFA_def_cfa_register
:
913 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
914 fs
->cfa_how
= CFA_REG_OFFSET
;
917 case DW_CFA_def_cfa_offset
:
918 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
919 fs
->cfa_offset
= utmp
;
920 /* cfa_how deliberately not set. */
923 case DW_CFA_def_cfa_expression
:
924 fs
->cfa_exp
= insn_ptr
;
925 fs
->cfa_how
= CFA_EXP
;
926 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
930 case DW_CFA_expression
:
931 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
932 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_EXP
;
933 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
934 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
938 /* From the 2.1 draft. */
939 case DW_CFA_offset_extended_sf
:
940 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
941 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
942 offset
= stmp
* fs
->data_align
;
943 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
945 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
948 case DW_CFA_def_cfa_sf
:
949 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
950 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
951 fs
->cfa_how
= CFA_REG_OFFSET
;
954 case DW_CFA_def_cfa_offset_sf
:
955 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
956 /* cfa_how deliberately not set. */
959 case DW_CFA_GNU_window_save
:
960 /* ??? Hardcoded for SPARC register window configuration. */
961 for (reg
= 16; reg
< 32; ++reg
)
963 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
964 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
968 case DW_CFA_GNU_args_size
:
969 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
972 case DW_CFA_GNU_negative_offset_extended
:
973 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
974 older PowerPC code. */
975 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
976 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
977 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
978 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
980 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= -offset
;
989 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
990 its caller and decode it into FS. This function also sets the
991 args_size and lsda members of CONTEXT, as they are really information
992 about the caller's frame. */
994 static _Unwind_Reason_Code
995 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
997 struct dwarf_fde
*fde
;
998 struct dwarf_cie
*cie
;
999 const unsigned char *aug
, *insn
, *end
;
1001 memset (fs
, 0, sizeof (*fs
));
1002 context
->args_size
= 0;
1005 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
1008 /* Couldn't find frame unwind info for this function. Try a
1009 target-specific fallback mechanism. This will necessarily
1010 not provide a personality routine or LSDA. */
1011 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1012 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
1013 return _URC_END_OF_STACK
;
1015 return _URC_NO_REASON
;
1017 return _URC_END_OF_STACK
;
1021 fs
->pc
= context
->bases
.func
;
1023 cie
= get_cie (fde
);
1024 insn
= extract_cie_info (cie
, context
, fs
);
1026 /* CIE contained unknown augmentation. */
1027 return _URC_FATAL_PHASE1_ERROR
;
1029 /* First decode all the insns in the CIE. */
1030 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
1031 execute_cfa_program (insn
, end
, context
, fs
);
1033 /* Locate augmentation for the fde. */
1034 aug
= (unsigned char *) fde
+ sizeof (*fde
);
1035 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
1040 aug
= read_uleb128 (aug
, &i
);
1043 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1044 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
1045 (_Unwind_Ptr
*) &context
->lsda
);
1047 /* Then the insns in the FDE up to our target PC. */
1050 end
= (unsigned char *) next_fde (fde
);
1051 execute_cfa_program (insn
, end
, context
, fs
);
1053 return _URC_NO_REASON
;
1056 typedef struct frame_state
1062 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1063 unsigned short cfa_reg
;
1064 unsigned short retaddr_column
;
1065 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1068 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1070 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1071 a given PC_TARGET. The caller should allocate a local variable of
1072 `struct frame_state' and pass its address to STATE_IN. */
1074 struct frame_state
*
1075 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1077 struct _Unwind_Context context
;
1078 _Unwind_FrameState fs
;
1081 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1082 context
.ra
= pc_target
+ 1;
1084 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1087 /* We have no way to pass a location expression for the CFA to our
1088 caller. It wouldn't understand it anyway. */
1089 if (fs
.cfa_how
== CFA_EXP
)
1092 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1094 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1095 switch (state_in
->saved
[reg
])
1098 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1100 case REG_SAVED_OFFSET
:
1101 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1104 state_in
->reg_or_offset
[reg
] = 0;
1109 state_in
->cfa_offset
= fs
.cfa_offset
;
1110 state_in
->cfa_reg
= fs
.cfa_reg
;
1111 state_in
->retaddr_column
= fs
.retaddr_column
;
1112 state_in
->args_size
= context
.args_size
;
1113 state_in
->eh_ptr
= fs
.eh_ptr
;
1118 typedef union { _Unwind_Ptr ptr
; _Unwind_Word word
; } _Unwind_SpTmp
;
1121 _Unwind_SetSpColumn (struct _Unwind_Context
*context
, void *cfa
,
1122 _Unwind_SpTmp
*tmp_sp
)
1124 int size
= dwarf_reg_size_table
[__builtin_dwarf_sp_column ()];
1126 if (size
== sizeof(_Unwind_Ptr
))
1127 tmp_sp
->ptr
= (_Unwind_Ptr
) cfa
;
1128 else if (size
== sizeof(_Unwind_Word
))
1129 tmp_sp
->word
= (_Unwind_Ptr
) cfa
;
1132 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), tmp_sp
);
1136 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1138 struct _Unwind_Context orig_context
= *context
;
1142 #ifdef EH_RETURN_STACKADJ_RTX
1143 /* Special handling here: Many machines do not use a frame pointer,
1144 and track the CFA only through offsets from the stack pointer from
1145 one frame to the next. In this case, the stack pointer is never
1146 stored, so it has no saved address in the context. What we do
1147 have is the CFA from the previous stack frame.
1149 In very special situations (such as unwind info for signal return),
1150 there may be location expressions that use the stack pointer as well.
1152 Do this conditionally for one frame. This allows the unwind info
1153 for one frame to save a copy of the stack pointer from the previous
1154 frame, and be able to use much easier CFA mechanisms to do it.
1155 Always zap the saved stack pointer value for the next frame; carrying
1156 the value over from one frame to another doesn't make sense. */
1158 _Unwind_SpTmp tmp_sp
;
1160 if (!_Unwind_GetGRPtr (&orig_context
, __builtin_dwarf_sp_column ()))
1161 _Unwind_SetSpColumn (&orig_context
, context
->cfa
, &tmp_sp
);
1162 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), NULL
);
1165 /* Compute this frame's CFA. */
1166 switch (fs
->cfa_how
)
1168 case CFA_REG_OFFSET
:
1169 cfa
= _Unwind_GetPtr (&orig_context
, fs
->cfa_reg
);
1170 cfa
+= fs
->cfa_offset
;
1175 const unsigned char *exp
= fs
->cfa_exp
;
1178 exp
= read_uleb128 (exp
, &len
);
1179 cfa
= (void *) (_Unwind_Ptr
)
1180 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1189 /* Compute the addresses of all registers saved in this frame. */
1190 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1191 switch (fs
->regs
.reg
[i
].how
)
1196 case REG_SAVED_OFFSET
:
1197 _Unwind_SetGRPtr (context
, i
,
1198 (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1204 _Unwind_GetGRPtr (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
));
1209 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1213 exp
= read_uleb128 (exp
, &len
);
1214 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1216 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1221 MD_FROB_UPDATE_CONTEXT (context
, fs
);
1224 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1225 of its caller. Update CONTEXT to refer to the caller as well. Note
1226 that the args_size and lsda members are not updated here, but later in
1227 uw_frame_state_for. */
1230 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1232 uw_update_context_1 (context
, fs
);
1234 /* Compute the return address now, since the return address column
1235 can change from frame to frame. */
1236 context
->ra
= __builtin_extract_return_addr
1237 (_Unwind_GetPtr (context
, fs
->retaddr_column
));
1240 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1241 level will be the return address and the CFA. */
1243 #define uw_init_context(CONTEXT) \
1246 /* Do any necessary initialization to access arbitrary stack frames. \
1247 On the SPARC, this means flushing the register windows. */ \
1248 __builtin_unwind_init (); \
1249 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1250 __builtin_return_address (0)); \
1255 init_dwarf_reg_size_table (void)
1257 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1261 uw_init_context_1 (struct _Unwind_Context
*context
,
1262 void *outer_cfa
, void *outer_ra
)
1264 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1265 _Unwind_FrameState fs
;
1266 _Unwind_SpTmp sp_slot
;
1268 memset (context
, 0, sizeof (struct _Unwind_Context
));
1271 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1276 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1277 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1278 || dwarf_reg_size_table
[0] == 0)
1279 init_dwarf_reg_size_table ();
1282 if (dwarf_reg_size_table
[0] == 0)
1283 init_dwarf_reg_size_table ();
1286 /* Force the frame state to use the known cfa value. */
1287 _Unwind_SetSpColumn (context
, outer_cfa
, &sp_slot
);
1288 fs
.cfa_how
= CFA_REG_OFFSET
;
1289 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1292 uw_update_context_1 (context
, &fs
);
1294 /* If the return address column was saved in a register in the
1295 initialization context, then we can't see it in the given
1296 call frame data. So have the initialization context tell us. */
1297 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1301 /* Install TARGET into CURRENT so that we can return to it. This is a
1302 macro because __builtin_eh_return must be invoked in the context of
1305 #define uw_install_context(CURRENT, TARGET) \
1308 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1309 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1310 __builtin_eh_return (offset, handler); \
1315 uw_install_context_1 (struct _Unwind_Context
*current
,
1316 struct _Unwind_Context
*target
)
1320 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1322 void *c
= current
->reg
[i
];
1323 void *t
= target
->reg
[i
];
1325 if (t
&& c
&& t
!= c
)
1326 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1329 #ifdef EH_RETURN_STACKADJ_RTX
1333 /* If the last frame records a saved stack pointer, use it. */
1334 if (_Unwind_GetGRPtr (target
, __builtin_dwarf_sp_column ()))
1335 target_cfa
= _Unwind_GetPtr (target
, __builtin_dwarf_sp_column ());
1337 target_cfa
= target
->cfa
;
1339 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1340 if (STACK_GROWS_DOWNWARD
)
1341 return target_cfa
- current
->cfa
+ target
->args_size
;
1343 return current
->cfa
- target_cfa
- target
->args_size
;
1350 static inline _Unwind_Ptr
1351 uw_identify_context (struct _Unwind_Context
*context
)
1353 return _Unwind_GetIP (context
);
1357 #include "unwind.inc"
1359 #endif /* !USING_SJLJ_EXCEPTIONS */