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