1af526226Smrg /* DWARF2 exception handling and frame unwind runtime interface routines.
2*2f055536Smrg    Copyright (C) 1997-2020 Free Software Foundation, Inc.
3af526226Smrg 
4af526226Smrg    This file is part of GCC.
5af526226Smrg 
6af526226Smrg    GCC is free software; you can redistribute it and/or modify it
7af526226Smrg    under the terms of the GNU General Public License as published by
8af526226Smrg    the Free Software Foundation; either version 3, or (at your option)
9af526226Smrg    any later version.
10af526226Smrg 
11af526226Smrg    GCC is distributed in the hope that it will be useful, but WITHOUT
12af526226Smrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13af526226Smrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14af526226Smrg    License for more details.
15af526226Smrg 
16af526226Smrg    Under Section 7 of GPL version 3, you are granted additional
17af526226Smrg    permissions described in the GCC Runtime Library Exception, version
18af526226Smrg    3.1, as published by the Free Software Foundation.
19af526226Smrg 
20af526226Smrg    You should have received a copy of the GNU General Public License and
21af526226Smrg    a copy of the GCC Runtime Library Exception along with this program;
22af526226Smrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23af526226Smrg    <http://www.gnu.org/licenses/>.  */
24af526226Smrg 
25af526226Smrg #include "tconfig.h"
26af526226Smrg #include "tsystem.h"
27af526226Smrg #include "coretypes.h"
28af526226Smrg #include "tm.h"
29af526226Smrg #include "libgcc_tm.h"
30af526226Smrg #include "dwarf2.h"
31af526226Smrg #include "unwind.h"
32af526226Smrg #ifdef __USING_SJLJ_EXCEPTIONS__
33af526226Smrg # define NO_SIZE_OF_ENCODED_VALUE
34af526226Smrg #endif
35af526226Smrg #include "unwind-pe.h"
36af526226Smrg #include "unwind-dw2-fde.h"
37af526226Smrg #include "gthr.h"
38af526226Smrg #include "unwind-dw2.h"
39af526226Smrg 
40af526226Smrg #ifdef HAVE_SYS_SDT_H
41af526226Smrg #include <sys/sdt.h>
42af526226Smrg #endif
43af526226Smrg 
44af526226Smrg #ifndef __USING_SJLJ_EXCEPTIONS__
45af526226Smrg 
464646d632Smrg #ifndef __LIBGCC_STACK_GROWS_DOWNWARD__
474646d632Smrg #define __LIBGCC_STACK_GROWS_DOWNWARD__ 0
48af526226Smrg #else
494646d632Smrg #undef __LIBGCC_STACK_GROWS_DOWNWARD__
504646d632Smrg #define __LIBGCC_STACK_GROWS_DOWNWARD__ 1
51af526226Smrg #endif
52af526226Smrg 
53af526226Smrg /* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
54af526226Smrg #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
554646d632Smrg #define PRE_GCC3_DWARF_FRAME_REGISTERS __LIBGCC_DWARF_FRAME_REGISTERS__
56af526226Smrg #endif
57af526226Smrg 
58af526226Smrg /* ??? For the public function interfaces, we tend to gcc_assert that the
59af526226Smrg    column numbers are in range.  For the dwarf2 unwind info this does happen,
60af526226Smrg    although so far in a case that doesn't actually matter.
61af526226Smrg 
62af526226Smrg    See PR49146, in which a call from x86_64 ms abi to x86_64 unix abi stores
63af526226Smrg    the call-saved xmm registers and annotates them.  We havn't bothered
64af526226Smrg    providing support for the xmm registers for the x86_64 port primarily
65af526226Smrg    because the 64-bit windows targets don't use dwarf2 unwind, using sjlj or
66af526226Smrg    SEH instead.  Adding the support for unix targets would generally be a
67af526226Smrg    waste.  However, some runtime libraries supplied with ICC do contain such
68af526226Smrg    an unorthodox transition, as well as the unwind info to match.  This loss
69af526226Smrg    of register restoration doesn't matter in practice, because the exception
70af526226Smrg    is caught in the native unix abi, where all of the xmm registers are
71af526226Smrg    call clobbered.
72af526226Smrg 
73af526226Smrg    Ideally, we'd record some bit to notice when we're failing to restore some
74af526226Smrg    register recorded in the unwind info, but to do that we need annotation on
75af526226Smrg    the unix->ms abi edge, so that we know when the register data may be
76af526226Smrg    discarded.  And since this edge is also within the ICC library, we're
77af526226Smrg    unlikely to be able to get the new annotation.
78af526226Smrg 
79af526226Smrg    Barring a magic solution to restore the ms abi defined 128-bit xmm registers
80af526226Smrg    (as distictly opposed to the full runtime width) without causing extra
81af526226Smrg    overhead for normal unix abis, the best solution seems to be to simply
82af526226Smrg    ignore unwind data for unknown columns.  */
83af526226Smrg 
84af526226Smrg #define UNWIND_COLUMN_IN_RANGE(x) \
854646d632Smrg     __builtin_expect((x) <= __LIBGCC_DWARF_FRAME_REGISTERS__, 1)
86af526226Smrg 
87af526226Smrg #ifdef REG_VALUE_IN_UNWIND_CONTEXT
88af526226Smrg typedef _Unwind_Word _Unwind_Context_Reg_Val;
89af526226Smrg 
90af526226Smrg #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
91af526226Smrg #define ASSUME_EXTENDED_UNWIND_CONTEXT 1
92af526226Smrg #endif
93af526226Smrg 
94af526226Smrg static inline _Unwind_Word
_Unwind_Get_Unwind_Word(_Unwind_Context_Reg_Val val)95af526226Smrg _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
96af526226Smrg {
97af526226Smrg   return val;
98af526226Smrg }
99af526226Smrg 
100af526226Smrg static inline _Unwind_Context_Reg_Val
_Unwind_Get_Unwind_Context_Reg_Val(_Unwind_Word val)101af526226Smrg _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
102af526226Smrg {
103af526226Smrg   return val;
104af526226Smrg }
105af526226Smrg #else
106af526226Smrg typedef void *_Unwind_Context_Reg_Val;
107af526226Smrg 
108af526226Smrg static inline _Unwind_Word
_Unwind_Get_Unwind_Word(_Unwind_Context_Reg_Val val)109af526226Smrg _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
110af526226Smrg {
111af526226Smrg   return (_Unwind_Word) (_Unwind_Internal_Ptr) val;
112af526226Smrg }
113af526226Smrg 
114af526226Smrg static inline _Unwind_Context_Reg_Val
_Unwind_Get_Unwind_Context_Reg_Val(_Unwind_Word val)115af526226Smrg _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
116af526226Smrg {
117af526226Smrg   return (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) val;
118af526226Smrg }
119af526226Smrg #endif
120af526226Smrg 
121af526226Smrg #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
122af526226Smrg #define ASSUME_EXTENDED_UNWIND_CONTEXT 0
123af526226Smrg #endif
124af526226Smrg 
125af526226Smrg /* This is the register and unwind state for a particular frame.  This
126af526226Smrg    provides the information necessary to unwind up past a frame and return
127af526226Smrg    to its caller.  */
128af526226Smrg struct _Unwind_Context
129af526226Smrg {
1304646d632Smrg   _Unwind_Context_Reg_Val reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
131af526226Smrg   void *cfa;
132af526226Smrg   void *ra;
133af526226Smrg   void *lsda;
134af526226Smrg   struct dwarf_eh_bases bases;
135af526226Smrg   /* Signal frame context.  */
136af526226Smrg #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
137af526226Smrg   /* Context which has version/args_size/by_value fields.  */
138af526226Smrg #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
139*2f055536Smrg   /* Bit reserved on AArch64, return address has been signed with A or B
140*2f055536Smrg      key.  */
141*2f055536Smrg #define RA_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
142af526226Smrg   _Unwind_Word flags;
143af526226Smrg   /* 0 for now, can be increased when further fields are added to
144af526226Smrg      struct _Unwind_Context.  */
145af526226Smrg   _Unwind_Word version;
146af526226Smrg   _Unwind_Word args_size;
1474646d632Smrg   char by_value[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
148af526226Smrg };
149af526226Smrg 
150af526226Smrg /* Byte size of every register managed by these routines.  */
1514646d632Smrg static unsigned char dwarf_reg_size_table[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
152af526226Smrg 
153af526226Smrg 
154af526226Smrg /* Read unaligned data from the instruction buffer.  */
155af526226Smrg 
156af526226Smrg union unaligned
157af526226Smrg {
158af526226Smrg   void *p;
159af526226Smrg   unsigned u2 __attribute__ ((mode (HI)));
160af526226Smrg   unsigned u4 __attribute__ ((mode (SI)));
161af526226Smrg   unsigned u8 __attribute__ ((mode (DI)));
162af526226Smrg   signed s2 __attribute__ ((mode (HI)));
163af526226Smrg   signed s4 __attribute__ ((mode (SI)));
164af526226Smrg   signed s8 __attribute__ ((mode (DI)));
165af526226Smrg } __attribute__ ((packed));
166af526226Smrg 
167af526226Smrg static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
168af526226Smrg static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
169af526226Smrg 					       _Unwind_FrameState *);
170af526226Smrg 
171af526226Smrg static inline void *
read_pointer(const void * p)172af526226Smrg read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
173af526226Smrg 
174af526226Smrg static inline int
read_1u(const void * p)175af526226Smrg read_1u (const void *p) { return *(const unsigned char *) p; }
176af526226Smrg 
177af526226Smrg static inline int
read_1s(const void * p)178af526226Smrg read_1s (const void *p) { return *(const signed char *) p; }
179af526226Smrg 
180af526226Smrg static inline int
read_2u(const void * p)181af526226Smrg read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
182af526226Smrg 
183af526226Smrg static inline int
read_2s(const void * p)184af526226Smrg read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
185af526226Smrg 
186af526226Smrg static inline unsigned int
read_4u(const void * p)187af526226Smrg read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
188af526226Smrg 
189af526226Smrg static inline int
read_4s(const void * p)190af526226Smrg read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
191af526226Smrg 
192af526226Smrg static inline unsigned long
read_8u(const void * p)193af526226Smrg read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
194af526226Smrg 
195af526226Smrg static inline unsigned long
read_8s(const void * p)196af526226Smrg read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
197af526226Smrg 
198af526226Smrg static inline _Unwind_Word
_Unwind_IsSignalFrame(struct _Unwind_Context * context)199af526226Smrg _Unwind_IsSignalFrame (struct _Unwind_Context *context)
200af526226Smrg {
201af526226Smrg   return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
202af526226Smrg }
203af526226Smrg 
204af526226Smrg static inline void
_Unwind_SetSignalFrame(struct _Unwind_Context * context,int val)205af526226Smrg _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
206af526226Smrg {
207af526226Smrg   if (val)
208af526226Smrg     context->flags |= SIGNAL_FRAME_BIT;
209af526226Smrg   else
210af526226Smrg     context->flags &= ~SIGNAL_FRAME_BIT;
211af526226Smrg }
212af526226Smrg 
213af526226Smrg static inline _Unwind_Word
_Unwind_IsExtendedContext(struct _Unwind_Context * context)214af526226Smrg _Unwind_IsExtendedContext (struct _Unwind_Context *context)
215af526226Smrg {
216af526226Smrg   return (ASSUME_EXTENDED_UNWIND_CONTEXT
217af526226Smrg 	  || (context->flags & EXTENDED_CONTEXT_BIT));
218af526226Smrg }
219af526226Smrg 
220e56e5d0aSmrg /* Get the value of register REGNO as saved in CONTEXT.  */
221af526226Smrg 
222af526226Smrg inline _Unwind_Word
_Unwind_GetGR(struct _Unwind_Context * context,int regno)223e56e5d0aSmrg _Unwind_GetGR (struct _Unwind_Context *context, int regno)
224af526226Smrg {
225e56e5d0aSmrg   int size, index;
226af526226Smrg   _Unwind_Context_Reg_Val val;
227af526226Smrg 
228af526226Smrg #ifdef DWARF_ZERO_REG
229e56e5d0aSmrg   if (regno == DWARF_ZERO_REG)
230af526226Smrg     return 0;
231af526226Smrg #endif
232af526226Smrg 
233e56e5d0aSmrg   index = DWARF_REG_TO_UNWIND_COLUMN (regno);
234af526226Smrg   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
235af526226Smrg   size = dwarf_reg_size_table[index];
236af526226Smrg   val = context->reg[index];
237af526226Smrg 
238af526226Smrg   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
239af526226Smrg     return _Unwind_Get_Unwind_Word (val);
240af526226Smrg 
241e56e5d0aSmrg #ifdef DWARF_LAZY_REGISTER_VALUE
242e56e5d0aSmrg   {
243e56e5d0aSmrg     _Unwind_Word value;
244e56e5d0aSmrg     if (DWARF_LAZY_REGISTER_VALUE (regno, &value))
245e56e5d0aSmrg       return value;
246e56e5d0aSmrg   }
247e56e5d0aSmrg #endif
248e56e5d0aSmrg 
249af526226Smrg   /* This will segfault if the register hasn't been saved.  */
250af526226Smrg   if (size == sizeof(_Unwind_Ptr))
251af526226Smrg     return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
252af526226Smrg   else
253af526226Smrg     {
254af526226Smrg       gcc_assert (size == sizeof(_Unwind_Word));
255af526226Smrg       return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val;
256af526226Smrg     }
257af526226Smrg }
258af526226Smrg 
259af526226Smrg static inline void *
_Unwind_GetPtr(struct _Unwind_Context * context,int index)260af526226Smrg _Unwind_GetPtr (struct _Unwind_Context *context, int index)
261af526226Smrg {
262af526226Smrg   return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
263af526226Smrg }
264af526226Smrg 
265af526226Smrg /* Get the value of the CFA as saved in CONTEXT.  */
266af526226Smrg 
267af526226Smrg _Unwind_Word
_Unwind_GetCFA(struct _Unwind_Context * context)268af526226Smrg _Unwind_GetCFA (struct _Unwind_Context *context)
269af526226Smrg {
270af526226Smrg   return (_Unwind_Ptr) context->cfa;
271af526226Smrg }
272af526226Smrg 
273af526226Smrg /* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
274af526226Smrg 
275af526226Smrg inline void
_Unwind_SetGR(struct _Unwind_Context * context,int index,_Unwind_Word val)276af526226Smrg _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
277af526226Smrg {
278af526226Smrg   int size;
279af526226Smrg   void *ptr;
280af526226Smrg 
281af526226Smrg   index = DWARF_REG_TO_UNWIND_COLUMN (index);
282af526226Smrg   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
283af526226Smrg   size = dwarf_reg_size_table[index];
284af526226Smrg 
285af526226Smrg   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
286af526226Smrg     {
287af526226Smrg       context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
288af526226Smrg       return;
289af526226Smrg     }
290af526226Smrg 
291af526226Smrg   ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
292af526226Smrg 
293af526226Smrg   if (size == sizeof(_Unwind_Ptr))
294af526226Smrg     * (_Unwind_Ptr *) ptr = val;
295af526226Smrg   else
296af526226Smrg     {
297af526226Smrg       gcc_assert (size == sizeof(_Unwind_Word));
298af526226Smrg       * (_Unwind_Word *) ptr = val;
299af526226Smrg     }
300af526226Smrg }
301af526226Smrg 
302af526226Smrg /* Get the pointer to a register INDEX as saved in CONTEXT.  */
303af526226Smrg 
304af526226Smrg static inline void *
_Unwind_GetGRPtr(struct _Unwind_Context * context,int index)305af526226Smrg _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
306af526226Smrg {
307af526226Smrg   index = DWARF_REG_TO_UNWIND_COLUMN (index);
308af526226Smrg   if (_Unwind_IsExtendedContext (context) && context->by_value[index])
309af526226Smrg     return &context->reg[index];
310af526226Smrg   return (void *) (_Unwind_Internal_Ptr) context->reg[index];
311af526226Smrg }
312af526226Smrg 
313af526226Smrg /* Set the pointer to a register INDEX as saved in CONTEXT.  */
314af526226Smrg 
315af526226Smrg static inline void
_Unwind_SetGRPtr(struct _Unwind_Context * context,int index,void * p)316af526226Smrg _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
317af526226Smrg {
318af526226Smrg   index = DWARF_REG_TO_UNWIND_COLUMN (index);
319af526226Smrg   if (_Unwind_IsExtendedContext (context))
320af526226Smrg     context->by_value[index] = 0;
321af526226Smrg   context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
322af526226Smrg }
323af526226Smrg 
324af526226Smrg /* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
325af526226Smrg 
326af526226Smrg static inline void
_Unwind_SetGRValue(struct _Unwind_Context * context,int index,_Unwind_Word val)327af526226Smrg _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
328af526226Smrg 		    _Unwind_Word val)
329af526226Smrg {
330af526226Smrg   index = DWARF_REG_TO_UNWIND_COLUMN (index);
331af526226Smrg   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
332af526226Smrg   /* Return column size may be smaller than _Unwind_Context_Reg_Val.  */
333af526226Smrg   gcc_assert (dwarf_reg_size_table[index] <= sizeof (_Unwind_Context_Reg_Val));
334af526226Smrg 
335af526226Smrg   context->by_value[index] = 1;
336af526226Smrg   context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
337af526226Smrg }
338af526226Smrg 
339af526226Smrg /* Return nonzero if register INDEX is stored by value rather than
340af526226Smrg    by reference.  */
341af526226Smrg 
342af526226Smrg static inline int
_Unwind_GRByValue(struct _Unwind_Context * context,int index)343af526226Smrg _Unwind_GRByValue (struct _Unwind_Context *context, int index)
344af526226Smrg {
345af526226Smrg   index = DWARF_REG_TO_UNWIND_COLUMN (index);
346af526226Smrg   return context->by_value[index];
347af526226Smrg }
348af526226Smrg 
349af526226Smrg /* Retrieve the return address for CONTEXT.  */
350af526226Smrg 
351af526226Smrg inline _Unwind_Ptr
_Unwind_GetIP(struct _Unwind_Context * context)352af526226Smrg _Unwind_GetIP (struct _Unwind_Context *context)
353af526226Smrg {
354af526226Smrg   return (_Unwind_Ptr) context->ra;
355af526226Smrg }
356af526226Smrg 
357af526226Smrg /* Retrieve the return address and flag whether that IP is before
358af526226Smrg    or after first not yet fully executed instruction.  */
359af526226Smrg 
360af526226Smrg inline _Unwind_Ptr
_Unwind_GetIPInfo(struct _Unwind_Context * context,int * ip_before_insn)361af526226Smrg _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
362af526226Smrg {
363af526226Smrg   *ip_before_insn = _Unwind_IsSignalFrame (context);
364af526226Smrg   return (_Unwind_Ptr) context->ra;
365af526226Smrg }
366af526226Smrg 
367af526226Smrg /* Overwrite the return address for CONTEXT with VAL.  */
368af526226Smrg 
369af526226Smrg inline void
_Unwind_SetIP(struct _Unwind_Context * context,_Unwind_Ptr val)370af526226Smrg _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
371af526226Smrg {
372af526226Smrg   context->ra = (void *) val;
373af526226Smrg }
374af526226Smrg 
375f062cf65Sjoerg _Unwind_Ptr
_Unwind_GetLanguageSpecificData(struct _Unwind_Context * context)376af526226Smrg _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
377af526226Smrg {
3784564265fSjoerg   return (_Unwind_Ptr) context->lsda;
379af526226Smrg }
380af526226Smrg 
381af526226Smrg _Unwind_Ptr
_Unwind_GetRegionStart(struct _Unwind_Context * context)382af526226Smrg _Unwind_GetRegionStart (struct _Unwind_Context *context)
383af526226Smrg {
384af526226Smrg   return (_Unwind_Ptr) context->bases.func;
385af526226Smrg }
386af526226Smrg 
387af526226Smrg void *
_Unwind_FindEnclosingFunction(void * pc)388af526226Smrg _Unwind_FindEnclosingFunction (void *pc)
389af526226Smrg {
390af526226Smrg   struct dwarf_eh_bases bases;
391af526226Smrg   const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
392af526226Smrg   if (fde)
393af526226Smrg     return bases.func;
394af526226Smrg   else
395af526226Smrg     return NULL;
396af526226Smrg }
397af526226Smrg 
398af526226Smrg #ifndef __ia64__
399af526226Smrg _Unwind_Ptr
_Unwind_GetDataRelBase(struct _Unwind_Context * context)400af526226Smrg _Unwind_GetDataRelBase (struct _Unwind_Context *context)
401af526226Smrg {
402af526226Smrg   return (_Unwind_Ptr) context->bases.dbase;
403af526226Smrg }
404af526226Smrg 
405af526226Smrg _Unwind_Ptr
_Unwind_GetTextRelBase(struct _Unwind_Context * context)406af526226Smrg _Unwind_GetTextRelBase (struct _Unwind_Context *context)
407af526226Smrg {
408af526226Smrg   return (_Unwind_Ptr) context->bases.tbase;
409af526226Smrg }
410af526226Smrg #endif
411af526226Smrg 
412af526226Smrg #include "md-unwind-support.h"
413af526226Smrg 
414af526226Smrg /* Extract any interesting information from the CIE for the translation
415af526226Smrg    unit F belongs to.  Return a pointer to the byte after the augmentation,
416af526226Smrg    or NULL if we encountered an undecipherable augmentation.  */
417af526226Smrg 
418af526226Smrg static const unsigned char *
extract_cie_info(const struct dwarf_cie * cie,struct _Unwind_Context * context,_Unwind_FrameState * fs)419af526226Smrg extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
420af526226Smrg 		  _Unwind_FrameState *fs)
421af526226Smrg {
422af526226Smrg   const unsigned char *aug = cie->augmentation;
423af526226Smrg   const unsigned char *p = aug + strlen ((const char *)aug) + 1;
424af526226Smrg   const unsigned char *ret = NULL;
425af526226Smrg   _uleb128_t utmp;
426af526226Smrg   _sleb128_t stmp;
427af526226Smrg 
428af526226Smrg   /* g++ v2 "eh" has pointer immediately following augmentation string,
429af526226Smrg      so it must be handled first.  */
430af526226Smrg   if (aug[0] == 'e' && aug[1] == 'h')
431af526226Smrg     {
432af526226Smrg       fs->eh_ptr = read_pointer (p);
433af526226Smrg       p += sizeof (void *);
434af526226Smrg       aug += 2;
435af526226Smrg     }
436af526226Smrg 
437af526226Smrg   /* After the augmentation resp. pointer for "eh" augmentation
438af526226Smrg      follows for CIE version >= 4 address size byte and
439af526226Smrg      segment size byte.  */
440af526226Smrg   if (__builtin_expect (cie->version >= 4, 0))
441af526226Smrg     {
442af526226Smrg       if (p[0] != sizeof (void *) || p[1] != 0)
443af526226Smrg 	return NULL;
444af526226Smrg       p += 2;
445af526226Smrg     }
446af526226Smrg   /* Immediately following this are the code and
447af526226Smrg      data alignment and return address column.  */
448af526226Smrg   p = read_uleb128 (p, &utmp);
449af526226Smrg   fs->code_align = (_Unwind_Word)utmp;
450af526226Smrg   p = read_sleb128 (p, &stmp);
451af526226Smrg   fs->data_align = (_Unwind_Sword)stmp;
452af526226Smrg   if (cie->version == 1)
453af526226Smrg     fs->retaddr_column = *p++;
454af526226Smrg   else
455af526226Smrg     {
456af526226Smrg       p = read_uleb128 (p, &utmp);
457af526226Smrg       fs->retaddr_column = (_Unwind_Word)utmp;
458af526226Smrg     }
459af526226Smrg   fs->lsda_encoding = DW_EH_PE_omit;
460af526226Smrg 
461af526226Smrg   /* If the augmentation starts with 'z', then a uleb128 immediately
462af526226Smrg      follows containing the length of the augmentation field following
463af526226Smrg      the size.  */
464af526226Smrg   if (*aug == 'z')
465af526226Smrg     {
466af526226Smrg       p = read_uleb128 (p, &utmp);
467af526226Smrg       ret = p + utmp;
468af526226Smrg 
469af526226Smrg       fs->saw_z = 1;
470af526226Smrg       ++aug;
471af526226Smrg     }
472af526226Smrg 
473af526226Smrg   /* Iterate over recognized augmentation subsequences.  */
474af526226Smrg   while (*aug != '\0')
475af526226Smrg     {
476af526226Smrg       /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
477af526226Smrg       if (aug[0] == 'L')
478af526226Smrg 	{
479af526226Smrg 	  fs->lsda_encoding = *p++;
480af526226Smrg 	  aug += 1;
481af526226Smrg 	}
482af526226Smrg 
483af526226Smrg       /* "R" indicates a byte indicating how FDE addresses are encoded.  */
484af526226Smrg       else if (aug[0] == 'R')
485af526226Smrg 	{
486af526226Smrg 	  fs->fde_encoding = *p++;
487af526226Smrg 	  aug += 1;
488af526226Smrg 	}
489af526226Smrg 
490af526226Smrg       /* "P" indicates a personality routine in the CIE augmentation.  */
491af526226Smrg       else if (aug[0] == 'P')
492af526226Smrg 	{
493af526226Smrg 	  _Unwind_Ptr personality;
494af526226Smrg 
495af526226Smrg 	  p = read_encoded_value (context, *p, p + 1, &personality);
496af526226Smrg 	  fs->personality = (_Unwind_Personality_Fn) personality;
497af526226Smrg 	  aug += 1;
498af526226Smrg 	}
499af526226Smrg 
500af526226Smrg       /* "S" indicates a signal frame.  */
501af526226Smrg       else if (aug[0] == 'S')
502af526226Smrg 	{
503af526226Smrg 	  fs->signal_frame = 1;
504af526226Smrg 	  aug += 1;
505af526226Smrg 	}
506*2f055536Smrg       /* aarch64 B-key pointer authentication.  */
507*2f055536Smrg       else if (aug[0] == 'B')
508*2f055536Smrg 	{
509*2f055536Smrg 	  aug += 1;
510*2f055536Smrg       }
511af526226Smrg 
512af526226Smrg       /* Otherwise we have an unknown augmentation string.
513af526226Smrg 	 Bail unless we saw a 'z' prefix.  */
514af526226Smrg       else
515af526226Smrg 	return ret;
516af526226Smrg     }
517af526226Smrg 
518af526226Smrg   return ret ? ret : p;
519af526226Smrg }
520af526226Smrg 
521af526226Smrg 
522af526226Smrg /* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
523af526226Smrg    onto the stack to start.  */
524af526226Smrg 
525af526226Smrg static _Unwind_Word
execute_stack_op(const unsigned char * op_ptr,const unsigned char * op_end,struct _Unwind_Context * context,_Unwind_Word initial)526af526226Smrg execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
527af526226Smrg 		  struct _Unwind_Context *context, _Unwind_Word initial)
528af526226Smrg {
529af526226Smrg   _Unwind_Word stack[64];	/* ??? Assume this is enough.  */
530af526226Smrg   int stack_elt;
531af526226Smrg 
532af526226Smrg   stack[0] = initial;
533af526226Smrg   stack_elt = 1;
534af526226Smrg 
535af526226Smrg   while (op_ptr < op_end)
536af526226Smrg     {
537af526226Smrg       enum dwarf_location_atom op = *op_ptr++;
538af526226Smrg       _Unwind_Word result;
539af526226Smrg       _uleb128_t reg, utmp;
540af526226Smrg       _sleb128_t offset, stmp;
541af526226Smrg 
542af526226Smrg       switch (op)
543af526226Smrg 	{
544af526226Smrg 	case DW_OP_lit0:
545af526226Smrg 	case DW_OP_lit1:
546af526226Smrg 	case DW_OP_lit2:
547af526226Smrg 	case DW_OP_lit3:
548af526226Smrg 	case DW_OP_lit4:
549af526226Smrg 	case DW_OP_lit5:
550af526226Smrg 	case DW_OP_lit6:
551af526226Smrg 	case DW_OP_lit7:
552af526226Smrg 	case DW_OP_lit8:
553af526226Smrg 	case DW_OP_lit9:
554af526226Smrg 	case DW_OP_lit10:
555af526226Smrg 	case DW_OP_lit11:
556af526226Smrg 	case DW_OP_lit12:
557af526226Smrg 	case DW_OP_lit13:
558af526226Smrg 	case DW_OP_lit14:
559af526226Smrg 	case DW_OP_lit15:
560af526226Smrg 	case DW_OP_lit16:
561af526226Smrg 	case DW_OP_lit17:
562af526226Smrg 	case DW_OP_lit18:
563af526226Smrg 	case DW_OP_lit19:
564af526226Smrg 	case DW_OP_lit20:
565af526226Smrg 	case DW_OP_lit21:
566af526226Smrg 	case DW_OP_lit22:
567af526226Smrg 	case DW_OP_lit23:
568af526226Smrg 	case DW_OP_lit24:
569af526226Smrg 	case DW_OP_lit25:
570af526226Smrg 	case DW_OP_lit26:
571af526226Smrg 	case DW_OP_lit27:
572af526226Smrg 	case DW_OP_lit28:
573af526226Smrg 	case DW_OP_lit29:
574af526226Smrg 	case DW_OP_lit30:
575af526226Smrg 	case DW_OP_lit31:
576af526226Smrg 	  result = op - DW_OP_lit0;
577af526226Smrg 	  break;
578af526226Smrg 
579af526226Smrg 	case DW_OP_addr:
580af526226Smrg 	  result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
581af526226Smrg 	  op_ptr += sizeof (void *);
582af526226Smrg 	  break;
583af526226Smrg 
584af526226Smrg 	case DW_OP_GNU_encoded_addr:
585af526226Smrg 	  {
586af526226Smrg 	    _Unwind_Ptr presult;
587af526226Smrg 	    op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
588af526226Smrg 	    result = presult;
589af526226Smrg 	  }
590af526226Smrg 	  break;
591af526226Smrg 
592af526226Smrg 	case DW_OP_const1u:
593af526226Smrg 	  result = read_1u (op_ptr);
594af526226Smrg 	  op_ptr += 1;
595af526226Smrg 	  break;
596af526226Smrg 	case DW_OP_const1s:
597af526226Smrg 	  result = read_1s (op_ptr);
598af526226Smrg 	  op_ptr += 1;
599af526226Smrg 	  break;
600af526226Smrg 	case DW_OP_const2u:
601af526226Smrg 	  result = read_2u (op_ptr);
602af526226Smrg 	  op_ptr += 2;
603af526226Smrg 	  break;
604af526226Smrg 	case DW_OP_const2s:
605af526226Smrg 	  result = read_2s (op_ptr);
606af526226Smrg 	  op_ptr += 2;
607af526226Smrg 	  break;
608af526226Smrg 	case DW_OP_const4u:
609af526226Smrg 	  result = read_4u (op_ptr);
610af526226Smrg 	  op_ptr += 4;
611af526226Smrg 	  break;
612af526226Smrg 	case DW_OP_const4s:
613af526226Smrg 	  result = read_4s (op_ptr);
614af526226Smrg 	  op_ptr += 4;
615af526226Smrg 	  break;
616af526226Smrg 	case DW_OP_const8u:
617af526226Smrg 	  result = read_8u (op_ptr);
618af526226Smrg 	  op_ptr += 8;
619af526226Smrg 	  break;
620af526226Smrg 	case DW_OP_const8s:
621af526226Smrg 	  result = read_8s (op_ptr);
622af526226Smrg 	  op_ptr += 8;
623af526226Smrg 	  break;
624af526226Smrg 	case DW_OP_constu:
625af526226Smrg 	  op_ptr = read_uleb128 (op_ptr, &utmp);
626af526226Smrg 	  result = (_Unwind_Word)utmp;
627af526226Smrg 	  break;
628af526226Smrg 	case DW_OP_consts:
629af526226Smrg 	  op_ptr = read_sleb128 (op_ptr, &stmp);
630af526226Smrg 	  result = (_Unwind_Sword)stmp;
631af526226Smrg 	  break;
632af526226Smrg 
633af526226Smrg 	case DW_OP_reg0:
634af526226Smrg 	case DW_OP_reg1:
635af526226Smrg 	case DW_OP_reg2:
636af526226Smrg 	case DW_OP_reg3:
637af526226Smrg 	case DW_OP_reg4:
638af526226Smrg 	case DW_OP_reg5:
639af526226Smrg 	case DW_OP_reg6:
640af526226Smrg 	case DW_OP_reg7:
641af526226Smrg 	case DW_OP_reg8:
642af526226Smrg 	case DW_OP_reg9:
643af526226Smrg 	case DW_OP_reg10:
644af526226Smrg 	case DW_OP_reg11:
645af526226Smrg 	case DW_OP_reg12:
646af526226Smrg 	case DW_OP_reg13:
647af526226Smrg 	case DW_OP_reg14:
648af526226Smrg 	case DW_OP_reg15:
649af526226Smrg 	case DW_OP_reg16:
650af526226Smrg 	case DW_OP_reg17:
651af526226Smrg 	case DW_OP_reg18:
652af526226Smrg 	case DW_OP_reg19:
653af526226Smrg 	case DW_OP_reg20:
654af526226Smrg 	case DW_OP_reg21:
655af526226Smrg 	case DW_OP_reg22:
656af526226Smrg 	case DW_OP_reg23:
657af526226Smrg 	case DW_OP_reg24:
658af526226Smrg 	case DW_OP_reg25:
659af526226Smrg 	case DW_OP_reg26:
660af526226Smrg 	case DW_OP_reg27:
661af526226Smrg 	case DW_OP_reg28:
662af526226Smrg 	case DW_OP_reg29:
663af526226Smrg 	case DW_OP_reg30:
664af526226Smrg 	case DW_OP_reg31:
665af526226Smrg 	  result = _Unwind_GetGR (context, op - DW_OP_reg0);
666af526226Smrg 	  break;
667af526226Smrg 	case DW_OP_regx:
668af526226Smrg 	  op_ptr = read_uleb128 (op_ptr, &reg);
669af526226Smrg 	  result = _Unwind_GetGR (context, reg);
670af526226Smrg 	  break;
671af526226Smrg 
672af526226Smrg 	case DW_OP_breg0:
673af526226Smrg 	case DW_OP_breg1:
674af526226Smrg 	case DW_OP_breg2:
675af526226Smrg 	case DW_OP_breg3:
676af526226Smrg 	case DW_OP_breg4:
677af526226Smrg 	case DW_OP_breg5:
678af526226Smrg 	case DW_OP_breg6:
679af526226Smrg 	case DW_OP_breg7:
680af526226Smrg 	case DW_OP_breg8:
681af526226Smrg 	case DW_OP_breg9:
682af526226Smrg 	case DW_OP_breg10:
683af526226Smrg 	case DW_OP_breg11:
684af526226Smrg 	case DW_OP_breg12:
685af526226Smrg 	case DW_OP_breg13:
686af526226Smrg 	case DW_OP_breg14:
687af526226Smrg 	case DW_OP_breg15:
688af526226Smrg 	case DW_OP_breg16:
689af526226Smrg 	case DW_OP_breg17:
690af526226Smrg 	case DW_OP_breg18:
691af526226Smrg 	case DW_OP_breg19:
692af526226Smrg 	case DW_OP_breg20:
693af526226Smrg 	case DW_OP_breg21:
694af526226Smrg 	case DW_OP_breg22:
695af526226Smrg 	case DW_OP_breg23:
696af526226Smrg 	case DW_OP_breg24:
697af526226Smrg 	case DW_OP_breg25:
698af526226Smrg 	case DW_OP_breg26:
699af526226Smrg 	case DW_OP_breg27:
700af526226Smrg 	case DW_OP_breg28:
701af526226Smrg 	case DW_OP_breg29:
702af526226Smrg 	case DW_OP_breg30:
703af526226Smrg 	case DW_OP_breg31:
704af526226Smrg 	  op_ptr = read_sleb128 (op_ptr, &offset);
705af526226Smrg 	  result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
706af526226Smrg 	  break;
707af526226Smrg 	case DW_OP_bregx:
708af526226Smrg 	  op_ptr = read_uleb128 (op_ptr, &reg);
709af526226Smrg 	  op_ptr = read_sleb128 (op_ptr, &offset);
710af526226Smrg 	  result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
711af526226Smrg 	  break;
712af526226Smrg 
713af526226Smrg 	case DW_OP_dup:
714af526226Smrg 	  gcc_assert (stack_elt);
715af526226Smrg 	  result = stack[stack_elt - 1];
716af526226Smrg 	  break;
717af526226Smrg 
718af526226Smrg 	case DW_OP_drop:
719af526226Smrg 	  gcc_assert (stack_elt);
720af526226Smrg 	  stack_elt -= 1;
721af526226Smrg 	  goto no_push;
722af526226Smrg 
723af526226Smrg 	case DW_OP_pick:
724af526226Smrg 	  offset = *op_ptr++;
725af526226Smrg 	  gcc_assert (offset < stack_elt - 1);
726af526226Smrg 	  result = stack[stack_elt - 1 - offset];
727af526226Smrg 	  break;
728af526226Smrg 
729af526226Smrg 	case DW_OP_over:
730af526226Smrg 	  gcc_assert (stack_elt >= 2);
731af526226Smrg 	  result = stack[stack_elt - 2];
732af526226Smrg 	  break;
733af526226Smrg 
734af526226Smrg 	case DW_OP_swap:
735af526226Smrg 	  {
736af526226Smrg 	    _Unwind_Word t;
737af526226Smrg 	    gcc_assert (stack_elt >= 2);
738af526226Smrg 	    t = stack[stack_elt - 1];
739af526226Smrg 	    stack[stack_elt - 1] = stack[stack_elt - 2];
740af526226Smrg 	    stack[stack_elt - 2] = t;
741af526226Smrg 	    goto no_push;
742af526226Smrg 	  }
743af526226Smrg 
744af526226Smrg 	case DW_OP_rot:
745af526226Smrg 	  {
746af526226Smrg 	    _Unwind_Word t1, t2, t3;
747af526226Smrg 
748af526226Smrg 	    gcc_assert (stack_elt >= 3);
749af526226Smrg 	    t1 = stack[stack_elt - 1];
750af526226Smrg 	    t2 = stack[stack_elt - 2];
751af526226Smrg 	    t3 = stack[stack_elt - 3];
752af526226Smrg 	    stack[stack_elt - 1] = t2;
753af526226Smrg 	    stack[stack_elt - 2] = t3;
754af526226Smrg 	    stack[stack_elt - 3] = t1;
755af526226Smrg 	    goto no_push;
756af526226Smrg 	  }
757af526226Smrg 
758af526226Smrg 	case DW_OP_deref:
759af526226Smrg 	case DW_OP_deref_size:
760af526226Smrg 	case DW_OP_abs:
761af526226Smrg 	case DW_OP_neg:
762af526226Smrg 	case DW_OP_not:
763af526226Smrg 	case DW_OP_plus_uconst:
764af526226Smrg 	  /* Unary operations.  */
765af526226Smrg 	  gcc_assert (stack_elt);
766af526226Smrg 	  stack_elt -= 1;
767af526226Smrg 
768af526226Smrg 	  result = stack[stack_elt];
769af526226Smrg 
770af526226Smrg 	  switch (op)
771af526226Smrg 	    {
772af526226Smrg 	    case DW_OP_deref:
773af526226Smrg 	      {
774af526226Smrg 		void *ptr = (void *) (_Unwind_Ptr) result;
775af526226Smrg 		result = (_Unwind_Ptr) read_pointer (ptr);
776af526226Smrg 	      }
777af526226Smrg 	      break;
778af526226Smrg 
779af526226Smrg 	    case DW_OP_deref_size:
780af526226Smrg 	      {
781af526226Smrg 		void *ptr = (void *) (_Unwind_Ptr) result;
782af526226Smrg 		switch (*op_ptr++)
783af526226Smrg 		  {
784af526226Smrg 		  case 1:
785af526226Smrg 		    result = read_1u (ptr);
786af526226Smrg 		    break;
787af526226Smrg 		  case 2:
788af526226Smrg 		    result = read_2u (ptr);
789af526226Smrg 		    break;
790af526226Smrg 		  case 4:
791af526226Smrg 		    result = read_4u (ptr);
792af526226Smrg 		    break;
793af526226Smrg 		  case 8:
794af526226Smrg 		    result = read_8u (ptr);
795af526226Smrg 		    break;
796af526226Smrg 		  default:
797af526226Smrg 		    gcc_unreachable ();
798af526226Smrg 		  }
799af526226Smrg 	      }
800af526226Smrg 	      break;
801af526226Smrg 
802af526226Smrg 	    case DW_OP_abs:
803af526226Smrg 	      if ((_Unwind_Sword) result < 0)
804af526226Smrg 		result = -result;
805af526226Smrg 	      break;
806af526226Smrg 	    case DW_OP_neg:
807af526226Smrg 	      result = -result;
808af526226Smrg 	      break;
809af526226Smrg 	    case DW_OP_not:
810af526226Smrg 	      result = ~result;
811af526226Smrg 	      break;
812af526226Smrg 	    case DW_OP_plus_uconst:
813af526226Smrg 	      op_ptr = read_uleb128 (op_ptr, &utmp);
814af526226Smrg 	      result += (_Unwind_Word)utmp;
815af526226Smrg 	      break;
816af526226Smrg 
817af526226Smrg 	    default:
818af526226Smrg 	      gcc_unreachable ();
819af526226Smrg 	    }
820af526226Smrg 	  break;
821af526226Smrg 
822af526226Smrg 	case DW_OP_and:
823af526226Smrg 	case DW_OP_div:
824af526226Smrg 	case DW_OP_minus:
825af526226Smrg 	case DW_OP_mod:
826af526226Smrg 	case DW_OP_mul:
827af526226Smrg 	case DW_OP_or:
828af526226Smrg 	case DW_OP_plus:
829af526226Smrg 	case DW_OP_shl:
830af526226Smrg 	case DW_OP_shr:
831af526226Smrg 	case DW_OP_shra:
832af526226Smrg 	case DW_OP_xor:
833af526226Smrg 	case DW_OP_le:
834af526226Smrg 	case DW_OP_ge:
835af526226Smrg 	case DW_OP_eq:
836af526226Smrg 	case DW_OP_lt:
837af526226Smrg 	case DW_OP_gt:
838af526226Smrg 	case DW_OP_ne:
839af526226Smrg 	  {
840af526226Smrg 	    /* Binary operations.  */
841af526226Smrg 	    _Unwind_Word first, second;
842af526226Smrg 	    gcc_assert (stack_elt >= 2);
843af526226Smrg 	    stack_elt -= 2;
844af526226Smrg 
845af526226Smrg 	    second = stack[stack_elt];
846af526226Smrg 	    first = stack[stack_elt + 1];
847af526226Smrg 
848af526226Smrg 	    switch (op)
849af526226Smrg 	      {
850af526226Smrg 	      case DW_OP_and:
851af526226Smrg 		result = second & first;
852af526226Smrg 		break;
853af526226Smrg 	      case DW_OP_div:
854af526226Smrg 		result = (_Unwind_Sword) second / (_Unwind_Sword) first;
855af526226Smrg 		break;
856af526226Smrg 	      case DW_OP_minus:
857af526226Smrg 		result = second - first;
858af526226Smrg 		break;
859af526226Smrg 	      case DW_OP_mod:
860af526226Smrg 		result = second % first;
861af526226Smrg 		break;
862af526226Smrg 	      case DW_OP_mul:
863af526226Smrg 		result = second * first;
864af526226Smrg 		break;
865af526226Smrg 	      case DW_OP_or:
866af526226Smrg 		result = second | first;
867af526226Smrg 		break;
868af526226Smrg 	      case DW_OP_plus:
869af526226Smrg 		result = second + first;
870af526226Smrg 		break;
871af526226Smrg 	      case DW_OP_shl:
872af526226Smrg 		result = second << first;
873af526226Smrg 		break;
874af526226Smrg 	      case DW_OP_shr:
875af526226Smrg 		result = second >> first;
876af526226Smrg 		break;
877af526226Smrg 	      case DW_OP_shra:
878af526226Smrg 		result = (_Unwind_Sword) second >> first;
879af526226Smrg 		break;
880af526226Smrg 	      case DW_OP_xor:
881af526226Smrg 		result = second ^ first;
882af526226Smrg 		break;
883af526226Smrg 	      case DW_OP_le:
884af526226Smrg 		result = (_Unwind_Sword) second <= (_Unwind_Sword) first;
885af526226Smrg 		break;
886af526226Smrg 	      case DW_OP_ge:
887af526226Smrg 		result = (_Unwind_Sword) second >= (_Unwind_Sword) first;
888af526226Smrg 		break;
889af526226Smrg 	      case DW_OP_eq:
890af526226Smrg 		result = (_Unwind_Sword) second == (_Unwind_Sword) first;
891af526226Smrg 		break;
892af526226Smrg 	      case DW_OP_lt:
893af526226Smrg 		result = (_Unwind_Sword) second < (_Unwind_Sword) first;
894af526226Smrg 		break;
895af526226Smrg 	      case DW_OP_gt:
896af526226Smrg 		result = (_Unwind_Sword) second > (_Unwind_Sword) first;
897af526226Smrg 		break;
898af526226Smrg 	      case DW_OP_ne:
899af526226Smrg 		result = (_Unwind_Sword) second != (_Unwind_Sword) first;
900af526226Smrg 		break;
901af526226Smrg 
902af526226Smrg 	      default:
903af526226Smrg 		gcc_unreachable ();
904af526226Smrg 	      }
905af526226Smrg 	  }
906af526226Smrg 	  break;
907af526226Smrg 
908af526226Smrg 	case DW_OP_skip:
909af526226Smrg 	  offset = read_2s (op_ptr);
910af526226Smrg 	  op_ptr += 2;
911af526226Smrg 	  op_ptr += offset;
912af526226Smrg 	  goto no_push;
913af526226Smrg 
914af526226Smrg 	case DW_OP_bra:
915af526226Smrg 	  gcc_assert (stack_elt);
916af526226Smrg 	  stack_elt -= 1;
917af526226Smrg 
918af526226Smrg 	  offset = read_2s (op_ptr);
919af526226Smrg 	  op_ptr += 2;
920af526226Smrg 	  if (stack[stack_elt] != 0)
921af526226Smrg 	    op_ptr += offset;
922af526226Smrg 	  goto no_push;
923af526226Smrg 
924af526226Smrg 	case DW_OP_nop:
925af526226Smrg 	  goto no_push;
926af526226Smrg 
927af526226Smrg 	default:
928af526226Smrg 	  gcc_unreachable ();
929af526226Smrg 	}
930af526226Smrg 
931af526226Smrg       /* Most things push a result value.  */
932af526226Smrg       gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
933af526226Smrg       stack[stack_elt++] = result;
934af526226Smrg     no_push:;
935af526226Smrg     }
936af526226Smrg 
937af526226Smrg   /* We were executing this program to get a value.  It should be
938af526226Smrg      at top of stack.  */
939af526226Smrg   gcc_assert (stack_elt);
940af526226Smrg   stack_elt -= 1;
941af526226Smrg   return stack[stack_elt];
942af526226Smrg }
943af526226Smrg 
944af526226Smrg 
945af526226Smrg /* Decode DWARF 2 call frame information. Takes pointers the
946af526226Smrg    instruction sequence to decode, current register information and
947af526226Smrg    CIE info, and the PC range to evaluate.  */
948af526226Smrg 
949af526226Smrg static void
execute_cfa_program(const unsigned char * insn_ptr,const unsigned char * insn_end,struct _Unwind_Context * context,_Unwind_FrameState * fs)950af526226Smrg execute_cfa_program (const unsigned char *insn_ptr,
951af526226Smrg 		     const unsigned char *insn_end,
952af526226Smrg 		     struct _Unwind_Context *context,
953af526226Smrg 		     _Unwind_FrameState *fs)
954af526226Smrg {
955af526226Smrg   struct frame_state_reg_info *unused_rs = NULL;
956af526226Smrg 
957af526226Smrg   /* Don't allow remember/restore between CIE and FDE programs.  */
958af526226Smrg   fs->regs.prev = NULL;
959af526226Smrg 
960af526226Smrg   /* The comparison with the return address uses < rather than <= because
961af526226Smrg      we are only interested in the effects of code before the call; for a
962af526226Smrg      noreturn function, the return address may point to unrelated code with
963af526226Smrg      a different stack configuration that we are not interested in.  We
964af526226Smrg      assume that the call itself is unwind info-neutral; if not, or if
965af526226Smrg      there are delay instructions that adjust the stack, these must be
966af526226Smrg      reflected at the point immediately before the call insn.
967af526226Smrg      In signal frames, return address is after last completed instruction,
968af526226Smrg      so we add 1 to return address to make the comparison <=.  */
969af526226Smrg   while (insn_ptr < insn_end
970af526226Smrg 	 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
971af526226Smrg     {
972af526226Smrg       unsigned char insn = *insn_ptr++;
973af526226Smrg       _uleb128_t reg, utmp;
974af526226Smrg       _sleb128_t offset, stmp;
975af526226Smrg 
976af526226Smrg       if ((insn & 0xc0) == DW_CFA_advance_loc)
977af526226Smrg 	fs->pc += (insn & 0x3f) * fs->code_align;
978af526226Smrg       else if ((insn & 0xc0) == DW_CFA_offset)
979af526226Smrg 	{
980af526226Smrg 	  reg = insn & 0x3f;
981af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
982af526226Smrg 	  offset = (_Unwind_Sword) utmp * fs->data_align;
983af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
984af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
985af526226Smrg 	    {
986af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
987af526226Smrg 	      fs->regs.reg[reg].loc.offset = offset;
988af526226Smrg 	    }
989af526226Smrg 	}
990af526226Smrg       else if ((insn & 0xc0) == DW_CFA_restore)
991af526226Smrg 	{
992af526226Smrg 	  reg = insn & 0x3f;
993af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
994af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
995af526226Smrg 	    fs->regs.reg[reg].how = REG_UNSAVED;
996af526226Smrg 	}
997af526226Smrg       else switch (insn)
998af526226Smrg 	{
999af526226Smrg 	case DW_CFA_set_loc:
1000af526226Smrg 	  {
1001af526226Smrg 	    _Unwind_Ptr pc;
1002af526226Smrg 
1003af526226Smrg 	    insn_ptr = read_encoded_value (context, fs->fde_encoding,
1004af526226Smrg 					   insn_ptr, &pc);
1005af526226Smrg 	    fs->pc = (void *) pc;
1006af526226Smrg 	  }
1007af526226Smrg 	  break;
1008af526226Smrg 
1009af526226Smrg 	case DW_CFA_advance_loc1:
1010af526226Smrg 	  fs->pc += read_1u (insn_ptr) * fs->code_align;
1011af526226Smrg 	  insn_ptr += 1;
1012af526226Smrg 	  break;
1013af526226Smrg 	case DW_CFA_advance_loc2:
1014af526226Smrg 	  fs->pc += read_2u (insn_ptr) * fs->code_align;
1015af526226Smrg 	  insn_ptr += 2;
1016af526226Smrg 	  break;
1017af526226Smrg 	case DW_CFA_advance_loc4:
1018af526226Smrg 	  fs->pc += read_4u (insn_ptr) * fs->code_align;
1019af526226Smrg 	  insn_ptr += 4;
1020af526226Smrg 	  break;
1021af526226Smrg 
1022af526226Smrg 	case DW_CFA_offset_extended:
1023af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1024af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1025af526226Smrg 	  offset = (_Unwind_Sword) utmp * fs->data_align;
1026af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1027af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1028af526226Smrg 	    {
1029af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1030af526226Smrg 	      fs->regs.reg[reg].loc.offset = offset;
1031af526226Smrg 	    }
1032af526226Smrg 	  break;
1033af526226Smrg 
1034af526226Smrg 	case DW_CFA_restore_extended:
1035af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1036af526226Smrg 	  /* FIXME, this is wrong; the CIE might have said that the
1037af526226Smrg 	     register was saved somewhere.  */
1038af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1039af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1040af526226Smrg 	    fs->regs.reg[reg].how = REG_UNSAVED;
1041af526226Smrg 	  break;
1042af526226Smrg 
1043af526226Smrg 	case DW_CFA_same_value:
1044af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1045af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1046af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1047af526226Smrg 	    fs->regs.reg[reg].how = REG_UNSAVED;
1048af526226Smrg 	  break;
1049af526226Smrg 
1050af526226Smrg 	case DW_CFA_undefined:
1051af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1052af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1053af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1054af526226Smrg 	    fs->regs.reg[reg].how = REG_UNDEFINED;
1055af526226Smrg 	  break;
1056af526226Smrg 
1057af526226Smrg 	case DW_CFA_nop:
1058af526226Smrg 	  break;
1059af526226Smrg 
1060af526226Smrg 	case DW_CFA_register:
1061af526226Smrg 	  {
1062af526226Smrg 	    _uleb128_t reg2;
1063af526226Smrg 	    insn_ptr = read_uleb128 (insn_ptr, &reg);
1064af526226Smrg 	    insn_ptr = read_uleb128 (insn_ptr, &reg2);
1065af526226Smrg 	    reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1066af526226Smrg 	    if (UNWIND_COLUMN_IN_RANGE (reg))
1067af526226Smrg 	      {
1068af526226Smrg 	        fs->regs.reg[reg].how = REG_SAVED_REG;
1069af526226Smrg 	        fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2;
1070af526226Smrg 	      }
1071af526226Smrg 	  }
1072af526226Smrg 	  break;
1073af526226Smrg 
1074af526226Smrg 	case DW_CFA_remember_state:
1075af526226Smrg 	  {
1076af526226Smrg 	    struct frame_state_reg_info *new_rs;
1077af526226Smrg 	    if (unused_rs)
1078af526226Smrg 	      {
1079af526226Smrg 		new_rs = unused_rs;
1080af526226Smrg 		unused_rs = unused_rs->prev;
1081af526226Smrg 	      }
1082af526226Smrg 	    else
1083af526226Smrg 	      new_rs = alloca (sizeof (struct frame_state_reg_info));
1084af526226Smrg 
1085af526226Smrg 	    *new_rs = fs->regs;
1086af526226Smrg 	    fs->regs.prev = new_rs;
1087af526226Smrg 	  }
1088af526226Smrg 	  break;
1089af526226Smrg 
1090af526226Smrg 	case DW_CFA_restore_state:
1091af526226Smrg 	  {
1092af526226Smrg 	    struct frame_state_reg_info *old_rs = fs->regs.prev;
1093af526226Smrg 	    fs->regs = *old_rs;
1094af526226Smrg 	    old_rs->prev = unused_rs;
1095af526226Smrg 	    unused_rs = old_rs;
1096af526226Smrg 	  }
1097af526226Smrg 	  break;
1098af526226Smrg 
1099af526226Smrg 	case DW_CFA_def_cfa:
1100af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1101af526226Smrg 	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
1102af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1103af526226Smrg 	  fs->regs.cfa_offset = (_Unwind_Word)utmp;
1104af526226Smrg 	  fs->regs.cfa_how = CFA_REG_OFFSET;
1105af526226Smrg 	  break;
1106af526226Smrg 
1107af526226Smrg 	case DW_CFA_def_cfa_register:
1108af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1109af526226Smrg 	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
1110af526226Smrg 	  fs->regs.cfa_how = CFA_REG_OFFSET;
1111af526226Smrg 	  break;
1112af526226Smrg 
1113af526226Smrg 	case DW_CFA_def_cfa_offset:
1114af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1115af526226Smrg 	  fs->regs.cfa_offset = utmp;
1116af526226Smrg 	  /* cfa_how deliberately not set.  */
1117af526226Smrg 	  break;
1118af526226Smrg 
1119af526226Smrg 	case DW_CFA_def_cfa_expression:
1120af526226Smrg 	  fs->regs.cfa_exp = insn_ptr;
1121af526226Smrg 	  fs->regs.cfa_how = CFA_EXP;
1122af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1123af526226Smrg 	  insn_ptr += utmp;
1124af526226Smrg 	  break;
1125af526226Smrg 
1126af526226Smrg 	case DW_CFA_expression:
1127af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1128af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1129af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1130af526226Smrg 	    {
1131af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_EXP;
1132af526226Smrg 	      fs->regs.reg[reg].loc.exp = insn_ptr;
1133af526226Smrg 	    }
1134af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1135af526226Smrg 	  insn_ptr += utmp;
1136af526226Smrg 	  break;
1137af526226Smrg 
1138af526226Smrg 	  /* Dwarf3.  */
1139af526226Smrg 	case DW_CFA_offset_extended_sf:
1140af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1141af526226Smrg 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
1142af526226Smrg 	  offset = stmp * fs->data_align;
1143af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1144af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1145af526226Smrg 	    {
1146af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1147af526226Smrg 	      fs->regs.reg[reg].loc.offset = offset;
1148af526226Smrg 	    }
1149af526226Smrg 	  break;
1150af526226Smrg 
1151af526226Smrg 	case DW_CFA_def_cfa_sf:
1152af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1153af526226Smrg 	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
1154af526226Smrg 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
1155af526226Smrg 	  fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1156af526226Smrg 	  fs->regs.cfa_how = CFA_REG_OFFSET;
1157af526226Smrg 	  fs->regs.cfa_offset *= fs->data_align;
1158af526226Smrg 	  break;
1159af526226Smrg 
1160af526226Smrg 	case DW_CFA_def_cfa_offset_sf:
1161af526226Smrg 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
1162af526226Smrg 	  fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1163af526226Smrg 	  fs->regs.cfa_offset *= fs->data_align;
1164af526226Smrg 	  /* cfa_how deliberately not set.  */
1165af526226Smrg 	  break;
1166af526226Smrg 
1167af526226Smrg 	case DW_CFA_val_offset:
1168af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1169af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1170af526226Smrg 	  offset = (_Unwind_Sword) utmp * fs->data_align;
1171af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1172af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1173af526226Smrg 	    {
1174af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
1175af526226Smrg 	      fs->regs.reg[reg].loc.offset = offset;
1176af526226Smrg 	    }
1177af526226Smrg 	  break;
1178af526226Smrg 
1179af526226Smrg 	case DW_CFA_val_offset_sf:
1180af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1181af526226Smrg 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
1182af526226Smrg 	  offset = stmp * fs->data_align;
1183af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1184af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1185af526226Smrg 	    {
1186af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
1187af526226Smrg 	      fs->regs.reg[reg].loc.offset = offset;
1188af526226Smrg 	    }
1189af526226Smrg 	  break;
1190af526226Smrg 
1191af526226Smrg 	case DW_CFA_val_expression:
1192af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1193af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1194af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1195af526226Smrg 	    {
1196af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_VAL_EXP;
1197af526226Smrg 	      fs->regs.reg[reg].loc.exp = insn_ptr;
1198af526226Smrg 	    }
1199af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1200af526226Smrg 	  insn_ptr += utmp;
1201af526226Smrg 	  break;
1202af526226Smrg 
1203af526226Smrg 	case DW_CFA_GNU_window_save:
12043bf62c3fSmrg #if defined (__aarch64__) && !defined (__ILP32__)
12053bf62c3fSmrg 	  /* This CFA is multiplexed with Sparc.  On AArch64 it's used to toggle
12063bf62c3fSmrg 	     return address signing status.  */
12073bf62c3fSmrg 	  fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset ^= 1;
12083bf62c3fSmrg #else
1209af526226Smrg 	  /* ??? Hardcoded for SPARC register window configuration.  */
12104646d632Smrg 	  if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
1211af526226Smrg 	    for (reg = 16; reg < 32; ++reg)
1212af526226Smrg 	      {
1213af526226Smrg 		fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1214af526226Smrg 		fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1215af526226Smrg 	      }
12163bf62c3fSmrg #endif
1217af526226Smrg 	  break;
1218af526226Smrg 
1219af526226Smrg 	case DW_CFA_GNU_args_size:
1220af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1221af526226Smrg 	  context->args_size = (_Unwind_Word)utmp;
1222af526226Smrg 	  break;
1223af526226Smrg 
1224af526226Smrg 	case DW_CFA_GNU_negative_offset_extended:
1225af526226Smrg 	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1226af526226Smrg 	     older PowerPC code.  */
1227af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
1228af526226Smrg 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
1229af526226Smrg 	  offset = (_Unwind_Word) utmp * fs->data_align;
1230af526226Smrg 	  reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1231af526226Smrg 	  if (UNWIND_COLUMN_IN_RANGE (reg))
1232af526226Smrg 	    {
1233af526226Smrg 	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1234af526226Smrg 	      fs->regs.reg[reg].loc.offset = -offset;
1235af526226Smrg 	    }
1236af526226Smrg 	  break;
1237af526226Smrg 
1238af526226Smrg 	default:
1239af526226Smrg 	  gcc_unreachable ();
1240af526226Smrg 	}
1241af526226Smrg     }
1242af526226Smrg }
1243af526226Smrg 
1244af526226Smrg /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1245af526226Smrg    its caller and decode it into FS.  This function also sets the
1246af526226Smrg    args_size and lsda members of CONTEXT, as they are really information
1247af526226Smrg    about the caller's frame.  */
1248af526226Smrg 
1249af526226Smrg static _Unwind_Reason_Code
uw_frame_state_for(struct _Unwind_Context * context,_Unwind_FrameState * fs)1250af526226Smrg uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1251af526226Smrg {
1252af526226Smrg   const struct dwarf_fde *fde;
1253af526226Smrg   const struct dwarf_cie *cie;
1254af526226Smrg   const unsigned char *aug, *insn, *end;
1255af526226Smrg 
1256af526226Smrg   memset (fs, 0, sizeof (*fs));
1257af526226Smrg   context->args_size = 0;
1258af526226Smrg   context->lsda = 0;
1259af526226Smrg 
1260af526226Smrg   if (context->ra == 0)
1261af526226Smrg     return _URC_END_OF_STACK;
1262af526226Smrg 
1263af526226Smrg   fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
1264af526226Smrg 			  &context->bases);
1265af526226Smrg   if (fde == NULL)
1266af526226Smrg     {
1267af526226Smrg #ifdef MD_FALLBACK_FRAME_STATE_FOR
1268af526226Smrg       /* Couldn't find frame unwind info for this function.  Try a
1269af526226Smrg 	 target-specific fallback mechanism.  This will necessarily
1270af526226Smrg 	 not provide a personality routine or LSDA.  */
1271af526226Smrg       return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1272af526226Smrg #else
1273af526226Smrg       return _URC_END_OF_STACK;
1274af526226Smrg #endif
1275af526226Smrg     }
1276af526226Smrg 
1277af526226Smrg   fs->pc = context->bases.func;
1278af526226Smrg 
1279af526226Smrg   cie = get_cie (fde);
1280af526226Smrg   insn = extract_cie_info (cie, context, fs);
1281af526226Smrg   if (insn == NULL)
1282af526226Smrg     /* CIE contained unknown augmentation.  */
1283af526226Smrg     return _URC_FATAL_PHASE1_ERROR;
1284af526226Smrg 
1285af526226Smrg   /* First decode all the insns in the CIE.  */
1286af526226Smrg   end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
1287af526226Smrg   execute_cfa_program (insn, end, context, fs);
1288af526226Smrg 
1289af526226Smrg   /* Locate augmentation for the fde.  */
1290af526226Smrg   aug = (const unsigned char *) fde + sizeof (*fde);
1291af526226Smrg   aug += 2 * size_of_encoded_value (fs->fde_encoding);
1292af526226Smrg   insn = NULL;
1293af526226Smrg   if (fs->saw_z)
1294af526226Smrg     {
1295af526226Smrg       _uleb128_t i;
1296af526226Smrg       aug = read_uleb128 (aug, &i);
1297af526226Smrg       insn = aug + i;
1298af526226Smrg     }
1299af526226Smrg   if (fs->lsda_encoding != DW_EH_PE_omit)
1300af526226Smrg     {
1301af526226Smrg       _Unwind_Ptr lsda;
1302af526226Smrg 
1303af526226Smrg       aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1304af526226Smrg       context->lsda = (void *) lsda;
1305af526226Smrg     }
1306af526226Smrg 
1307af526226Smrg   /* Then the insns in the FDE up to our target PC.  */
1308af526226Smrg   if (insn == NULL)
1309af526226Smrg     insn = aug;
1310af526226Smrg   end = (const unsigned char *) next_fde (fde);
1311af526226Smrg   execute_cfa_program (insn, end, context, fs);
1312af526226Smrg 
1313af526226Smrg   return _URC_NO_REASON;
1314af526226Smrg }
1315af526226Smrg 
1316af526226Smrg typedef struct frame_state
1317af526226Smrg {
1318af526226Smrg   void *cfa;
1319af526226Smrg   void *eh_ptr;
1320af526226Smrg   long cfa_offset;
1321af526226Smrg   long args_size;
1322af526226Smrg   long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1323af526226Smrg   unsigned short cfa_reg;
1324af526226Smrg   unsigned short retaddr_column;
1325af526226Smrg   char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1326af526226Smrg } frame_state;
1327af526226Smrg 
1328af526226Smrg struct frame_state * __frame_state_for (void *, struct frame_state *);
1329af526226Smrg 
1330af526226Smrg /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1331af526226Smrg    a given PC_TARGET.  The caller should allocate a local variable of
1332af526226Smrg    `struct frame_state' and pass its address to STATE_IN.  */
1333af526226Smrg 
1334af526226Smrg struct frame_state *
__frame_state_for(void * pc_target,struct frame_state * state_in)1335af526226Smrg __frame_state_for (void *pc_target, struct frame_state *state_in)
1336af526226Smrg {
1337af526226Smrg   struct _Unwind_Context context;
1338af526226Smrg   _Unwind_FrameState fs;
1339af526226Smrg   int reg;
1340af526226Smrg 
1341af526226Smrg   memset (&context, 0, sizeof (struct _Unwind_Context));
1342af526226Smrg   if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1343af526226Smrg     context.flags = EXTENDED_CONTEXT_BIT;
1344af526226Smrg   context.ra = pc_target + 1;
1345af526226Smrg 
1346af526226Smrg   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1347af526226Smrg     return 0;
1348af526226Smrg 
1349af526226Smrg   /* We have no way to pass a location expression for the CFA to our
1350af526226Smrg      caller.  It wouldn't understand it anyway.  */
1351af526226Smrg   if (fs.regs.cfa_how == CFA_EXP)
1352af526226Smrg     return 0;
1353af526226Smrg 
1354af526226Smrg   for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1355af526226Smrg     {
1356af526226Smrg       state_in->saved[reg] = fs.regs.reg[reg].how;
1357af526226Smrg       switch (state_in->saved[reg])
1358af526226Smrg 	{
1359af526226Smrg 	case REG_SAVED_REG:
1360af526226Smrg 	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1361af526226Smrg 	  break;
1362af526226Smrg 	case REG_SAVED_OFFSET:
1363af526226Smrg 	  state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1364af526226Smrg 	  break;
1365af526226Smrg 	default:
1366af526226Smrg 	  state_in->reg_or_offset[reg] = 0;
1367af526226Smrg 	  break;
1368af526226Smrg 	}
1369af526226Smrg     }
1370af526226Smrg 
1371af526226Smrg   state_in->cfa_offset = fs.regs.cfa_offset;
1372af526226Smrg   state_in->cfa_reg = fs.regs.cfa_reg;
1373af526226Smrg   state_in->retaddr_column = fs.retaddr_column;
1374af526226Smrg   state_in->args_size = context.args_size;
1375af526226Smrg   state_in->eh_ptr = fs.eh_ptr;
1376af526226Smrg 
1377af526226Smrg   return state_in;
1378af526226Smrg }
1379af526226Smrg 
1380af526226Smrg typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1381af526226Smrg 
1382af526226Smrg static inline void
_Unwind_SetSpColumn(struct _Unwind_Context * context,void * cfa,_Unwind_SpTmp * tmp_sp)1383af526226Smrg _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1384af526226Smrg 		     _Unwind_SpTmp *tmp_sp)
1385af526226Smrg {
1386af526226Smrg   int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1387af526226Smrg 
1388af526226Smrg   if (size == sizeof(_Unwind_Ptr))
1389af526226Smrg     tmp_sp->ptr = (_Unwind_Ptr) cfa;
1390af526226Smrg   else
1391af526226Smrg     {
1392af526226Smrg       gcc_assert (size == sizeof(_Unwind_Word));
1393af526226Smrg       tmp_sp->word = (_Unwind_Ptr) cfa;
1394af526226Smrg     }
1395af526226Smrg   _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1396af526226Smrg }
1397af526226Smrg 
1398af526226Smrg static void
uw_update_context_1(struct _Unwind_Context * context,_Unwind_FrameState * fs)1399af526226Smrg uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1400af526226Smrg {
1401af526226Smrg   struct _Unwind_Context orig_context = *context;
1402af526226Smrg   void *cfa;
1403af526226Smrg   long i;
1404af526226Smrg 
14054646d632Smrg #ifdef __LIBGCC_EH_RETURN_STACKADJ_RTX__
1406af526226Smrg   /* Special handling here: Many machines do not use a frame pointer,
1407af526226Smrg      and track the CFA only through offsets from the stack pointer from
1408af526226Smrg      one frame to the next.  In this case, the stack pointer is never
1409af526226Smrg      stored, so it has no saved address in the context.  What we do
1410af526226Smrg      have is the CFA from the previous stack frame.
1411af526226Smrg 
1412af526226Smrg      In very special situations (such as unwind info for signal return),
1413af526226Smrg      there may be location expressions that use the stack pointer as well.
1414af526226Smrg 
1415af526226Smrg      Do this conditionally for one frame.  This allows the unwind info
1416af526226Smrg      for one frame to save a copy of the stack pointer from the previous
1417af526226Smrg      frame, and be able to use much easier CFA mechanisms to do it.
1418af526226Smrg      Always zap the saved stack pointer value for the next frame; carrying
1419af526226Smrg      the value over from one frame to another doesn't make sense.  */
1420af526226Smrg 
1421af526226Smrg   _Unwind_SpTmp tmp_sp;
1422af526226Smrg 
1423af526226Smrg   if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1424af526226Smrg     _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1425af526226Smrg   _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1426af526226Smrg #endif
1427af526226Smrg 
1428af526226Smrg   /* Compute this frame's CFA.  */
1429af526226Smrg   switch (fs->regs.cfa_how)
1430af526226Smrg     {
1431af526226Smrg     case CFA_REG_OFFSET:
1432af526226Smrg       cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1433af526226Smrg       cfa += fs->regs.cfa_offset;
1434af526226Smrg       break;
1435af526226Smrg 
1436af526226Smrg     case CFA_EXP:
1437af526226Smrg       {
1438af526226Smrg 	const unsigned char *exp = fs->regs.cfa_exp;
1439af526226Smrg 	_uleb128_t len;
1440af526226Smrg 
1441af526226Smrg 	exp = read_uleb128 (exp, &len);
1442af526226Smrg 	cfa = (void *) (_Unwind_Ptr)
1443af526226Smrg 	  execute_stack_op (exp, exp + len, &orig_context, 0);
1444af526226Smrg 	break;
1445af526226Smrg       }
1446af526226Smrg 
1447af526226Smrg     default:
1448af526226Smrg       gcc_unreachable ();
1449af526226Smrg     }
1450af526226Smrg   context->cfa = cfa;
1451af526226Smrg 
1452af526226Smrg   /* Compute the addresses of all registers saved in this frame.  */
14534646d632Smrg   for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__ + 1; ++i)
1454af526226Smrg     switch (fs->regs.reg[i].how)
1455af526226Smrg       {
1456af526226Smrg       case REG_UNSAVED:
1457af526226Smrg       case REG_UNDEFINED:
1458af526226Smrg 	break;
1459af526226Smrg 
1460af526226Smrg       case REG_SAVED_OFFSET:
1461af526226Smrg 	_Unwind_SetGRPtr (context, i,
1462af526226Smrg 			  (void *) (cfa + fs->regs.reg[i].loc.offset));
1463af526226Smrg 	break;
1464af526226Smrg 
1465af526226Smrg       case REG_SAVED_REG:
1466af526226Smrg 	if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1467af526226Smrg 	  _Unwind_SetGRValue (context, i,
1468af526226Smrg 			      _Unwind_GetGR (&orig_context,
1469af526226Smrg 					     fs->regs.reg[i].loc.reg));
1470af526226Smrg 	else
1471af526226Smrg 	  _Unwind_SetGRPtr (context, i,
1472af526226Smrg 			    _Unwind_GetGRPtr (&orig_context,
1473af526226Smrg 					      fs->regs.reg[i].loc.reg));
1474af526226Smrg 	break;
1475af526226Smrg 
1476af526226Smrg       case REG_SAVED_EXP:
1477af526226Smrg 	{
1478af526226Smrg 	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
1479af526226Smrg 	  _uleb128_t len;
1480af526226Smrg 	  _Unwind_Ptr val;
1481af526226Smrg 
1482af526226Smrg 	  exp = read_uleb128 (exp, &len);
1483af526226Smrg 	  val = execute_stack_op (exp, exp + len, &orig_context,
1484af526226Smrg 				  (_Unwind_Ptr) cfa);
1485af526226Smrg 	  _Unwind_SetGRPtr (context, i, (void *) val);
1486af526226Smrg 	}
1487af526226Smrg 	break;
1488af526226Smrg 
1489af526226Smrg       case REG_SAVED_VAL_OFFSET:
1490af526226Smrg 	_Unwind_SetGRValue (context, i,
1491af526226Smrg 			    (_Unwind_Internal_Ptr)
1492af526226Smrg 			    (cfa + fs->regs.reg[i].loc.offset));
1493af526226Smrg 	break;
1494af526226Smrg 
1495af526226Smrg       case REG_SAVED_VAL_EXP:
1496af526226Smrg 	{
1497af526226Smrg 	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
1498af526226Smrg 	  _uleb128_t len;
1499af526226Smrg 	  _Unwind_Ptr val;
1500af526226Smrg 
1501af526226Smrg 	  exp = read_uleb128 (exp, &len);
1502af526226Smrg 	  val = execute_stack_op (exp, exp + len, &orig_context,
1503af526226Smrg 				  (_Unwind_Ptr) cfa);
1504af526226Smrg 	  _Unwind_SetGRValue (context, i, val);
1505af526226Smrg 	}
1506af526226Smrg 	break;
1507af526226Smrg       }
1508af526226Smrg 
1509af526226Smrg   _Unwind_SetSignalFrame (context, fs->signal_frame);
1510af526226Smrg 
1511af526226Smrg #ifdef MD_FROB_UPDATE_CONTEXT
1512af526226Smrg   MD_FROB_UPDATE_CONTEXT (context, fs);
1513af526226Smrg #endif
1514af526226Smrg }
1515af526226Smrg 
1516af526226Smrg /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1517af526226Smrg    of its caller.  Update CONTEXT to refer to the caller as well.  Note
1518af526226Smrg    that the args_size and lsda members are not updated here, but later in
1519af526226Smrg    uw_frame_state_for.  */
1520af526226Smrg 
1521af526226Smrg static void
uw_update_context(struct _Unwind_Context * context,_Unwind_FrameState * fs)1522af526226Smrg uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1523af526226Smrg {
1524af526226Smrg   uw_update_context_1 (context, fs);
1525af526226Smrg 
1526af526226Smrg   /* In general this unwinder doesn't make any distinction between
1527af526226Smrg      undefined and same_value rule.  Call-saved registers are assumed
1528af526226Smrg      to have same_value rule by default and explicit undefined
1529af526226Smrg      rule is handled like same_value.  The only exception is
1530af526226Smrg      DW_CFA_undefined on retaddr_column which is supposed to
1531af526226Smrg      mark outermost frame in DWARF 3.  */
1532af526226Smrg   if (fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)].how
1533af526226Smrg       == REG_UNDEFINED)
1534af526226Smrg     /* uw_frame_state_for uses context->ra == 0 check to find outermost
1535af526226Smrg        stack frame.  */
1536af526226Smrg     context->ra = 0;
1537af526226Smrg   else
15383bf62c3fSmrg     {
1539af526226Smrg       /* Compute the return address now, since the return address column
1540af526226Smrg 	 can change from frame to frame.  */
1541*2f055536Smrg       void *ret_addr;
1542*2f055536Smrg #ifdef MD_DEMANGLE_RETURN_ADDR
1543*2f055536Smrg       _Unwind_Word ra = _Unwind_GetGR (context, fs->retaddr_column);
1544*2f055536Smrg       ret_addr = MD_DEMANGLE_RETURN_ADDR (context, fs, ra);
1545*2f055536Smrg #else
1546*2f055536Smrg       ret_addr = _Unwind_GetPtr (context, fs->retaddr_column);
15473bf62c3fSmrg #endif
1548*2f055536Smrg       context->ra = __builtin_extract_return_addr (ret_addr);
15493bf62c3fSmrg     }
1550af526226Smrg }
1551af526226Smrg 
1552af526226Smrg static void
uw_advance_context(struct _Unwind_Context * context,_Unwind_FrameState * fs)1553af526226Smrg uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1554af526226Smrg {
1555af526226Smrg   uw_update_context (context, fs);
1556af526226Smrg }
1557af526226Smrg 
1558af526226Smrg /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
1559af526226Smrg    level will be the return address and the CFA.  */
1560af526226Smrg 
1561af526226Smrg #define uw_init_context(CONTEXT)					   \
1562af526226Smrg   do									   \
1563af526226Smrg     {									   \
1564af526226Smrg       /* Do any necessary initialization to access arbitrary stack frames. \
1565af526226Smrg 	 On the SPARC, this means flushing the register windows.  */	   \
1566af526226Smrg       __builtin_unwind_init ();						   \
1567af526226Smrg       uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),		   \
1568af526226Smrg 			 __builtin_return_address (0));			   \
1569af526226Smrg     }									   \
1570af526226Smrg   while (0)
1571af526226Smrg 
1572af526226Smrg static inline void
init_dwarf_reg_size_table(void)1573af526226Smrg init_dwarf_reg_size_table (void)
1574af526226Smrg {
1575af526226Smrg   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1576af526226Smrg }
1577af526226Smrg 
1578af526226Smrg static void __attribute__((noinline))
uw_init_context_1(struct _Unwind_Context * context,void * outer_cfa,void * outer_ra)1579af526226Smrg uw_init_context_1 (struct _Unwind_Context *context,
1580af526226Smrg 		   void *outer_cfa, void *outer_ra)
1581af526226Smrg {
1582af526226Smrg   void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1583af526226Smrg   _Unwind_FrameState fs;
1584af526226Smrg   _Unwind_SpTmp sp_slot;
1585af526226Smrg   _Unwind_Reason_Code code;
1586af526226Smrg 
1587af526226Smrg   memset (context, 0, sizeof (struct _Unwind_Context));
1588af526226Smrg   context->ra = ra;
1589af526226Smrg   if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1590af526226Smrg     context->flags = EXTENDED_CONTEXT_BIT;
1591af526226Smrg 
1592af526226Smrg   code = uw_frame_state_for (context, &fs);
1593af526226Smrg   gcc_assert (code == _URC_NO_REASON);
1594af526226Smrg 
1595af526226Smrg #if __GTHREADS
1596af526226Smrg   {
1597af526226Smrg     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1598af526226Smrg     if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1599af526226Smrg 	&& dwarf_reg_size_table[0] == 0)
1600af526226Smrg       init_dwarf_reg_size_table ();
1601af526226Smrg   }
1602af526226Smrg #else
1603af526226Smrg   if (dwarf_reg_size_table[0] == 0)
1604af526226Smrg     init_dwarf_reg_size_table ();
1605af526226Smrg #endif
1606af526226Smrg 
1607af526226Smrg   /* Force the frame state to use the known cfa value.  */
1608af526226Smrg   _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1609af526226Smrg   fs.regs.cfa_how = CFA_REG_OFFSET;
1610af526226Smrg   fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1611af526226Smrg   fs.regs.cfa_offset = 0;
1612af526226Smrg 
1613af526226Smrg   uw_update_context_1 (context, &fs);
1614af526226Smrg 
1615af526226Smrg   /* If the return address column was saved in a register in the
1616af526226Smrg      initialization context, then we can't see it in the given
1617af526226Smrg      call frame data.  So have the initialization context tell us.  */
1618af526226Smrg   context->ra = __builtin_extract_return_addr (outer_ra);
1619af526226Smrg }
1620af526226Smrg 
1621af526226Smrg static void _Unwind_DebugHook (void *, void *)
1622af526226Smrg   __attribute__ ((__noinline__, __used__, __noclone__));
1623af526226Smrg 
1624af526226Smrg /* This function is called during unwinding.  It is intended as a hook
1625af526226Smrg    for a debugger to intercept exceptions.  CFA is the CFA of the
1626af526226Smrg    target frame.  HANDLER is the PC to which control will be
1627af526226Smrg    transferred.  */
1628af526226Smrg static void
_Unwind_DebugHook(void * cfa,void * handler)1629af526226Smrg _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1630af526226Smrg 		   void *handler __attribute__ ((__unused__)))
1631af526226Smrg {
1632af526226Smrg   /* We only want to use stap probes starting with v3.  Earlier
1633af526226Smrg      versions added too much startup cost.  */
1634af526226Smrg #if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
1635af526226Smrg   STAP_PROBE2 (libgcc, unwind, cfa, handler);
1636af526226Smrg #else
1637af526226Smrg   asm ("");
1638af526226Smrg #endif
1639af526226Smrg }
1640af526226Smrg 
1641af526226Smrg /* Install TARGET into CURRENT so that we can return to it.  This is a
1642af526226Smrg    macro because __builtin_eh_return must be invoked in the context of
1643e56e5d0aSmrg    our caller.  FRAMES is a number of frames to be unwind.
1644e56e5d0aSmrg    _Unwind_Frames_Extra is a macro to do additional work during unwinding
1645e56e5d0aSmrg    if needed, for example shadow stack pointer adjustment for Intel CET
1646e56e5d0aSmrg    technology.  */
1647af526226Smrg 
1648e56e5d0aSmrg #define uw_install_context(CURRENT, TARGET, FRAMES)			\
1649af526226Smrg   do									\
1650af526226Smrg     {									\
1651af526226Smrg       long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
1652*2f055536Smrg       void *handler = __builtin_frob_return_addr ((TARGET)->ra);	\
1653af526226Smrg       _Unwind_DebugHook ((TARGET)->cfa, handler);			\
1654e56e5d0aSmrg       _Unwind_Frames_Extra (FRAMES);					\
1655af526226Smrg       __builtin_eh_return (offset, handler);				\
1656af526226Smrg     }									\
1657af526226Smrg   while (0)
1658af526226Smrg 
1659af526226Smrg static long
uw_install_context_1(struct _Unwind_Context * current,struct _Unwind_Context * target)1660af526226Smrg uw_install_context_1 (struct _Unwind_Context *current,
1661af526226Smrg 		      struct _Unwind_Context *target)
1662af526226Smrg {
1663af526226Smrg   long i;
1664af526226Smrg   _Unwind_SpTmp sp_slot;
1665af526226Smrg 
1666af526226Smrg   /* If the target frame does not have a saved stack pointer,
1667af526226Smrg      then set up the target's CFA.  */
1668af526226Smrg   if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1669af526226Smrg     _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1670af526226Smrg 
16714646d632Smrg   for (i = 0; i < __LIBGCC_DWARF_FRAME_REGISTERS__; ++i)
1672af526226Smrg     {
1673af526226Smrg       void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
1674af526226Smrg       void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
1675af526226Smrg 
1676af526226Smrg       gcc_assert (current->by_value[i] == 0);
1677af526226Smrg       if (target->by_value[i] && c)
1678af526226Smrg 	{
1679af526226Smrg 	  _Unwind_Word w;
1680af526226Smrg 	  _Unwind_Ptr p;
1681af526226Smrg 	  if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1682af526226Smrg 	    {
1683af526226Smrg 	      w = (_Unwind_Internal_Ptr) t;
1684af526226Smrg 	      memcpy (c, &w, sizeof (_Unwind_Word));
1685af526226Smrg 	    }
1686af526226Smrg 	  else
1687af526226Smrg 	    {
1688af526226Smrg 	      gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1689af526226Smrg 	      p = (_Unwind_Internal_Ptr) t;
1690af526226Smrg 	      memcpy (c, &p, sizeof (_Unwind_Ptr));
1691af526226Smrg 	    }
1692af526226Smrg 	}
1693af526226Smrg       else if (t && c && t != c)
1694af526226Smrg 	memcpy (c, t, dwarf_reg_size_table[i]);
1695af526226Smrg     }
1696af526226Smrg 
1697af526226Smrg   /* If the current frame doesn't have a saved stack pointer, then we
1698af526226Smrg      need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1699af526226Smrg      pointer value reloaded.  */
1700af526226Smrg   if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1701af526226Smrg     {
1702af526226Smrg       void *target_cfa;
1703af526226Smrg 
1704af526226Smrg       target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1705af526226Smrg 
1706af526226Smrg       /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
17074646d632Smrg       if (__LIBGCC_STACK_GROWS_DOWNWARD__)
1708af526226Smrg 	return target_cfa - current->cfa + target->args_size;
1709af526226Smrg       else
1710af526226Smrg 	return current->cfa - target_cfa - target->args_size;
1711af526226Smrg     }
1712af526226Smrg   return 0;
1713af526226Smrg }
1714af526226Smrg 
1715af526226Smrg static inline _Unwind_Ptr
uw_identify_context(struct _Unwind_Context * context)1716af526226Smrg uw_identify_context (struct _Unwind_Context *context)
1717af526226Smrg {
1718af526226Smrg   /* The CFA is not sufficient to disambiguate the context of a function
1719af526226Smrg      interrupted by a signal before establishing its frame and the context
1720af526226Smrg      of the signal itself.  */
17214646d632Smrg   if (__LIBGCC_STACK_GROWS_DOWNWARD__)
1722af526226Smrg     return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
1723af526226Smrg   else
1724af526226Smrg     return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
1725af526226Smrg }
1726af526226Smrg 
1727af526226Smrg 
1728af526226Smrg #include "unwind.inc"
1729af526226Smrg 
1730af526226Smrg #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1731af526226Smrg alias (_Unwind_Backtrace);
1732af526226Smrg alias (_Unwind_DeleteException);
1733af526226Smrg alias (_Unwind_FindEnclosingFunction);
1734af526226Smrg alias (_Unwind_ForcedUnwind);
1735af526226Smrg alias (_Unwind_GetDataRelBase);
1736af526226Smrg alias (_Unwind_GetTextRelBase);
1737af526226Smrg alias (_Unwind_GetCFA);
1738af526226Smrg alias (_Unwind_GetGR);
1739af526226Smrg alias (_Unwind_GetIP);
1740af526226Smrg alias (_Unwind_GetLanguageSpecificData);
1741af526226Smrg alias (_Unwind_GetRegionStart);
1742af526226Smrg alias (_Unwind_RaiseException);
1743af526226Smrg alias (_Unwind_Resume);
1744af526226Smrg alias (_Unwind_Resume_or_Rethrow);
1745af526226Smrg alias (_Unwind_SetGR);
1746af526226Smrg alias (_Unwind_SetIP);
1747af526226Smrg #endif
1748af526226Smrg 
1749af526226Smrg #endif /* !USING_SJLJ_EXCEPTIONS */
1750