xref: /trueos/contrib/gcc/unwind-dw2.c (revision 1e5107043085964bba002e6a91aa04e864f74d02)
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.  */
66 struct _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.  */
86 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
87 
88 
89 /* Read unaligned data from the instruction buffer.  */
90 
91 union 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 
102 static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
103 static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
104 					       _Unwind_FrameState *);
105 
106 static inline void *
read_pointer(const void * p)107 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
108 
109 static inline int
read_1u(const void * p)110 read_1u (const void *p) { return *(const unsigned char *) p; }
111 
112 static inline int
read_1s(const void * p)113 read_1s (const void *p) { return *(const signed char *) p; }
114 
115 static inline int
read_2u(const void * p)116 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
117 
118 static inline int
read_2s(const void * p)119 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
120 
121 static inline unsigned int
read_4u(const void * p)122 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
123 
124 static inline int
read_4s(const void * p)125 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
126 
127 static inline unsigned long
read_8u(const void * p)128 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
129 
130 static inline unsigned long
read_8s(const void * p)131 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
132 
133 static inline _Unwind_Word
_Unwind_IsSignalFrame(struct _Unwind_Context * context)134 _Unwind_IsSignalFrame (struct _Unwind_Context *context)
135 {
136   return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
137 }
138 
139 static inline void
_Unwind_SetSignalFrame(struct _Unwind_Context * context,int val)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 
148 static inline _Unwind_Word
_Unwind_IsExtendedContext(struct _Unwind_Context * context)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 
156 inline _Unwind_Word
_Unwind_GetGR(struct _Unwind_Context * context,int index)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 
185 static inline void *
_Unwind_GetPtr(struct _Unwind_Context * context,int index)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
_Unwind_GetCFA(struct _Unwind_Context * context)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 
201 inline void
_Unwind_SetGR(struct _Unwind_Context * context,int index,_Unwind_Word val)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 
230 static inline void *
_Unwind_GetGRPtr(struct _Unwind_Context * context,int index)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 
241 static inline void
_Unwind_SetGRPtr(struct _Unwind_Context * context,int index,void * p)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 
252 static inline void
_Unwind_SetGRValue(struct _Unwind_Context * context,int index,_Unwind_Word val)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 
267 static inline int
_Unwind_GRByValue(struct _Unwind_Context * context,int index)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 
276 inline _Unwind_Ptr
_Unwind_GetIP(struct _Unwind_Context * context)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 
285 inline _Unwind_Ptr
_Unwind_GetIPInfo(struct _Unwind_Context * context,int * ip_before_insn)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 
294 inline void
_Unwind_SetIP(struct _Unwind_Context * context,_Unwind_Ptr val)295 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
296 {
297   context->ra = (void *) val;
298 }
299 
300 void *
_Unwind_GetLanguageSpecificData(struct _Unwind_Context * context)301 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
302 {
303   return context->lsda;
304 }
305 
306 _Unwind_Ptr
_Unwind_GetRegionStart(struct _Unwind_Context * context)307 _Unwind_GetRegionStart (struct _Unwind_Context *context)
308 {
309   return (_Unwind_Ptr) context->bases.func;
310 }
311 
312 void *
_Unwind_FindEnclosingFunction(void * pc)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
_Unwind_GetDataRelBase(struct _Unwind_Context * context)325 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
326 {
327   return (_Unwind_Ptr) context->bases.dbase;
328 }
329 
330 _Unwind_Ptr
_Unwind_GetTextRelBase(struct _Unwind_Context * context)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 
345 static const unsigned char *
extract_cie_info(const struct dwarf_cie * cie,struct _Unwind_Context * context,_Unwind_FrameState * fs)346 extract_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 
432 static _Unwind_Word
execute_stack_op(const unsigned char * op_ptr,const unsigned char * op_end,struct _Unwind_Context * context,_Unwind_Word initial)433 execute_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 
846 static void
execute_cfa_program(const unsigned char * insn_ptr,const unsigned char * insn_end,struct _Unwind_Context * context,_Unwind_FrameState * fs)847 execute_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 
1092 static _Unwind_Reason_Code
uw_frame_state_for(struct _Unwind_Context * context,_Unwind_FrameState * fs)1093 uw_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 
1159 typedef 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 
1171 struct 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 
1177 struct frame_state *
__frame_state_for(void * pc_target,struct frame_state * state_in)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 
1222 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1223 
1224 static inline void
_Unwind_SetSpColumn(struct _Unwind_Context * context,void * cfa,_Unwind_SpTmp * tmp_sp)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 
1240 static void
uw_update_context_1(struct _Unwind_Context * context,_Unwind_FrameState * fs)1241 uw_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 
1362 static void
uw_update_context(struct _Unwind_Context * context,_Unwind_FrameState * fs)1363 uw_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 
1373 static void
uw_advance_context(struct _Unwind_Context * context,_Unwind_FrameState * fs)1374 uw_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 
1393 static inline void
init_dwarf_reg_size_table(void)1394 init_dwarf_reg_size_table (void)
1395 {
1396   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1397 }
1398 
1399 static void
uw_init_context_1(struct _Unwind_Context * context,void * outer_cfa,void * outer_ra)1400 uw_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 
1455 static long
uw_install_context_1(struct _Unwind_Context * current,struct _Unwind_Context * target)1456 uw_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 
1511 static inline _Unwind_Ptr
uw_identify_context(struct _Unwind_Context * context)1512 uw_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)
1521 alias (_Unwind_Backtrace);
1522 alias (_Unwind_DeleteException);
1523 alias (_Unwind_FindEnclosingFunction);
1524 alias (_Unwind_ForcedUnwind);
1525 alias (_Unwind_GetDataRelBase);
1526 alias (_Unwind_GetTextRelBase);
1527 alias (_Unwind_GetCFA);
1528 alias (_Unwind_GetGR);
1529 alias (_Unwind_GetIP);
1530 alias (_Unwind_GetLanguageSpecificData);
1531 alias (_Unwind_GetRegionStart);
1532 alias (_Unwind_RaiseException);
1533 alias (_Unwind_Resume);
1534 alias (_Unwind_Resume_or_Rethrow);
1535 alias (_Unwind_SetGR);
1536 alias (_Unwind_SetIP);
1537 #endif
1538 
1539 #endif /* !USING_SJLJ_EXCEPTIONS */
1540