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