2004-02-11 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / unwind-dw2.c
blob70d32215c7f37dceb81003a35ebc3a9027ac50ff
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 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 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 fs->retaddr_column = *p++;
341 fs->lsda_encoding = DW_EH_PE_omit;
343 /* If the augmentation starts with 'z', then a uleb128 immediately
344 follows containing the length of the augmentation field following
345 the size. */
346 if (*aug == 'z')
348 p = read_uleb128 (p, &utmp);
349 ret = p + utmp;
351 fs->saw_z = 1;
352 ++aug;
355 /* Iterate over recognized augmentation subsequences. */
356 while (*aug != '\0')
358 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
359 if (aug[0] == 'L')
361 fs->lsda_encoding = *p++;
362 aug += 1;
365 /* "R" indicates a byte indicating how FDE addresses are encoded. */
366 else if (aug[0] == 'R')
368 fs->fde_encoding = *p++;
369 aug += 1;
372 /* "P" indicates a personality routine in the CIE augmentation. */
373 else if (aug[0] == 'P')
375 p = read_encoded_value (context, *p, p + 1,
376 (_Unwind_Ptr *) &fs->personality);
377 aug += 1;
380 /* Otherwise we have an unknown augmentation string.
381 Bail unless we saw a 'z' prefix. */
382 else
383 return ret;
386 return ret ? ret : p;
390 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
391 onto the stack to start. */
393 static _Unwind_Word
394 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
395 struct _Unwind_Context *context, _Unwind_Word initial)
397 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
398 int stack_elt;
400 stack[0] = initial;
401 stack_elt = 1;
403 while (op_ptr < op_end)
405 enum dwarf_location_atom op = *op_ptr++;
406 _Unwind_Word result, reg, utmp;
407 _Unwind_Sword offset, stmp;
409 switch (op)
411 case DW_OP_lit0:
412 case DW_OP_lit1:
413 case DW_OP_lit2:
414 case DW_OP_lit3:
415 case DW_OP_lit4:
416 case DW_OP_lit5:
417 case DW_OP_lit6:
418 case DW_OP_lit7:
419 case DW_OP_lit8:
420 case DW_OP_lit9:
421 case DW_OP_lit10:
422 case DW_OP_lit11:
423 case DW_OP_lit12:
424 case DW_OP_lit13:
425 case DW_OP_lit14:
426 case DW_OP_lit15:
427 case DW_OP_lit16:
428 case DW_OP_lit17:
429 case DW_OP_lit18:
430 case DW_OP_lit19:
431 case DW_OP_lit20:
432 case DW_OP_lit21:
433 case DW_OP_lit22:
434 case DW_OP_lit23:
435 case DW_OP_lit24:
436 case DW_OP_lit25:
437 case DW_OP_lit26:
438 case DW_OP_lit27:
439 case DW_OP_lit28:
440 case DW_OP_lit29:
441 case DW_OP_lit30:
442 case DW_OP_lit31:
443 result = op - DW_OP_lit0;
444 break;
446 case DW_OP_addr:
447 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
448 op_ptr += sizeof (void *);
449 break;
451 case DW_OP_const1u:
452 result = read_1u (op_ptr);
453 op_ptr += 1;
454 break;
455 case DW_OP_const1s:
456 result = read_1s (op_ptr);
457 op_ptr += 1;
458 break;
459 case DW_OP_const2u:
460 result = read_2u (op_ptr);
461 op_ptr += 2;
462 break;
463 case DW_OP_const2s:
464 result = read_2s (op_ptr);
465 op_ptr += 2;
466 break;
467 case DW_OP_const4u:
468 result = read_4u (op_ptr);
469 op_ptr += 4;
470 break;
471 case DW_OP_const4s:
472 result = read_4s (op_ptr);
473 op_ptr += 4;
474 break;
475 case DW_OP_const8u:
476 result = read_8u (op_ptr);
477 op_ptr += 8;
478 break;
479 case DW_OP_const8s:
480 result = read_8s (op_ptr);
481 op_ptr += 8;
482 break;
483 case DW_OP_constu:
484 op_ptr = read_uleb128 (op_ptr, &result);
485 break;
486 case DW_OP_consts:
487 op_ptr = read_sleb128 (op_ptr, &stmp);
488 result = stmp;
489 break;
491 case DW_OP_reg0:
492 case DW_OP_reg1:
493 case DW_OP_reg2:
494 case DW_OP_reg3:
495 case DW_OP_reg4:
496 case DW_OP_reg5:
497 case DW_OP_reg6:
498 case DW_OP_reg7:
499 case DW_OP_reg8:
500 case DW_OP_reg9:
501 case DW_OP_reg10:
502 case DW_OP_reg11:
503 case DW_OP_reg12:
504 case DW_OP_reg13:
505 case DW_OP_reg14:
506 case DW_OP_reg15:
507 case DW_OP_reg16:
508 case DW_OP_reg17:
509 case DW_OP_reg18:
510 case DW_OP_reg19:
511 case DW_OP_reg20:
512 case DW_OP_reg21:
513 case DW_OP_reg22:
514 case DW_OP_reg23:
515 case DW_OP_reg24:
516 case DW_OP_reg25:
517 case DW_OP_reg26:
518 case DW_OP_reg27:
519 case DW_OP_reg28:
520 case DW_OP_reg29:
521 case DW_OP_reg30:
522 case DW_OP_reg31:
523 result = _Unwind_GetGR (context, op - DW_OP_reg0);
524 break;
525 case DW_OP_regx:
526 op_ptr = read_uleb128 (op_ptr, &reg);
527 result = _Unwind_GetGR (context, reg);
528 break;
530 case DW_OP_breg0:
531 case DW_OP_breg1:
532 case DW_OP_breg2:
533 case DW_OP_breg3:
534 case DW_OP_breg4:
535 case DW_OP_breg5:
536 case DW_OP_breg6:
537 case DW_OP_breg7:
538 case DW_OP_breg8:
539 case DW_OP_breg9:
540 case DW_OP_breg10:
541 case DW_OP_breg11:
542 case DW_OP_breg12:
543 case DW_OP_breg13:
544 case DW_OP_breg14:
545 case DW_OP_breg15:
546 case DW_OP_breg16:
547 case DW_OP_breg17:
548 case DW_OP_breg18:
549 case DW_OP_breg19:
550 case DW_OP_breg20:
551 case DW_OP_breg21:
552 case DW_OP_breg22:
553 case DW_OP_breg23:
554 case DW_OP_breg24:
555 case DW_OP_breg25:
556 case DW_OP_breg26:
557 case DW_OP_breg27:
558 case DW_OP_breg28:
559 case DW_OP_breg29:
560 case DW_OP_breg30:
561 case DW_OP_breg31:
562 op_ptr = read_sleb128 (op_ptr, &offset);
563 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
564 break;
565 case DW_OP_bregx:
566 op_ptr = read_uleb128 (op_ptr, &reg);
567 op_ptr = read_sleb128 (op_ptr, &offset);
568 result = _Unwind_GetGR (context, reg) + offset;
569 break;
571 case DW_OP_dup:
572 if (stack_elt < 1)
573 abort ();
574 result = stack[stack_elt - 1];
575 break;
577 case DW_OP_drop:
578 if (--stack_elt < 0)
579 abort ();
580 goto no_push;
582 case DW_OP_pick:
583 offset = *op_ptr++;
584 if (offset >= stack_elt - 1)
585 abort ();
586 result = stack[stack_elt - 1 - offset];
587 break;
589 case DW_OP_over:
590 if (stack_elt < 2)
591 abort ();
592 result = stack[stack_elt - 2];
593 break;
595 case DW_OP_rot:
597 _Unwind_Word t1, t2, t3;
599 if (stack_elt < 3)
600 abort ();
601 t1 = stack[stack_elt - 1];
602 t2 = stack[stack_elt - 2];
603 t3 = stack[stack_elt - 3];
604 stack[stack_elt - 1] = t2;
605 stack[stack_elt - 2] = t3;
606 stack[stack_elt - 3] = t1;
607 goto no_push;
610 case DW_OP_deref:
611 case DW_OP_deref_size:
612 case DW_OP_abs:
613 case DW_OP_neg:
614 case DW_OP_not:
615 case DW_OP_plus_uconst:
616 /* Unary operations. */
617 if (--stack_elt < 0)
618 abort ();
619 result = stack[stack_elt];
621 switch (op)
623 case DW_OP_deref:
625 void *ptr = (void *) (_Unwind_Ptr) result;
626 result = (_Unwind_Ptr) read_pointer (ptr);
628 break;
630 case DW_OP_deref_size:
632 void *ptr = (void *) (_Unwind_Ptr) result;
633 switch (*op_ptr++)
635 case 1:
636 result = read_1u (ptr);
637 break;
638 case 2:
639 result = read_2u (ptr);
640 break;
641 case 4:
642 result = read_4u (ptr);
643 break;
644 case 8:
645 result = read_8u (ptr);
646 break;
647 default:
648 abort ();
651 break;
653 case DW_OP_abs:
654 if ((_Unwind_Sword) result < 0)
655 result = -result;
656 break;
657 case DW_OP_neg:
658 result = -result;
659 break;
660 case DW_OP_not:
661 result = ~result;
662 break;
663 case DW_OP_plus_uconst:
664 op_ptr = read_uleb128 (op_ptr, &utmp);
665 result += utmp;
666 break;
668 default:
669 abort ();
671 break;
673 case DW_OP_and:
674 case DW_OP_div:
675 case DW_OP_minus:
676 case DW_OP_mod:
677 case DW_OP_mul:
678 case DW_OP_or:
679 case DW_OP_plus:
680 case DW_OP_le:
681 case DW_OP_ge:
682 case DW_OP_eq:
683 case DW_OP_lt:
684 case DW_OP_gt:
685 case DW_OP_ne:
687 /* Binary operations. */
688 _Unwind_Word first, second;
689 if ((stack_elt -= 2) < 0)
690 abort ();
691 second = stack[stack_elt];
692 first = stack[stack_elt + 1];
694 switch (op)
696 case DW_OP_and:
697 result = second & first;
698 break;
699 case DW_OP_div:
700 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
701 break;
702 case DW_OP_minus:
703 result = second - first;
704 break;
705 case DW_OP_mod:
706 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
707 break;
708 case DW_OP_mul:
709 result = second * first;
710 break;
711 case DW_OP_or:
712 result = second | first;
713 break;
714 case DW_OP_plus:
715 result = second + first;
716 break;
717 case DW_OP_shl:
718 result = second << first;
719 break;
720 case DW_OP_shr:
721 result = second >> first;
722 break;
723 case DW_OP_shra:
724 result = (_Unwind_Sword) second >> first;
725 break;
726 case DW_OP_xor:
727 result = second ^ first;
728 break;
729 case DW_OP_le:
730 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
731 break;
732 case DW_OP_ge:
733 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
734 break;
735 case DW_OP_eq:
736 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
737 break;
738 case DW_OP_lt:
739 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
740 break;
741 case DW_OP_gt:
742 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
743 break;
744 case DW_OP_ne:
745 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
746 break;
748 default:
749 abort ();
752 break;
754 case DW_OP_skip:
755 offset = read_2s (op_ptr);
756 op_ptr += 2;
757 op_ptr += offset;
758 goto no_push;
760 case DW_OP_bra:
761 if (--stack_elt < 0)
762 abort ();
763 offset = read_2s (op_ptr);
764 op_ptr += 2;
765 if (stack[stack_elt] != 0)
766 op_ptr += offset;
767 goto no_push;
769 case DW_OP_nop:
770 goto no_push;
772 default:
773 abort ();
776 /* Most things push a result value. */
777 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
778 abort ();
779 stack[stack_elt++] = result;
780 no_push:;
783 /* We were executing this program to get a value. It should be
784 at top of stack. */
785 if (--stack_elt < 0)
786 abort ();
787 return stack[stack_elt];
791 /* Decode DWARF 2 call frame information. Takes pointers the
792 instruction sequence to decode, current register information and
793 CIE info, and the PC range to evaluate. */
795 static void
796 execute_cfa_program (const unsigned char *insn_ptr,
797 const unsigned char *insn_end,
798 struct _Unwind_Context *context,
799 _Unwind_FrameState *fs)
801 struct frame_state_reg_info *unused_rs = NULL;
803 /* Don't allow remember/restore between CIE and FDE programs. */
804 fs->regs.prev = NULL;
806 /* The comparison with the return address uses < rather than <= because
807 we are only interested in the effects of code before the call; for a
808 noreturn function, the return address may point to unrelated code with
809 a different stack configuration that we are not interested in. We
810 assume that the call itself is unwind info-neutral; if not, or if
811 there are delay instructions that adjust the stack, these must be
812 reflected at the point immediately before the call insn. */
813 while (insn_ptr < insn_end && fs->pc < context->ra)
815 unsigned char insn = *insn_ptr++;
816 _Unwind_Word reg, utmp;
817 _Unwind_Sword offset, stmp;
819 if ((insn & 0xc0) == DW_CFA_advance_loc)
820 fs->pc += (insn & 0x3f) * fs->code_align;
821 else if ((insn & 0xc0) == DW_CFA_offset)
823 reg = insn & 0x3f;
824 insn_ptr = read_uleb128 (insn_ptr, &utmp);
825 offset = (_Unwind_Sword) utmp * fs->data_align;
826 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
827 = REG_SAVED_OFFSET;
828 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
830 else if ((insn & 0xc0) == DW_CFA_restore)
832 reg = insn & 0x3f;
833 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
835 else switch (insn)
837 case DW_CFA_set_loc:
838 insn_ptr = read_encoded_value (context, fs->fde_encoding,
839 insn_ptr, (_Unwind_Ptr *) &fs->pc);
840 break;
842 case DW_CFA_advance_loc1:
843 fs->pc += read_1u (insn_ptr) * fs->code_align;
844 insn_ptr += 1;
845 break;
846 case DW_CFA_advance_loc2:
847 fs->pc += read_2u (insn_ptr) * fs->code_align;
848 insn_ptr += 2;
849 break;
850 case DW_CFA_advance_loc4:
851 fs->pc += read_4u (insn_ptr) * fs->code_align;
852 insn_ptr += 4;
853 break;
855 case DW_CFA_offset_extended:
856 insn_ptr = read_uleb128 (insn_ptr, &reg);
857 insn_ptr = read_uleb128 (insn_ptr, &utmp);
858 offset = (_Unwind_Sword) utmp * fs->data_align;
859 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
860 = REG_SAVED_OFFSET;
861 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
862 break;
864 case DW_CFA_restore_extended:
865 insn_ptr = read_uleb128 (insn_ptr, &reg);
866 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
867 break;
869 case DW_CFA_undefined:
870 case DW_CFA_same_value:
871 insn_ptr = read_uleb128 (insn_ptr, &reg);
872 break;
874 case DW_CFA_nop:
875 break;
877 case DW_CFA_register:
879 _Unwind_Word reg2;
880 insn_ptr = read_uleb128 (insn_ptr, &reg);
881 insn_ptr = read_uleb128 (insn_ptr, &reg2);
882 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
883 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
885 break;
887 case DW_CFA_remember_state:
889 struct frame_state_reg_info *new_rs;
890 if (unused_rs)
892 new_rs = unused_rs;
893 unused_rs = unused_rs->prev;
895 else
896 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
898 *new_rs = fs->regs;
899 fs->regs.prev = new_rs;
901 break;
903 case DW_CFA_restore_state:
905 struct frame_state_reg_info *old_rs = fs->regs.prev;
906 fs->regs = *old_rs;
907 old_rs->prev = unused_rs;
908 unused_rs = old_rs;
910 break;
912 case DW_CFA_def_cfa:
913 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
914 insn_ptr = read_uleb128 (insn_ptr, &utmp);
915 fs->cfa_offset = utmp;
916 fs->cfa_how = CFA_REG_OFFSET;
917 break;
919 case DW_CFA_def_cfa_register:
920 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
921 fs->cfa_how = CFA_REG_OFFSET;
922 break;
924 case DW_CFA_def_cfa_offset:
925 insn_ptr = read_uleb128 (insn_ptr, &utmp);
926 fs->cfa_offset = utmp;
927 /* cfa_how deliberately not set. */
928 break;
930 case DW_CFA_def_cfa_expression:
931 fs->cfa_exp = insn_ptr;
932 fs->cfa_how = CFA_EXP;
933 insn_ptr = read_uleb128 (insn_ptr, &utmp);
934 insn_ptr += utmp;
935 break;
937 case DW_CFA_expression:
938 insn_ptr = read_uleb128 (insn_ptr, &reg);
939 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
940 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
941 insn_ptr = read_uleb128 (insn_ptr, &utmp);
942 insn_ptr += utmp;
943 break;
945 /* From the 2.1 draft. */
946 case DW_CFA_offset_extended_sf:
947 insn_ptr = read_uleb128 (insn_ptr, &reg);
948 insn_ptr = read_sleb128 (insn_ptr, &stmp);
949 offset = stmp * fs->data_align;
950 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
951 = REG_SAVED_OFFSET;
952 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
953 break;
955 case DW_CFA_def_cfa_sf:
956 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
957 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
958 fs->cfa_how = CFA_REG_OFFSET;
959 break;
961 case DW_CFA_def_cfa_offset_sf:
962 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
963 /* cfa_how deliberately not set. */
964 break;
966 case DW_CFA_GNU_window_save:
967 /* ??? Hardcoded for SPARC register window configuration. */
968 for (reg = 16; reg < 32; ++reg)
970 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
971 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
973 break;
975 case DW_CFA_GNU_args_size:
976 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
977 break;
979 case DW_CFA_GNU_negative_offset_extended:
980 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
981 older PowerPC code. */
982 insn_ptr = read_uleb128 (insn_ptr, &reg);
983 insn_ptr = read_uleb128 (insn_ptr, &utmp);
984 offset = (_Unwind_Word) utmp * fs->data_align;
985 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
986 = REG_SAVED_OFFSET;
987 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
988 break;
990 default:
991 abort ();
996 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
997 its caller and decode it into FS. This function also sets the
998 args_size and lsda members of CONTEXT, as they are really information
999 about the caller's frame. */
1001 static _Unwind_Reason_Code
1002 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1004 const struct dwarf_fde *fde;
1005 const struct dwarf_cie *cie;
1006 const unsigned char *aug, *insn, *end;
1008 memset (fs, 0, sizeof (*fs));
1009 context->args_size = 0;
1010 context->lsda = 0;
1012 if (context->ra == 0)
1013 return _URC_END_OF_STACK;
1015 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
1016 if (fde == NULL)
1018 /* Couldn't find frame unwind info for this function. Try a
1019 target-specific fallback mechanism. This will necessarily
1020 not provide a personality routine or LSDA. */
1021 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1022 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
1023 return _URC_END_OF_STACK;
1024 success:
1025 return _URC_NO_REASON;
1026 #else
1027 return _URC_END_OF_STACK;
1028 #endif
1031 fs->pc = context->bases.func;
1033 cie = get_cie (fde);
1034 insn = extract_cie_info (cie, context, fs);
1035 if (insn == NULL)
1036 /* CIE contained unknown augmentation. */
1037 return _URC_FATAL_PHASE1_ERROR;
1039 /* First decode all the insns in the CIE. */
1040 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1041 execute_cfa_program (insn, end, context, fs);
1043 /* Locate augmentation for the fde. */
1044 aug = (unsigned char *) fde + sizeof (*fde);
1045 aug += 2 * size_of_encoded_value (fs->fde_encoding);
1046 insn = NULL;
1047 if (fs->saw_z)
1049 _Unwind_Word i;
1050 aug = read_uleb128 (aug, &i);
1051 insn = aug + i;
1053 if (fs->lsda_encoding != DW_EH_PE_omit)
1054 aug = read_encoded_value (context, fs->lsda_encoding, aug,
1055 (_Unwind_Ptr *) &context->lsda);
1057 /* Then the insns in the FDE up to our target PC. */
1058 if (insn == NULL)
1059 insn = aug;
1060 end = (unsigned char *) next_fde (fde);
1061 execute_cfa_program (insn, end, context, fs);
1063 return _URC_NO_REASON;
1066 typedef struct frame_state
1068 void *cfa;
1069 void *eh_ptr;
1070 long cfa_offset;
1071 long args_size;
1072 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1073 unsigned short cfa_reg;
1074 unsigned short retaddr_column;
1075 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1076 } frame_state;
1078 struct frame_state * __frame_state_for (void *, struct frame_state *);
1080 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1081 a given PC_TARGET. The caller should allocate a local variable of
1082 `struct frame_state' and pass its address to STATE_IN. */
1084 struct frame_state *
1085 __frame_state_for (void *pc_target, struct frame_state *state_in)
1087 struct _Unwind_Context context;
1088 _Unwind_FrameState fs;
1089 int reg;
1091 memset (&context, 0, sizeof (struct _Unwind_Context));
1092 context.ra = pc_target + 1;
1094 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1095 return 0;
1097 /* We have no way to pass a location expression for the CFA to our
1098 caller. It wouldn't understand it anyway. */
1099 if (fs.cfa_how == CFA_EXP)
1100 return 0;
1102 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1104 state_in->saved[reg] = fs.regs.reg[reg].how;
1105 switch (state_in->saved[reg])
1107 case REG_SAVED_REG:
1108 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1109 break;
1110 case REG_SAVED_OFFSET:
1111 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1112 break;
1113 default:
1114 state_in->reg_or_offset[reg] = 0;
1115 break;
1119 state_in->cfa_offset = fs.cfa_offset;
1120 state_in->cfa_reg = fs.cfa_reg;
1121 state_in->retaddr_column = fs.retaddr_column;
1122 state_in->args_size = context.args_size;
1123 state_in->eh_ptr = fs.eh_ptr;
1125 return state_in;
1128 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1130 static inline void
1131 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1132 _Unwind_SpTmp *tmp_sp)
1134 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1136 if (size == sizeof(_Unwind_Ptr))
1137 tmp_sp->ptr = (_Unwind_Ptr) cfa;
1138 else if (size == sizeof(_Unwind_Word))
1139 tmp_sp->word = (_Unwind_Ptr) cfa;
1140 else
1141 abort ();
1142 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1145 static void
1146 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1148 struct _Unwind_Context orig_context = *context;
1149 void *cfa;
1150 long i;
1152 #ifdef EH_RETURN_STACKADJ_RTX
1153 /* Special handling here: Many machines do not use a frame pointer,
1154 and track the CFA only through offsets from the stack pointer from
1155 one frame to the next. In this case, the stack pointer is never
1156 stored, so it has no saved address in the context. What we do
1157 have is the CFA from the previous stack frame.
1159 In very special situations (such as unwind info for signal return),
1160 there may be location expressions that use the stack pointer as well.
1162 Do this conditionally for one frame. This allows the unwind info
1163 for one frame to save a copy of the stack pointer from the previous
1164 frame, and be able to use much easier CFA mechanisms to do it.
1165 Always zap the saved stack pointer value for the next frame; carrying
1166 the value over from one frame to another doesn't make sense. */
1168 _Unwind_SpTmp tmp_sp;
1170 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1171 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1172 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1173 #endif
1175 /* Compute this frame's CFA. */
1176 switch (fs->cfa_how)
1178 case CFA_REG_OFFSET:
1179 cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
1180 cfa += fs->cfa_offset;
1181 break;
1183 case CFA_EXP:
1185 const unsigned char *exp = fs->cfa_exp;
1186 _Unwind_Word len;
1188 exp = read_uleb128 (exp, &len);
1189 cfa = (void *) (_Unwind_Ptr)
1190 execute_stack_op (exp, exp + len, &orig_context, 0);
1191 break;
1194 default:
1195 abort ();
1197 context->cfa = cfa;
1199 /* Compute the addresses of all registers saved in this frame. */
1200 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1201 switch (fs->regs.reg[i].how)
1203 case REG_UNSAVED:
1204 break;
1206 case REG_SAVED_OFFSET:
1207 _Unwind_SetGRPtr (context, i,
1208 (void *) (cfa + fs->regs.reg[i].loc.offset));
1209 break;
1211 case REG_SAVED_REG:
1212 _Unwind_SetGRPtr
1213 (context, i,
1214 _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
1215 break;
1217 case REG_SAVED_EXP:
1219 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1220 _Unwind_Word len;
1221 _Unwind_Ptr val;
1223 exp = read_uleb128 (exp, &len);
1224 val = execute_stack_op (exp, exp + len, &orig_context,
1225 (_Unwind_Ptr) cfa);
1226 _Unwind_SetGRPtr (context, i, (void *) val);
1228 break;
1231 MD_FROB_UPDATE_CONTEXT (context, fs);
1234 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1235 of its caller. Update CONTEXT to refer to the caller as well. Note
1236 that the args_size and lsda members are not updated here, but later in
1237 uw_frame_state_for. */
1239 static void
1240 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1242 uw_update_context_1 (context, fs);
1244 /* Compute the return address now, since the return address column
1245 can change from frame to frame. */
1246 context->ra = __builtin_extract_return_addr
1247 (_Unwind_GetPtr (context, fs->retaddr_column));
1250 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1251 level will be the return address and the CFA. */
1253 #define uw_init_context(CONTEXT) \
1254 do \
1256 /* Do any necessary initialization to access arbitrary stack frames. \
1257 On the SPARC, this means flushing the register windows. */ \
1258 __builtin_unwind_init (); \
1259 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1260 __builtin_return_address (0)); \
1262 while (0)
1264 static inline void
1265 init_dwarf_reg_size_table (void)
1267 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1270 static void
1271 uw_init_context_1 (struct _Unwind_Context *context,
1272 void *outer_cfa, void *outer_ra)
1274 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1275 _Unwind_FrameState fs;
1276 _Unwind_SpTmp sp_slot;
1278 memset (context, 0, sizeof (struct _Unwind_Context));
1279 context->ra = ra;
1281 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1282 abort ();
1284 #if __GTHREADS
1286 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1287 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1288 || dwarf_reg_size_table[0] == 0)
1289 init_dwarf_reg_size_table ();
1291 #else
1292 if (dwarf_reg_size_table[0] == 0)
1293 init_dwarf_reg_size_table ();
1294 #endif
1296 /* Force the frame state to use the known cfa value. */
1297 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1298 fs.cfa_how = CFA_REG_OFFSET;
1299 fs.cfa_reg = __builtin_dwarf_sp_column ();
1300 fs.cfa_offset = 0;
1302 uw_update_context_1 (context, &fs);
1304 /* If the return address column was saved in a register in the
1305 initialization context, then we can't see it in the given
1306 call frame data. So have the initialization context tell us. */
1307 context->ra = __builtin_extract_return_addr (outer_ra);
1311 /* Install TARGET into CURRENT so that we can return to it. This is a
1312 macro because __builtin_eh_return must be invoked in the context of
1313 our caller. */
1315 #define uw_install_context(CURRENT, TARGET) \
1316 do \
1318 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1319 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1320 __builtin_eh_return (offset, handler); \
1322 while (0)
1324 static long
1325 uw_install_context_1 (struct _Unwind_Context *current,
1326 struct _Unwind_Context *target)
1328 long i;
1330 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1332 void *c = current->reg[i];
1333 void *t = target->reg[i];
1335 if (t && c && t != c)
1336 memcpy (c, t, dwarf_reg_size_table[i]);
1339 #ifdef EH_RETURN_STACKADJ_RTX
1341 void *target_cfa;
1343 /* If the last frame records a saved stack pointer, use it. */
1344 if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1345 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1346 else
1347 target_cfa = target->cfa;
1349 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1350 if (STACK_GROWS_DOWNWARD)
1351 return target_cfa - current->cfa + target->args_size;
1352 else
1353 return current->cfa - target_cfa - target->args_size;
1355 #else
1356 return 0;
1357 #endif
1360 static inline _Unwind_Ptr
1361 uw_identify_context (struct _Unwind_Context *context)
1363 return _Unwind_GetIP (context);
1367 #include "unwind.inc"
1369 #endif /* !USING_SJLJ_EXCEPTIONS */