FSF GCC merge 02/23/03
[official-gcc.git] / gcc / unwind-dw2.c
blob6a44865d7c35669c2a389ebde05855b5e4cb0253
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 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "tconfig.h"
23 #include "tsystem.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "dwarf2.h"
27 #include "unwind.h"
28 #include "unwind-pe.h"
29 #include "unwind-dw2-fde.h"
30 #include "gthr.h"
33 #ifndef __USING_SJLJ_EXCEPTIONS__
35 #ifndef STACK_GROWS_DOWNWARD
36 #define STACK_GROWS_DOWNWARD 0
37 #else
38 #undef STACK_GROWS_DOWNWARD
39 #define STACK_GROWS_DOWNWARD 1
40 #endif
42 /* A target can override (perhaps for backward compatibility) how
43 many dwarf2 columns are unwound. */
44 #ifndef DWARF_FRAME_REGISTERS
45 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
46 #endif
48 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
49 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
50 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
51 #endif
53 /* This is the register and unwind state for a particular frame. This
54 provides the information necessary to unwind up past a frame and return
55 to its caller. */
56 struct _Unwind_Context
58 void *reg[DWARF_FRAME_REGISTERS+1];
59 void *cfa;
60 void *ra;
61 void *lsda;
62 struct dwarf_eh_bases bases;
63 _Unwind_Word args_size;
66 /* Byte size of every register managed by these routines. */
67 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
70 /* The result of interpreting the frame unwind info for a frame.
71 This is all symbolic at this point, as none of the values can
72 be resolved until the target pc is located. */
73 typedef struct
75 /* Each register save state can be described in terms of a CFA slot,
76 another register, or a location expression. */
77 struct frame_state_reg_info
79 struct {
80 union {
81 _Unwind_Word reg;
82 _Unwind_Sword offset;
83 const unsigned char *exp;
84 } loc;
85 enum {
86 REG_UNSAVED,
87 REG_SAVED_OFFSET,
88 REG_SAVED_REG,
89 REG_SAVED_EXP,
90 } how;
91 } reg[DWARF_FRAME_REGISTERS+1];
93 /* Used to implement DW_CFA_remember_state. */
94 struct frame_state_reg_info *prev;
95 } regs;
97 /* The CFA can be described in terms of a reg+offset or a
98 location expression. */
99 _Unwind_Sword cfa_offset;
100 _Unwind_Word cfa_reg;
101 const unsigned char *cfa_exp;
102 enum {
103 CFA_UNSET,
104 CFA_REG_OFFSET,
105 CFA_EXP,
106 } cfa_how;
108 /* The PC described by the current frame state. */
109 void *pc;
111 /* The information we care about from the CIE/FDE. */
112 _Unwind_Personality_Fn personality;
113 _Unwind_Sword data_align;
114 _Unwind_Word code_align;
115 unsigned char retaddr_column;
116 unsigned char fde_encoding;
117 unsigned char lsda_encoding;
118 unsigned char saw_z;
119 void *eh_ptr;
120 } _Unwind_FrameState;
122 /* Read unaligned data from the instruction buffer. */
124 union unaligned
126 void *p;
127 unsigned u2 __attribute__ ((mode (HI)));
128 unsigned u4 __attribute__ ((mode (SI)));
129 unsigned u8 __attribute__ ((mode (DI)));
130 signed s2 __attribute__ ((mode (HI)));
131 signed s4 __attribute__ ((mode (SI)));
132 signed s8 __attribute__ ((mode (DI)));
133 } __attribute__ ((packed));
135 static inline void *
136 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
138 static inline int
139 read_1u (const void *p) { return *(const unsigned char *) p; }
141 static inline int
142 read_1s (const void *p) { return *(const signed char *) p; }
144 static inline int
145 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
147 static inline int
148 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
150 static inline unsigned int
151 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
153 static inline int
154 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
156 static inline unsigned long
157 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
159 static inline unsigned long
160 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
162 /* Get the value of register REG as saved in CONTEXT. */
164 inline _Unwind_Word
165 _Unwind_GetGR (struct _Unwind_Context *context, int index)
167 /* This will segfault if the register hasn't been saved. */
168 return * (_Unwind_Word *) context->reg[index];
171 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
173 inline void
174 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
176 * (_Unwind_Word *) context->reg[index] = val;
179 /* Retrieve the return address for CONTEXT. */
181 inline _Unwind_Ptr
182 _Unwind_GetIP (struct _Unwind_Context *context)
184 return (_Unwind_Ptr) context->ra;
187 /* Overwrite the return address for CONTEXT with VAL. */
189 inline void
190 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
192 context->ra = (void *) val;
195 void *
196 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
198 return context->lsda;
201 _Unwind_Ptr
202 _Unwind_GetRegionStart (struct _Unwind_Context *context)
204 return (_Unwind_Ptr) context->bases.func;
207 void *
208 _Unwind_FindEnclosingFunction (void *pc)
210 struct dwarf_eh_bases bases;
211 struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
212 if (fde)
213 return bases.func;
214 else
215 return NULL;
218 #ifndef __ia64__
219 _Unwind_Ptr
220 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
222 return (_Unwind_Ptr) context->bases.dbase;
225 _Unwind_Ptr
226 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
228 return (_Unwind_Ptr) context->bases.tbase;
230 #endif
232 /* Extract any interesting information from the CIE for the translation
233 unit F belongs to. Return a pointer to the byte after the augmentation,
234 or NULL if we encountered an undecipherable augmentation. */
236 static const unsigned char *
237 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
238 _Unwind_FrameState *fs)
240 const unsigned char *aug = cie->augmentation;
241 const unsigned char *p = aug + strlen (aug) + 1;
242 const unsigned char *ret = NULL;
243 _Unwind_Word utmp;
245 /* g++ v2 "eh" has pointer immediately following augmentation string,
246 so it must be handled first. */
247 if (aug[0] == 'e' && aug[1] == 'h')
249 fs->eh_ptr = read_pointer (p);
250 p += sizeof (void *);
251 aug += 2;
254 /* Immediately following the augmentation are the code and
255 data alignment and return address column. */
256 p = read_uleb128 (p, &fs->code_align);
257 p = read_sleb128 (p, &fs->data_align);
258 fs->retaddr_column = *p++;
259 fs->lsda_encoding = DW_EH_PE_omit;
261 /* If the augmentation starts with 'z', then a uleb128 immediately
262 follows containing the length of the augmentation field following
263 the size. */
264 if (*aug == 'z')
266 p = read_uleb128 (p, &utmp);
267 ret = p + utmp;
269 fs->saw_z = 1;
270 ++aug;
273 /* Iterate over recognized augmentation subsequences. */
274 while (*aug != '\0')
276 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
277 if (aug[0] == 'L')
279 fs->lsda_encoding = *p++;
280 aug += 1;
283 /* "R" indicates a byte indicating how FDE addresses are encoded. */
284 else if (aug[0] == 'R')
286 fs->fde_encoding = *p++;
287 aug += 1;
290 /* "P" indicates a personality routine in the CIE augmentation. */
291 else if (aug[0] == 'P')
293 p = read_encoded_value (context, *p, p + 1,
294 (_Unwind_Ptr *) &fs->personality);
295 aug += 1;
298 /* Otherwise we have an unknown augmentation string.
299 Bail unless we saw a 'z' prefix. */
300 else
301 return ret;
304 return ret ? ret : p;
308 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
309 onto the stack to start. */
311 static _Unwind_Word
312 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
313 struct _Unwind_Context *context, _Unwind_Word initial)
315 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
316 int stack_elt;
318 stack[0] = initial;
319 stack_elt = 1;
321 while (op_ptr < op_end)
323 enum dwarf_location_atom op = *op_ptr++;
324 _Unwind_Word result, reg, utmp;
325 _Unwind_Sword offset, stmp;
327 switch (op)
329 case DW_OP_lit0:
330 case DW_OP_lit1:
331 case DW_OP_lit2:
332 case DW_OP_lit3:
333 case DW_OP_lit4:
334 case DW_OP_lit5:
335 case DW_OP_lit6:
336 case DW_OP_lit7:
337 case DW_OP_lit8:
338 case DW_OP_lit9:
339 case DW_OP_lit10:
340 case DW_OP_lit11:
341 case DW_OP_lit12:
342 case DW_OP_lit13:
343 case DW_OP_lit14:
344 case DW_OP_lit15:
345 case DW_OP_lit16:
346 case DW_OP_lit17:
347 case DW_OP_lit18:
348 case DW_OP_lit19:
349 case DW_OP_lit20:
350 case DW_OP_lit21:
351 case DW_OP_lit22:
352 case DW_OP_lit23:
353 case DW_OP_lit24:
354 case DW_OP_lit25:
355 case DW_OP_lit26:
356 case DW_OP_lit27:
357 case DW_OP_lit28:
358 case DW_OP_lit29:
359 case DW_OP_lit30:
360 case DW_OP_lit31:
361 result = op - DW_OP_lit0;
362 break;
364 case DW_OP_addr:
365 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
366 op_ptr += sizeof (void *);
367 break;
369 case DW_OP_const1u:
370 result = read_1u (op_ptr);
371 op_ptr += 1;
372 break;
373 case DW_OP_const1s:
374 result = read_1s (op_ptr);
375 op_ptr += 1;
376 break;
377 case DW_OP_const2u:
378 result = read_2u (op_ptr);
379 op_ptr += 2;
380 break;
381 case DW_OP_const2s:
382 result = read_2s (op_ptr);
383 op_ptr += 2;
384 break;
385 case DW_OP_const4u:
386 result = read_4u (op_ptr);
387 op_ptr += 4;
388 break;
389 case DW_OP_const4s:
390 result = read_4s (op_ptr);
391 op_ptr += 4;
392 break;
393 case DW_OP_const8u:
394 result = read_8u (op_ptr);
395 op_ptr += 8;
396 break;
397 case DW_OP_const8s:
398 result = read_8s (op_ptr);
399 op_ptr += 8;
400 break;
401 case DW_OP_constu:
402 op_ptr = read_uleb128 (op_ptr, &result);
403 break;
404 case DW_OP_consts:
405 op_ptr = read_sleb128 (op_ptr, &stmp);
406 result = stmp;
407 break;
409 case DW_OP_reg0:
410 case DW_OP_reg1:
411 case DW_OP_reg2:
412 case DW_OP_reg3:
413 case DW_OP_reg4:
414 case DW_OP_reg5:
415 case DW_OP_reg6:
416 case DW_OP_reg7:
417 case DW_OP_reg8:
418 case DW_OP_reg9:
419 case DW_OP_reg10:
420 case DW_OP_reg11:
421 case DW_OP_reg12:
422 case DW_OP_reg13:
423 case DW_OP_reg14:
424 case DW_OP_reg15:
425 case DW_OP_reg16:
426 case DW_OP_reg17:
427 case DW_OP_reg18:
428 case DW_OP_reg19:
429 case DW_OP_reg20:
430 case DW_OP_reg21:
431 case DW_OP_reg22:
432 case DW_OP_reg23:
433 case DW_OP_reg24:
434 case DW_OP_reg25:
435 case DW_OP_reg26:
436 case DW_OP_reg27:
437 case DW_OP_reg28:
438 case DW_OP_reg29:
439 case DW_OP_reg30:
440 case DW_OP_reg31:
441 result = _Unwind_GetGR (context, op - DW_OP_reg0);
442 break;
443 case DW_OP_regx:
444 op_ptr = read_uleb128 (op_ptr, &reg);
445 result = _Unwind_GetGR (context, reg);
446 break;
448 case DW_OP_breg0:
449 case DW_OP_breg1:
450 case DW_OP_breg2:
451 case DW_OP_breg3:
452 case DW_OP_breg4:
453 case DW_OP_breg5:
454 case DW_OP_breg6:
455 case DW_OP_breg7:
456 case DW_OP_breg8:
457 case DW_OP_breg9:
458 case DW_OP_breg10:
459 case DW_OP_breg11:
460 case DW_OP_breg12:
461 case DW_OP_breg13:
462 case DW_OP_breg14:
463 case DW_OP_breg15:
464 case DW_OP_breg16:
465 case DW_OP_breg17:
466 case DW_OP_breg18:
467 case DW_OP_breg19:
468 case DW_OP_breg20:
469 case DW_OP_breg21:
470 case DW_OP_breg22:
471 case DW_OP_breg23:
472 case DW_OP_breg24:
473 case DW_OP_breg25:
474 case DW_OP_breg26:
475 case DW_OP_breg27:
476 case DW_OP_breg28:
477 case DW_OP_breg29:
478 case DW_OP_breg30:
479 case DW_OP_breg31:
480 op_ptr = read_sleb128 (op_ptr, &offset);
481 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
482 break;
483 case DW_OP_bregx:
484 op_ptr = read_uleb128 (op_ptr, &reg);
485 op_ptr = read_sleb128 (op_ptr, &offset);
486 result = _Unwind_GetGR (context, reg) + offset;
487 break;
489 case DW_OP_dup:
490 if (stack_elt < 1)
491 abort ();
492 result = stack[stack_elt - 1];
493 break;
495 case DW_OP_drop:
496 if (--stack_elt < 0)
497 abort ();
498 goto no_push;
500 case DW_OP_pick:
501 offset = *op_ptr++;
502 if (offset >= stack_elt - 1)
503 abort ();
504 result = stack[stack_elt - 1 - offset];
505 break;
507 case DW_OP_over:
508 if (stack_elt < 2)
509 abort ();
510 result = stack[stack_elt - 2];
511 break;
513 case DW_OP_rot:
515 _Unwind_Word t1, t2, t3;
517 if (stack_elt < 3)
518 abort ();
519 t1 = stack[stack_elt - 1];
520 t2 = stack[stack_elt - 2];
521 t3 = stack[stack_elt - 3];
522 stack[stack_elt - 1] = t2;
523 stack[stack_elt - 2] = t3;
524 stack[stack_elt - 3] = t1;
525 goto no_push;
528 case DW_OP_deref:
529 case DW_OP_deref_size:
530 case DW_OP_abs:
531 case DW_OP_neg:
532 case DW_OP_not:
533 case DW_OP_plus_uconst:
534 /* Unary operations. */
535 if (--stack_elt < 0)
536 abort ();
537 result = stack[stack_elt];
539 switch (op)
541 case DW_OP_deref:
543 void *ptr = (void *) (_Unwind_Ptr) result;
544 result = (_Unwind_Ptr) read_pointer (ptr);
546 break;
548 case DW_OP_deref_size:
550 void *ptr = (void *) (_Unwind_Ptr) result;
551 switch (*op_ptr++)
553 case 1:
554 result = read_1u (ptr);
555 break;
556 case 2:
557 result = read_2u (ptr);
558 break;
559 case 4:
560 result = read_4u (ptr);
561 break;
562 case 8:
563 result = read_8u (ptr);
564 break;
565 default:
566 abort ();
569 break;
571 case DW_OP_abs:
572 if ((_Unwind_Sword) result < 0)
573 result = -result;
574 break;
575 case DW_OP_neg:
576 result = -result;
577 break;
578 case DW_OP_not:
579 result = ~result;
580 break;
581 case DW_OP_plus_uconst:
582 op_ptr = read_uleb128 (op_ptr, &utmp);
583 result += utmp;
584 break;
586 default:
587 abort ();
589 break;
591 case DW_OP_and:
592 case DW_OP_div:
593 case DW_OP_minus:
594 case DW_OP_mod:
595 case DW_OP_mul:
596 case DW_OP_or:
597 case DW_OP_plus:
598 case DW_OP_le:
599 case DW_OP_ge:
600 case DW_OP_eq:
601 case DW_OP_lt:
602 case DW_OP_gt:
603 case DW_OP_ne:
605 /* Binary operations. */
606 _Unwind_Word first, second;
607 if ((stack_elt -= 2) < 0)
608 abort ();
609 second = stack[stack_elt];
610 first = stack[stack_elt + 1];
612 switch (op)
614 case DW_OP_and:
615 result = second & first;
616 break;
617 case DW_OP_div:
618 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
619 break;
620 case DW_OP_minus:
621 result = second - first;
622 break;
623 case DW_OP_mod:
624 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
625 break;
626 case DW_OP_mul:
627 result = second * first;
628 break;
629 case DW_OP_or:
630 result = second | first;
631 break;
632 case DW_OP_plus:
633 result = second + first;
634 break;
635 case DW_OP_shl:
636 result = second << first;
637 break;
638 case DW_OP_shr:
639 result = second >> first;
640 break;
641 case DW_OP_shra:
642 result = (_Unwind_Sword) second >> first;
643 break;
644 case DW_OP_xor:
645 result = second ^ first;
646 break;
647 case DW_OP_le:
648 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
649 break;
650 case DW_OP_ge:
651 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
652 break;
653 case DW_OP_eq:
654 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
655 break;
656 case DW_OP_lt:
657 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
658 break;
659 case DW_OP_gt:
660 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
661 break;
662 case DW_OP_ne:
663 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
664 break;
666 default:
667 abort ();
670 break;
672 case DW_OP_skip:
673 offset = read_2s (op_ptr);
674 op_ptr += 2;
675 op_ptr += offset;
676 goto no_push;
678 case DW_OP_bra:
679 if (--stack_elt < 0)
680 abort ();
681 offset = read_2s (op_ptr);
682 op_ptr += 2;
683 if (stack[stack_elt] != 0)
684 op_ptr += offset;
685 goto no_push;
687 case DW_OP_nop:
688 goto no_push;
690 default:
691 abort ();
694 /* Most things push a result value. */
695 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
696 abort ();
697 stack[++stack_elt] = result;
698 no_push:;
701 /* We were executing this program to get a value. It should be
702 at top of stack. */
703 if (--stack_elt < 0)
704 abort ();
705 return stack[stack_elt];
709 /* Decode DWARF 2 call frame information. Takes pointers the
710 instruction sequence to decode, current register information and
711 CIE info, and the PC range to evaluate. */
713 static void
714 execute_cfa_program (const unsigned char *insn_ptr,
715 const unsigned char *insn_end,
716 struct _Unwind_Context *context,
717 _Unwind_FrameState *fs)
719 struct frame_state_reg_info *unused_rs = NULL;
721 /* Don't allow remember/restore between CIE and FDE programs. */
722 fs->regs.prev = NULL;
724 /* The comparison with the return address uses < rather than <= because
725 we are only interested in the effects of code before the call; for a
726 noreturn function, the return address may point to unrelated code with
727 a different stack configuration that we are not interested in. We
728 assume that the call itself is unwind info-neutral; if not, or if
729 there are delay instructions that adjust the stack, these must be
730 reflected at the point immediately before the call insn. */
731 while (insn_ptr < insn_end && fs->pc < context->ra)
733 unsigned char insn = *insn_ptr++;
734 _Unwind_Word reg, utmp;
735 _Unwind_Sword offset, stmp;
737 if ((insn & 0xc0) == DW_CFA_advance_loc)
738 fs->pc += (insn & 0x3f) * fs->code_align;
739 else if ((insn & 0xc0) == DW_CFA_offset)
741 reg = insn & 0x3f;
742 insn_ptr = read_uleb128 (insn_ptr, &utmp);
743 offset = (_Unwind_Sword) utmp * fs->data_align;
744 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
745 fs->regs.reg[reg].loc.offset = offset;
747 else if ((insn & 0xc0) == DW_CFA_restore)
749 reg = insn & 0x3f;
750 fs->regs.reg[reg].how = REG_UNSAVED;
752 else switch (insn)
754 case DW_CFA_set_loc:
755 insn_ptr = read_encoded_value (context, fs->fde_encoding,
756 insn_ptr, (_Unwind_Ptr *) &fs->pc);
757 break;
759 case DW_CFA_advance_loc1:
760 fs->pc += read_1u (insn_ptr) * fs->code_align;
761 insn_ptr += 1;
762 break;
763 case DW_CFA_advance_loc2:
764 fs->pc += read_2u (insn_ptr) * fs->code_align;
765 insn_ptr += 2;
766 break;
767 case DW_CFA_advance_loc4:
768 fs->pc += read_4u (insn_ptr) * fs->code_align;
769 insn_ptr += 4;
770 break;
772 case DW_CFA_offset_extended:
773 insn_ptr = read_uleb128 (insn_ptr, &reg);
774 insn_ptr = read_uleb128 (insn_ptr, &utmp);
775 offset = (_Unwind_Sword) utmp * fs->data_align;
776 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
777 fs->regs.reg[reg].loc.offset = offset;
778 break;
780 case DW_CFA_restore_extended:
781 insn_ptr = read_uleb128 (insn_ptr, &reg);
782 fs->regs.reg[reg].how = REG_UNSAVED;
783 break;
785 case DW_CFA_undefined:
786 case DW_CFA_same_value:
787 insn_ptr = read_uleb128 (insn_ptr, &reg);
788 break;
790 case DW_CFA_nop:
791 break;
793 case DW_CFA_register:
795 _Unwind_Word reg2;
796 insn_ptr = read_uleb128 (insn_ptr, &reg);
797 insn_ptr = read_uleb128 (insn_ptr, &reg2);
798 fs->regs.reg[reg].how = REG_SAVED_REG;
799 fs->regs.reg[reg].loc.reg = reg2;
801 break;
803 case DW_CFA_remember_state:
805 struct frame_state_reg_info *new_rs;
806 if (unused_rs)
808 new_rs = unused_rs;
809 unused_rs = unused_rs->prev;
811 else
812 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
814 *new_rs = fs->regs;
815 fs->regs.prev = new_rs;
817 break;
819 case DW_CFA_restore_state:
821 struct frame_state_reg_info *old_rs = fs->regs.prev;
822 fs->regs = *old_rs;
823 old_rs->prev = unused_rs;
824 unused_rs = old_rs;
826 break;
828 case DW_CFA_def_cfa:
829 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
830 insn_ptr = read_uleb128 (insn_ptr, &utmp);
831 fs->cfa_offset = utmp;
832 fs->cfa_how = CFA_REG_OFFSET;
833 break;
835 case DW_CFA_def_cfa_register:
836 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
837 fs->cfa_how = CFA_REG_OFFSET;
838 break;
840 case DW_CFA_def_cfa_offset:
841 insn_ptr = read_uleb128 (insn_ptr, &utmp);
842 fs->cfa_offset = utmp;
843 /* cfa_how deliberately not set. */
844 break;
846 case DW_CFA_def_cfa_expression:
847 insn_ptr = read_uleb128 (insn_ptr, &utmp);
848 fs->cfa_exp = insn_ptr;
849 fs->cfa_how = CFA_EXP;
850 insn_ptr += utmp;
851 break;
853 case DW_CFA_expression:
854 insn_ptr = read_uleb128 (insn_ptr, &reg);
855 insn_ptr = read_uleb128 (insn_ptr, &utmp);
856 fs->regs.reg[reg].how = REG_SAVED_EXP;
857 fs->regs.reg[reg].loc.exp = insn_ptr;
858 insn_ptr += utmp;
859 break;
861 /* From the 2.1 draft. */
862 case DW_CFA_offset_extended_sf:
863 insn_ptr = read_uleb128 (insn_ptr, &reg);
864 insn_ptr = read_sleb128 (insn_ptr, &stmp);
865 offset = stmp * fs->data_align;
866 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
867 fs->regs.reg[reg].loc.offset = offset;
868 break;
870 case DW_CFA_def_cfa_sf:
871 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
872 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
873 fs->cfa_how = CFA_REG_OFFSET;
874 break;
876 case DW_CFA_def_cfa_offset_sf:
877 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
878 /* cfa_how deliberately not set. */
879 break;
881 case DW_CFA_GNU_window_save:
882 /* ??? Hardcoded for SPARC register window configuration. */
883 for (reg = 16; reg < 32; ++reg)
885 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
886 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
888 break;
890 case DW_CFA_GNU_args_size:
891 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
892 break;
894 case DW_CFA_GNU_negative_offset_extended:
895 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
896 older PowerPC code. */
897 insn_ptr = read_uleb128 (insn_ptr, &reg);
898 insn_ptr = read_uleb128 (insn_ptr, &utmp);
899 offset = (_Unwind_Word) utmp * fs->data_align;
900 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
901 fs->regs.reg[reg].loc.offset = -offset;
902 break;
904 default:
905 abort ();
910 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
911 its caller and decode it into FS. This function also sets the
912 args_size and lsda members of CONTEXT, as they are really information
913 about the caller's frame. */
915 static _Unwind_Reason_Code
916 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
918 struct dwarf_fde *fde;
919 struct dwarf_cie *cie;
920 const unsigned char *aug, *insn, *end;
922 memset (fs, 0, sizeof (*fs));
923 context->args_size = 0;
924 context->lsda = 0;
926 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
927 if (fde == NULL)
929 /* Couldn't find frame unwind info for this function. Try a
930 target-specific fallback mechanism. This will necessarily
931 not provide a personality routine or LSDA. */
932 #ifdef MD_FALLBACK_FRAME_STATE_FOR
933 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
934 return _URC_END_OF_STACK;
935 success:
936 return _URC_NO_REASON;
937 #else
938 return _URC_END_OF_STACK;
939 #endif
942 fs->pc = context->bases.func;
944 cie = get_cie (fde);
945 insn = extract_cie_info (cie, context, fs);
946 if (insn == NULL)
947 /* CIE contained unknown augmentation. */
948 return _URC_FATAL_PHASE1_ERROR;
950 /* First decode all the insns in the CIE. */
951 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
952 execute_cfa_program (insn, end, context, fs);
954 /* Locate augmentation for the fde. */
955 aug = (unsigned char *) fde + sizeof (*fde);
956 aug += 2 * size_of_encoded_value (fs->fde_encoding);
957 insn = NULL;
958 if (fs->saw_z)
960 _Unwind_Word i;
961 aug = read_uleb128 (aug, &i);
962 insn = aug + i;
964 if (fs->lsda_encoding != DW_EH_PE_omit)
965 aug = read_encoded_value (context, fs->lsda_encoding, aug,
966 (_Unwind_Ptr *) &context->lsda);
968 /* Then the insns in the FDE up to our target PC. */
969 if (insn == NULL)
970 insn = aug;
971 end = (unsigned char *) next_fde (fde);
972 execute_cfa_program (insn, end, context, fs);
974 return _URC_NO_REASON;
977 typedef struct frame_state
979 void *cfa;
980 void *eh_ptr;
981 long cfa_offset;
982 long args_size;
983 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
984 unsigned short cfa_reg;
985 unsigned short retaddr_column;
986 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
987 } frame_state;
989 struct frame_state * __frame_state_for (void *, struct frame_state *);
991 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
992 a given PC_TARGET. The caller should allocate a local variable of
993 `struct frame_state' and pass its address to STATE_IN. */
995 struct frame_state *
996 __frame_state_for (void *pc_target, struct frame_state *state_in)
998 struct _Unwind_Context context;
999 _Unwind_FrameState fs;
1000 int reg;
1002 memset (&context, 0, sizeof (struct _Unwind_Context));
1003 context.ra = pc_target + 1;
1005 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1006 return 0;
1008 /* We have no way to pass a location expression for the CFA to our
1009 caller. It wouldn't understand it anyway. */
1010 if (fs.cfa_how == CFA_EXP)
1011 return 0;
1013 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1015 state_in->saved[reg] = fs.regs.reg[reg].how;
1016 switch (state_in->saved[reg])
1018 case REG_SAVED_REG:
1019 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1020 break;
1021 case REG_SAVED_OFFSET:
1022 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1023 break;
1024 default:
1025 state_in->reg_or_offset[reg] = 0;
1026 break;
1030 state_in->cfa_offset = fs.cfa_offset;
1031 state_in->cfa_reg = fs.cfa_reg;
1032 state_in->retaddr_column = fs.retaddr_column;
1033 state_in->args_size = context.args_size;
1034 state_in->eh_ptr = fs.eh_ptr;
1036 return state_in;
1039 static void
1040 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1042 struct _Unwind_Context orig_context = *context;
1043 void *cfa;
1044 long i;
1046 /* Compute this frame's CFA. */
1047 switch (fs->cfa_how)
1049 case CFA_REG_OFFSET:
1050 /* Special handling here: Many machines do not use a frame pointer,
1051 and track the CFA only through offsets from the stack pointer from
1052 one frame to the next. In this case, the stack pointer is never
1053 stored, so it has no saved address in the context. What we do
1054 have is the CFA from the previous stack frame. */
1055 if (context->reg[fs->cfa_reg] == NULL)
1056 cfa = context->cfa;
1057 else
1058 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1059 cfa += fs->cfa_offset;
1060 break;
1062 case CFA_EXP:
1063 /* ??? No way of knowing what register number is the stack pointer
1064 to do the same sort of handling as above. Assume that if the
1065 CFA calculation is so complicated as to require a stack program
1066 that this will not be a problem. */
1068 const unsigned char *exp = fs->cfa_exp;
1069 _Unwind_Word len;
1071 exp = read_uleb128 (exp, &len);
1072 cfa = (void *) (_Unwind_Ptr)
1073 execute_stack_op (exp, exp + len, context, 0);
1074 break;
1077 default:
1078 abort ();
1080 context->cfa = cfa;
1082 /* Compute the addresses of all registers saved in this frame. */
1083 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1084 switch (fs->regs.reg[i].how)
1086 case REG_UNSAVED:
1087 break;
1088 case REG_SAVED_OFFSET:
1089 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1090 break;
1091 case REG_SAVED_REG:
1092 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1093 break;
1094 case REG_SAVED_EXP:
1096 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1097 _Unwind_Word len;
1098 _Unwind_Ptr val;
1100 exp = read_uleb128 (exp, &len);
1101 val = execute_stack_op (exp, exp + len, &orig_context,
1102 (_Unwind_Ptr) cfa);
1103 context->reg[i] = (void *) val;
1105 break;
1109 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1110 of its caller. Update CONTEXT to refer to the caller as well. Note
1111 that the args_size and lsda members are not updated here, but later in
1112 uw_frame_state_for. */
1114 static void
1115 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1117 uw_update_context_1 (context, fs);
1119 /* Compute the return address now, since the return address column
1120 can change from frame to frame. */
1121 context->ra = __builtin_extract_return_addr
1122 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1125 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1126 level will be the return address and the CFA. */
1128 #define uw_init_context(CONTEXT) \
1129 do \
1131 /* Do any necessary initialization to access arbitrary stack frames. \
1132 On the SPARC, this means flushing the register windows. */ \
1133 __builtin_unwind_init (); \
1134 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1135 __builtin_return_address (0)); \
1137 while (0)
1139 static void
1140 uw_init_context_1 (struct _Unwind_Context *context,
1141 void *outer_cfa, void *outer_ra)
1143 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1144 _Unwind_FrameState fs;
1146 memset (context, 0, sizeof (struct _Unwind_Context));
1147 context->ra = ra;
1149 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1150 abort ();
1152 /* Force the frame state to use the known cfa value. */
1153 context->cfa = outer_cfa;
1154 fs.cfa_how = CFA_REG_OFFSET;
1155 fs.cfa_reg = 0;
1156 fs.cfa_offset = 0;
1158 uw_update_context_1 (context, &fs);
1160 /* If the return address column was saved in a register in the
1161 initialization context, then we can't see it in the given
1162 call frame data. So have the initialization context tell us. */
1163 context->ra = __builtin_extract_return_addr (outer_ra);
1167 /* Install TARGET into CURRENT so that we can return to it. This is a
1168 macro because __builtin_eh_return must be invoked in the context of
1169 our caller. */
1171 #define uw_install_context(CURRENT, TARGET) \
1172 do \
1174 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1175 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1176 __builtin_eh_return (offset, handler); \
1178 while (0)
1180 static inline void
1181 init_dwarf_reg_size_table (void)
1183 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1186 static long
1187 uw_install_context_1 (struct _Unwind_Context *current,
1188 struct _Unwind_Context *target)
1190 long i;
1192 #if __GTHREADS
1194 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1195 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1196 || dwarf_reg_size_table[0] == 0)
1197 init_dwarf_reg_size_table ();
1199 #else
1200 if (dwarf_reg_size_table[0] == 0)
1201 init_dwarf_reg_size_table ();
1202 #endif
1204 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1206 void *c = current->reg[i];
1207 void *t = target->reg[i];
1208 if (t && c && t != c)
1209 memcpy (c, t, dwarf_reg_size_table[i]);
1212 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1213 if (STACK_GROWS_DOWNWARD)
1214 return target->cfa - current->cfa + target->args_size;
1215 else
1216 return current->cfa - target->cfa - target->args_size;
1219 static inline _Unwind_Ptr
1220 uw_identify_context (struct _Unwind_Context *context)
1222 return _Unwind_GetIP (context);
1226 #include "unwind.inc"
1228 #endif /* !USING_SJLJ_EXCEPTIONS */