1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
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 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include "unwind-pe.h"
27 #include "unwind-dw2-fde.h"
31 #ifndef __USING_SJLJ_EXCEPTIONS__
33 #ifndef STACK_GROWS_DOWNWARD
34 #define STACK_GROWS_DOWNWARD 0
36 #undef STACK_GROWS_DOWNWARD
37 #define STACK_GROWS_DOWNWARD 1
40 /* A target can override (perhaps for backward compatibility) how
41 many dwarf2 columns are unwound. */
42 #ifndef DWARF_FRAME_REGISTERS
43 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
46 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
47 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
48 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
51 /* This is the register and unwind state for a particular frame. This
52 provides the information necessary to unwind up past a frame and return
54 struct _Unwind_Context
56 void *reg[DWARF_FRAME_REGISTERS+1];
60 struct dwarf_eh_bases bases;
61 _Unwind_Word args_size;
64 /* Byte size of every register managed by these routines. */
65 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
68 /* The result of interpreting the frame unwind info for a frame.
69 This is all symbolic at this point, as none of the values can
70 be resolved until the target pc is located. */
73 /* Each register save state can be described in terms of a CFA slot,
74 another register, or a location expression. */
75 struct frame_state_reg_info
81 const unsigned char *exp;
89 } reg[DWARF_FRAME_REGISTERS+1];
91 /* Used to implement DW_CFA_remember_state. */
92 struct frame_state_reg_info *prev;
95 /* The CFA can be described in terms of a reg+offset or a
96 location expression. */
97 _Unwind_Sword cfa_offset;
99 const unsigned char *cfa_exp;
106 /* The PC described by the current frame state. */
109 /* The information we care about from the CIE/FDE. */
110 _Unwind_Personality_Fn personality;
111 _Unwind_Sword data_align;
112 _Unwind_Word code_align;
113 unsigned char retaddr_column;
114 unsigned char fde_encoding;
115 unsigned char lsda_encoding;
118 } _Unwind_FrameState;
120 /* Read unaligned data from the instruction buffer. */
125 unsigned u2 __attribute__ ((mode (HI)));
126 unsigned u4 __attribute__ ((mode (SI)));
127 unsigned u8 __attribute__ ((mode (DI)));
128 signed s2 __attribute__ ((mode (HI)));
129 signed s4 __attribute__ ((mode (SI)));
130 signed s8 __attribute__ ((mode (DI)));
131 } __attribute__ ((packed));
134 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
137 read_1u (const void *p) { return *(const unsigned char *) p; }
140 read_1s (const void *p) { return *(const signed char *) p; }
143 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
146 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
148 static inline unsigned int
149 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
152 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
154 static inline unsigned long
155 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
157 static inline unsigned long
158 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
160 /* Get the value of register REG as saved in CONTEXT. */
163 _Unwind_GetGR (struct _Unwind_Context *context, int index)
165 /* This will segfault if the register hasn't been saved. */
166 return * (_Unwind_Word *) context->reg[index];
169 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
172 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
174 * (_Unwind_Word *) context->reg[index] = val;
177 /* Retrieve the return address for CONTEXT. */
180 _Unwind_GetIP (struct _Unwind_Context *context)
182 return (_Unwind_Ptr) context->ra;
185 /* Overwrite the return address for CONTEXT with VAL. */
188 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
190 context->ra = (void *) val;
194 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
196 return context->lsda;
200 _Unwind_GetRegionStart (struct _Unwind_Context *context)
202 return (_Unwind_Ptr) context->bases.func;
206 _Unwind_FindEnclosingFunction (void *pc)
208 struct dwarf_eh_bases bases;
209 struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
218 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
220 return (_Unwind_Ptr) context->bases.dbase;
224 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
226 return (_Unwind_Ptr) context->bases.tbase;
230 /* Extract any interesting information from the CIE for the translation
231 unit F belongs to. Return a pointer to the byte after the augmentation,
232 or NULL if we encountered an undecipherable augmentation. */
234 static const unsigned char *
235 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
236 _Unwind_FrameState *fs)
238 const unsigned char *aug = cie->augmentation;
239 const unsigned char *p = aug + strlen (aug) + 1;
240 const unsigned char *ret = NULL;
243 /* g++ v2 "eh" has pointer immediately following augmentation string,
244 so it must be handled first. */
245 if (aug[0] == 'e' && aug[1] == 'h')
247 fs->eh_ptr = read_pointer (p);
248 p += sizeof (void *);
252 /* Immediately following the augmentation are the code and
253 data alignment and return address column. */
254 p = read_uleb128 (p, &fs->code_align);
255 p = read_sleb128 (p, &fs->data_align);
256 fs->retaddr_column = *p++;
257 fs->lsda_encoding = DW_EH_PE_omit;
259 /* If the augmentation starts with 'z', then a uleb128 immediately
260 follows containing the length of the augmentation field following
264 p = read_uleb128 (p, &utmp);
271 /* Iterate over recognized augmentation subsequences. */
274 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
277 fs->lsda_encoding = *p++;
281 /* "R" indicates a byte indicating how FDE addresses are encoded. */
282 else if (aug[0] == 'R')
284 fs->fde_encoding = *p++;
288 /* "P" indicates a personality routine in the CIE augmentation. */
289 else if (aug[0] == 'P')
291 p = read_encoded_value (context, *p, p + 1,
292 (_Unwind_Ptr *) &fs->personality);
296 /* Otherwise we have an unknown augmentation string.
297 Bail unless we saw a 'z' prefix. */
302 return ret ? ret : p;
306 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
307 onto the stack to start. */
310 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
311 struct _Unwind_Context *context, _Unwind_Word initial)
313 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
319 while (op_ptr < op_end)
321 enum dwarf_location_atom op = *op_ptr++;
322 _Unwind_Word result, reg, utmp;
323 _Unwind_Sword offset, stmp;
359 result = op - DW_OP_lit0;
363 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
364 op_ptr += sizeof (void *);
368 result = read_1u (op_ptr);
372 result = read_1s (op_ptr);
376 result = read_2u (op_ptr);
380 result = read_2s (op_ptr);
384 result = read_4u (op_ptr);
388 result = read_4s (op_ptr);
392 result = read_8u (op_ptr);
396 result = read_8s (op_ptr);
400 op_ptr = read_uleb128 (op_ptr, &result);
403 op_ptr = read_sleb128 (op_ptr, &stmp);
439 result = _Unwind_GetGR (context, op - DW_OP_reg0);
442 op_ptr = read_uleb128 (op_ptr, ®);
443 result = _Unwind_GetGR (context, reg);
478 op_ptr = read_sleb128 (op_ptr, &offset);
479 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
482 op_ptr = read_uleb128 (op_ptr, ®);
483 op_ptr = read_sleb128 (op_ptr, &offset);
484 result = _Unwind_GetGR (context, reg) + offset;
490 result = stack[stack_elt - 1];
500 if (offset >= stack_elt - 1)
502 result = stack[stack_elt - 1 - offset];
508 result = stack[stack_elt - 2];
513 _Unwind_Word t1, t2, t3;
517 t1 = stack[stack_elt - 1];
518 t2 = stack[stack_elt - 2];
519 t3 = stack[stack_elt - 3];
520 stack[stack_elt - 1] = t2;
521 stack[stack_elt - 2] = t3;
522 stack[stack_elt - 3] = t1;
527 case DW_OP_deref_size:
531 case DW_OP_plus_uconst:
532 /* Unary operations. */
535 result = stack[stack_elt];
541 void *ptr = (void *) (_Unwind_Ptr) result;
542 result = (_Unwind_Ptr) read_pointer (ptr);
546 case DW_OP_deref_size:
548 void *ptr = (void *) (_Unwind_Ptr) result;
552 result = read_1u (ptr);
555 result = read_2u (ptr);
558 result = read_4u (ptr);
561 result = read_8u (ptr);
570 if ((_Unwind_Sword) result < 0)
579 case DW_OP_plus_uconst:
580 op_ptr = read_uleb128 (op_ptr, &utmp);
603 /* Binary operations. */
604 _Unwind_Word first, second;
605 if ((stack_elt -= 2) < 0)
607 second = stack[stack_elt];
608 first = stack[stack_elt + 1];
613 result = second & first;
616 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
619 result = second - first;
622 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
625 result = second * first;
628 result = second | first;
631 result = second + first;
634 result = second << first;
637 result = second >> first;
640 result = (_Unwind_Sword) second >> first;
643 result = second ^ first;
646 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
649 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
652 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
655 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
658 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
661 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
671 offset = read_2s (op_ptr);
679 offset = read_2s (op_ptr);
681 if (stack[stack_elt] != 0)
692 /* Most things push a result value. */
693 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
695 stack[++stack_elt] = result;
699 /* We were executing this program to get a value. It should be
703 return stack[stack_elt];
707 /* Decode DWARF 2 call frame information. Takes pointers the
708 instruction sequence to decode, current register information and
709 CIE info, and the PC range to evaluate. */
712 execute_cfa_program (const unsigned char *insn_ptr,
713 const unsigned char *insn_end,
714 struct _Unwind_Context *context,
715 _Unwind_FrameState *fs)
717 struct frame_state_reg_info *unused_rs = NULL;
719 /* Don't allow remember/restore between CIE and FDE programs. */
720 fs->regs.prev = NULL;
722 /* The comparison with the return address uses < rather than <= because
723 we are only interested in the effects of code before the call; for a
724 noreturn function, the return address may point to unrelated code with
725 a different stack configuration that we are not interested in. We
726 assume that the call itself is unwind info-neutral; if not, or if
727 there are delay instructions that adjust the stack, these must be
728 reflected at the point immediately before the call insn. */
729 while (insn_ptr < insn_end && fs->pc < context->ra)
731 unsigned char insn = *insn_ptr++;
732 _Unwind_Word reg, utmp;
733 _Unwind_Sword offset, stmp;
735 if ((insn & 0xc0) == DW_CFA_advance_loc)
736 fs->pc += (insn & 0x3f) * fs->code_align;
737 else if ((insn & 0xc0) == DW_CFA_offset)
740 insn_ptr = read_uleb128 (insn_ptr, &utmp);
741 offset = (_Unwind_Sword) utmp * fs->data_align;
742 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
743 fs->regs.reg[reg].loc.offset = offset;
745 else if ((insn & 0xc0) == DW_CFA_restore)
748 fs->regs.reg[reg].how = REG_UNSAVED;
753 insn_ptr = read_encoded_value (context, fs->fde_encoding,
754 insn_ptr, (_Unwind_Ptr *) &fs->pc);
757 case DW_CFA_advance_loc1:
758 fs->pc += read_1u (insn_ptr) * fs->code_align;
761 case DW_CFA_advance_loc2:
762 fs->pc += read_2u (insn_ptr) * fs->code_align;
765 case DW_CFA_advance_loc4:
766 fs->pc += read_4u (insn_ptr) * fs->code_align;
770 case DW_CFA_offset_extended:
771 insn_ptr = read_uleb128 (insn_ptr, ®);
772 insn_ptr = read_uleb128 (insn_ptr, &utmp);
773 offset = (_Unwind_Sword) utmp * fs->data_align;
774 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
775 fs->regs.reg[reg].loc.offset = offset;
778 case DW_CFA_restore_extended:
779 insn_ptr = read_uleb128 (insn_ptr, ®);
780 fs->regs.reg[reg].how = REG_UNSAVED;
783 case DW_CFA_undefined:
784 case DW_CFA_same_value:
788 case DW_CFA_register:
791 insn_ptr = read_uleb128 (insn_ptr, ®);
792 insn_ptr = read_uleb128 (insn_ptr, ®2);
793 fs->regs.reg[reg].how = REG_SAVED_REG;
794 fs->regs.reg[reg].loc.reg = reg2;
798 case DW_CFA_remember_state:
800 struct frame_state_reg_info *new_rs;
804 unused_rs = unused_rs->prev;
807 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
810 fs->regs.prev = new_rs;
814 case DW_CFA_restore_state:
816 struct frame_state_reg_info *old_rs = fs->regs.prev;
818 old_rs->prev = unused_rs;
824 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
825 insn_ptr = read_uleb128 (insn_ptr, &utmp);
826 fs->cfa_offset = utmp;
827 fs->cfa_how = CFA_REG_OFFSET;
830 case DW_CFA_def_cfa_register:
831 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
832 fs->cfa_how = CFA_REG_OFFSET;
835 case DW_CFA_def_cfa_offset:
836 insn_ptr = read_uleb128 (insn_ptr, &utmp);
837 fs->cfa_offset = utmp;
838 /* cfa_how deliberately not set. */
841 case DW_CFA_def_cfa_expression:
842 insn_ptr = read_uleb128 (insn_ptr, &utmp);
843 fs->cfa_exp = insn_ptr;
844 fs->cfa_how = CFA_EXP;
848 case DW_CFA_expression:
849 insn_ptr = read_uleb128 (insn_ptr, ®);
850 insn_ptr = read_uleb128 (insn_ptr, &utmp);
851 fs->regs.reg[reg].how = REG_SAVED_EXP;
852 fs->regs.reg[reg].loc.exp = insn_ptr;
856 /* From the 2.1 draft. */
857 case DW_CFA_offset_extended_sf:
858 insn_ptr = read_uleb128 (insn_ptr, ®);
859 insn_ptr = read_sleb128 (insn_ptr, &stmp);
860 offset = stmp * fs->data_align;
861 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
862 fs->regs.reg[reg].loc.offset = offset;
865 case DW_CFA_def_cfa_sf:
866 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
867 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
868 fs->cfa_how = CFA_REG_OFFSET;
871 case DW_CFA_def_cfa_offset_sf:
872 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
873 /* cfa_how deliberately not set. */
876 case DW_CFA_GNU_window_save:
877 /* ??? Hardcoded for SPARC register window configuration. */
878 for (reg = 16; reg < 32; ++reg)
880 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
881 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
885 case DW_CFA_GNU_args_size:
886 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
889 case DW_CFA_GNU_negative_offset_extended:
890 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
891 older PowerPC code. */
892 insn_ptr = read_uleb128 (insn_ptr, ®);
893 insn_ptr = read_uleb128 (insn_ptr, &utmp);
894 offset = (_Unwind_Word) utmp * fs->data_align;
895 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
896 fs->regs.reg[reg].loc.offset = -offset;
905 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
906 its caller and decode it into FS. This function also sets the
907 args_size and lsda members of CONTEXT, as they are really information
908 about the caller's frame. */
910 static _Unwind_Reason_Code
911 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
913 struct dwarf_fde *fde;
914 struct dwarf_cie *cie;
915 const unsigned char *aug, *insn, *end;
917 memset (fs, 0, sizeof (*fs));
918 context->args_size = 0;
921 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
924 /* Couldn't find frame unwind info for this function. Try a
925 target-specific fallback mechanism. This will necessarily
926 not provide a personality routine or LSDA. */
927 #ifdef MD_FALLBACK_FRAME_STATE_FOR
928 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
929 return _URC_END_OF_STACK;
931 return _URC_NO_REASON;
933 return _URC_END_OF_STACK;
937 fs->pc = context->bases.func;
940 insn = extract_cie_info (cie, context, fs);
942 /* CIE contained unknown augmentation. */
943 return _URC_FATAL_PHASE1_ERROR;
945 /* First decode all the insns in the CIE. */
946 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
947 execute_cfa_program (insn, end, context, fs);
949 /* Locate augmentation for the fde. */
950 aug = (unsigned char *) fde + sizeof (*fde);
951 aug += 2 * size_of_encoded_value (fs->fde_encoding);
956 aug = read_uleb128 (aug, &i);
959 if (fs->lsda_encoding != DW_EH_PE_omit)
960 aug = read_encoded_value (context, fs->lsda_encoding, aug,
961 (_Unwind_Ptr *) &context->lsda);
963 /* Then the insns in the FDE up to our target PC. */
966 end = (unsigned char *) next_fde (fde);
967 execute_cfa_program (insn, end, context, fs);
969 return _URC_NO_REASON;
972 typedef struct frame_state
978 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
979 unsigned short cfa_reg;
980 unsigned short retaddr_column;
981 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
984 struct frame_state * __frame_state_for (void *, struct frame_state *);
986 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
987 a given PC_TARGET. The caller should allocate a local variable of
988 `struct frame_state' and pass its address to STATE_IN. */
991 __frame_state_for (void *pc_target, struct frame_state *state_in)
993 struct _Unwind_Context context;
994 _Unwind_FrameState fs;
997 memset (&context, 0, sizeof (struct _Unwind_Context));
998 context.ra = pc_target + 1;
1000 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1003 /* We have no way to pass a location expression for the CFA to our
1004 caller. It wouldn't understand it anyway. */
1005 if (fs.cfa_how == CFA_EXP)
1008 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1010 state_in->saved[reg] = fs.regs.reg[reg].how;
1011 switch (state_in->saved[reg])
1014 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1016 case REG_SAVED_OFFSET:
1017 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1020 state_in->reg_or_offset[reg] = 0;
1025 state_in->cfa_offset = fs.cfa_offset;
1026 state_in->cfa_reg = fs.cfa_reg;
1027 state_in->retaddr_column = fs.retaddr_column;
1028 state_in->args_size = context.args_size;
1029 state_in->eh_ptr = fs.eh_ptr;
1035 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1037 struct _Unwind_Context orig_context = *context;
1041 /* Compute this frame's CFA. */
1042 switch (fs->cfa_how)
1044 case CFA_REG_OFFSET:
1045 /* Special handling here: Many machines do not use a frame pointer,
1046 and track the CFA only through offsets from the stack pointer from
1047 one frame to the next. In this case, the stack pointer is never
1048 stored, so it has no saved address in the context. What we do
1049 have is the CFA from the previous stack frame. */
1050 if (context->reg[fs->cfa_reg] == NULL)
1053 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1054 cfa += fs->cfa_offset;
1058 /* ??? No way of knowing what register number is the stack pointer
1059 to do the same sort of handling as above. Assume that if the
1060 CFA calculation is so complicated as to require a stack program
1061 that this will not be a problem. */
1063 const unsigned char *exp = fs->cfa_exp;
1066 exp = read_uleb128 (exp, &len);
1067 cfa = (void *) (_Unwind_Ptr)
1068 execute_stack_op (exp, exp + len, context, 0);
1077 /* Compute the addresses of all registers saved in this frame. */
1078 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1079 switch (fs->regs.reg[i].how)
1083 case REG_SAVED_OFFSET:
1084 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1087 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1091 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1095 exp = read_uleb128 (exp, &len);
1096 val = execute_stack_op (exp, exp + len, &orig_context,
1098 context->reg[i] = (void *) val;
1104 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1105 of its caller. Update CONTEXT to refer to the caller as well. Note
1106 that the args_size and lsda members are not updated here, but later in
1107 uw_frame_state_for. */
1110 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1112 uw_update_context_1 (context, fs);
1114 /* Compute the return address now, since the return address column
1115 can change from frame to frame. */
1116 context->ra = __builtin_extract_return_addr
1117 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1120 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1121 level will be the return address and the CFA. */
1123 #define uw_init_context(CONTEXT) \
1126 /* Do any necessary initialization to access arbitrary stack frames. \
1127 On the SPARC, this means flushing the register windows. */ \
1128 __builtin_unwind_init (); \
1129 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1130 __builtin_return_address (0)); \
1135 uw_init_context_1 (struct _Unwind_Context *context,
1136 void *outer_cfa, void *outer_ra)
1138 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1139 _Unwind_FrameState fs;
1141 memset (context, 0, sizeof (struct _Unwind_Context));
1144 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1147 /* Force the frame state to use the known cfa value. */
1148 context->cfa = outer_cfa;
1149 fs.cfa_how = CFA_REG_OFFSET;
1153 uw_update_context_1 (context, &fs);
1155 /* If the return address column was saved in a register in the
1156 initialization context, then we can't see it in the given
1157 call frame data. So have the initialization context tell us. */
1158 context->ra = __builtin_extract_return_addr (outer_ra);
1162 /* Install TARGET into CURRENT so that we can return to it. This is a
1163 macro because __builtin_eh_return must be invoked in the context of
1166 #define uw_install_context(CURRENT, TARGET) \
1169 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1170 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1171 __builtin_eh_return (offset, handler); \
1176 init_dwarf_reg_size_table (void)
1178 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1182 uw_install_context_1 (struct _Unwind_Context *current,
1183 struct _Unwind_Context *target)
1189 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1190 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1191 || dwarf_reg_size_table[0] == 0)
1192 init_dwarf_reg_size_table ();
1195 if (dwarf_reg_size_table[0] == 0)
1196 init_dwarf_reg_size_table ();
1199 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1201 void *c = current->reg[i];
1202 void *t = target->reg[i];
1203 if (t && c && t != c)
1204 memcpy (c, t, dwarf_reg_size_table[i]);
1207 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1208 if (STACK_GROWS_DOWNWARD)
1209 return target->cfa - current->cfa + target->args_size;
1211 return current->cfa - target->cfa - target->args_size;
1214 static inline _Unwind_Ptr
1215 uw_identify_context (struct _Unwind_Context *context)
1217 return _Unwind_GetIP (context);
1221 #include "unwind.inc"
1223 #endif /* !USING_SJLJ_EXCEPTIONS */