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