PR libgfortran/27107:
[official-gcc.git] / gcc / unwind-dw2.c
blobda8289f794fb4c7676f36c2d85fbc6a5fa2af905
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.
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 2, or (at your option)
10 any later version.
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.)
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.
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. */
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"
45 #ifndef __USING_SJLJ_EXCEPTIONS__
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
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
59 #ifndef DWARF_REG_TO_UNWIND_COLUMN
60 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
61 #endif
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
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];
85 /* Byte size of every register managed by these routines. */
86 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
89 /* Read unaligned data from the instruction buffer. */
91 union unaligned
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));
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 *);
106 static inline void *
107 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
109 static inline int
110 read_1u (const void *p) { return *(const unsigned char *) p; }
112 static inline int
113 read_1s (const void *p) { return *(const signed char *) p; }
115 static inline int
116 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
118 static inline int
119 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
121 static inline unsigned int
122 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
124 static inline int
125 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
127 static inline unsigned long
128 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
130 static inline unsigned long
131 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
133 static inline _Unwind_Word
134 _Unwind_IsSignalFrame (struct _Unwind_Context *context)
136 return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
139 static inline void
140 _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
142 if (val)
143 context->flags |= SIGNAL_FRAME_BIT;
144 else
145 context->flags &= ~SIGNAL_FRAME_BIT;
148 static inline _Unwind_Word
149 _Unwind_IsExtendedContext (struct _Unwind_Context *context)
151 return context->flags & EXTENDED_CONTEXT_BIT;
154 /* Get the value of register INDEX as saved in CONTEXT. */
156 inline _Unwind_Word
157 _Unwind_GetGR (struct _Unwind_Context *context, int index)
159 int size;
160 void *ptr;
162 #ifdef DWARF_ZERO_REG
163 if (index == DWARF_ZERO_REG)
164 return 0;
165 #endif
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];
172 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
173 return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
175 /* This will segfault if the register hasn't been saved. */
176 if (size == sizeof(_Unwind_Ptr))
177 return * (_Unwind_Ptr *) ptr;
178 else
180 gcc_assert (size == sizeof(_Unwind_Word));
181 return * (_Unwind_Word *) ptr;
185 static inline void *
186 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
188 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
191 /* Get the value of the CFA as saved in CONTEXT. */
193 _Unwind_Word
194 _Unwind_GetCFA (struct _Unwind_Context *context)
196 return (_Unwind_Ptr) context->cfa;
199 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
201 inline void
202 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
204 int size;
205 void *ptr;
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];
211 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
213 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
214 return;
217 ptr = context->reg[index];
219 if (size == sizeof(_Unwind_Ptr))
220 * (_Unwind_Ptr *) ptr = val;
221 else
223 gcc_assert (size == sizeof(_Unwind_Word));
224 * (_Unwind_Word *) ptr = val;
228 /* Get the pointer to a register INDEX as saved in CONTEXT. */
230 static inline void *
231 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
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];
239 /* Set the pointer to a register INDEX as saved in CONTEXT. */
241 static inline void
242 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
244 index = DWARF_REG_TO_UNWIND_COLUMN (index);
245 if (_Unwind_IsExtendedContext (context))
246 context->by_value[index] = 0;
247 context->reg[index] = p;
250 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
252 static inline void
253 _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
254 _Unwind_Word val)
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));
260 context->by_value[index] = 1;
261 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
264 /* Return nonzero if register INDEX is stored by value rather than
265 by reference. */
267 static inline int
268 _Unwind_GRByValue (struct _Unwind_Context *context, int index)
270 index = DWARF_REG_TO_UNWIND_COLUMN (index);
271 return context->by_value[index];
274 /* Retrieve the return address for CONTEXT. */
276 inline _Unwind_Ptr
277 _Unwind_GetIP (struct _Unwind_Context *context)
279 return (_Unwind_Ptr) context->ra;
282 /* Retrieve the return address and flag whether that IP is before
283 or after first not yet fully executed instruction. */
285 inline _Unwind_Ptr
286 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
288 *ip_before_insn = _Unwind_IsSignalFrame (context);
289 return (_Unwind_Ptr) context->ra;
292 /* Overwrite the return address for CONTEXT with VAL. */
294 inline void
295 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
297 context->ra = (void *) val;
300 void *
301 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
303 return context->lsda;
306 _Unwind_Ptr
307 _Unwind_GetRegionStart (struct _Unwind_Context *context)
309 return (_Unwind_Ptr) context->bases.func;
312 void *
313 _Unwind_FindEnclosingFunction (void *pc)
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;
323 #ifndef __ia64__
324 _Unwind_Ptr
325 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
327 return (_Unwind_Ptr) context->bases.dbase;
330 _Unwind_Ptr
331 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
333 return (_Unwind_Ptr) context->bases.tbase;
335 #endif
337 #ifdef MD_UNWIND_SUPPORT
338 #include MD_UNWIND_SUPPORT
339 #endif
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. */
345 static const unsigned char *
346 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
347 _Unwind_FrameState *fs)
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;
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')
358 fs->eh_ptr = read_pointer (p);
359 p += sizeof (void *);
360 aug += 2;
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;
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')
378 p = read_uleb128 (p, &utmp);
379 ret = p + utmp;
381 fs->saw_z = 1;
382 ++aug;
385 /* Iterate over recognized augmentation subsequences. */
386 while (*aug != '\0')
388 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
389 if (aug[0] == 'L')
391 fs->lsda_encoding = *p++;
392 aug += 1;
395 /* "R" indicates a byte indicating how FDE addresses are encoded. */
396 else if (aug[0] == 'R')
398 fs->fde_encoding = *p++;
399 aug += 1;
402 /* "P" indicates a personality routine in the CIE augmentation. */
403 else if (aug[0] == 'P')
405 _Unwind_Ptr personality;
407 p = read_encoded_value (context, *p, p + 1, &personality);
408 fs->personality = (_Unwind_Personality_Fn) personality;
409 aug += 1;
412 /* "S" indicates a signal frame. */
413 else if (aug[0] == 'S')
415 fs->signal_frame = 1;
416 aug += 1;
419 /* Otherwise we have an unknown augmentation string.
420 Bail unless we saw a 'z' prefix. */
421 else
422 return ret;
425 return ret ? ret : p;
429 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
430 onto the stack to start. */
432 static _Unwind_Word
433 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
434 struct _Unwind_Context *context, _Unwind_Word initial)
436 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
437 int stack_elt;
439 stack[0] = initial;
440 stack_elt = 1;
442 while (op_ptr < op_end)
444 enum dwarf_location_atom op = *op_ptr++;
445 _Unwind_Word result, reg, utmp;
446 _Unwind_Sword offset, stmp;
448 switch (op)
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;
485 case DW_OP_addr:
486 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
487 op_ptr += sizeof (void *);
488 break;
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;
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;
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;
610 case DW_OP_dup:
611 gcc_assert (stack_elt);
612 result = stack[stack_elt - 1];
613 break;
615 case DW_OP_drop:
616 gcc_assert (stack_elt);
617 stack_elt -= 1;
618 goto no_push;
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;
626 case DW_OP_over:
627 gcc_assert (stack_elt >= 2);
628 result = stack[stack_elt - 2];
629 break;
631 case DW_OP_rot:
633 _Unwind_Word t1, t2, t3;
635 gcc_assert (stack_elt >= 3);
636 t1 = stack[stack_elt - 1];
637 t2 = stack[stack_elt - 2];
638 t3 = stack[stack_elt - 3];
639 stack[stack_elt - 1] = t2;
640 stack[stack_elt - 2] = t3;
641 stack[stack_elt - 3] = t1;
642 goto no_push;
645 case DW_OP_deref:
646 case DW_OP_deref_size:
647 case DW_OP_abs:
648 case DW_OP_neg:
649 case DW_OP_not:
650 case DW_OP_plus_uconst:
651 /* Unary operations. */
652 gcc_assert (stack_elt);
653 stack_elt -= 1;
655 result = stack[stack_elt];
657 switch (op)
659 case DW_OP_deref:
661 void *ptr = (void *) (_Unwind_Ptr) result;
662 result = (_Unwind_Ptr) read_pointer (ptr);
664 break;
666 case DW_OP_deref_size:
668 void *ptr = (void *) (_Unwind_Ptr) result;
669 switch (*op_ptr++)
671 case 1:
672 result = read_1u (ptr);
673 break;
674 case 2:
675 result = read_2u (ptr);
676 break;
677 case 4:
678 result = read_4u (ptr);
679 break;
680 case 8:
681 result = read_8u (ptr);
682 break;
683 default:
684 gcc_unreachable ();
687 break;
689 case DW_OP_abs:
690 if ((_Unwind_Sword) result < 0)
691 result = -result;
692 break;
693 case DW_OP_neg:
694 result = -result;
695 break;
696 case DW_OP_not:
697 result = ~result;
698 break;
699 case DW_OP_plus_uconst:
700 op_ptr = read_uleb128 (op_ptr, &utmp);
701 result += utmp;
702 break;
704 default:
705 gcc_unreachable ();
707 break;
709 case DW_OP_and:
710 case DW_OP_div:
711 case DW_OP_minus:
712 case DW_OP_mod:
713 case DW_OP_mul:
714 case DW_OP_or:
715 case DW_OP_plus:
716 case DW_OP_shl:
717 case DW_OP_shr:
718 case DW_OP_shra:
719 case DW_OP_xor:
720 case DW_OP_le:
721 case DW_OP_ge:
722 case DW_OP_eq:
723 case DW_OP_lt:
724 case DW_OP_gt:
725 case DW_OP_ne:
727 /* Binary operations. */
728 _Unwind_Word first, second;
729 gcc_assert (stack_elt >= 2);
730 stack_elt -= 2;
732 second = stack[stack_elt];
733 first = stack[stack_elt + 1];
735 switch (op)
737 case DW_OP_and:
738 result = second & first;
739 break;
740 case DW_OP_div:
741 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
742 break;
743 case DW_OP_minus:
744 result = second - first;
745 break;
746 case DW_OP_mod:
747 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
748 break;
749 case DW_OP_mul:
750 result = second * first;
751 break;
752 case DW_OP_or:
753 result = second | first;
754 break;
755 case DW_OP_plus:
756 result = second + first;
757 break;
758 case DW_OP_shl:
759 result = second << first;
760 break;
761 case DW_OP_shr:
762 result = second >> first;
763 break;
764 case DW_OP_shra:
765 result = (_Unwind_Sword) second >> first;
766 break;
767 case DW_OP_xor:
768 result = second ^ first;
769 break;
770 case DW_OP_le:
771 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
772 break;
773 case DW_OP_ge:
774 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
775 break;
776 case DW_OP_eq:
777 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
778 break;
779 case DW_OP_lt:
780 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
781 break;
782 case DW_OP_gt:
783 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
784 break;
785 case DW_OP_ne:
786 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
787 break;
789 default:
790 gcc_unreachable ();
793 break;
795 case DW_OP_skip:
796 offset = read_2s (op_ptr);
797 op_ptr += 2;
798 op_ptr += offset;
799 goto no_push;
801 case DW_OP_bra:
802 gcc_assert (stack_elt);
803 stack_elt -= 1;
805 offset = read_2s (op_ptr);
806 op_ptr += 2;
807 if (stack[stack_elt] != 0)
808 op_ptr += offset;
809 goto no_push;
811 case DW_OP_nop:
812 goto no_push;
814 default:
815 gcc_unreachable ();
818 /* Most things push a result value. */
819 gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
820 stack[stack_elt++] = result;
821 no_push:;
824 /* We were executing this program to get a value. It should be
825 at top of stack. */
826 gcc_assert (stack_elt);
827 stack_elt -= 1;
828 return stack[stack_elt];
832 /* Decode DWARF 2 call frame information. Takes pointers the
833 instruction sequence to decode, current register information and
834 CIE info, and the PC range to evaluate. */
836 static void
837 execute_cfa_program (const unsigned char *insn_ptr,
838 const unsigned char *insn_end,
839 struct _Unwind_Context *context,
840 _Unwind_FrameState *fs)
842 struct frame_state_reg_info *unused_rs = NULL;
844 /* Don't allow remember/restore between CIE and FDE programs. */
845 fs->regs.prev = NULL;
847 /* The comparison with the return address uses < rather than <= because
848 we are only interested in the effects of code before the call; for a
849 noreturn function, the return address may point to unrelated code with
850 a different stack configuration that we are not interested in. We
851 assume that the call itself is unwind info-neutral; if not, or if
852 there are delay instructions that adjust the stack, these must be
853 reflected at the point immediately before the call insn.
854 In signal frames, return address is after last completed instruction,
855 so we add 1 to return address to make the comparison <=. */
856 while (insn_ptr < insn_end
857 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
859 unsigned char insn = *insn_ptr++;
860 _Unwind_Word reg, utmp;
861 _Unwind_Sword offset, stmp;
863 if ((insn & 0xc0) == DW_CFA_advance_loc)
864 fs->pc += (insn & 0x3f) * fs->code_align;
865 else if ((insn & 0xc0) == DW_CFA_offset)
867 reg = insn & 0x3f;
868 insn_ptr = read_uleb128 (insn_ptr, &utmp);
869 offset = (_Unwind_Sword) utmp * fs->data_align;
870 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
871 = REG_SAVED_OFFSET;
872 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
874 else if ((insn & 0xc0) == DW_CFA_restore)
876 reg = insn & 0x3f;
877 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
879 else switch (insn)
881 case DW_CFA_set_loc:
883 _Unwind_Ptr pc;
885 insn_ptr = read_encoded_value (context, fs->fde_encoding,
886 insn_ptr, &pc);
887 fs->pc = (void *) pc;
889 break;
891 case DW_CFA_advance_loc1:
892 fs->pc += read_1u (insn_ptr) * fs->code_align;
893 insn_ptr += 1;
894 break;
895 case DW_CFA_advance_loc2:
896 fs->pc += read_2u (insn_ptr) * fs->code_align;
897 insn_ptr += 2;
898 break;
899 case DW_CFA_advance_loc4:
900 fs->pc += read_4u (insn_ptr) * fs->code_align;
901 insn_ptr += 4;
902 break;
904 case DW_CFA_offset_extended:
905 insn_ptr = read_uleb128 (insn_ptr, &reg);
906 insn_ptr = read_uleb128 (insn_ptr, &utmp);
907 offset = (_Unwind_Sword) utmp * fs->data_align;
908 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
909 = REG_SAVED_OFFSET;
910 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
911 break;
913 case DW_CFA_restore_extended:
914 insn_ptr = read_uleb128 (insn_ptr, &reg);
915 /* FIXME, this is wrong; the CIE might have said that the
916 register was saved somewhere. */
917 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
918 break;
920 case DW_CFA_undefined:
921 case DW_CFA_same_value:
922 insn_ptr = read_uleb128 (insn_ptr, &reg);
923 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
924 break;
926 case DW_CFA_nop:
927 break;
929 case DW_CFA_register:
931 _Unwind_Word reg2;
932 insn_ptr = read_uleb128 (insn_ptr, &reg);
933 insn_ptr = read_uleb128 (insn_ptr, &reg2);
934 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
935 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
937 break;
939 case DW_CFA_remember_state:
941 struct frame_state_reg_info *new_rs;
942 if (unused_rs)
944 new_rs = unused_rs;
945 unused_rs = unused_rs->prev;
947 else
948 new_rs = alloca (sizeof (struct frame_state_reg_info));
950 *new_rs = fs->regs;
951 fs->regs.prev = new_rs;
953 break;
955 case DW_CFA_restore_state:
957 struct frame_state_reg_info *old_rs = fs->regs.prev;
958 fs->regs = *old_rs;
959 old_rs->prev = unused_rs;
960 unused_rs = old_rs;
962 break;
964 case DW_CFA_def_cfa:
965 insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
966 insn_ptr = read_uleb128 (insn_ptr, &utmp);
967 fs->regs.cfa_offset = utmp;
968 fs->regs.cfa_how = CFA_REG_OFFSET;
969 break;
971 case DW_CFA_def_cfa_register:
972 insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
973 fs->regs.cfa_how = CFA_REG_OFFSET;
974 break;
976 case DW_CFA_def_cfa_offset:
977 insn_ptr = read_uleb128 (insn_ptr, &utmp);
978 fs->regs.cfa_offset = utmp;
979 /* cfa_how deliberately not set. */
980 break;
982 case DW_CFA_def_cfa_expression:
983 fs->regs.cfa_exp = insn_ptr;
984 fs->regs.cfa_how = CFA_EXP;
985 insn_ptr = read_uleb128 (insn_ptr, &utmp);
986 insn_ptr += utmp;
987 break;
989 case DW_CFA_expression:
990 insn_ptr = read_uleb128 (insn_ptr, &reg);
991 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
992 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
993 insn_ptr = read_uleb128 (insn_ptr, &utmp);
994 insn_ptr += utmp;
995 break;
997 /* Dwarf3. */
998 case DW_CFA_offset_extended_sf:
999 insn_ptr = read_uleb128 (insn_ptr, &reg);
1000 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1001 offset = stmp * fs->data_align;
1002 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1003 = REG_SAVED_OFFSET;
1004 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1005 break;
1007 case DW_CFA_def_cfa_sf:
1008 insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
1009 insn_ptr = read_sleb128 (insn_ptr, &fs->regs.cfa_offset);
1010 fs->regs.cfa_how = CFA_REG_OFFSET;
1011 fs->regs.cfa_offset *= fs->data_align;
1012 break;
1014 case DW_CFA_def_cfa_offset_sf:
1015 insn_ptr = read_sleb128 (insn_ptr, &fs->regs.cfa_offset);
1016 fs->regs.cfa_offset *= fs->data_align;
1017 /* cfa_how deliberately not set. */
1018 break;
1020 case DW_CFA_val_offset:
1021 insn_ptr = read_uleb128 (insn_ptr, &reg);
1022 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1023 offset = (_Unwind_Sword) utmp * fs->data_align;
1024 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1025 = REG_SAVED_VAL_OFFSET;
1026 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1027 break;
1029 case DW_CFA_val_offset_sf:
1030 insn_ptr = read_uleb128 (insn_ptr, &reg);
1031 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1032 offset = stmp * fs->data_align;
1033 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1034 = REG_SAVED_VAL_OFFSET;
1035 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1036 break;
1038 case DW_CFA_val_expression:
1039 insn_ptr = read_uleb128 (insn_ptr, &reg);
1040 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1041 = REG_SAVED_VAL_EXP;
1042 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1043 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1044 insn_ptr += utmp;
1045 break;
1047 case DW_CFA_GNU_window_save:
1048 /* ??? Hardcoded for SPARC register window configuration. */
1049 for (reg = 16; reg < 32; ++reg)
1051 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1052 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1054 break;
1056 case DW_CFA_GNU_args_size:
1057 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
1058 break;
1060 case DW_CFA_GNU_negative_offset_extended:
1061 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1062 older PowerPC code. */
1063 insn_ptr = read_uleb128 (insn_ptr, &reg);
1064 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1065 offset = (_Unwind_Word) utmp * fs->data_align;
1066 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1067 = REG_SAVED_OFFSET;
1068 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
1069 break;
1071 default:
1072 gcc_unreachable ();
1077 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1078 its caller and decode it into FS. This function also sets the
1079 args_size and lsda members of CONTEXT, as they are really information
1080 about the caller's frame. */
1082 static _Unwind_Reason_Code
1083 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1085 const struct dwarf_fde *fde;
1086 const struct dwarf_cie *cie;
1087 const unsigned char *aug, *insn, *end;
1089 memset (fs, 0, sizeof (*fs));
1090 context->args_size = 0;
1091 context->lsda = 0;
1093 if (context->ra == 0)
1094 return _URC_END_OF_STACK;
1096 fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
1097 &context->bases);
1098 if (fde == NULL)
1100 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1101 /* Couldn't find frame unwind info for this function. Try a
1102 target-specific fallback mechanism. This will necessarily
1103 not provide a personality routine or LSDA. */
1104 return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1105 #else
1106 return _URC_END_OF_STACK;
1107 #endif
1110 fs->pc = context->bases.func;
1112 cie = get_cie (fde);
1113 insn = extract_cie_info (cie, context, fs);
1114 if (insn == NULL)
1115 /* CIE contained unknown augmentation. */
1116 return _URC_FATAL_PHASE1_ERROR;
1118 /* First decode all the insns in the CIE. */
1119 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1120 execute_cfa_program (insn, end, context, fs);
1122 /* Locate augmentation for the fde. */
1123 aug = (unsigned char *) fde + sizeof (*fde);
1124 aug += 2 * size_of_encoded_value (fs->fde_encoding);
1125 insn = NULL;
1126 if (fs->saw_z)
1128 _Unwind_Word i;
1129 aug = read_uleb128 (aug, &i);
1130 insn = aug + i;
1132 if (fs->lsda_encoding != DW_EH_PE_omit)
1134 _Unwind_Ptr lsda;
1136 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1137 context->lsda = (void *) lsda;
1140 /* Then the insns in the FDE up to our target PC. */
1141 if (insn == NULL)
1142 insn = aug;
1143 end = (unsigned char *) next_fde (fde);
1144 execute_cfa_program (insn, end, context, fs);
1146 return _URC_NO_REASON;
1149 typedef struct frame_state
1151 void *cfa;
1152 void *eh_ptr;
1153 long cfa_offset;
1154 long args_size;
1155 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1156 unsigned short cfa_reg;
1157 unsigned short retaddr_column;
1158 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1159 } frame_state;
1161 struct frame_state * __frame_state_for (void *, struct frame_state *);
1163 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1164 a given PC_TARGET. The caller should allocate a local variable of
1165 `struct frame_state' and pass its address to STATE_IN. */
1167 struct frame_state *
1168 __frame_state_for (void *pc_target, struct frame_state *state_in)
1170 struct _Unwind_Context context;
1171 _Unwind_FrameState fs;
1172 int reg;
1174 memset (&context, 0, sizeof (struct _Unwind_Context));
1175 context.flags = EXTENDED_CONTEXT_BIT;
1176 context.ra = pc_target + 1;
1178 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1179 return 0;
1181 /* We have no way to pass a location expression for the CFA to our
1182 caller. It wouldn't understand it anyway. */
1183 if (fs.regs.cfa_how == CFA_EXP)
1184 return 0;
1186 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1188 state_in->saved[reg] = fs.regs.reg[reg].how;
1189 switch (state_in->saved[reg])
1191 case REG_SAVED_REG:
1192 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1193 break;
1194 case REG_SAVED_OFFSET:
1195 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1196 break;
1197 default:
1198 state_in->reg_or_offset[reg] = 0;
1199 break;
1203 state_in->cfa_offset = fs.regs.cfa_offset;
1204 state_in->cfa_reg = fs.regs.cfa_reg;
1205 state_in->retaddr_column = fs.retaddr_column;
1206 state_in->args_size = context.args_size;
1207 state_in->eh_ptr = fs.eh_ptr;
1209 return state_in;
1212 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1214 static inline void
1215 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1216 _Unwind_SpTmp *tmp_sp)
1218 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1220 if (size == sizeof(_Unwind_Ptr))
1221 tmp_sp->ptr = (_Unwind_Ptr) cfa;
1222 else
1224 gcc_assert (size == sizeof(_Unwind_Word));
1225 tmp_sp->word = (_Unwind_Ptr) cfa;
1227 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1230 static void
1231 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1233 struct _Unwind_Context orig_context = *context;
1234 void *cfa;
1235 long i;
1237 #ifdef EH_RETURN_STACKADJ_RTX
1238 /* Special handling here: Many machines do not use a frame pointer,
1239 and track the CFA only through offsets from the stack pointer from
1240 one frame to the next. In this case, the stack pointer is never
1241 stored, so it has no saved address in the context. What we do
1242 have is the CFA from the previous stack frame.
1244 In very special situations (such as unwind info for signal return),
1245 there may be location expressions that use the stack pointer as well.
1247 Do this conditionally for one frame. This allows the unwind info
1248 for one frame to save a copy of the stack pointer from the previous
1249 frame, and be able to use much easier CFA mechanisms to do it.
1250 Always zap the saved stack pointer value for the next frame; carrying
1251 the value over from one frame to another doesn't make sense. */
1253 _Unwind_SpTmp tmp_sp;
1255 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1256 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1257 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1258 #endif
1260 /* Compute this frame's CFA. */
1261 switch (fs->regs.cfa_how)
1263 case CFA_REG_OFFSET:
1264 cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1265 cfa += fs->regs.cfa_offset;
1266 break;
1268 case CFA_EXP:
1270 const unsigned char *exp = fs->regs.cfa_exp;
1271 _Unwind_Word len;
1273 exp = read_uleb128 (exp, &len);
1274 cfa = (void *) (_Unwind_Ptr)
1275 execute_stack_op (exp, exp + len, &orig_context, 0);
1276 break;
1279 default:
1280 gcc_unreachable ();
1282 context->cfa = cfa;
1284 /* Compute the addresses of all registers saved in this frame. */
1285 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1286 switch (fs->regs.reg[i].how)
1288 case REG_UNSAVED:
1289 break;
1291 case REG_SAVED_OFFSET:
1292 _Unwind_SetGRPtr (context, i,
1293 (void *) (cfa + fs->regs.reg[i].loc.offset));
1294 break;
1296 case REG_SAVED_REG:
1297 if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1298 _Unwind_SetGRValue (context, i,
1299 _Unwind_GetGR (&orig_context,
1300 fs->regs.reg[i].loc.reg));
1301 else
1302 _Unwind_SetGRPtr (context, i,
1303 _Unwind_GetGRPtr (&orig_context,
1304 fs->regs.reg[i].loc.reg));
1305 break;
1307 case REG_SAVED_EXP:
1309 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1310 _Unwind_Word len;
1311 _Unwind_Ptr val;
1313 exp = read_uleb128 (exp, &len);
1314 val = execute_stack_op (exp, exp + len, &orig_context,
1315 (_Unwind_Ptr) cfa);
1316 _Unwind_SetGRPtr (context, i, (void *) val);
1318 break;
1320 case REG_SAVED_VAL_OFFSET:
1321 _Unwind_SetGRValue (context, i,
1322 (_Unwind_Internal_Ptr)
1323 (cfa + fs->regs.reg[i].loc.offset));
1324 break;
1326 case REG_SAVED_VAL_EXP:
1328 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1329 _Unwind_Word len;
1330 _Unwind_Ptr val;
1332 exp = read_uleb128 (exp, &len);
1333 val = execute_stack_op (exp, exp + len, &orig_context,
1334 (_Unwind_Ptr) cfa);
1335 _Unwind_SetGRValue (context, i, val);
1337 break;
1340 _Unwind_SetSignalFrame (context, fs->signal_frame);
1342 #ifdef MD_FROB_UPDATE_CONTEXT
1343 MD_FROB_UPDATE_CONTEXT (context, fs);
1344 #endif
1347 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1348 of its caller. Update CONTEXT to refer to the caller as well. Note
1349 that the args_size and lsda members are not updated here, but later in
1350 uw_frame_state_for. */
1352 static void
1353 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1355 uw_update_context_1 (context, fs);
1357 /* Compute the return address now, since the return address column
1358 can change from frame to frame. */
1359 context->ra = __builtin_extract_return_addr
1360 (_Unwind_GetPtr (context, fs->retaddr_column));
1363 static void
1364 uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1366 uw_update_context (context, fs);
1369 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1370 level will be the return address and the CFA. */
1372 #define uw_init_context(CONTEXT) \
1373 do \
1375 /* Do any necessary initialization to access arbitrary stack frames. \
1376 On the SPARC, this means flushing the register windows. */ \
1377 __builtin_unwind_init (); \
1378 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1379 __builtin_return_address (0)); \
1381 while (0)
1383 static inline void
1384 init_dwarf_reg_size_table (void)
1386 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1389 static void
1390 uw_init_context_1 (struct _Unwind_Context *context,
1391 void *outer_cfa, void *outer_ra)
1393 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1394 _Unwind_FrameState fs;
1395 _Unwind_SpTmp sp_slot;
1396 _Unwind_Reason_Code code;
1398 memset (context, 0, sizeof (struct _Unwind_Context));
1399 context->ra = ra;
1400 context->flags = EXTENDED_CONTEXT_BIT;
1402 code = uw_frame_state_for (context, &fs);
1403 gcc_assert (code == _URC_NO_REASON);
1405 #if __GTHREADS
1407 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1408 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1409 && dwarf_reg_size_table[0] == 0)
1410 init_dwarf_reg_size_table ();
1412 #else
1413 if (dwarf_reg_size_table[0] == 0)
1414 init_dwarf_reg_size_table ();
1415 #endif
1417 /* Force the frame state to use the known cfa value. */
1418 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1419 fs.regs.cfa_how = CFA_REG_OFFSET;
1420 fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1421 fs.regs.cfa_offset = 0;
1423 uw_update_context_1 (context, &fs);
1425 /* If the return address column was saved in a register in the
1426 initialization context, then we can't see it in the given
1427 call frame data. So have the initialization context tell us. */
1428 context->ra = __builtin_extract_return_addr (outer_ra);
1432 /* Install TARGET into CURRENT so that we can return to it. This is a
1433 macro because __builtin_eh_return must be invoked in the context of
1434 our caller. */
1436 #define uw_install_context(CURRENT, TARGET) \
1437 do \
1439 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1440 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1441 __builtin_eh_return (offset, handler); \
1443 while (0)
1445 static long
1446 uw_install_context_1 (struct _Unwind_Context *current,
1447 struct _Unwind_Context *target)
1449 long i;
1450 _Unwind_SpTmp sp_slot;
1452 /* If the target frame does not have a saved stack pointer,
1453 then set up the target's CFA. */
1454 if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1455 _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1457 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1459 void *c = current->reg[i];
1460 void *t = target->reg[i];
1462 gcc_assert (current->by_value[i] == 0);
1463 if (target->by_value[i] && c)
1465 _Unwind_Word w;
1466 _Unwind_Ptr p;
1467 if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1469 w = (_Unwind_Internal_Ptr) t;
1470 memcpy (c, &w, sizeof (_Unwind_Word));
1472 else
1474 gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1475 p = (_Unwind_Internal_Ptr) t;
1476 memcpy (c, &p, sizeof (_Unwind_Ptr));
1479 else if (t && c && t != c)
1480 memcpy (c, t, dwarf_reg_size_table[i]);
1483 /* If the current frame doesn't have a saved stack pointer, then we
1484 need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1485 pointer value reloaded. */
1486 if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1488 void *target_cfa;
1490 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1492 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1493 if (STACK_GROWS_DOWNWARD)
1494 return target_cfa - current->cfa + target->args_size;
1495 else
1496 return current->cfa - target_cfa - target->args_size;
1498 return 0;
1501 static inline _Unwind_Ptr
1502 uw_identify_context (struct _Unwind_Context *context)
1504 return _Unwind_GetIP (context);
1508 #include "unwind.inc"
1510 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1511 alias (_Unwind_Backtrace);
1512 alias (_Unwind_DeleteException);
1513 alias (_Unwind_FindEnclosingFunction);
1514 alias (_Unwind_ForcedUnwind);
1515 alias (_Unwind_GetDataRelBase);
1516 alias (_Unwind_GetTextRelBase);
1517 alias (_Unwind_GetCFA);
1518 alias (_Unwind_GetGR);
1519 alias (_Unwind_GetIP);
1520 alias (_Unwind_GetLanguageSpecificData);
1521 alias (_Unwind_GetRegionStart);
1522 alias (_Unwind_RaiseException);
1523 alias (_Unwind_Resume);
1524 alias (_Unwind_Resume_or_Rethrow);
1525 alias (_Unwind_SetGR);
1526 alias (_Unwind_SetIP);
1527 #endif
1529 #endif /* !USING_SJLJ_EXCEPTIONS */