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 GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 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 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include "unwind-pe.h"
26 #include "unwind-dw2-fde.h"
30 #if !USING_SJLJ_EXCEPTIONS
32 #ifndef STACK_GROWS_DOWNWARD
33 #define STACK_GROWS_DOWNWARD 0
35 #undef STACK_GROWS_DOWNWARD
36 #define STACK_GROWS_DOWNWARD 1
39 /* A target can override (perhaps for backward compatibility) how
40 many dwarf2 columns are unwound. */
41 #ifndef DWARF_FRAME_REGISTERS
42 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
45 /* This is the register and unwind state for a particular frame. */
46 struct _Unwind_Context
48 void *reg[DWARF_FRAME_REGISTERS+1];
52 struct dwarf_eh_bases bases;
53 _Unwind_Word args_size;
56 /* Byte size of every register managed by these routines. */
57 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
60 /* The result of interpreting the frame unwind info for a frame.
61 This is all symbolic at this point, as none of the values can
62 be resolved until the target pc is located. */
65 /* Each register save state can be described in terms of a CFA slot,
66 another register, or a location expression. */
67 struct frame_state_reg_info
73 const unsigned char *exp;
81 } reg[DWARF_FRAME_REGISTERS+1];
83 /* Used to implement DW_CFA_remember_state. */
84 struct frame_state_reg_info *prev;
87 /* The CFA can be described in terms of a reg+offset or a
88 location expression. */
89 _Unwind_Sword cfa_offset;
91 const unsigned char *cfa_exp;
98 /* The PC described by the current frame state. */
101 /* The information we care about from the CIE/FDE. */
102 _Unwind_Personality_Fn personality;
103 signed int data_align;
104 unsigned int code_align;
105 unsigned char retaddr_column;
106 unsigned char fde_encoding;
107 unsigned char lsda_encoding;
110 } _Unwind_FrameState;
112 /* Read unaligned data from the instruction buffer. */
117 unsigned u2 __attribute__ ((mode (HI)));
118 unsigned u4 __attribute__ ((mode (SI)));
119 unsigned u8 __attribute__ ((mode (DI)));
120 signed s2 __attribute__ ((mode (HI)));
121 signed s4 __attribute__ ((mode (SI)));
122 signed s8 __attribute__ ((mode (DI)));
123 } __attribute__ ((packed));
126 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
129 read_1u (const void *p) { return *(const unsigned char *)p; }
132 read_1s (const void *p) { return *(const signed char *)p; }
135 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
138 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
140 static inline unsigned int
141 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
144 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
146 static inline unsigned long
147 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
149 static inline unsigned long
150 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
152 /* Get the value of register REG as saved in CONTEXT. */
155 _Unwind_GetGR (struct _Unwind_Context *context, int index)
157 /* This will segfault if the register hasn't been saved. */
158 return * (_Unwind_Word *) context->reg[index];
161 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
164 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
166 * (_Unwind_Word *) context->reg[index] = val;
169 /* Retrieve the return address for CONTEXT. */
172 _Unwind_GetIP (struct _Unwind_Context *context)
174 return (_Unwind_Ptr) context->ra;
177 /* Overwrite the return address for CONTEXT with VAL. */
180 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
182 context->ra = (void *) val;
186 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
188 return context->lsda;
192 _Unwind_GetRegionStart (struct _Unwind_Context *context)
194 return (_Unwind_Ptr) context->bases.func;
199 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
201 return (_Unwind_Ptr) context->bases.dbase;
205 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
207 return (_Unwind_Ptr) context->bases.tbase;
211 /* Extract any interesting information from the CIE for the translation
212 unit F belongs to. Return a pointer to the byte after the augmentation,
213 or NULL if we encountered an undecipherable augmentation. */
215 static const unsigned char *
216 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
217 _Unwind_FrameState *fs)
219 const unsigned char *aug = cie->augmentation;
220 const unsigned char *p = aug + strlen (aug) + 1;
221 const unsigned char *ret = NULL;
224 /* g++ v2 "eh" has pointer immediately following augmentation string,
225 so it must be handled first. */
226 if (aug[0] == 'e' && aug[1] == 'h')
228 fs->eh_ptr = read_pointer (p);
229 p += sizeof (void *);
233 /* Immediately following the augmentation are the code and
234 data alignment and return address column. */
235 p = read_uleb128 (p, &tmp); fs->code_align = tmp;
236 p = read_sleb128 (p, &tmp); fs->data_align = (saddr) tmp;
237 fs->retaddr_column = *p++;
238 fs->lsda_encoding = DW_EH_PE_omit;
240 /* If the augmentation starts with 'z', then a uleb128 immediately
241 follows containing the length of the augmentation field following
245 p = read_uleb128 (p, &tmp);
252 /* Iterate over recognized augmentation subsequences. */
255 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
258 fs->lsda_encoding = *p++;
262 /* "R" indicates a byte indicating how FDE addresses are encoded. */
263 else if (aug[0] == 'R')
265 fs->fde_encoding = *p++;
269 /* "P" indicates a personality routine in the CIE augmentation. */
270 else if (aug[0] == 'P')
272 p = read_encoded_value (context, *p, p + 1,
273 (_Unwind_Ptr *) &fs->personality);
277 /* Otherwise we have an unknown augmentation string.
278 Bail unless we saw a 'z' prefix. */
283 return ret ? ret : p;
287 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
288 onto the stack to start. */
291 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
292 struct _Unwind_Context *context, _Unwind_Word initial)
294 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
300 while (op_ptr < op_end)
302 enum dwarf_location_atom op = *op_ptr++;
303 _Unwind_Word result, reg;
304 _Unwind_Sword offset;
341 result = op - DW_OP_lit0;
345 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
346 op_ptr += sizeof (void *);
350 result = read_1u (op_ptr);
354 result = read_1s (op_ptr);
358 result = read_2u (op_ptr);
362 result = read_2s (op_ptr);
366 result = read_4u (op_ptr);
370 result = read_4s (op_ptr);
374 result = read_8u (op_ptr);
378 result = read_8s (op_ptr);
382 op_ptr = read_uleb128 (op_ptr, &ptrtmp);
386 op_ptr = read_sleb128 (op_ptr, &ptrtmp);
387 result = (saddr)ptrtmp;
422 result = _Unwind_GetGR (context, op - DW_OP_reg0);
425 op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
426 result = _Unwind_GetGR (context, reg);
461 op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
462 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
465 op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
466 op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
467 result = _Unwind_GetGR (context, reg) + offset;
473 result = stack[stack_elt - 1];
483 if (offset >= stack_elt - 1)
485 result = stack[stack_elt - 1 - offset];
491 result = stack[stack_elt - 2];
496 _Unwind_Word t1, t2, t3;
500 t1 = stack[stack_elt - 1];
501 t2 = stack[stack_elt - 2];
502 t3 = stack[stack_elt - 3];
503 stack[stack_elt - 1] = t2;
504 stack[stack_elt - 2] = t3;
505 stack[stack_elt - 3] = t1;
510 case DW_OP_deref_size:
514 case DW_OP_plus_uconst:
515 /* Unary operations. */
518 result = stack[stack_elt];
524 void *ptr = (void *)(_Unwind_Ptr) result;
525 result = (_Unwind_Ptr) read_pointer (ptr);
529 case DW_OP_deref_size:
531 void *ptr = (void *)(_Unwind_Ptr) result;
535 result = read_1u (ptr);
538 result = read_2u (ptr);
541 result = read_4u (ptr);
544 result = read_8u (ptr);
553 if ((_Unwind_Sword) result < 0)
562 case DW_OP_plus_uconst:
563 op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
586 /* Binary operations. */
587 _Unwind_Word first, second;
588 if ((stack_elt -= 2) < 0)
590 second = stack[stack_elt];
591 first = stack[stack_elt + 1];
596 result = second & first;
599 result = (_Unwind_Sword)second / (_Unwind_Sword)first;
602 result = second - first;
605 result = (_Unwind_Sword)second % (_Unwind_Sword)first;
608 result = second * first;
611 result = second | first;
614 result = second + first;
617 result = second << first;
620 result = second >> first;
623 result = (_Unwind_Sword)second >> first;
626 result = second ^ first;
629 result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
632 result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
635 result = (_Unwind_Sword)first == (_Unwind_Sword)second;
638 result = (_Unwind_Sword)first < (_Unwind_Sword)second;
641 result = (_Unwind_Sword)first > (_Unwind_Sword)second;
644 result = (_Unwind_Sword)first != (_Unwind_Sword)second;
654 offset = read_2s (op_ptr);
662 offset = read_2s (op_ptr);
664 if (stack[stack_elt] != 0)
675 /* Most things push a result value. */
676 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
678 stack[++stack_elt] = result;
682 /* We were executing this program to get a value. It should be
686 return stack[stack_elt];
690 /* Decode DWARF 2 call frame information. Takes pointers the
691 instruction sequence to decode, current register information and
692 CIE info, and the PC range to evaluate. */
695 execute_cfa_program (const unsigned char *insn_ptr,
696 const unsigned char *insn_end,
697 struct _Unwind_Context *context,
698 _Unwind_FrameState *fs)
700 struct frame_state_reg_info *unused_rs = NULL;
702 /* Don't allow remember/restore between CIE and FDE programs. */
703 fs->regs.prev = NULL;
705 while (insn_ptr < insn_end && fs->pc < context->ra)
707 unsigned char insn = *insn_ptr++;
709 _Unwind_Sword offset;
712 if (insn & DW_CFA_advance_loc)
713 fs->pc += (insn & 0x3f) * fs->code_align;
714 else if (insn & DW_CFA_offset)
717 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
718 offset = ptrtmp * fs->data_align;
719 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
720 fs->regs.reg[reg].loc.offset = offset;
722 else if (insn & DW_CFA_restore)
725 fs->regs.reg[reg].how = REG_UNSAVED;
730 insn_ptr = read_encoded_value (context, fs->fde_encoding,
731 insn_ptr, (_Unwind_Ptr *) &fs->pc);
734 case DW_CFA_advance_loc1:
735 fs->pc += read_1u (insn_ptr) * fs->code_align;
738 case DW_CFA_advance_loc2:
739 fs->pc += read_2u (insn_ptr) * fs->code_align;
742 case DW_CFA_advance_loc4:
743 fs->pc += read_4u (insn_ptr) * fs->code_align;
747 case DW_CFA_offset_extended:
748 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
749 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
750 offset = ptrtmp * fs->data_align;
751 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
752 fs->regs.reg[reg].loc.offset = offset;
755 case DW_CFA_restore_extended:
756 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
757 fs->regs.reg[reg].how = REG_UNSAVED;
760 case DW_CFA_undefined:
761 case DW_CFA_same_value:
765 case DW_CFA_register:
768 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
769 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
770 fs->regs.reg[reg].how = REG_SAVED_REG;
771 fs->regs.reg[reg].loc.reg = reg2;
775 case DW_CFA_remember_state:
777 struct frame_state_reg_info *new_rs;
781 unused_rs = unused_rs->prev;
784 new_rs = alloca (sizeof (struct frame_state_reg_info));
787 fs->regs.prev = new_rs;
791 case DW_CFA_restore_state:
793 struct frame_state_reg_info *old_rs = fs->regs.prev;
795 old_rs->prev = unused_rs;
801 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
802 fs->cfa_reg = ptrtmp;
803 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
804 fs->cfa_offset = ptrtmp;
805 fs->cfa_how = CFA_REG_OFFSET;
808 case DW_CFA_def_cfa_register:
809 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
810 fs->cfa_reg = ptrtmp;
811 fs->cfa_how = CFA_REG_OFFSET;
814 case DW_CFA_def_cfa_offset:
815 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
816 fs->cfa_offset = ptrtmp;
817 /* cfa_how deliberately not set. */
820 case DW_CFA_def_cfa_expression:
821 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
822 fs->cfa_exp = insn_ptr;
823 fs->cfa_how = CFA_EXP;
827 case DW_CFA_expression:
828 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
829 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
830 fs->regs.reg[reg].how = REG_SAVED_EXP;
831 fs->regs.reg[reg].loc.exp = insn_ptr;
835 /* From the 2.1 draft. */
836 case DW_CFA_offset_extended_sf:
837 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
838 insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
839 offset = (saddr)ptrtmp * fs->data_align;
840 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
841 fs->regs.reg[reg].loc.offset = offset;
844 case DW_CFA_def_cfa_sf:
845 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
846 fs->cfa_reg = ptrtmp;
847 insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
848 fs->cfa_offset = (saddr)ptrtmp;
849 fs->cfa_how = CFA_REG_OFFSET;
852 case DW_CFA_def_cfa_offset_sf:
853 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
854 fs->cfa_offset = ptrtmp;
855 /* cfa_how deliberately not set. */
858 case DW_CFA_GNU_window_save:
859 /* ??? Hardcoded for SPARC register window configuration. */
860 for (reg = 16; reg < 32; ++reg)
862 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
863 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
867 case DW_CFA_GNU_args_size:
868 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
869 context->args_size = ptrtmp;
872 case DW_CFA_GNU_negative_offset_extended:
873 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
874 older PowerPC code. */
875 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
876 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
877 offset = ptrtmp * fs->data_align;
878 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
879 fs->regs.reg[reg].loc.offset = -offset;
888 static _Unwind_Reason_Code
889 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
891 struct dwarf_fde *fde;
892 struct dwarf_cie *cie;
893 const unsigned char *aug, *insn, *end;
895 memset (fs, 0, sizeof (*fs));
896 context->args_size = 0;
899 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
902 /* Couldn't find frame unwind info for this function. Try a
903 target-specific fallback mechanism. This will necessarily
904 not profide a personality routine or LSDA. */
905 #ifdef MD_FALLBACK_FRAME_STATE_FOR
906 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
907 return _URC_END_OF_STACK;
909 return _URC_NO_REASON;
911 return _URC_END_OF_STACK;
915 fs->pc = context->bases.func;
918 insn = extract_cie_info (cie, context, fs);
920 /* CIE contained unknown augmentation. */
921 return _URC_FATAL_PHASE1_ERROR;
923 /* First decode all the insns in the CIE. */
924 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
925 execute_cfa_program (insn, end, context, fs);
927 /* Locate augmentation for the fde. */
928 aug = (unsigned char *)fde + sizeof (*fde);
929 aug += 2 * size_of_encoded_value (fs->fde_encoding);
934 aug = read_uleb128 (aug, &i);
937 if (fs->lsda_encoding != DW_EH_PE_omit)
938 aug = read_encoded_value (context, fs->lsda_encoding, aug,
939 (_Unwind_Ptr *) &context->lsda);
941 /* Then the insns in the FDE up to our target PC. */
944 end = (unsigned char *) next_fde (fde);
945 execute_cfa_program (insn, end, context, fs);
947 return _URC_NO_REASON;
950 typedef struct frame_state
956 long reg_or_offset[DWARF_FRAME_REGISTERS+1];
957 unsigned short cfa_reg;
958 unsigned short retaddr_column;
959 char saved[DWARF_FRAME_REGISTERS+1];
962 struct frame_state * __frame_state_for (void *, struct frame_state *);
964 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
965 a given PC_TARGET. The caller should allocate a local variable of
966 `struct frame_state' and pass its address to STATE_IN. */
969 __frame_state_for (void *pc_target, struct frame_state *state_in)
971 struct _Unwind_Context context;
972 _Unwind_FrameState fs;
975 memset (&context, 0, sizeof (struct _Unwind_Context));
976 context.ra = pc_target + 1;
978 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
981 /* We have no way to pass a location expression for the CFA to our
982 caller. It wouldn't understand it anyway. */
983 if (fs.cfa_how == CFA_EXP)
986 for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++)
988 state_in->saved[reg] = fs.regs.reg[reg].how;
989 switch (state_in->saved[reg])
992 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
994 case REG_SAVED_OFFSET:
995 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
998 state_in->reg_or_offset[reg] = 0;
1003 state_in->cfa_offset = fs.cfa_offset;
1004 state_in->cfa_reg = fs.cfa_reg;
1005 state_in->retaddr_column = fs.retaddr_column;
1006 state_in->args_size = context.args_size;
1007 state_in->eh_ptr = fs.eh_ptr;
1013 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1015 struct _Unwind_Context orig_context = *context;
1019 /* Compute this frame's CFA. */
1020 switch (fs->cfa_how)
1022 case CFA_REG_OFFSET:
1023 /* Special handling here: Many machines do not use a frame pointer,
1024 and track the CFA only through offsets from the stack pointer from
1025 one frame to the next. In this case, the stack pointer is never
1026 stored, so it has no saved address in the context. What we do
1027 have is the CFA from the previous stack frame. */
1028 if (context->reg[fs->cfa_reg] == NULL)
1031 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1032 cfa += fs->cfa_offset;
1036 /* ??? No way of knowing what register number is the stack pointer
1037 to do the same sort of handling as above. Assume that if the
1038 CFA calculation is so complicated as to require a stack program
1039 that this will not be a problem. */
1041 const unsigned char *exp = fs->cfa_exp;
1044 exp = read_uleb128 (exp, &len);
1045 cfa = (void *) (_Unwind_Ptr)
1046 execute_stack_op (exp, exp + len, context, 0);
1055 /* Compute the addresses of all registers saved in this frame. */
1056 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1057 switch (fs->regs.reg[i].how)
1061 case REG_SAVED_OFFSET:
1062 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1065 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1069 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1073 exp = read_uleb128 (exp, &len);
1074 val = execute_stack_op (exp, exp + len, &orig_context,
1076 context->reg[i] = (void *) val;
1083 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1085 uw_update_context_1 (context, fs);
1087 /* Compute the return address now, since the return address column
1088 can change from frame to frame. */
1089 context->ra = __builtin_extract_return_addr
1090 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1093 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1094 level will be the return address and the CFA. */
1096 #define uw_init_context(CONTEXT) \
1098 /* Do any necessary initialization to access arbitrary stack frames. \
1099 On the SPARC, this means flushing the register windows. */ \
1100 __builtin_unwind_init (); \
1101 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1102 __builtin_return_address (0)); \
1106 uw_init_context_1 (struct _Unwind_Context *context,
1107 void *outer_cfa, void *outer_ra)
1109 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1110 _Unwind_FrameState fs;
1112 memset (context, 0, sizeof (struct _Unwind_Context));
1115 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1118 /* Force the frame state to use the known cfa value. */
1119 context->cfa = outer_cfa;
1120 fs.cfa_how = CFA_REG_OFFSET;
1124 uw_update_context_1 (context, &fs);
1126 /* If the return address column was saved in a register in the
1127 initialization context, then we can't see it in the given
1128 call frame data. So have the initialization context tell us. */
1129 context->ra = __builtin_extract_return_addr (outer_ra);
1133 /* Install TARGET into CURRENT so that we can return to it. This is a
1134 macro because __builtin_eh_return must be invoked in the context of
1137 #define uw_install_context(CURRENT, TARGET) \
1139 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1140 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1141 __builtin_eh_return (offset, handler); \
1145 init_dwarf_reg_size_table (void)
1147 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1151 uw_install_context_1 (struct _Unwind_Context *current,
1152 struct _Unwind_Context *target)
1158 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1159 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1160 || dwarf_reg_size_table[0] == 0)
1161 init_dwarf_reg_size_table ();
1164 if (dwarf_reg_size_table[0] == 0)
1165 init_dwarf_reg_size_table ();
1168 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1170 void *c = current->reg[i];
1171 void *t = target->reg[i];
1172 if (t && c && t != c)
1173 memcpy (c, t, dwarf_reg_size_table[i]);
1176 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1177 if (STACK_GROWS_DOWNWARD)
1178 return target->cfa - current->cfa + target->args_size;
1180 return current->cfa - target->cfa - target->args_size;
1183 static inline _Unwind_Ptr
1184 uw_identify_context (struct _Unwind_Context *context)
1186 return _Unwind_GetIP (context);
1190 #include "unwind.inc"
1192 #endif /* !USING_SJLJ_EXCEPTIONS */