1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include "unwind-dw2-fde.h"
29 #if !USING_SJLJ_EXCEPTIONS
31 #ifndef STACK_GROWS_DOWNWARD
32 #define STACK_GROWS_DOWNWARD 0
34 #undef STACK_GROWS_DOWNWARD
35 #define STACK_GROWS_DOWNWARD 1
38 /* A target can override (perhaps for backward compatibility) how
39 many dwarf2 columns are unwound. */
40 #ifndef DWARF_FRAME_REGISTERS
41 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
44 /* This is the register and unwind state for a particular frame. */
45 struct _Unwind_Context
47 void *reg
[DWARF_FRAME_REGISTERS
+1];
51 struct dwarf_eh_bases bases
;
52 _Unwind_Word args_size
;
55 /* Byte size of every register managed by these routines. */
56 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
59 /* The result of interpreting the frame unwind info for a frame.
60 This is all symbolic at this point, as none of the values can
61 be resolved until the target pc is located. */
64 /* Each register save state can be described in terms of a CFA slot,
65 another register, or a location expression. */
66 struct frame_state_reg_info
80 } reg
[DWARF_FRAME_REGISTERS
+1];
82 /* Used to implement DW_CFA_remember_state. */
83 struct frame_state_reg_info
*prev
;
86 /* The CFA can be described in terms of a reg+offset or a
87 location expression. */
88 _Unwind_Sword cfa_offset
;
90 unsigned char *cfa_exp
;
97 /* The PC described by the current frame state. */
100 /* The information we care about from the CIE/FDE. */
101 _Unwind_Personality_Fn personality
;
102 signed int data_align
;
103 unsigned int code_align
;
104 unsigned char retaddr_column
;
105 unsigned char addr_encoding
;
107 unsigned char saw_lsda
;
108 } _Unwind_FrameState
;
110 /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
111 by R, and return the new value of BUF. */
113 static unsigned char *
114 read_uleb128 (unsigned char *buf
, _Unwind_Word
*r
)
117 _Unwind_Word result
= 0;
121 unsigned char byte
= *buf
++;
122 result
|= (byte
& 0x7f) << shift
;
123 if ((byte
& 0x80) == 0)
131 /* Decode the signed LEB128 constant at BUF into the variable pointed to
132 by R, and return the new value of BUF. */
134 static unsigned char *
135 read_sleb128 (unsigned char *buf
, _Unwind_Sword
*r
)
138 _Unwind_Sword result
= 0;
144 result
|= (byte
& 0x7f) << shift
;
146 if ((byte
& 0x80) == 0)
149 if (shift
< (sizeof (*r
) * 8) && (byte
& 0x40) != 0)
150 result
|= - (1 << shift
);
156 /* Read unaligned data from the instruction buffer. */
161 unsigned u2
__attribute__ ((mode (HI
)));
162 unsigned u4
__attribute__ ((mode (SI
)));
163 unsigned u8
__attribute__ ((mode (DI
)));
164 signed s2
__attribute__ ((mode (HI
)));
165 signed s4
__attribute__ ((mode (SI
)));
166 signed s8
__attribute__ ((mode (DI
)));
167 } __attribute__ ((packed
));
170 read_pointer (void *p
) { union unaligned
*up
= p
; return up
->p
; }
173 read_1u (void *p
) { return *(unsigned char *)p
; }
176 read_1s (void *p
) { return *(signed char *)p
; }
179 read_2u (void *p
) { union unaligned
*up
= p
; return up
->u2
; }
182 read_2s (void *p
) { union unaligned
*up
= p
; return up
->s2
; }
184 static inline unsigned int
185 read_4u (void *p
) { union unaligned
*up
= p
; return up
->u4
; }
188 read_4s (void *p
) { union unaligned
*up
= p
; return up
->s4
; }
190 static inline unsigned long
191 read_8u (void *p
) { union unaligned
*up
= p
; return up
->u8
; }
193 static inline unsigned long
194 read_8s (void *p
) { union unaligned
*up
= p
; return up
->s8
; }
196 static unsigned char *
197 read_encoded_pointer (unsigned char *p
, unsigned char encoding
,
198 struct dwarf_eh_bases
*bases
, void **pptr
)
203 switch (encoding
& 0x0f)
205 case DW_EH_PE_absptr
:
206 val
= (_Unwind_Ptr
) read_pointer (p
);
207 ret
= p
+ sizeof (void *);
210 case DW_EH_PE_uleb128
:
211 ret
= read_uleb128 (p
, &val
);
213 case DW_EH_PE_sleb128
:
214 ret
= read_sleb128 (p
, &val
);
217 case DW_EH_PE_udata2
:
221 case DW_EH_PE_udata4
:
225 case DW_EH_PE_udata8
:
230 case DW_EH_PE_sdata2
:
234 case DW_EH_PE_sdata4
:
238 case DW_EH_PE_sdata8
:
248 switch (encoding
& 0xf0)
250 case DW_EH_PE_absptr
:
253 val
+= (_Unwind_Ptr
) p
;
255 case DW_EH_PE_textrel
:
256 val
+= (_Unwind_Ptr
) bases
->tbase
;
258 case DW_EH_PE_datarel
:
259 val
+= (_Unwind_Ptr
) bases
->dbase
;
261 case DW_EH_PE_funcrel
:
262 val
+= (_Unwind_Ptr
) bases
->func
;
268 *pptr
= (void *) (_Unwind_Ptr
) val
;
272 /* Get the value of register REG as saved in CONTEXT. */
275 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
277 /* This will segfault if the register hasn't been saved. */
278 return * (_Unwind_Word
*) context
->reg
[index
];
281 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
284 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
286 * (_Unwind_Word
*) context
->reg
[index
] = val
;
289 /* Retrieve the return address for CONTEXT. */
292 _Unwind_GetIP (struct _Unwind_Context
*context
)
294 return (_Unwind_Ptr
) context
->ra
;
297 /* Overwrite the return address for CONTEXT with VAL. */
300 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
302 context
->ra
= (void *) val
;
306 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
308 return context
->lsda
;
312 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
314 return (_Unwind_Ptr
) context
->bases
.func
;
318 /* Extract any interesting information from the CIE for the translation
319 unit F belongs to. Return a pointer to the byte after the augmentation,
320 or NULL if we encountered an undecipherable augmentation. */
322 static unsigned char *
323 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
324 _Unwind_FrameState
*fs
)
326 unsigned char *aug
= cie
->augmentation
;
327 unsigned char *p
= aug
+ strlen (aug
) + 1;
328 unsigned char *ret
= NULL
;
329 _Unwind_Word code_align
;
330 _Unwind_Sword data_align
;
332 /* Immediately following the augmentation are the code and
333 data alignment and return address column. */
334 p
= read_uleb128 (p
, &code_align
);
335 p
= read_sleb128 (p
, &data_align
);
336 fs
->code_align
= code_align
;
337 fs
->data_align
= data_align
;
338 fs
->retaddr_column
= *p
++;
340 /* If the augmentation starts with 'z', then a uleb128 immediately
341 follows containing the length of the augmentation field following
346 p
= read_uleb128 (p
, &i
);
353 /* Iterate over recognized augmentation subsequences. */
356 /* "eh" was used by g++ v2; recognize and skip. */
357 if (aug
[0] == 'e' && aug
[1] == 'h')
359 p
+= sizeof (void *);
363 /* "R" indicates a byte indicating how addresses are encoded. */
364 else if (aug
[0] == 'R')
366 fs
->addr_encoding
= *p
++;
370 /* "P" indicates a personality routine in the CIE augmentation
371 and an lsda pointer in the FDE augmentation. */
372 else if (aug
[0] == 'P')
374 p
= read_encoded_pointer (p
, fs
->addr_encoding
, &context
->bases
,
375 (void **) &fs
->personality
);
380 /* Otherwise we have an unknown augmentation string.
381 Bail unless we saw a 'z' prefix. */
386 return ret
? ret
: p
;
390 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
391 onto the stack to start. */
394 execute_stack_op (unsigned char *op_ptr
, unsigned char *op_end
,
395 struct _Unwind_Context
*context
, _Unwind_Word initial
)
397 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
403 while (op_ptr
< op_end
)
405 enum dwarf_location_atom op
= *op_ptr
++;
406 _Unwind_Word result
, reg
;
407 _Unwind_Sword offset
;
443 result
= op
- DW_OP_lit0
;
447 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
448 op_ptr
+= sizeof (void *);
452 result
= read_1u (op_ptr
);
456 result
= read_1s (op_ptr
);
460 result
= read_2u (op_ptr
);
464 result
= read_2s (op_ptr
);
468 result
= read_4u (op_ptr
);
472 result
= read_4s (op_ptr
);
476 result
= read_8u (op_ptr
);
480 result
= read_8s (op_ptr
);
484 op_ptr
= read_uleb128 (op_ptr
, &result
);
487 op_ptr
= read_sleb128 (op_ptr
, &offset
);
523 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
526 op_ptr
= read_uleb128 (op_ptr
, ®
);
527 result
= _Unwind_GetGR (context
, reg
);
562 op_ptr
= read_sleb128 (op_ptr
, &offset
);
563 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
566 op_ptr
= read_uleb128 (op_ptr
, ®
);
567 op_ptr
= read_sleb128 (op_ptr
, &offset
);
568 result
= _Unwind_GetGR (context
, reg
) + offset
;
574 result
= stack
[stack_elt
- 1];
584 if (offset
>= stack_elt
- 1)
586 result
= stack
[stack_elt
- 1 - offset
];
592 result
= stack
[stack_elt
- 2];
597 _Unwind_Word t1
, t2
, t3
;
601 t1
= stack
[stack_elt
- 1];
602 t2
= stack
[stack_elt
- 2];
603 t3
= stack
[stack_elt
- 3];
604 stack
[stack_elt
- 1] = t2
;
605 stack
[stack_elt
- 2] = t3
;
606 stack
[stack_elt
- 3] = t1
;
611 case DW_OP_deref_size
:
615 case DW_OP_plus_uconst
:
616 /* Unary operations. */
619 result
= stack
[stack_elt
];
625 void *ptr
= (void *)(_Unwind_Ptr
) result
;
626 result
= (_Unwind_Ptr
) read_pointer (ptr
);
630 case DW_OP_deref_size
:
632 void *ptr
= (void *)(_Unwind_Ptr
) result
;
636 result
= read_1u (ptr
);
639 result
= read_2u (ptr
);
642 result
= read_4u (ptr
);
645 result
= read_8u (ptr
);
654 if ((_Unwind_Sword
) result
< 0)
663 case DW_OP_plus_uconst
:
664 op_ptr
= read_uleb128 (op_ptr
, ®
);
684 /* Binary operations. */
685 _Unwind_Word first
, second
;
686 if ((stack_elt
-= 2) < 0)
688 second
= stack
[stack_elt
];
689 first
= stack
[stack_elt
+ 1];
694 result
= second
& first
;
697 result
= (_Unwind_Sword
)second
/ (_Unwind_Sword
)first
;
700 result
= second
- first
;
703 result
= (_Unwind_Sword
)second
% (_Unwind_Sword
)first
;
706 result
= second
* first
;
709 result
= second
| first
;
712 result
= second
+ first
;
715 result
= second
<< first
;
718 result
= second
>> first
;
721 result
= (_Unwind_Sword
)second
>> first
;
724 result
= second
^ first
;
727 result
= (_Unwind_Sword
)first
<= (_Unwind_Sword
)second
;
730 result
= (_Unwind_Sword
)first
>= (_Unwind_Sword
)second
;
733 result
= (_Unwind_Sword
)first
== (_Unwind_Sword
)second
;
736 result
= (_Unwind_Sword
)first
< (_Unwind_Sword
)second
;
739 result
= (_Unwind_Sword
)first
> (_Unwind_Sword
)second
;
742 result
= (_Unwind_Sword
)first
!= (_Unwind_Sword
)second
;
749 offset
= read_2s (op_ptr
);
757 offset
= read_2s (op_ptr
);
759 if (stack
[stack_elt
] != 0)
770 /* Most things push a result value. */
771 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
773 stack
[++stack_elt
] = result
;
777 /* We were executing this program to get a value. It should be
781 return stack
[stack_elt
];
785 /* Decode DWARF 2 call frame information. Takes pointers the
786 instruction sequence to decode, current register information and
787 CIE info, and the PC range to evaluate. */
790 execute_cfa_program (unsigned char *insn_ptr
, unsigned char *insn_end
,
791 struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
793 struct frame_state_reg_info
*unused_rs
= NULL
;
795 /* Don't allow remember/restore between CIE and FDE programs. */
796 fs
->regs
.prev
= NULL
;
798 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
800 unsigned char insn
= *insn_ptr
++;
801 _Unwind_Word reg
, uoffset
;
802 _Unwind_Sword offset
;
804 if (insn
& DW_CFA_advance_loc
)
805 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
806 else if (insn
& DW_CFA_offset
)
809 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
810 offset
= (_Unwind_Sword
)uoffset
* fs
->data_align
;
811 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
812 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
814 else if (insn
& DW_CFA_restore
)
817 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
822 insn_ptr
= read_encoded_pointer (insn_ptr
, fs
->addr_encoding
,
823 &context
->bases
, &fs
->pc
);
826 case DW_CFA_advance_loc1
:
827 fs
->pc
+= read_1u (insn_ptr
);
830 case DW_CFA_advance_loc2
:
831 fs
->pc
+= read_2u (insn_ptr
);
834 case DW_CFA_advance_loc4
:
835 fs
->pc
+= read_4u (insn_ptr
);
839 case DW_CFA_offset_extended
:
840 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
841 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
842 offset
= (_Unwind_Sword
)uoffset
* fs
->data_align
;
843 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
844 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
847 case DW_CFA_restore_extended
:
848 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
849 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
852 case DW_CFA_undefined
:
853 case DW_CFA_same_value
:
857 case DW_CFA_register
:
860 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
861 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
862 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
863 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
867 case DW_CFA_remember_state
:
869 struct frame_state_reg_info
*new_rs
;
873 unused_rs
= unused_rs
->prev
;
876 new_rs
= alloca (sizeof (struct frame_state_reg_info
));
879 fs
->regs
.prev
= new_rs
;
883 case DW_CFA_restore_state
:
885 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
887 old_rs
->prev
= unused_rs
;
893 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
894 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
895 fs
->cfa_offset
= uoffset
;
896 fs
->cfa_how
= CFA_REG_OFFSET
;
899 case DW_CFA_def_cfa_register
:
900 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
901 fs
->cfa_how
= CFA_REG_OFFSET
;
904 case DW_CFA_def_cfa_offset
:
905 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
906 fs
->cfa_offset
= uoffset
;
907 /* cfa_how deliberately not set. */
910 case DW_CFA_def_cfa_expression
:
911 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
912 fs
->cfa_exp
= insn_ptr
;
913 fs
->cfa_how
= CFA_EXP
;
917 case DW_CFA_expression
:
918 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
919 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
920 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
921 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
925 /* From the 2.1 draft. */
926 case DW_CFA_offset_extended_sf
:
927 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
928 insn_ptr
= read_sleb128 (insn_ptr
, &offset
);
929 offset
*= fs
->data_align
;
930 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
931 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
934 case DW_CFA_def_cfa_sf
:
935 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
936 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
937 fs
->cfa_how
= CFA_REG_OFFSET
;
940 case DW_CFA_def_cfa_offset_sf
:
941 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_offset
);
942 /* cfa_how deliberately not set. */
945 case DW_CFA_GNU_window_save
:
946 /* ??? Hardcoded for SPARC register window configuration. */
947 for (reg
= 16; reg
< 32; ++reg
)
949 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
950 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
954 case DW_CFA_GNU_args_size
:
955 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
958 case DW_CFA_GNU_negative_offset_extended
:
959 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
960 older PowerPC code. */
961 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
962 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
963 offset
= (_Unwind_Sword
)uoffset
* fs
->data_align
;
964 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
965 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
974 static _Unwind_Reason_Code
975 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
977 struct dwarf_fde
*fde
;
978 struct dwarf_cie
*cie
;
979 unsigned char *aug
, *insn
, *end
;
981 memset (fs
, 0, sizeof (*fs
));
982 context
->args_size
= 0;
985 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
988 /* Couldn't find frame unwind info for this function. Try a
989 target-specific fallback mechanism. This will necessarily
990 not profide a personality routine or LSDA. */
991 #ifdef MD_FALLBACK_FRAME_STATE_FOR
992 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
993 return _URC_END_OF_STACK
;
995 return _URC_NO_REASON
;
997 return _URC_END_OF_STACK
;
1001 context
->bases
.func
= fde
->pc_begin
;
1002 fs
->pc
= fde
->pc_begin
;
1004 cie
= get_cie (fde
);
1005 insn
= extract_cie_info (cie
, context
, fs
);
1007 /* CIE contained unknown augmentation. */
1008 return _URC_FATAL_PHASE1_ERROR
;
1010 /* First decode all the insns in the CIE. */
1011 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
1012 execute_cfa_program (insn
, end
, context
, fs
);
1014 /* Locate augmentation for the fde. */
1015 aug
= (unsigned char *)fde
+ sizeof (*fde
);
1020 aug
= read_uleb128 (aug
, &i
);
1024 aug
= read_encoded_pointer (aug
, fs
->addr_encoding
,
1025 &context
->bases
, &context
->lsda
);
1027 /* Then the insns in the FDE up to our target PC. */
1030 end
= (unsigned char *) next_fde (fde
);
1031 execute_cfa_program (insn
, end
, context
, fs
);
1033 return _URC_NO_REASON
;
1038 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1040 struct _Unwind_Context orig_context
= *context
;
1044 /* Compute this frame's CFA. */
1045 switch (fs
->cfa_how
)
1047 case CFA_REG_OFFSET
:
1048 /* Special handling here: Many machines do not use a frame pointer,
1049 and track the CFA only through offsets from the stack pointer from
1050 one frame to the next. In this case, the stack pointer is never
1051 stored, so it has no saved address in the context. What we do
1052 have is the CFA from the previous stack frame. */
1053 if (context
->reg
[fs
->cfa_reg
] == NULL
)
1056 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->cfa_reg
);
1057 cfa
+= fs
->cfa_offset
;
1061 /* ??? No way of knowing what register number is the stack pointer
1062 to do the same sort of handling as above. Assume that if the
1063 CFA calculation is so complicated as to require a stack program
1064 that this will not be a problem. */
1066 unsigned char *exp
= fs
->cfa_exp
;
1069 exp
= read_uleb128 (exp
, &len
);
1070 cfa
= (void *) (_Unwind_Ptr
)
1071 execute_stack_op (exp
, exp
+ len
, context
, 0);
1080 /* Compute the addresses of all registers saved in this frame. */
1081 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1082 switch (fs
->regs
.reg
[i
].how
)
1086 case REG_SAVED_OFFSET
:
1087 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
1090 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
1094 unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1098 exp
= read_uleb128 (exp
, &len
);
1099 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1101 context
->reg
[i
] = (void *) val
;
1108 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1110 uw_update_context_1 (context
, fs
);
1112 /* Compute the return address now, since the return address column
1113 can change from frame to frame. */
1114 context
->ra
= __builtin_extract_return_addr
1115 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1118 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1119 level will be the return address and the CFA. */
1121 #define uw_init_context(CONTEXT) \
1123 /* Do any necessary initialization to access arbitrary stack frames. \
1124 On the SPARC, this means flushing the register windows. */ \
1125 __builtin_unwind_init (); \
1126 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1127 __builtin_return_address (0)); \
1131 uw_init_context_1 (struct _Unwind_Context
*context
,
1132 void *outer_cfa
, void *outer_ra
)
1134 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1135 _Unwind_FrameState fs
;
1137 memset (context
, 0, sizeof (struct _Unwind_Context
));
1140 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1143 /* Force the frame state to use the known cfa value. */
1144 context
->cfa
= outer_cfa
;
1145 fs
.cfa_how
= CFA_REG_OFFSET
;
1149 uw_update_context_1 (context
, &fs
);
1151 /* If the return address column was saved in a register in the
1152 initialization context, then we can't see it in the given
1153 call frame data. So have the initialization context tell us. */
1154 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1158 /* Install TARGET into CURRENT so that we can return to it. This is a
1159 macro because __builtin_eh_return must be invoked in the context of
1162 #define uw_install_context(CURRENT, TARGET) \
1164 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1165 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1166 __builtin_eh_return (offset, handler); \
1170 init_dwarf_reg_size_table (void)
1172 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1176 uw_install_context_1 (struct _Unwind_Context
*current
,
1177 struct _Unwind_Context
*target
)
1183 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1184 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1185 || dwarf_reg_size_table
[0] == 0)
1186 init_dwarf_reg_size_table ();
1189 if (dwarf_reg_size_table
[0] == 0)
1190 init_dwarf_reg_size_table ();
1193 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1195 void *c
= current
->reg
[i
];
1196 void *t
= target
->reg
[i
];
1197 if (t
&& c
&& t
!= c
)
1198 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1201 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1202 if (STACK_GROWS_DOWNWARD
)
1203 return target
->cfa
- current
->cfa
+ target
->args_size
;
1205 return current
->cfa
- target
->cfa
- target
->args_size
;
1208 static inline _Unwind_Ptr
1209 uw_identify_context (struct _Unwind_Context
*context
)
1211 return _Unwind_GetIP (context
);
1215 #include "unwind.inc"
1217 #endif /* !USING_SJLJ_EXCEPTIONS */