2005-01-20 Michael Koch <konqueror@gmx.de>
[official-gcc.git] / gcc / unwind-dw2.c
blobb99b7007a00ccd9c96b2fa9d2587158b45d06898
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
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 _Unwind_Word 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 index = DWARF_REG_TO_UNWIND_COLUMN (index);
192 if (index >= (int) sizeof(dwarf_reg_size_table))
193 abort ();
194 size = dwarf_reg_size_table[index];
195 ptr = context->reg[index];
197 /* This will segfault if the register hasn't been saved. */
198 if (size == sizeof(_Unwind_Ptr))
199 return * (_Unwind_Ptr *) ptr;
201 if (size == sizeof(_Unwind_Word))
202 return * (_Unwind_Word *) ptr;
204 abort ();
207 static inline void *
208 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
210 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
213 /* Get the value of the CFA as saved in CONTEXT. */
215 _Unwind_Word
216 _Unwind_GetCFA (struct _Unwind_Context *context)
218 return (_Unwind_Ptr) context->cfa;
221 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
223 inline void
224 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
226 int size;
227 void *ptr;
229 index = DWARF_REG_TO_UNWIND_COLUMN (index);
230 if (index >= (int) sizeof(dwarf_reg_size_table))
231 abort ();
232 size = dwarf_reg_size_table[index];
233 ptr = context->reg[index];
235 if (size == sizeof(_Unwind_Ptr))
236 * (_Unwind_Ptr *) ptr = val;
237 else if (size == sizeof(_Unwind_Word))
238 * (_Unwind_Word *) ptr = val;
239 else
240 abort ();
243 /* Get the pointer to a register INDEX as saved in CONTEXT. */
245 static inline void *
246 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
248 index = DWARF_REG_TO_UNWIND_COLUMN (index);
249 return context->reg[index];
252 /* Set the pointer to a register INDEX as saved in CONTEXT. */
254 static inline void
255 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
257 index = DWARF_REG_TO_UNWIND_COLUMN (index);
258 context->reg[index] = p;
261 /* Retrieve the return address for CONTEXT. */
263 inline _Unwind_Ptr
264 _Unwind_GetIP (struct _Unwind_Context *context)
266 return (_Unwind_Ptr) context->ra;
269 /* Overwrite the return address for CONTEXT with VAL. */
271 inline void
272 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
274 context->ra = (void *) val;
277 void *
278 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
280 return context->lsda;
283 _Unwind_Ptr
284 _Unwind_GetRegionStart (struct _Unwind_Context *context)
286 return (_Unwind_Ptr) context->bases.func;
289 void *
290 _Unwind_FindEnclosingFunction (void *pc)
292 struct dwarf_eh_bases bases;
293 const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
294 if (fde)
295 return bases.func;
296 else
297 return NULL;
300 #ifndef __ia64__
301 _Unwind_Ptr
302 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
304 return (_Unwind_Ptr) context->bases.dbase;
307 _Unwind_Ptr
308 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
310 return (_Unwind_Ptr) context->bases.tbase;
312 #endif
314 /* Extract any interesting information from the CIE for the translation
315 unit F belongs to. Return a pointer to the byte after the augmentation,
316 or NULL if we encountered an undecipherable augmentation. */
318 static const unsigned char *
319 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
320 _Unwind_FrameState *fs)
322 const unsigned char *aug = cie->augmentation;
323 const unsigned char *p = aug + strlen (aug) + 1;
324 const unsigned char *ret = NULL;
325 _Unwind_Word utmp;
327 /* g++ v2 "eh" has pointer immediately following augmentation string,
328 so it must be handled first. */
329 if (aug[0] == 'e' && aug[1] == 'h')
331 fs->eh_ptr = read_pointer (p);
332 p += sizeof (void *);
333 aug += 2;
336 /* Immediately following the augmentation are the code and
337 data alignment and return address column. */
338 p = read_uleb128 (p, &fs->code_align);
339 p = read_sleb128 (p, &fs->data_align);
340 if (cie->version == 1)
341 fs->retaddr_column = *p++;
342 else
343 p = read_uleb128 (p, &fs->retaddr_column);
344 fs->lsda_encoding = DW_EH_PE_omit;
346 /* If the augmentation starts with 'z', then a uleb128 immediately
347 follows containing the length of the augmentation field following
348 the size. */
349 if (*aug == 'z')
351 p = read_uleb128 (p, &utmp);
352 ret = p + utmp;
354 fs->saw_z = 1;
355 ++aug;
358 /* Iterate over recognized augmentation subsequences. */
359 while (*aug != '\0')
361 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
362 if (aug[0] == 'L')
364 fs->lsda_encoding = *p++;
365 aug += 1;
368 /* "R" indicates a byte indicating how FDE addresses are encoded. */
369 else if (aug[0] == 'R')
371 fs->fde_encoding = *p++;
372 aug += 1;
375 /* "P" indicates a personality routine in the CIE augmentation. */
376 else if (aug[0] == 'P')
378 p = read_encoded_value (context, *p, p + 1,
379 (_Unwind_Ptr *) &fs->personality);
380 aug += 1;
383 /* Otherwise we have an unknown augmentation string.
384 Bail unless we saw a 'z' prefix. */
385 else
386 return ret;
389 return ret ? ret : p;
393 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
394 onto the stack to start. */
396 static _Unwind_Word
397 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
398 struct _Unwind_Context *context, _Unwind_Word initial)
400 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
401 int stack_elt;
403 stack[0] = initial;
404 stack_elt = 1;
406 while (op_ptr < op_end)
408 enum dwarf_location_atom op = *op_ptr++;
409 _Unwind_Word result, reg, utmp;
410 _Unwind_Sword offset, stmp;
412 switch (op)
414 case DW_OP_lit0:
415 case DW_OP_lit1:
416 case DW_OP_lit2:
417 case DW_OP_lit3:
418 case DW_OP_lit4:
419 case DW_OP_lit5:
420 case DW_OP_lit6:
421 case DW_OP_lit7:
422 case DW_OP_lit8:
423 case DW_OP_lit9:
424 case DW_OP_lit10:
425 case DW_OP_lit11:
426 case DW_OP_lit12:
427 case DW_OP_lit13:
428 case DW_OP_lit14:
429 case DW_OP_lit15:
430 case DW_OP_lit16:
431 case DW_OP_lit17:
432 case DW_OP_lit18:
433 case DW_OP_lit19:
434 case DW_OP_lit20:
435 case DW_OP_lit21:
436 case DW_OP_lit22:
437 case DW_OP_lit23:
438 case DW_OP_lit24:
439 case DW_OP_lit25:
440 case DW_OP_lit26:
441 case DW_OP_lit27:
442 case DW_OP_lit28:
443 case DW_OP_lit29:
444 case DW_OP_lit30:
445 case DW_OP_lit31:
446 result = op - DW_OP_lit0;
447 break;
449 case DW_OP_addr:
450 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
451 op_ptr += sizeof (void *);
452 break;
454 case DW_OP_const1u:
455 result = read_1u (op_ptr);
456 op_ptr += 1;
457 break;
458 case DW_OP_const1s:
459 result = read_1s (op_ptr);
460 op_ptr += 1;
461 break;
462 case DW_OP_const2u:
463 result = read_2u (op_ptr);
464 op_ptr += 2;
465 break;
466 case DW_OP_const2s:
467 result = read_2s (op_ptr);
468 op_ptr += 2;
469 break;
470 case DW_OP_const4u:
471 result = read_4u (op_ptr);
472 op_ptr += 4;
473 break;
474 case DW_OP_const4s:
475 result = read_4s (op_ptr);
476 op_ptr += 4;
477 break;
478 case DW_OP_const8u:
479 result = read_8u (op_ptr);
480 op_ptr += 8;
481 break;
482 case DW_OP_const8s:
483 result = read_8s (op_ptr);
484 op_ptr += 8;
485 break;
486 case DW_OP_constu:
487 op_ptr = read_uleb128 (op_ptr, &result);
488 break;
489 case DW_OP_consts:
490 op_ptr = read_sleb128 (op_ptr, &stmp);
491 result = stmp;
492 break;
494 case DW_OP_reg0:
495 case DW_OP_reg1:
496 case DW_OP_reg2:
497 case DW_OP_reg3:
498 case DW_OP_reg4:
499 case DW_OP_reg5:
500 case DW_OP_reg6:
501 case DW_OP_reg7:
502 case DW_OP_reg8:
503 case DW_OP_reg9:
504 case DW_OP_reg10:
505 case DW_OP_reg11:
506 case DW_OP_reg12:
507 case DW_OP_reg13:
508 case DW_OP_reg14:
509 case DW_OP_reg15:
510 case DW_OP_reg16:
511 case DW_OP_reg17:
512 case DW_OP_reg18:
513 case DW_OP_reg19:
514 case DW_OP_reg20:
515 case DW_OP_reg21:
516 case DW_OP_reg22:
517 case DW_OP_reg23:
518 case DW_OP_reg24:
519 case DW_OP_reg25:
520 case DW_OP_reg26:
521 case DW_OP_reg27:
522 case DW_OP_reg28:
523 case DW_OP_reg29:
524 case DW_OP_reg30:
525 case DW_OP_reg31:
526 result = _Unwind_GetGR (context, op - DW_OP_reg0);
527 break;
528 case DW_OP_regx:
529 op_ptr = read_uleb128 (op_ptr, &reg);
530 result = _Unwind_GetGR (context, reg);
531 break;
533 case DW_OP_breg0:
534 case DW_OP_breg1:
535 case DW_OP_breg2:
536 case DW_OP_breg3:
537 case DW_OP_breg4:
538 case DW_OP_breg5:
539 case DW_OP_breg6:
540 case DW_OP_breg7:
541 case DW_OP_breg8:
542 case DW_OP_breg9:
543 case DW_OP_breg10:
544 case DW_OP_breg11:
545 case DW_OP_breg12:
546 case DW_OP_breg13:
547 case DW_OP_breg14:
548 case DW_OP_breg15:
549 case DW_OP_breg16:
550 case DW_OP_breg17:
551 case DW_OP_breg18:
552 case DW_OP_breg19:
553 case DW_OP_breg20:
554 case DW_OP_breg21:
555 case DW_OP_breg22:
556 case DW_OP_breg23:
557 case DW_OP_breg24:
558 case DW_OP_breg25:
559 case DW_OP_breg26:
560 case DW_OP_breg27:
561 case DW_OP_breg28:
562 case DW_OP_breg29:
563 case DW_OP_breg30:
564 case DW_OP_breg31:
565 op_ptr = read_sleb128 (op_ptr, &offset);
566 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
567 break;
568 case DW_OP_bregx:
569 op_ptr = read_uleb128 (op_ptr, &reg);
570 op_ptr = read_sleb128 (op_ptr, &offset);
571 result = _Unwind_GetGR (context, reg) + offset;
572 break;
574 case DW_OP_dup:
575 if (stack_elt < 1)
576 abort ();
577 result = stack[stack_elt - 1];
578 break;
580 case DW_OP_drop:
581 if (--stack_elt < 0)
582 abort ();
583 goto no_push;
585 case DW_OP_pick:
586 offset = *op_ptr++;
587 if (offset >= stack_elt - 1)
588 abort ();
589 result = stack[stack_elt - 1 - offset];
590 break;
592 case DW_OP_over:
593 if (stack_elt < 2)
594 abort ();
595 result = stack[stack_elt - 2];
596 break;
598 case DW_OP_rot:
600 _Unwind_Word t1, t2, t3;
602 if (stack_elt < 3)
603 abort ();
604 t1 = stack[stack_elt - 1];
605 t2 = stack[stack_elt - 2];
606 t3 = stack[stack_elt - 3];
607 stack[stack_elt - 1] = t2;
608 stack[stack_elt - 2] = t3;
609 stack[stack_elt - 3] = t1;
610 goto no_push;
613 case DW_OP_deref:
614 case DW_OP_deref_size:
615 case DW_OP_abs:
616 case DW_OP_neg:
617 case DW_OP_not:
618 case DW_OP_plus_uconst:
619 /* Unary operations. */
620 if (--stack_elt < 0)
621 abort ();
622 result = stack[stack_elt];
624 switch (op)
626 case DW_OP_deref:
628 void *ptr = (void *) (_Unwind_Ptr) result;
629 result = (_Unwind_Ptr) read_pointer (ptr);
631 break;
633 case DW_OP_deref_size:
635 void *ptr = (void *) (_Unwind_Ptr) result;
636 switch (*op_ptr++)
638 case 1:
639 result = read_1u (ptr);
640 break;
641 case 2:
642 result = read_2u (ptr);
643 break;
644 case 4:
645 result = read_4u (ptr);
646 break;
647 case 8:
648 result = read_8u (ptr);
649 break;
650 default:
651 abort ();
654 break;
656 case DW_OP_abs:
657 if ((_Unwind_Sword) result < 0)
658 result = -result;
659 break;
660 case DW_OP_neg:
661 result = -result;
662 break;
663 case DW_OP_not:
664 result = ~result;
665 break;
666 case DW_OP_plus_uconst:
667 op_ptr = read_uleb128 (op_ptr, &utmp);
668 result += utmp;
669 break;
671 default:
672 abort ();
674 break;
676 case DW_OP_and:
677 case DW_OP_div:
678 case DW_OP_minus:
679 case DW_OP_mod:
680 case DW_OP_mul:
681 case DW_OP_or:
682 case DW_OP_plus:
683 case DW_OP_le:
684 case DW_OP_ge:
685 case DW_OP_eq:
686 case DW_OP_lt:
687 case DW_OP_gt:
688 case DW_OP_ne:
690 /* Binary operations. */
691 _Unwind_Word first, second;
692 if ((stack_elt -= 2) < 0)
693 abort ();
694 second = stack[stack_elt];
695 first = stack[stack_elt + 1];
697 switch (op)
699 case DW_OP_and:
700 result = second & first;
701 break;
702 case DW_OP_div:
703 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
704 break;
705 case DW_OP_minus:
706 result = second - first;
707 break;
708 case DW_OP_mod:
709 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
710 break;
711 case DW_OP_mul:
712 result = second * first;
713 break;
714 case DW_OP_or:
715 result = second | first;
716 break;
717 case DW_OP_plus:
718 result = second + first;
719 break;
720 case DW_OP_shl:
721 result = second << first;
722 break;
723 case DW_OP_shr:
724 result = second >> first;
725 break;
726 case DW_OP_shra:
727 result = (_Unwind_Sword) second >> first;
728 break;
729 case DW_OP_xor:
730 result = second ^ first;
731 break;
732 case DW_OP_le:
733 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
734 break;
735 case DW_OP_ge:
736 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
737 break;
738 case DW_OP_eq:
739 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
740 break;
741 case DW_OP_lt:
742 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
743 break;
744 case DW_OP_gt:
745 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
746 break;
747 case DW_OP_ne:
748 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
749 break;
751 default:
752 abort ();
755 break;
757 case DW_OP_skip:
758 offset = read_2s (op_ptr);
759 op_ptr += 2;
760 op_ptr += offset;
761 goto no_push;
763 case DW_OP_bra:
764 if (--stack_elt < 0)
765 abort ();
766 offset = read_2s (op_ptr);
767 op_ptr += 2;
768 if (stack[stack_elt] != 0)
769 op_ptr += offset;
770 goto no_push;
772 case DW_OP_nop:
773 goto no_push;
775 default:
776 abort ();
779 /* Most things push a result value. */
780 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
781 abort ();
782 stack[stack_elt++] = result;
783 no_push:;
786 /* We were executing this program to get a value. It should be
787 at top of stack. */
788 if (--stack_elt < 0)
789 abort ();
790 return stack[stack_elt];
794 /* Decode DWARF 2 call frame information. Takes pointers the
795 instruction sequence to decode, current register information and
796 CIE info, and the PC range to evaluate. */
798 static void
799 execute_cfa_program (const unsigned char *insn_ptr,
800 const unsigned char *insn_end,
801 struct _Unwind_Context *context,
802 _Unwind_FrameState *fs)
804 struct frame_state_reg_info *unused_rs = NULL;
806 /* Don't allow remember/restore between CIE and FDE programs. */
807 fs->regs.prev = NULL;
809 /* The comparison with the return address uses < rather than <= because
810 we are only interested in the effects of code before the call; for a
811 noreturn function, the return address may point to unrelated code with
812 a different stack configuration that we are not interested in. We
813 assume that the call itself is unwind info-neutral; if not, or if
814 there are delay instructions that adjust the stack, these must be
815 reflected at the point immediately before the call insn. */
816 while (insn_ptr < insn_end && fs->pc < context->ra)
818 unsigned char insn = *insn_ptr++;
819 _Unwind_Word reg, utmp;
820 _Unwind_Sword offset, stmp;
822 if ((insn & 0xc0) == DW_CFA_advance_loc)
823 fs->pc += (insn & 0x3f) * fs->code_align;
824 else if ((insn & 0xc0) == DW_CFA_offset)
826 reg = insn & 0x3f;
827 insn_ptr = read_uleb128 (insn_ptr, &utmp);
828 offset = (_Unwind_Sword) utmp * fs->data_align;
829 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
830 = REG_SAVED_OFFSET;
831 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
833 else if ((insn & 0xc0) == DW_CFA_restore)
835 reg = insn & 0x3f;
836 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
838 else switch (insn)
840 case DW_CFA_set_loc:
841 insn_ptr = read_encoded_value (context, fs->fde_encoding,
842 insn_ptr, (_Unwind_Ptr *) &fs->pc);
843 break;
845 case DW_CFA_advance_loc1:
846 fs->pc += read_1u (insn_ptr) * fs->code_align;
847 insn_ptr += 1;
848 break;
849 case DW_CFA_advance_loc2:
850 fs->pc += read_2u (insn_ptr) * fs->code_align;
851 insn_ptr += 2;
852 break;
853 case DW_CFA_advance_loc4:
854 fs->pc += read_4u (insn_ptr) * fs->code_align;
855 insn_ptr += 4;
856 break;
858 case DW_CFA_offset_extended:
859 insn_ptr = read_uleb128 (insn_ptr, &reg);
860 insn_ptr = read_uleb128 (insn_ptr, &utmp);
861 offset = (_Unwind_Sword) utmp * fs->data_align;
862 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
863 = REG_SAVED_OFFSET;
864 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
865 break;
867 case DW_CFA_restore_extended:
868 insn_ptr = read_uleb128 (insn_ptr, &reg);
869 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
870 break;
872 case DW_CFA_undefined:
873 case DW_CFA_same_value:
874 insn_ptr = read_uleb128 (insn_ptr, &reg);
875 break;
877 case DW_CFA_nop:
878 break;
880 case DW_CFA_register:
882 _Unwind_Word reg2;
883 insn_ptr = read_uleb128 (insn_ptr, &reg);
884 insn_ptr = read_uleb128 (insn_ptr, &reg2);
885 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
886 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
888 break;
890 case DW_CFA_remember_state:
892 struct frame_state_reg_info *new_rs;
893 if (unused_rs)
895 new_rs = unused_rs;
896 unused_rs = unused_rs->prev;
898 else
899 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
901 *new_rs = fs->regs;
902 fs->regs.prev = new_rs;
904 break;
906 case DW_CFA_restore_state:
908 struct frame_state_reg_info *old_rs = fs->regs.prev;
909 fs->regs = *old_rs;
910 old_rs->prev = unused_rs;
911 unused_rs = old_rs;
913 break;
915 case DW_CFA_def_cfa:
916 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
917 insn_ptr = read_uleb128 (insn_ptr, &utmp);
918 fs->cfa_offset = utmp;
919 fs->cfa_how = CFA_REG_OFFSET;
920 break;
922 case DW_CFA_def_cfa_register:
923 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
924 fs->cfa_how = CFA_REG_OFFSET;
925 break;
927 case DW_CFA_def_cfa_offset:
928 insn_ptr = read_uleb128 (insn_ptr, &utmp);
929 fs->cfa_offset = utmp;
930 /* cfa_how deliberately not set. */
931 break;
933 case DW_CFA_def_cfa_expression:
934 fs->cfa_exp = insn_ptr;
935 fs->cfa_how = CFA_EXP;
936 insn_ptr = read_uleb128 (insn_ptr, &utmp);
937 insn_ptr += utmp;
938 break;
940 case DW_CFA_expression:
941 insn_ptr = read_uleb128 (insn_ptr, &reg);
942 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
943 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
944 insn_ptr = read_uleb128 (insn_ptr, &utmp);
945 insn_ptr += utmp;
946 break;
948 /* From the 2.1 draft. */
949 case DW_CFA_offset_extended_sf:
950 insn_ptr = read_uleb128 (insn_ptr, &reg);
951 insn_ptr = read_sleb128 (insn_ptr, &stmp);
952 offset = stmp * fs->data_align;
953 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
954 = REG_SAVED_OFFSET;
955 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
956 break;
958 case DW_CFA_def_cfa_sf:
959 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
960 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
961 fs->cfa_how = CFA_REG_OFFSET;
962 break;
964 case DW_CFA_def_cfa_offset_sf:
965 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
966 /* cfa_how deliberately not set. */
967 break;
969 case DW_CFA_GNU_window_save:
970 /* ??? Hardcoded for SPARC register window configuration. */
971 for (reg = 16; reg < 32; ++reg)
973 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
974 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
976 break;
978 case DW_CFA_GNU_args_size:
979 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
980 break;
982 case DW_CFA_GNU_negative_offset_extended:
983 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
984 older PowerPC code. */
985 insn_ptr = read_uleb128 (insn_ptr, &reg);
986 insn_ptr = read_uleb128 (insn_ptr, &utmp);
987 offset = (_Unwind_Word) utmp * fs->data_align;
988 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
989 = REG_SAVED_OFFSET;
990 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
991 break;
993 default:
994 abort ();
999 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1000 its caller and decode it into FS. This function also sets the
1001 args_size and lsda members of CONTEXT, as they are really information
1002 about the caller's frame. */
1004 static _Unwind_Reason_Code
1005 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1007 const struct dwarf_fde *fde;
1008 const struct dwarf_cie *cie;
1009 const unsigned char *aug, *insn, *end;
1011 memset (fs, 0, sizeof (*fs));
1012 context->args_size = 0;
1013 context->lsda = 0;
1015 if (context->ra == 0)
1016 return _URC_END_OF_STACK;
1018 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
1019 if (fde == NULL)
1021 /* Couldn't find frame unwind info for this function. Try a
1022 target-specific fallback mechanism. This will necessarily
1023 not provide a personality routine or LSDA. */
1024 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1025 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
1026 return _URC_END_OF_STACK;
1027 success:
1028 return _URC_NO_REASON;
1029 #else
1030 return _URC_END_OF_STACK;
1031 #endif
1034 fs->pc = context->bases.func;
1036 cie = get_cie (fde);
1037 insn = extract_cie_info (cie, context, fs);
1038 if (insn == NULL)
1039 /* CIE contained unknown augmentation. */
1040 return _URC_FATAL_PHASE1_ERROR;
1042 /* First decode all the insns in the CIE. */
1043 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1044 execute_cfa_program (insn, end, context, fs);
1046 /* Locate augmentation for the fde. */
1047 aug = (unsigned char *) fde + sizeof (*fde);
1048 aug += 2 * size_of_encoded_value (fs->fde_encoding);
1049 insn = NULL;
1050 if (fs->saw_z)
1052 _Unwind_Word i;
1053 aug = read_uleb128 (aug, &i);
1054 insn = aug + i;
1056 if (fs->lsda_encoding != DW_EH_PE_omit)
1057 aug = read_encoded_value (context, fs->lsda_encoding, aug,
1058 (_Unwind_Ptr *) &context->lsda);
1060 /* Then the insns in the FDE up to our target PC. */
1061 if (insn == NULL)
1062 insn = aug;
1063 end = (unsigned char *) next_fde (fde);
1064 execute_cfa_program (insn, end, context, fs);
1066 return _URC_NO_REASON;
1069 typedef struct frame_state
1071 void *cfa;
1072 void *eh_ptr;
1073 long cfa_offset;
1074 long args_size;
1075 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1076 unsigned short cfa_reg;
1077 unsigned short retaddr_column;
1078 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1079 } frame_state;
1081 struct frame_state * __frame_state_for (void *, struct frame_state *);
1083 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1084 a given PC_TARGET. The caller should allocate a local variable of
1085 `struct frame_state' and pass its address to STATE_IN. */
1087 struct frame_state *
1088 __frame_state_for (void *pc_target, struct frame_state *state_in)
1090 struct _Unwind_Context context;
1091 _Unwind_FrameState fs;
1092 int reg;
1094 memset (&context, 0, sizeof (struct _Unwind_Context));
1095 context.ra = pc_target + 1;
1097 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1098 return 0;
1100 /* We have no way to pass a location expression for the CFA to our
1101 caller. It wouldn't understand it anyway. */
1102 if (fs.cfa_how == CFA_EXP)
1103 return 0;
1105 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1107 state_in->saved[reg] = fs.regs.reg[reg].how;
1108 switch (state_in->saved[reg])
1110 case REG_SAVED_REG:
1111 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1112 break;
1113 case REG_SAVED_OFFSET:
1114 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1115 break;
1116 default:
1117 state_in->reg_or_offset[reg] = 0;
1118 break;
1122 state_in->cfa_offset = fs.cfa_offset;
1123 state_in->cfa_reg = fs.cfa_reg;
1124 state_in->retaddr_column = fs.retaddr_column;
1125 state_in->args_size = context.args_size;
1126 state_in->eh_ptr = fs.eh_ptr;
1128 return state_in;
1131 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1133 static inline void
1134 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1135 _Unwind_SpTmp *tmp_sp)
1137 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1139 if (size == sizeof(_Unwind_Ptr))
1140 tmp_sp->ptr = (_Unwind_Ptr) cfa;
1141 else if (size == sizeof(_Unwind_Word))
1142 tmp_sp->word = (_Unwind_Ptr) cfa;
1143 else
1144 abort ();
1145 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1148 static void
1149 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1151 struct _Unwind_Context orig_context = *context;
1152 void *cfa;
1153 long i;
1155 #ifdef EH_RETURN_STACKADJ_RTX
1156 /* Special handling here: Many machines do not use a frame pointer,
1157 and track the CFA only through offsets from the stack pointer from
1158 one frame to the next. In this case, the stack pointer is never
1159 stored, so it has no saved address in the context. What we do
1160 have is the CFA from the previous stack frame.
1162 In very special situations (such as unwind info for signal return),
1163 there may be location expressions that use the stack pointer as well.
1165 Do this conditionally for one frame. This allows the unwind info
1166 for one frame to save a copy of the stack pointer from the previous
1167 frame, and be able to use much easier CFA mechanisms to do it.
1168 Always zap the saved stack pointer value for the next frame; carrying
1169 the value over from one frame to another doesn't make sense. */
1171 _Unwind_SpTmp tmp_sp;
1173 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1174 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1175 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1176 #endif
1178 /* Compute this frame's CFA. */
1179 switch (fs->cfa_how)
1181 case CFA_REG_OFFSET:
1182 cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
1183 cfa += fs->cfa_offset;
1184 break;
1186 case CFA_EXP:
1188 const unsigned char *exp = fs->cfa_exp;
1189 _Unwind_Word len;
1191 exp = read_uleb128 (exp, &len);
1192 cfa = (void *) (_Unwind_Ptr)
1193 execute_stack_op (exp, exp + len, &orig_context, 0);
1194 break;
1197 default:
1198 abort ();
1200 context->cfa = cfa;
1202 /* Compute the addresses of all registers saved in this frame. */
1203 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1204 switch (fs->regs.reg[i].how)
1206 case REG_UNSAVED:
1207 break;
1209 case REG_SAVED_OFFSET:
1210 _Unwind_SetGRPtr (context, i,
1211 (void *) (cfa + fs->regs.reg[i].loc.offset));
1212 break;
1214 case REG_SAVED_REG:
1215 _Unwind_SetGRPtr
1216 (context, i,
1217 _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
1218 break;
1220 case REG_SAVED_EXP:
1222 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1223 _Unwind_Word len;
1224 _Unwind_Ptr val;
1226 exp = read_uleb128 (exp, &len);
1227 val = execute_stack_op (exp, exp + len, &orig_context,
1228 (_Unwind_Ptr) cfa);
1229 _Unwind_SetGRPtr (context, i, (void *) val);
1231 break;
1234 MD_FROB_UPDATE_CONTEXT (context, fs);
1237 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1238 of its caller. Update CONTEXT to refer to the caller as well. Note
1239 that the args_size and lsda members are not updated here, but later in
1240 uw_frame_state_for. */
1242 static void
1243 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1245 uw_update_context_1 (context, fs);
1247 /* Compute the return address now, since the return address column
1248 can change from frame to frame. */
1249 context->ra = __builtin_extract_return_addr
1250 (_Unwind_GetPtr (context, fs->retaddr_column));
1253 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1254 level will be the return address and the CFA. */
1256 #define uw_init_context(CONTEXT) \
1257 do \
1259 /* Do any necessary initialization to access arbitrary stack frames. \
1260 On the SPARC, this means flushing the register windows. */ \
1261 __builtin_unwind_init (); \
1262 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1263 __builtin_return_address (0)); \
1265 while (0)
1267 static inline void
1268 init_dwarf_reg_size_table (void)
1270 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1273 static void
1274 uw_init_context_1 (struct _Unwind_Context *context,
1275 void *outer_cfa, void *outer_ra)
1277 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1278 _Unwind_FrameState fs;
1279 _Unwind_SpTmp sp_slot;
1281 memset (context, 0, sizeof (struct _Unwind_Context));
1282 context->ra = ra;
1284 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1285 abort ();
1287 #if __GTHREADS
1289 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1290 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1291 || dwarf_reg_size_table[0] == 0)
1292 init_dwarf_reg_size_table ();
1294 #else
1295 if (dwarf_reg_size_table[0] == 0)
1296 init_dwarf_reg_size_table ();
1297 #endif
1299 /* Force the frame state to use the known cfa value. */
1300 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1301 fs.cfa_how = CFA_REG_OFFSET;
1302 fs.cfa_reg = __builtin_dwarf_sp_column ();
1303 fs.cfa_offset = 0;
1305 uw_update_context_1 (context, &fs);
1307 /* If the return address column was saved in a register in the
1308 initialization context, then we can't see it in the given
1309 call frame data. So have the initialization context tell us. */
1310 context->ra = __builtin_extract_return_addr (outer_ra);
1314 /* Install TARGET into CURRENT so that we can return to it. This is a
1315 macro because __builtin_eh_return must be invoked in the context of
1316 our caller. */
1318 #define uw_install_context(CURRENT, TARGET) \
1319 do \
1321 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1322 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1323 __builtin_eh_return (offset, handler); \
1325 while (0)
1327 static long
1328 uw_install_context_1 (struct _Unwind_Context *current,
1329 struct _Unwind_Context *target)
1331 long i;
1333 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1335 void *c = current->reg[i];
1336 void *t = target->reg[i];
1338 if (t && c && t != c)
1339 memcpy (c, t, dwarf_reg_size_table[i]);
1342 #ifdef EH_RETURN_STACKADJ_RTX
1344 void *target_cfa;
1346 /* If the last frame records a saved stack pointer, use it. */
1347 if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1348 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1349 else
1350 target_cfa = target->cfa;
1352 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1353 if (STACK_GROWS_DOWNWARD)
1354 return target_cfa - current->cfa + target->args_size;
1355 else
1356 return current->cfa - target_cfa - target->args_size;
1358 #else
1359 return 0;
1360 #endif
1363 static inline _Unwind_Ptr
1364 uw_identify_context (struct _Unwind_Context *context)
1366 return _Unwind_GetIP (context);
1370 #include "unwind.inc"
1372 #endif /* !USING_SJLJ_EXCEPTIONS */