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