1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997-2023 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library 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 GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
28 #include <unwind-pe.h>
29 #include <unwind-dw2-fde.h>
35 #include "unwind-pe.h"
36 #include "unwind-dw2-fde.h"
42 #ifndef STACK_GROWS_DOWNWARD
43 #define STACK_GROWS_DOWNWARD 0
45 #undef STACK_GROWS_DOWNWARD
46 #define STACK_GROWS_DOWNWARD 1
49 /* A target can override (perhaps for backward compatibility) how
50 many dwarf2 columns are unwound. */
51 #ifndef DWARF_FRAME_REGISTERS
52 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
55 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
56 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
57 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
60 /* This is the register and unwind state for a particular frame. This
61 provides the information necessary to unwind up past a frame and return
63 struct _Unwind_Context
65 void *reg
[DWARF_FRAME_REGISTERS
+1];
69 struct dwarf_eh_bases bases
;
70 _Unwind_Word args_size
;
74 /* Byte size of every register managed by these routines. */
75 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
79 /* The result of interpreting the frame unwind info for a frame.
80 This is all symbolic at this point, as none of the values can
81 be resolved until the target pc is located. */
84 /* Each register save state can be described in terms of a CFA slot,
85 another register, or a location expression. */
86 struct frame_state_reg_info
92 const unsigned char *exp
;
100 } reg
[DWARF_FRAME_REGISTERS
+1];
102 /* Used to implement DW_CFA_remember_state. */
103 struct frame_state_reg_info
*prev
;
106 /* The CFA can be described in terms of a reg+offset or a
107 location expression. */
108 _Unwind_Sword cfa_offset
;
109 _Unwind_Word cfa_reg
;
110 const unsigned char *cfa_exp
;
117 /* The PC described by the current frame state. */
120 /* The information we care about from the CIE/FDE. */
121 _Unwind_Personality_Fn personality
;
122 _Unwind_Sword data_align
;
123 _Unwind_Word code_align
;
124 unsigned char retaddr_column
;
125 unsigned char fde_encoding
;
126 unsigned char lsda_encoding
;
129 } _Unwind_FrameState
;
131 /* Read unaligned data from the instruction buffer. */
136 unsigned u2
__attribute__ ((mode (HI
)));
137 unsigned u4
__attribute__ ((mode (SI
)));
138 unsigned u8
__attribute__ ((mode (DI
)));
139 signed s2
__attribute__ ((mode (HI
)));
140 signed s4
__attribute__ ((mode (SI
)));
141 signed s8
__attribute__ ((mode (DI
)));
142 } __attribute__ ((packed
));
145 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
148 read_1u (const void *p
) { return *(const unsigned char *) p
; }
151 read_1s (const void *p
) { return *(const signed char *) p
; }
154 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
157 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
159 static inline unsigned int
160 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
163 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
165 static inline unsigned long
166 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
168 static inline unsigned long
169 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
171 /* Get the value of register REG as saved in CONTEXT. */
174 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
176 /* This will segfault if the register hasn't been saved. */
177 return * (_Unwind_Word
*) context
->reg
[index
];
180 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
183 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
185 * (_Unwind_Word
*) context
->reg
[index
] = val
;
188 /* Retrieve the return address for CONTEXT. */
191 _Unwind_GetIP (struct _Unwind_Context
*context
)
193 return (_Unwind_Ptr
) context
->ra
;
196 /* Overwrite the return address for CONTEXT with VAL. */
199 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
201 context
->ra
= (void *) val
;
205 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
207 return context
->lsda
;
211 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
213 return (_Unwind_Ptr
) context
->bases
.func
;
217 _Unwind_FindEnclosingFunction (void *pc
)
219 struct dwarf_eh_bases bases
;
220 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
229 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
231 return (_Unwind_Ptr
) context
->bases
.dbase
;
235 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
237 return (_Unwind_Ptr
) context
->bases
.tbase
;
241 /* Extract any interesting information from the CIE for the translation
242 unit F belongs to. Return a pointer to the byte after the augmentation,
243 or NULL if we encountered an undecipherable augmentation. */
245 static const unsigned char *
246 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
247 _Unwind_FrameState
*fs
)
249 const unsigned char *aug
= cie
->augmentation
;
250 const unsigned char *p
= aug
+ strlen ((const char *) aug
) + 1;
251 const unsigned char *ret
= NULL
;
254 /* g++ v2 "eh" has pointer immediately following augmentation string,
255 so it must be handled first. */
256 if (aug
[0] == 'e' && aug
[1] == 'h')
258 fs
->eh_ptr
= read_pointer (p
);
259 p
+= sizeof (void *);
263 /* Immediately following the augmentation are the code and
264 data alignment and return address column. */
265 p
= read_uleb128 (p
, &fs
->code_align
);
266 p
= read_sleb128 (p
, &fs
->data_align
);
267 fs
->retaddr_column
= *p
++;
268 fs
->lsda_encoding
= DW_EH_PE_omit
;
270 /* If the augmentation starts with 'z', then a uleb128 immediately
271 follows containing the length of the augmentation field following
275 p
= read_uleb128 (p
, &utmp
);
282 /* Iterate over recognized augmentation subsequences. */
285 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
288 fs
->lsda_encoding
= *p
++;
292 /* "R" indicates a byte indicating how FDE addresses are encoded. */
293 else if (aug
[0] == 'R')
295 fs
->fde_encoding
= *p
++;
299 /* "P" indicates a personality routine in the CIE augmentation. */
300 else if (aug
[0] == 'P')
302 _Unwind_Ptr personality
;
303 p
= read_encoded_value (context
, *p
, p
+ 1, &personality
);
304 fs
->personality
= (_Unwind_Personality_Fn
) personality
;
308 /* Otherwise we have an unknown augmentation string.
309 Bail unless we saw a 'z' prefix. */
314 return ret
? ret
: p
;
318 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
319 onto the stack to start. */
322 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
323 struct _Unwind_Context
*context
, _Unwind_Word initial
)
325 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
331 while (op_ptr
< op_end
)
333 enum dwarf_location_atom op
= *op_ptr
++;
334 _Unwind_Word result
, reg
, utmp
;
335 _Unwind_Sword offset
, stmp
;
371 result
= op
- DW_OP_lit0
;
375 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
376 op_ptr
+= sizeof (void *);
380 result
= read_1u (op_ptr
);
384 result
= read_1s (op_ptr
);
388 result
= read_2u (op_ptr
);
392 result
= read_2s (op_ptr
);
396 result
= read_4u (op_ptr
);
400 result
= read_4s (op_ptr
);
404 result
= read_8u (op_ptr
);
408 result
= read_8s (op_ptr
);
412 op_ptr
= read_uleb128 (op_ptr
, &result
);
415 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
451 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
454 op_ptr
= read_uleb128 (op_ptr
, ®
);
455 result
= _Unwind_GetGR (context
, reg
);
490 op_ptr
= read_sleb128 (op_ptr
, &offset
);
491 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
494 op_ptr
= read_uleb128 (op_ptr
, ®
);
495 op_ptr
= read_sleb128 (op_ptr
, &offset
);
496 result
= _Unwind_GetGR (context
, reg
) + offset
;
502 result
= stack
[stack_elt
- 1];
512 if (offset
>= stack_elt
- 1)
514 result
= stack
[stack_elt
- 1 - offset
];
520 result
= stack
[stack_elt
- 2];
525 _Unwind_Word t1
, t2
, t3
;
529 t1
= stack
[stack_elt
- 1];
530 t2
= stack
[stack_elt
- 2];
531 t3
= stack
[stack_elt
- 3];
532 stack
[stack_elt
- 1] = t2
;
533 stack
[stack_elt
- 2] = t3
;
534 stack
[stack_elt
- 3] = t1
;
539 case DW_OP_deref_size
:
543 case DW_OP_plus_uconst
:
544 /* Unary operations. */
547 result
= stack
[stack_elt
];
553 void *ptr
= (void *) (_Unwind_Ptr
) result
;
554 result
= (_Unwind_Ptr
) read_pointer (ptr
);
558 case DW_OP_deref_size
:
560 void *ptr
= (void *) (_Unwind_Ptr
) result
;
564 result
= read_1u (ptr
);
567 result
= read_2u (ptr
);
570 result
= read_4u (ptr
);
573 result
= read_8u (ptr
);
582 if ((_Unwind_Sword
) result
< 0)
591 case DW_OP_plus_uconst
:
592 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
615 /* Binary operations. */
616 _Unwind_Word first
, second
;
617 if ((stack_elt
-= 2) < 0)
619 second
= stack
[stack_elt
];
620 first
= stack
[stack_elt
+ 1];
625 result
= second
& first
;
628 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
631 result
= second
- first
;
634 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
637 result
= second
* first
;
640 result
= second
| first
;
643 result
= second
+ first
;
646 result
= second
<< first
;
649 result
= second
>> first
;
652 result
= (_Unwind_Sword
) second
>> first
;
655 result
= second
^ first
;
658 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
661 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
664 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
667 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
670 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
673 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
683 offset
= read_2s (op_ptr
);
691 offset
= read_2s (op_ptr
);
693 if (stack
[stack_elt
] != 0)
704 /* Most things push a result value. */
705 if ((size_t) stack_elt
>= sizeof (stack
) / sizeof (*stack
))
707 stack
[stack_elt
++] = result
;
711 /* We were executing this program to get a value. It should be
715 return stack
[stack_elt
];
719 /* Decode DWARF 2 call frame information. Takes pointers the
720 instruction sequence to decode, current register information and
721 CIE info, and the PC range to evaluate. */
724 execute_cfa_program (const unsigned char *insn_ptr
,
725 const unsigned char *insn_end
,
726 struct _Unwind_Context
*context
,
727 _Unwind_FrameState
*fs
)
729 struct frame_state_reg_info
*unused_rs
= NULL
;
731 /* Don't allow remember/restore between CIE and FDE programs. */
732 fs
->regs
.prev
= NULL
;
734 /* The comparison with the return address uses < rather than <= because
735 we are only interested in the effects of code before the call; for a
736 noreturn function, the return address may point to unrelated code with
737 a different stack configuration that we are not interested in. We
738 assume that the call itself is unwind info-neutral; if not, or if
739 there are delay instructions that adjust the stack, these must be
740 reflected at the point immediately before the call insn. */
741 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
743 unsigned char insn
= *insn_ptr
++;
744 _Unwind_Word reg
, utmp
;
745 _Unwind_Sword offset
, stmp
;
747 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
748 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
749 else if ((insn
& 0xc0) == DW_CFA_offset
)
752 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
753 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
754 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
755 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
757 else if ((insn
& 0xc0) == DW_CFA_restore
)
760 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
767 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
769 fs
->pc
= (void *) pc
;
773 case DW_CFA_advance_loc1
:
774 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
777 case DW_CFA_advance_loc2
:
778 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
781 case DW_CFA_advance_loc4
:
782 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
786 case DW_CFA_offset_extended
:
787 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
788 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
789 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
790 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
791 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
794 case DW_CFA_restore_extended
:
795 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
796 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
799 case DW_CFA_undefined
:
800 case DW_CFA_same_value
:
801 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
807 case DW_CFA_register
:
810 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
811 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
812 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
813 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
817 case DW_CFA_remember_state
:
819 struct frame_state_reg_info
*new_rs
;
823 unused_rs
= unused_rs
->prev
;
826 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
829 fs
->regs
.prev
= new_rs
;
833 case DW_CFA_restore_state
:
835 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
838 __libc_fatal ("Invalid DWARF unwind data.\n");
843 old_rs
->prev
= unused_rs
;
850 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
851 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
852 fs
->cfa_offset
= utmp
;
853 fs
->cfa_how
= CFA_REG_OFFSET
;
856 case DW_CFA_def_cfa_register
:
857 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
858 fs
->cfa_how
= CFA_REG_OFFSET
;
861 case DW_CFA_def_cfa_offset
:
862 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
863 fs
->cfa_offset
= utmp
;
864 /* cfa_how deliberately not set. */
867 case DW_CFA_def_cfa_expression
:
868 fs
->cfa_exp
= insn_ptr
;
869 fs
->cfa_how
= CFA_EXP
;
870 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
874 case DW_CFA_expression
:
875 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
876 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
877 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
878 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
882 /* From the 2.1 draft. */
883 case DW_CFA_offset_extended_sf
:
884 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
885 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
886 offset
= stmp
* fs
->data_align
;
887 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
888 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
891 case DW_CFA_def_cfa_sf
:
892 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
893 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
894 fs
->cfa_how
= CFA_REG_OFFSET
;
897 case DW_CFA_def_cfa_offset_sf
:
898 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
899 /* cfa_how deliberately not set. */
902 case DW_CFA_GNU_window_save
:
903 /* ??? Hardcoded for SPARC register window configuration.
904 At least do not do anything for archs which explicitly
905 define a lower register number. */
906 #if DWARF_FRAME_REGISTERS >= 32
907 for (reg
= 16; reg
< 32; ++reg
)
909 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
910 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
915 case DW_CFA_GNU_args_size
:
916 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
919 case DW_CFA_GNU_negative_offset_extended
:
920 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
921 older PowerPC code. */
922 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
923 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
924 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
925 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
926 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
935 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
936 its caller and decode it into FS. This function also sets the
937 args_size and lsda members of CONTEXT, as they are really information
938 about the caller's frame. */
940 static _Unwind_Reason_Code
941 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
943 struct dwarf_fde
*fde
;
944 struct dwarf_cie
*cie
;
945 const unsigned char *aug
, *insn
, *end
;
947 memset (fs
, 0, sizeof (*fs
));
948 context
->args_size
= 0;
951 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
954 /* Couldn't find frame unwind info for this function. Try a
955 target-specific fallback mechanism. This will necessarily
956 not provide a personality routine or LSDA. */
957 #ifdef MD_FALLBACK_FRAME_STATE_FOR
958 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
959 return _URC_END_OF_STACK
;
961 return _URC_NO_REASON
;
963 return _URC_END_OF_STACK
;
967 fs
->pc
= context
->bases
.func
;
970 insn
= extract_cie_info (cie
, context
, fs
);
972 /* CIE contained unknown augmentation. */
973 return _URC_FATAL_PHASE1_ERROR
;
975 /* First decode all the insns in the CIE. */
976 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
977 execute_cfa_program (insn
, end
, context
, fs
);
979 /* Locate augmentation for the fde. */
980 aug
= (unsigned char *) fde
+ sizeof (*fde
);
981 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
986 aug
= read_uleb128 (aug
, &i
);
989 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
992 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
, &lsda
);
993 context
->lsda
= (void *) lsda
;
996 /* Then the insns in the FDE up to our target PC. */
999 end
= (unsigned char *) next_fde (fde
);
1000 execute_cfa_program (insn
, end
, context
, fs
);
1002 return _URC_NO_REASON
;
1005 typedef struct frame_state
1011 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1012 unsigned short cfa_reg
;
1013 unsigned short retaddr_column
;
1014 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1022 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1024 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1025 a given PC_TARGET. The caller should allocate a local variable of
1026 `struct frame_state' and pass its address to STATE_IN. */
1029 struct frame_state
*
1030 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1032 struct _Unwind_Context context
;
1033 _Unwind_FrameState fs
;
1036 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1037 context
.ra
= pc_target
+ 1;
1039 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1042 /* We have no way to pass a location expression for the CFA to our
1043 caller. It wouldn't understand it anyway. */
1044 if (fs
.cfa_how
== CFA_EXP
)
1047 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1049 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1050 switch (state_in
->saved
[reg
])
1053 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1055 case REG_SAVED_OFFSET
:
1056 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1059 state_in
->reg_or_offset
[reg
] = 0;
1064 state_in
->cfa_offset
= fs
.cfa_offset
;
1065 state_in
->cfa_reg
= fs
.cfa_reg
;
1066 state_in
->retaddr_column
= fs
.retaddr_column
;
1067 state_in
->args_size
= context
.args_size
;
1068 state_in
->eh_ptr
= fs
.eh_ptr
;
1076 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1078 struct _Unwind_Context orig_context
= *context
;
1082 #ifdef EH_RETURN_STACKADJ_RTX
1083 /* Special handling here: Many machines do not use a frame pointer,
1084 and track the CFA only through offsets from the stack pointer from
1085 one frame to the next. In this case, the stack pointer is never
1086 stored, so it has no saved address in the context. What we do
1087 have is the CFA from the previous stack frame.
1089 In very special situations (such as unwind info for signal return),
1090 there may be location expressions that use the stack pointer as well.
1092 Do this conditionally for one frame. This allows the unwind info
1093 for one frame to save a copy of the stack pointer from the previous
1094 frame, and be able to use much easier CFA mechanisms to do it.
1095 Always zap the saved stack pointer value for the next frame; carrying
1096 the value over from one frame to another doesn't make sense. */
1098 _Unwind_Word tmp_sp
;
1100 if (!orig_context
.reg
[__builtin_dwarf_sp_column ()])
1102 tmp_sp
= (_Unwind_Ptr
) context
->cfa
;
1103 orig_context
.reg
[__builtin_dwarf_sp_column ()] = &tmp_sp
;
1105 context
->reg
[__builtin_dwarf_sp_column ()] = NULL
;
1108 /* Compute this frame's CFA. */
1109 switch (fs
->cfa_how
)
1111 case CFA_REG_OFFSET
:
1112 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (&orig_context
, fs
->cfa_reg
);
1113 cfa
+= fs
->cfa_offset
;
1118 const unsigned char *exp
= fs
->cfa_exp
;
1121 exp
= read_uleb128 (exp
, &len
);
1122 cfa
= (void *) (_Unwind_Ptr
)
1123 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1132 /* Compute the addresses of all registers saved in this frame. */
1133 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1134 switch (fs
->regs
.reg
[i
].how
)
1139 case REG_SAVED_OFFSET
:
1140 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
1144 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
1149 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1153 exp
= read_uleb128 (exp
, &len
);
1154 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1156 context
->reg
[i
] = (void *) val
;
1162 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1163 of its caller. Update CONTEXT to refer to the caller as well. Note
1164 that the args_size and lsda members are not updated here, but later in
1165 uw_frame_state_for. */
1168 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1170 uw_update_context_1 (context
, fs
);
1172 /* Compute the return address now, since the return address column
1173 can change from frame to frame. */
1174 context
->ra
= __builtin_extract_return_addr
1175 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1178 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1179 level will be the return address and the CFA. */
1181 #define uw_init_context(CONTEXT) \
1184 /* Do any necessary initialization to access arbitrary stack frames. \
1185 On the SPARC, this means flushing the register windows. */ \
1186 __builtin_unwind_init (); \
1187 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1188 __builtin_return_address (0)); \
1193 uw_init_context_1 (struct _Unwind_Context
*context
,
1194 void *outer_cfa
, void *outer_ra
)
1196 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1197 _Unwind_FrameState fs
;
1198 _Unwind_Word sp_slot
;
1200 memset (context
, 0, sizeof (struct _Unwind_Context
));
1203 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1206 /* Force the frame state to use the known cfa value. */
1207 sp_slot
= (_Unwind_Ptr
) outer_cfa
;
1208 context
->reg
[__builtin_dwarf_sp_column ()] = &sp_slot
;
1209 fs
.cfa_how
= CFA_REG_OFFSET
;
1210 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1213 uw_update_context_1 (context
, &fs
);
1215 /* If the return address column was saved in a register in the
1216 initialization context, then we can't see it in the given
1217 call frame data. So have the initialization context tell us. */
1218 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1222 /* Install TARGET into CURRENT so that we can return to it. This is a
1223 macro because __builtin_eh_return must be invoked in the context of
1226 #define uw_install_context(CURRENT, TARGET) \
1229 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1230 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1231 __builtin_eh_return (offset, handler); \
1236 init_dwarf_reg_size_table (void)
1238 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1242 uw_install_context_1 (struct _Unwind_Context
*current
,
1243 struct _Unwind_Context
*target
)
1249 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1250 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1251 || dwarf_reg_size_table
[0] == 0)
1252 init_dwarf_reg_size_table ();
1255 if (dwarf_reg_size_table
[0] == 0)
1256 init_dwarf_reg_size_table ();
1259 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1261 void *c
= current
->reg
[i
];
1262 void *t
= target
->reg
[i
];
1263 if (t
&& c
&& t
!= c
)
1264 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1267 #ifdef EH_RETURN_STACKADJ_RTX
1271 /* If the last frame records a saved stack pointer, use it. */
1272 if (target
->reg
[__builtin_dwarf_sp_column ()])
1273 target_cfa
= (void *)(_Unwind_Ptr
)
1274 _Unwind_GetGR (target
, __builtin_dwarf_sp_column ());
1276 target_cfa
= target
->cfa
;
1278 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1279 if (STACK_GROWS_DOWNWARD
)
1280 return target_cfa
- current
->cfa
+ target
->args_size
;
1282 return current
->cfa
- target_cfa
- target
->args_size
;
1289 static inline _Unwind_Ptr
1290 uw_identify_context (struct _Unwind_Context
*context
)
1292 return _Unwind_GetIP (context
);
1296 #include "unwind.inc"