Fix DealII type problems.
[official-gcc/Ramakrishna.git] / gcc / unwind-dw2.c
blob28373c20bd865d2b36e3ce9b7ebfb648ece4ffd8
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2008, 2009 Free Software Foundation, Inc.
5 This file is part of GCC.
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 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 #include "tconfig.h"
27 #include "tsystem.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "dwarf2.h"
31 #include "unwind.h"
32 #ifdef __USING_SJLJ_EXCEPTIONS__
33 # define NO_SIZE_OF_ENCODED_VALUE
34 #endif
35 #include "unwind-pe.h"
36 #include "unwind-dw2-fde.h"
37 #include "gthr.h"
38 #include "unwind-dw2.h"
40 #ifndef __USING_SJLJ_EXCEPTIONS__
42 #ifndef STACK_GROWS_DOWNWARD
43 #define STACK_GROWS_DOWNWARD 0
44 #else
45 #undef STACK_GROWS_DOWNWARD
46 #define STACK_GROWS_DOWNWARD 1
47 #endif
49 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
50 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
51 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
52 #endif
54 #ifndef DWARF_REG_TO_UNWIND_COLUMN
55 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
56 #endif
58 /* This is the register and unwind state for a particular frame. This
59 provides the information necessary to unwind up past a frame and return
60 to its caller. */
61 struct _Unwind_Context
63 void *reg[DWARF_FRAME_REGISTERS+1];
64 void *cfa;
65 void *ra;
66 void *lsda;
67 struct dwarf_eh_bases bases;
68 /* Signal frame context. */
69 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
70 /* Context which has version/args_size/by_value fields. */
71 #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
72 _Unwind_Word flags;
73 /* 0 for now, can be increased when further fields are added to
74 struct _Unwind_Context. */
75 _Unwind_Word version;
76 _Unwind_Word args_size;
77 char by_value[DWARF_FRAME_REGISTERS+1];
80 /* Byte size of every register managed by these routines. */
81 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
84 /* Read unaligned data from the instruction buffer. */
86 union unaligned
88 void *p;
89 unsigned u2 __attribute__ ((mode (HI)));
90 unsigned u4 __attribute__ ((mode (SI)));
91 unsigned u8 __attribute__ ((mode (DI)));
92 signed s2 __attribute__ ((mode (HI)));
93 signed s4 __attribute__ ((mode (SI)));
94 signed s8 __attribute__ ((mode (DI)));
95 } __attribute__ ((packed));
97 static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
98 static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
99 _Unwind_FrameState *);
101 static inline void *
102 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
104 static inline int
105 read_1u (const void *p) { return *(const unsigned char *) p; }
107 static inline int
108 read_1s (const void *p) { return *(const signed char *) p; }
110 static inline int
111 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
113 static inline int
114 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
116 static inline unsigned int
117 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
119 static inline int
120 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
122 static inline unsigned long
123 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
125 static inline unsigned long
126 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
128 static inline _Unwind_Word
129 _Unwind_IsSignalFrame (struct _Unwind_Context *context)
131 return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
134 static inline void
135 _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
137 if (val)
138 context->flags |= SIGNAL_FRAME_BIT;
139 else
140 context->flags &= ~SIGNAL_FRAME_BIT;
143 static inline _Unwind_Word
144 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
146 return context->flags & EXTENDED_CONTEXT_BIT;
149 /* Get the value of register INDEX as saved in CONTEXT. */
151 inline _Unwind_Word
152 _Unwind_GetGR (struct _Unwind_Context *context, int index)
154 int size;
155 void *ptr;
157 #ifdef DWARF_ZERO_REG
158 if (index == DWARF_ZERO_REG)
159 return 0;
160 #endif
162 index = DWARF_REG_TO_UNWIND_COLUMN (index);
163 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
164 size = dwarf_reg_size_table[index];
165 ptr = context->reg[index];
167 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
168 return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
170 /* This will segfault if the register hasn't been saved. */
171 if (size == sizeof(_Unwind_Ptr))
172 return * (_Unwind_Ptr *) ptr;
173 else
175 gcc_assert (size == sizeof(_Unwind_Word));
176 return * (_Unwind_Word *) ptr;
180 static inline void *
181 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
183 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
186 /* Get the value of the CFA as saved in CONTEXT. */
188 _Unwind_Word
189 _Unwind_GetCFA (struct _Unwind_Context *context)
191 return (_Unwind_Ptr) context->cfa;
194 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
196 inline void
197 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
199 int size;
200 void *ptr;
202 index = DWARF_REG_TO_UNWIND_COLUMN (index);
203 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
204 size = dwarf_reg_size_table[index];
206 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
208 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
209 return;
212 ptr = context->reg[index];
214 if (size == sizeof(_Unwind_Ptr))
215 * (_Unwind_Ptr *) ptr = val;
216 else
218 gcc_assert (size == sizeof(_Unwind_Word));
219 * (_Unwind_Word *) ptr = val;
223 /* Get the pointer to a register INDEX as saved in CONTEXT. */
225 static inline void *
226 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
228 index = DWARF_REG_TO_UNWIND_COLUMN (index);
229 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
230 return &context->reg[index];
231 return context->reg[index];
234 /* Set the pointer to a register INDEX as saved in CONTEXT. */
236 static inline void
237 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
239 index = DWARF_REG_TO_UNWIND_COLUMN (index);
240 if (_Unwind_IsExtendedContext (context))
241 context->by_value[index] = 0;
242 context->reg[index] = p;
245 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
247 static inline void
248 _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
249 _Unwind_Word val)
251 index = DWARF_REG_TO_UNWIND_COLUMN (index);
252 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
253 gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
255 context->by_value[index] = 1;
256 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
259 /* Return nonzero if register INDEX is stored by value rather than
260 by reference. */
262 static inline int
263 _Unwind_GRByValue (struct _Unwind_Context *context, int index)
265 index = DWARF_REG_TO_UNWIND_COLUMN (index);
266 return context->by_value[index];
269 /* Retrieve the return address for CONTEXT. */
271 inline _Unwind_Ptr
272 _Unwind_GetIP (struct _Unwind_Context *context)
274 return (_Unwind_Ptr) context->ra;
277 /* Retrieve the return address and flag whether that IP is before
278 or after first not yet fully executed instruction. */
280 inline _Unwind_Ptr
281 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
283 *ip_before_insn = _Unwind_IsSignalFrame (context);
284 return (_Unwind_Ptr) context->ra;
287 /* Overwrite the return address for CONTEXT with VAL. */
289 inline void
290 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
292 context->ra = (void *) val;
295 void *
296 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
298 return context->lsda;
301 _Unwind_Ptr
302 _Unwind_GetRegionStart (struct _Unwind_Context *context)
304 return (_Unwind_Ptr) context->bases.func;
307 void *
308 _Unwind_FindEnclosingFunction (void *pc)
310 struct dwarf_eh_bases bases;
311 const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
312 if (fde)
313 return bases.func;
314 else
315 return NULL;
318 #ifndef __ia64__
319 _Unwind_Ptr
320 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
322 return (_Unwind_Ptr) context->bases.dbase;
325 _Unwind_Ptr
326 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
328 return (_Unwind_Ptr) context->bases.tbase;
330 #endif
332 #ifdef MD_UNWIND_SUPPORT
333 #include MD_UNWIND_SUPPORT
334 #endif
336 /* Extract any interesting information from the CIE for the translation
337 unit F belongs to. Return a pointer to the byte after the augmentation,
338 or NULL if we encountered an undecipherable augmentation. */
340 static const unsigned char *
341 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
342 _Unwind_FrameState *fs)
344 const unsigned char *aug = cie->augmentation;
345 const unsigned char *p = aug + strlen ((const char *)aug) + 1;
346 const unsigned char *ret = NULL;
347 _uleb128_t utmp;
348 _sleb128_t stmp;
350 /* g++ v2 "eh" has pointer immediately following augmentation string,
351 so it must be handled first. */
352 if (aug[0] == 'e' && aug[1] == 'h')
354 fs->eh_ptr = read_pointer (p);
355 p += sizeof (void *);
356 aug += 2;
359 /* Immediately following the augmentation are the code and
360 data alignment and return address column. */
361 p = read_uleb128 (p, &utmp);
362 fs->code_align = (_Unwind_Word)utmp;
363 p = read_sleb128 (p, &stmp);
364 fs->data_align = (_Unwind_Sword)stmp;
365 if (cie->version == 1)
366 fs->retaddr_column = *p++;
367 else
369 p = read_uleb128 (p, &utmp);
370 fs->retaddr_column = (_Unwind_Word)utmp;
372 fs->lsda_encoding = DW_EH_PE_omit;
374 /* If the augmentation starts with 'z', then a uleb128 immediately
375 follows containing the length of the augmentation field following
376 the size. */
377 if (*aug == 'z')
379 p = read_uleb128 (p, &utmp);
380 ret = p + utmp;
382 fs->saw_z = 1;
383 ++aug;
386 /* Iterate over recognized augmentation subsequences. */
387 while (*aug != '\0')
389 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
390 if (aug[0] == 'L')
392 fs->lsda_encoding = *p++;
393 aug += 1;
396 /* "R" indicates a byte indicating how FDE addresses are encoded. */
397 else if (aug[0] == 'R')
399 fs->fde_encoding = *p++;
400 aug += 1;
403 /* "P" indicates a personality routine in the CIE augmentation. */
404 else if (aug[0] == 'P')
406 _Unwind_Ptr personality;
408 p = read_encoded_value (context, *p, p + 1, &personality);
409 fs->personality = (_Unwind_Personality_Fn) personality;
410 aug += 1;
413 /* "S" indicates a signal frame. */
414 else if (aug[0] == 'S')
416 fs->signal_frame = 1;
417 aug += 1;
420 /* Otherwise we have an unknown augmentation string.
421 Bail unless we saw a 'z' prefix. */
422 else
423 return ret;
426 return ret ? ret : p;
430 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
431 onto the stack to start. */
433 static _Unwind_Word
434 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
435 struct _Unwind_Context *context, _Unwind_Word initial)
437 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
438 int stack_elt;
440 stack[0] = initial;
441 stack_elt = 1;
443 while (op_ptr < op_end)
445 enum dwarf_location_atom op = *op_ptr++;
446 _Unwind_Word result;
447 _uleb128_t reg, utmp;
448 _sleb128_t offset, stmp;
450 switch (op)
452 case DW_OP_lit0:
453 case DW_OP_lit1:
454 case DW_OP_lit2:
455 case DW_OP_lit3:
456 case DW_OP_lit4:
457 case DW_OP_lit5:
458 case DW_OP_lit6:
459 case DW_OP_lit7:
460 case DW_OP_lit8:
461 case DW_OP_lit9:
462 case DW_OP_lit10:
463 case DW_OP_lit11:
464 case DW_OP_lit12:
465 case DW_OP_lit13:
466 case DW_OP_lit14:
467 case DW_OP_lit15:
468 case DW_OP_lit16:
469 case DW_OP_lit17:
470 case DW_OP_lit18:
471 case DW_OP_lit19:
472 case DW_OP_lit20:
473 case DW_OP_lit21:
474 case DW_OP_lit22:
475 case DW_OP_lit23:
476 case DW_OP_lit24:
477 case DW_OP_lit25:
478 case DW_OP_lit26:
479 case DW_OP_lit27:
480 case DW_OP_lit28:
481 case DW_OP_lit29:
482 case DW_OP_lit30:
483 case DW_OP_lit31:
484 result = op - DW_OP_lit0;
485 break;
487 case DW_OP_addr:
488 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
489 op_ptr += sizeof (void *);
490 break;
492 case DW_OP_GNU_encoded_addr:
494 _Unwind_Ptr presult;
495 op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
496 result = presult;
498 break;
500 case DW_OP_const1u:
501 result = read_1u (op_ptr);
502 op_ptr += 1;
503 break;
504 case DW_OP_const1s:
505 result = read_1s (op_ptr);
506 op_ptr += 1;
507 break;
508 case DW_OP_const2u:
509 result = read_2u (op_ptr);
510 op_ptr += 2;
511 break;
512 case DW_OP_const2s:
513 result = read_2s (op_ptr);
514 op_ptr += 2;
515 break;
516 case DW_OP_const4u:
517 result = read_4u (op_ptr);
518 op_ptr += 4;
519 break;
520 case DW_OP_const4s:
521 result = read_4s (op_ptr);
522 op_ptr += 4;
523 break;
524 case DW_OP_const8u:
525 result = read_8u (op_ptr);
526 op_ptr += 8;
527 break;
528 case DW_OP_const8s:
529 result = read_8s (op_ptr);
530 op_ptr += 8;
531 break;
532 case DW_OP_constu:
533 op_ptr = read_uleb128 (op_ptr, &utmp);
534 result = (_Unwind_Word)utmp;
535 break;
536 case DW_OP_consts:
537 op_ptr = read_sleb128 (op_ptr, &stmp);
538 result = (_Unwind_Sword)stmp;
539 break;
541 case DW_OP_reg0:
542 case DW_OP_reg1:
543 case DW_OP_reg2:
544 case DW_OP_reg3:
545 case DW_OP_reg4:
546 case DW_OP_reg5:
547 case DW_OP_reg6:
548 case DW_OP_reg7:
549 case DW_OP_reg8:
550 case DW_OP_reg9:
551 case DW_OP_reg10:
552 case DW_OP_reg11:
553 case DW_OP_reg12:
554 case DW_OP_reg13:
555 case DW_OP_reg14:
556 case DW_OP_reg15:
557 case DW_OP_reg16:
558 case DW_OP_reg17:
559 case DW_OP_reg18:
560 case DW_OP_reg19:
561 case DW_OP_reg20:
562 case DW_OP_reg21:
563 case DW_OP_reg22:
564 case DW_OP_reg23:
565 case DW_OP_reg24:
566 case DW_OP_reg25:
567 case DW_OP_reg26:
568 case DW_OP_reg27:
569 case DW_OP_reg28:
570 case DW_OP_reg29:
571 case DW_OP_reg30:
572 case DW_OP_reg31:
573 result = _Unwind_GetGR (context, op - DW_OP_reg0);
574 break;
575 case DW_OP_regx:
576 op_ptr = read_uleb128 (op_ptr, &reg);
577 result = _Unwind_GetGR (context, reg);
578 break;
580 case DW_OP_breg0:
581 case DW_OP_breg1:
582 case DW_OP_breg2:
583 case DW_OP_breg3:
584 case DW_OP_breg4:
585 case DW_OP_breg5:
586 case DW_OP_breg6:
587 case DW_OP_breg7:
588 case DW_OP_breg8:
589 case DW_OP_breg9:
590 case DW_OP_breg10:
591 case DW_OP_breg11:
592 case DW_OP_breg12:
593 case DW_OP_breg13:
594 case DW_OP_breg14:
595 case DW_OP_breg15:
596 case DW_OP_breg16:
597 case DW_OP_breg17:
598 case DW_OP_breg18:
599 case DW_OP_breg19:
600 case DW_OP_breg20:
601 case DW_OP_breg21:
602 case DW_OP_breg22:
603 case DW_OP_breg23:
604 case DW_OP_breg24:
605 case DW_OP_breg25:
606 case DW_OP_breg26:
607 case DW_OP_breg27:
608 case DW_OP_breg28:
609 case DW_OP_breg29:
610 case DW_OP_breg30:
611 case DW_OP_breg31:
612 op_ptr = read_sleb128 (op_ptr, &offset);
613 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
614 break;
615 case DW_OP_bregx:
616 op_ptr = read_uleb128 (op_ptr, &reg);
617 op_ptr = read_sleb128 (op_ptr, &offset);
618 result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
619 break;
621 case DW_OP_dup:
622 gcc_assert (stack_elt);
623 result = stack[stack_elt - 1];
624 break;
626 case DW_OP_drop:
627 gcc_assert (stack_elt);
628 stack_elt -= 1;
629 goto no_push;
631 case DW_OP_pick:
632 offset = *op_ptr++;
633 gcc_assert (offset < stack_elt - 1);
634 result = stack[stack_elt - 1 - offset];
635 break;
637 case DW_OP_over:
638 gcc_assert (stack_elt >= 2);
639 result = stack[stack_elt - 2];
640 break;
642 case DW_OP_swap:
644 _Unwind_Word t;
645 gcc_assert (stack_elt >= 2);
646 t = stack[stack_elt - 1];
647 stack[stack_elt - 1] = stack[stack_elt - 2];
648 stack[stack_elt - 2] = t;
649 goto no_push;
652 case DW_OP_rot:
654 _Unwind_Word t1, t2, t3;
656 gcc_assert (stack_elt >= 3);
657 t1 = stack[stack_elt - 1];
658 t2 = stack[stack_elt - 2];
659 t3 = stack[stack_elt - 3];
660 stack[stack_elt - 1] = t2;
661 stack[stack_elt - 2] = t3;
662 stack[stack_elt - 3] = t1;
663 goto no_push;
666 case DW_OP_deref:
667 case DW_OP_deref_size:
668 case DW_OP_abs:
669 case DW_OP_neg:
670 case DW_OP_not:
671 case DW_OP_plus_uconst:
672 /* Unary operations. */
673 gcc_assert (stack_elt);
674 stack_elt -= 1;
676 result = stack[stack_elt];
678 switch (op)
680 case DW_OP_deref:
682 void *ptr = (void *) (_Unwind_Ptr) result;
683 result = (_Unwind_Ptr) read_pointer (ptr);
685 break;
687 case DW_OP_deref_size:
689 void *ptr = (void *) (_Unwind_Ptr) result;
690 switch (*op_ptr++)
692 case 1:
693 result = read_1u (ptr);
694 break;
695 case 2:
696 result = read_2u (ptr);
697 break;
698 case 4:
699 result = read_4u (ptr);
700 break;
701 case 8:
702 result = read_8u (ptr);
703 break;
704 default:
705 gcc_unreachable ();
708 break;
710 case DW_OP_abs:
711 if ((_Unwind_Sword) result < 0)
712 result = -result;
713 break;
714 case DW_OP_neg:
715 result = -result;
716 break;
717 case DW_OP_not:
718 result = ~result;
719 break;
720 case DW_OP_plus_uconst:
721 op_ptr = read_uleb128 (op_ptr, &utmp);
722 result += (_Unwind_Word)utmp;
723 break;
725 default:
726 gcc_unreachable ();
728 break;
730 case DW_OP_and:
731 case DW_OP_div:
732 case DW_OP_minus:
733 case DW_OP_mod:
734 case DW_OP_mul:
735 case DW_OP_or:
736 case DW_OP_plus:
737 case DW_OP_shl:
738 case DW_OP_shr:
739 case DW_OP_shra:
740 case DW_OP_xor:
741 case DW_OP_le:
742 case DW_OP_ge:
743 case DW_OP_eq:
744 case DW_OP_lt:
745 case DW_OP_gt:
746 case DW_OP_ne:
748 /* Binary operations. */
749 _Unwind_Word first, second;
750 gcc_assert (stack_elt >= 2);
751 stack_elt -= 2;
753 second = stack[stack_elt];
754 first = stack[stack_elt + 1];
756 switch (op)
758 case DW_OP_and:
759 result = second & first;
760 break;
761 case DW_OP_div:
762 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
763 break;
764 case DW_OP_minus:
765 result = second - first;
766 break;
767 case DW_OP_mod:
768 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
769 break;
770 case DW_OP_mul:
771 result = second * first;
772 break;
773 case DW_OP_or:
774 result = second | first;
775 break;
776 case DW_OP_plus:
777 result = second + first;
778 break;
779 case DW_OP_shl:
780 result = second << first;
781 break;
782 case DW_OP_shr:
783 result = second >> first;
784 break;
785 case DW_OP_shra:
786 result = (_Unwind_Sword) second >> first;
787 break;
788 case DW_OP_xor:
789 result = second ^ first;
790 break;
791 case DW_OP_le:
792 result = (_Unwind_Sword) second <= (_Unwind_Sword) first;
793 break;
794 case DW_OP_ge:
795 result = (_Unwind_Sword) second >= (_Unwind_Sword) first;
796 break;
797 case DW_OP_eq:
798 result = (_Unwind_Sword) second == (_Unwind_Sword) first;
799 break;
800 case DW_OP_lt:
801 result = (_Unwind_Sword) second < (_Unwind_Sword) first;
802 break;
803 case DW_OP_gt:
804 result = (_Unwind_Sword) second > (_Unwind_Sword) first;
805 break;
806 case DW_OP_ne:
807 result = (_Unwind_Sword) second != (_Unwind_Sword) first;
808 break;
810 default:
811 gcc_unreachable ();
814 break;
816 case DW_OP_skip:
817 offset = read_2s (op_ptr);
818 op_ptr += 2;
819 op_ptr += offset;
820 goto no_push;
822 case DW_OP_bra:
823 gcc_assert (stack_elt);
824 stack_elt -= 1;
826 offset = read_2s (op_ptr);
827 op_ptr += 2;
828 if (stack[stack_elt] != 0)
829 op_ptr += offset;
830 goto no_push;
832 case DW_OP_nop:
833 goto no_push;
835 default:
836 gcc_unreachable ();
839 /* Most things push a result value. */
840 gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
841 stack[stack_elt++] = result;
842 no_push:;
845 /* We were executing this program to get a value. It should be
846 at top of stack. */
847 gcc_assert (stack_elt);
848 stack_elt -= 1;
849 return stack[stack_elt];
853 /* Decode DWARF 2 call frame information. Takes pointers the
854 instruction sequence to decode, current register information and
855 CIE info, and the PC range to evaluate. */
857 static void
858 execute_cfa_program (const unsigned char *insn_ptr,
859 const unsigned char *insn_end,
860 struct _Unwind_Context *context,
861 _Unwind_FrameState *fs)
863 struct frame_state_reg_info *unused_rs = NULL;
865 /* Don't allow remember/restore between CIE and FDE programs. */
866 fs->regs.prev = NULL;
868 /* The comparison with the return address uses < rather than <= because
869 we are only interested in the effects of code before the call; for a
870 noreturn function, the return address may point to unrelated code with
871 a different stack configuration that we are not interested in. We
872 assume that the call itself is unwind info-neutral; if not, or if
873 there are delay instructions that adjust the stack, these must be
874 reflected at the point immediately before the call insn.
875 In signal frames, return address is after last completed instruction,
876 so we add 1 to return address to make the comparison <=. */
877 while (insn_ptr < insn_end
878 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
880 unsigned char insn = *insn_ptr++;
881 _uleb128_t reg, utmp;
882 _sleb128_t offset, stmp;
884 if ((insn & 0xc0) == DW_CFA_advance_loc)
885 fs->pc += (insn & 0x3f) * fs->code_align;
886 else if ((insn & 0xc0) == DW_CFA_offset)
888 reg = insn & 0x3f;
889 insn_ptr = read_uleb128 (insn_ptr, &utmp);
890 offset = (_Unwind_Sword) utmp * fs->data_align;
891 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
892 = REG_SAVED_OFFSET;
893 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
895 else if ((insn & 0xc0) == DW_CFA_restore)
897 reg = insn & 0x3f;
898 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
900 else switch (insn)
902 case DW_CFA_set_loc:
904 _Unwind_Ptr pc;
906 insn_ptr = read_encoded_value (context, fs->fde_encoding,
907 insn_ptr, &pc);
908 fs->pc = (void *) pc;
910 break;
912 case DW_CFA_advance_loc1:
913 fs->pc += read_1u (insn_ptr) * fs->code_align;
914 insn_ptr += 1;
915 break;
916 case DW_CFA_advance_loc2:
917 fs->pc += read_2u (insn_ptr) * fs->code_align;
918 insn_ptr += 2;
919 break;
920 case DW_CFA_advance_loc4:
921 fs->pc += read_4u (insn_ptr) * fs->code_align;
922 insn_ptr += 4;
923 break;
925 case DW_CFA_offset_extended:
926 insn_ptr = read_uleb128 (insn_ptr, &reg);
927 insn_ptr = read_uleb128 (insn_ptr, &utmp);
928 offset = (_Unwind_Sword) utmp * fs->data_align;
929 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
930 = REG_SAVED_OFFSET;
931 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
932 break;
934 case DW_CFA_restore_extended:
935 insn_ptr = read_uleb128 (insn_ptr, &reg);
936 /* FIXME, this is wrong; the CIE might have said that the
937 register was saved somewhere. */
938 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
939 break;
941 case DW_CFA_same_value:
942 insn_ptr = read_uleb128 (insn_ptr, &reg);
943 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
944 break;
946 case DW_CFA_undefined:
947 insn_ptr = read_uleb128 (insn_ptr, &reg);
948 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNDEFINED;
949 break;
951 case DW_CFA_nop:
952 break;
954 case DW_CFA_register:
956 _uleb128_t reg2;
957 insn_ptr = read_uleb128 (insn_ptr, &reg);
958 insn_ptr = read_uleb128 (insn_ptr, &reg2);
959 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
960 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg =
961 (_Unwind_Word)reg2;
963 break;
965 case DW_CFA_remember_state:
967 struct frame_state_reg_info *new_rs;
968 if (unused_rs)
970 new_rs = unused_rs;
971 unused_rs = unused_rs->prev;
973 else
974 new_rs = alloca (sizeof (struct frame_state_reg_info));
976 *new_rs = fs->regs;
977 fs->regs.prev = new_rs;
979 break;
981 case DW_CFA_restore_state:
983 struct frame_state_reg_info *old_rs = fs->regs.prev;
984 fs->regs = *old_rs;
985 old_rs->prev = unused_rs;
986 unused_rs = old_rs;
988 break;
990 case DW_CFA_def_cfa:
991 insn_ptr = read_uleb128 (insn_ptr, &utmp);
992 fs->regs.cfa_reg = (_Unwind_Word)utmp;
993 insn_ptr = read_uleb128 (insn_ptr, &utmp);
994 fs->regs.cfa_offset = (_Unwind_Word)utmp;
995 fs->regs.cfa_how = CFA_REG_OFFSET;
996 break;
998 case DW_CFA_def_cfa_register:
999 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1000 fs->regs.cfa_reg = (_Unwind_Word)utmp;
1001 fs->regs.cfa_how = CFA_REG_OFFSET;
1002 break;
1004 case DW_CFA_def_cfa_offset:
1005 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1006 fs->regs.cfa_offset = utmp;
1007 /* cfa_how deliberately not set. */
1008 break;
1010 case DW_CFA_def_cfa_expression:
1011 fs->regs.cfa_exp = insn_ptr;
1012 fs->regs.cfa_how = CFA_EXP;
1013 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1014 insn_ptr += utmp;
1015 break;
1017 case DW_CFA_expression:
1018 insn_ptr = read_uleb128 (insn_ptr, &reg);
1019 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
1020 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1021 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1022 insn_ptr += utmp;
1023 break;
1025 /* Dwarf3. */
1026 case DW_CFA_offset_extended_sf:
1027 insn_ptr = read_uleb128 (insn_ptr, &reg);
1028 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1029 offset = stmp * fs->data_align;
1030 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1031 = REG_SAVED_OFFSET;
1032 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1033 break;
1035 case DW_CFA_def_cfa_sf:
1036 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1037 fs->regs.cfa_reg = (_Unwind_Word)utmp;
1038 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1039 fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1040 fs->regs.cfa_how = CFA_REG_OFFSET;
1041 fs->regs.cfa_offset *= fs->data_align;
1042 break;
1044 case DW_CFA_def_cfa_offset_sf:
1045 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1046 fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1047 fs->regs.cfa_offset *= fs->data_align;
1048 /* cfa_how deliberately not set. */
1049 break;
1051 case DW_CFA_val_offset:
1052 insn_ptr = read_uleb128 (insn_ptr, &reg);
1053 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1054 offset = (_Unwind_Sword) utmp * fs->data_align;
1055 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1056 = REG_SAVED_VAL_OFFSET;
1057 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1058 break;
1060 case DW_CFA_val_offset_sf:
1061 insn_ptr = read_uleb128 (insn_ptr, &reg);
1062 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1063 offset = stmp * fs->data_align;
1064 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1065 = REG_SAVED_VAL_OFFSET;
1066 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1067 break;
1069 case DW_CFA_val_expression:
1070 insn_ptr = read_uleb128 (insn_ptr, &reg);
1071 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1072 = REG_SAVED_VAL_EXP;
1073 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1074 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1075 insn_ptr += utmp;
1076 break;
1078 case DW_CFA_GNU_window_save:
1079 /* ??? Hardcoded for SPARC register window configuration. */
1080 for (reg = 16; reg < 32; ++reg)
1082 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1083 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1085 break;
1087 case DW_CFA_GNU_args_size:
1088 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1089 context->args_size = (_Unwind_Word)utmp;
1090 break;
1092 case DW_CFA_GNU_negative_offset_extended:
1093 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1094 older PowerPC code. */
1095 insn_ptr = read_uleb128 (insn_ptr, &reg);
1096 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1097 offset = (_Unwind_Word) utmp * fs->data_align;
1098 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1099 = REG_SAVED_OFFSET;
1100 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
1101 break;
1103 default:
1104 gcc_unreachable ();
1109 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1110 its caller and decode it into FS. This function also sets the
1111 args_size and lsda members of CONTEXT, as they are really information
1112 about the caller's frame. */
1114 static _Unwind_Reason_Code
1115 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1117 const struct dwarf_fde *fde;
1118 const struct dwarf_cie *cie;
1119 const unsigned char *aug, *insn, *end;
1121 memset (fs, 0, sizeof (*fs));
1122 context->args_size = 0;
1123 context->lsda = 0;
1125 if (context->ra == 0)
1126 return _URC_END_OF_STACK;
1128 fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
1129 &context->bases);
1130 if (fde == NULL)
1132 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1133 /* Couldn't find frame unwind info for this function. Try a
1134 target-specific fallback mechanism. This will necessarily
1135 not provide a personality routine or LSDA. */
1136 return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1137 #else
1138 return _URC_END_OF_STACK;
1139 #endif
1142 fs->pc = context->bases.func;
1144 cie = get_cie (fde);
1145 insn = extract_cie_info (cie, context, fs);
1146 if (insn == NULL)
1147 /* CIE contained unknown augmentation. */
1148 return _URC_FATAL_PHASE1_ERROR;
1150 /* First decode all the insns in the CIE. */
1151 end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
1152 execute_cfa_program (insn, end, context, fs);
1154 /* Locate augmentation for the fde. */
1155 aug = (const unsigned char *) fde + sizeof (*fde);
1156 aug += 2 * size_of_encoded_value (fs->fde_encoding);
1157 insn = NULL;
1158 if (fs->saw_z)
1160 _uleb128_t i;
1161 aug = read_uleb128 (aug, &i);
1162 insn = aug + i;
1164 if (fs->lsda_encoding != DW_EH_PE_omit)
1166 _Unwind_Ptr lsda;
1168 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1169 context->lsda = (void *) lsda;
1172 /* Then the insns in the FDE up to our target PC. */
1173 if (insn == NULL)
1174 insn = aug;
1175 end = (const unsigned char *) next_fde (fde);
1176 execute_cfa_program (insn, end, context, fs);
1178 return _URC_NO_REASON;
1181 typedef struct frame_state
1183 void *cfa;
1184 void *eh_ptr;
1185 long cfa_offset;
1186 long args_size;
1187 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1188 unsigned short cfa_reg;
1189 unsigned short retaddr_column;
1190 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1191 } frame_state;
1193 struct frame_state * __frame_state_for (void *, struct frame_state *);
1195 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1196 a given PC_TARGET. The caller should allocate a local variable of
1197 `struct frame_state' and pass its address to STATE_IN. */
1199 struct frame_state *
1200 __frame_state_for (void *pc_target, struct frame_state *state_in)
1202 struct _Unwind_Context context;
1203 _Unwind_FrameState fs;
1204 int reg;
1206 memset (&context, 0, sizeof (struct _Unwind_Context));
1207 context.flags = EXTENDED_CONTEXT_BIT;
1208 context.ra = pc_target + 1;
1210 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1211 return 0;
1213 /* We have no way to pass a location expression for the CFA to our
1214 caller. It wouldn't understand it anyway. */
1215 if (fs.regs.cfa_how == CFA_EXP)
1216 return 0;
1218 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1220 state_in->saved[reg] = fs.regs.reg[reg].how;
1221 switch (state_in->saved[reg])
1223 case REG_SAVED_REG:
1224 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1225 break;
1226 case REG_SAVED_OFFSET:
1227 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1228 break;
1229 default:
1230 state_in->reg_or_offset[reg] = 0;
1231 break;
1235 state_in->cfa_offset = fs.regs.cfa_offset;
1236 state_in->cfa_reg = fs.regs.cfa_reg;
1237 state_in->retaddr_column = fs.retaddr_column;
1238 state_in->args_size = context.args_size;
1239 state_in->eh_ptr = fs.eh_ptr;
1241 return state_in;
1244 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1246 static inline void
1247 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1248 _Unwind_SpTmp *tmp_sp)
1250 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1252 if (size == sizeof(_Unwind_Ptr))
1253 tmp_sp->ptr = (_Unwind_Ptr) cfa;
1254 else
1256 gcc_assert (size == sizeof(_Unwind_Word));
1257 tmp_sp->word = (_Unwind_Ptr) cfa;
1259 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1262 static void
1263 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1265 struct _Unwind_Context orig_context = *context;
1266 void *cfa;
1267 long i;
1269 #ifdef EH_RETURN_STACKADJ_RTX
1270 /* Special handling here: Many machines do not use a frame pointer,
1271 and track the CFA only through offsets from the stack pointer from
1272 one frame to the next. In this case, the stack pointer is never
1273 stored, so it has no saved address in the context. What we do
1274 have is the CFA from the previous stack frame.
1276 In very special situations (such as unwind info for signal return),
1277 there may be location expressions that use the stack pointer as well.
1279 Do this conditionally for one frame. This allows the unwind info
1280 for one frame to save a copy of the stack pointer from the previous
1281 frame, and be able to use much easier CFA mechanisms to do it.
1282 Always zap the saved stack pointer value for the next frame; carrying
1283 the value over from one frame to another doesn't make sense. */
1285 _Unwind_SpTmp tmp_sp;
1287 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1288 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1289 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1290 #endif
1292 /* Compute this frame's CFA. */
1293 switch (fs->regs.cfa_how)
1295 case CFA_REG_OFFSET:
1296 cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1297 cfa += fs->regs.cfa_offset;
1298 break;
1300 case CFA_EXP:
1302 const unsigned char *exp = fs->regs.cfa_exp;
1303 _uleb128_t len;
1305 exp = read_uleb128 (exp, &len);
1306 cfa = (void *) (_Unwind_Ptr)
1307 execute_stack_op (exp, exp + len, &orig_context, 0);
1308 break;
1311 default:
1312 gcc_unreachable ();
1314 context->cfa = cfa;
1316 /* Compute the addresses of all registers saved in this frame. */
1317 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1318 switch (fs->regs.reg[i].how)
1320 case REG_UNSAVED:
1321 case REG_UNDEFINED:
1322 break;
1324 case REG_SAVED_OFFSET:
1325 _Unwind_SetGRPtr (context, i,
1326 (void *) (cfa + fs->regs.reg[i].loc.offset));
1327 break;
1329 case REG_SAVED_REG:
1330 if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1331 _Unwind_SetGRValue (context, i,
1332 _Unwind_GetGR (&orig_context,
1333 fs->regs.reg[i].loc.reg));
1334 else
1335 _Unwind_SetGRPtr (context, i,
1336 _Unwind_GetGRPtr (&orig_context,
1337 fs->regs.reg[i].loc.reg));
1338 break;
1340 case REG_SAVED_EXP:
1342 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1343 _uleb128_t len;
1344 _Unwind_Ptr val;
1346 exp = read_uleb128 (exp, &len);
1347 val = execute_stack_op (exp, exp + len, &orig_context,
1348 (_Unwind_Ptr) cfa);
1349 _Unwind_SetGRPtr (context, i, (void *) val);
1351 break;
1353 case REG_SAVED_VAL_OFFSET:
1354 _Unwind_SetGRValue (context, i,
1355 (_Unwind_Internal_Ptr)
1356 (cfa + fs->regs.reg[i].loc.offset));
1357 break;
1359 case REG_SAVED_VAL_EXP:
1361 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1362 _uleb128_t len;
1363 _Unwind_Ptr val;
1365 exp = read_uleb128 (exp, &len);
1366 val = execute_stack_op (exp, exp + len, &orig_context,
1367 (_Unwind_Ptr) cfa);
1368 _Unwind_SetGRValue (context, i, val);
1370 break;
1373 _Unwind_SetSignalFrame (context, fs->signal_frame);
1375 #ifdef MD_FROB_UPDATE_CONTEXT
1376 MD_FROB_UPDATE_CONTEXT (context, fs);
1377 #endif
1380 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1381 of its caller. Update CONTEXT to refer to the caller as well. Note
1382 that the args_size and lsda members are not updated here, but later in
1383 uw_frame_state_for. */
1385 static void
1386 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1388 uw_update_context_1 (context, fs);
1390 /* In general this unwinder doesn't make any distinction between
1391 undefined and same_value rule. Call-saved registers are assumed
1392 to have same_value rule by default and explicit undefined
1393 rule is handled like same_value. The only exception is
1394 DW_CFA_undefined on retaddr_column which is supposed to
1395 mark outermost frame in DWARF 3. */
1396 if (fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)].how
1397 == REG_UNDEFINED)
1398 /* uw_frame_state_for uses context->ra == 0 check to find outermost
1399 stack frame. */
1400 context->ra = 0;
1401 else
1402 /* Compute the return address now, since the return address column
1403 can change from frame to frame. */
1404 context->ra = __builtin_extract_return_addr
1405 (_Unwind_GetPtr (context, fs->retaddr_column));
1408 static void
1409 uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1411 uw_update_context (context, fs);
1414 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1415 level will be the return address and the CFA. */
1417 #define uw_init_context(CONTEXT) \
1418 do \
1420 /* Do any necessary initialization to access arbitrary stack frames. \
1421 On the SPARC, this means flushing the register windows. */ \
1422 __builtin_unwind_init (); \
1423 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1424 __builtin_return_address (0)); \
1426 while (0)
1428 static inline void
1429 init_dwarf_reg_size_table (void)
1431 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1434 static void __attribute__((noinline))
1435 uw_init_context_1 (struct _Unwind_Context *context,
1436 void *outer_cfa, void *outer_ra)
1438 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1439 _Unwind_FrameState fs;
1440 _Unwind_SpTmp sp_slot;
1441 _Unwind_Reason_Code code;
1443 memset (context, 0, sizeof (struct _Unwind_Context));
1444 context->ra = ra;
1445 context->flags = EXTENDED_CONTEXT_BIT;
1447 code = uw_frame_state_for (context, &fs);
1448 gcc_assert (code == _URC_NO_REASON);
1450 #if __GTHREADS
1452 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1453 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1454 && dwarf_reg_size_table[0] == 0)
1455 init_dwarf_reg_size_table ();
1457 #else
1458 if (dwarf_reg_size_table[0] == 0)
1459 init_dwarf_reg_size_table ();
1460 #endif
1462 /* Force the frame state to use the known cfa value. */
1463 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1464 fs.regs.cfa_how = CFA_REG_OFFSET;
1465 fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1466 fs.regs.cfa_offset = 0;
1468 uw_update_context_1 (context, &fs);
1470 /* If the return address column was saved in a register in the
1471 initialization context, then we can't see it in the given
1472 call frame data. So have the initialization context tell us. */
1473 context->ra = __builtin_extract_return_addr (outer_ra);
1476 static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
1478 /* This function is called during unwinding. It is intended as a hook
1479 for a debugger to intercept exceptions. CFA is the CFA of the
1480 target frame. HANDLER is the PC to which control will be
1481 transferred. */
1482 static void
1483 _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1484 void *handler __attribute__ ((__unused__)))
1486 asm ("");
1489 /* Install TARGET into CURRENT so that we can return to it. This is a
1490 macro because __builtin_eh_return must be invoked in the context of
1491 our caller. */
1493 #define uw_install_context(CURRENT, TARGET) \
1494 do \
1496 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1497 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1498 _Unwind_DebugHook ((TARGET)->cfa, handler); \
1499 __builtin_eh_return (offset, handler); \
1501 while (0)
1503 static long
1504 uw_install_context_1 (struct _Unwind_Context *current,
1505 struct _Unwind_Context *target)
1507 long i;
1508 _Unwind_SpTmp sp_slot;
1510 /* If the target frame does not have a saved stack pointer,
1511 then set up the target's CFA. */
1512 if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1513 _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1515 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1517 void *c = current->reg[i];
1518 void *t = target->reg[i];
1520 gcc_assert (current->by_value[i] == 0);
1521 if (target->by_value[i] && c)
1523 _Unwind_Word w;
1524 _Unwind_Ptr p;
1525 if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1527 w = (_Unwind_Internal_Ptr) t;
1528 memcpy (c, &w, sizeof (_Unwind_Word));
1530 else
1532 gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1533 p = (_Unwind_Internal_Ptr) t;
1534 memcpy (c, &p, sizeof (_Unwind_Ptr));
1537 else if (t && c && t != c)
1538 memcpy (c, t, dwarf_reg_size_table[i]);
1541 /* If the current frame doesn't have a saved stack pointer, then we
1542 need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1543 pointer value reloaded. */
1544 if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1546 void *target_cfa;
1548 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1550 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1551 if (STACK_GROWS_DOWNWARD)
1552 return target_cfa - current->cfa + target->args_size;
1553 else
1554 return current->cfa - target_cfa - target->args_size;
1556 return 0;
1559 static inline _Unwind_Ptr
1560 uw_identify_context (struct _Unwind_Context *context)
1562 /* The CFA is not sufficient to disambiguate the context of a function
1563 interrupted by a signal before establishing its frame and the context
1564 of the signal itself. */
1565 if (STACK_GROWS_DOWNWARD)
1566 return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
1567 else
1568 return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
1572 #include "unwind.inc"
1574 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1575 alias (_Unwind_Backtrace);
1576 alias (_Unwind_DeleteException);
1577 alias (_Unwind_FindEnclosingFunction);
1578 alias (_Unwind_ForcedUnwind);
1579 alias (_Unwind_GetDataRelBase);
1580 alias (_Unwind_GetTextRelBase);
1581 alias (_Unwind_GetCFA);
1582 alias (_Unwind_GetGR);
1583 alias (_Unwind_GetIP);
1584 alias (_Unwind_GetLanguageSpecificData);
1585 alias (_Unwind_GetRegionStart);
1586 alias (_Unwind_RaiseException);
1587 alias (_Unwind_Resume);
1588 alias (_Unwind_Resume_or_Rethrow);
1589 alias (_Unwind_SetGR);
1590 alias (_Unwind_SetIP);
1591 #endif
1593 #endif /* !USING_SJLJ_EXCEPTIONS */