* config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
[official-gcc.git] / gcc / unwind-dw2.c
blobe61664b79e828bf7bd31fcd9af9b3a235465b5b7
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 #ifndef DWARF_REG_TO_UNWIND_COLUMN
54 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
55 #endif
57 /* This is the register and unwind state for a particular frame. This
58 provides the information necessary to unwind up past a frame and return
59 to its caller. */
60 struct _Unwind_Context
62 void *reg[DWARF_FRAME_REGISTERS+1];
63 void *cfa;
64 void *ra;
65 void *lsda;
66 struct dwarf_eh_bases bases;
67 _Unwind_Word args_size;
70 /* Byte size of every register managed by these routines. */
71 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
74 /* The result of interpreting the frame unwind info for a frame.
75 This is all symbolic at this point, as none of the values can
76 be resolved until the target pc is located. */
77 typedef struct
79 /* Each register save state can be described in terms of a CFA slot,
80 another register, or a location expression. */
81 struct frame_state_reg_info
83 struct {
84 union {
85 _Unwind_Word reg;
86 _Unwind_Sword offset;
87 const unsigned char *exp;
88 } loc;
89 enum {
90 REG_UNSAVED,
91 REG_SAVED_OFFSET,
92 REG_SAVED_REG,
93 REG_SAVED_EXP,
94 } how;
95 } reg[DWARF_FRAME_REGISTERS+1];
97 /* Used to implement DW_CFA_remember_state. */
98 struct frame_state_reg_info *prev;
99 } regs;
101 /* The CFA can be described in terms of a reg+offset or a
102 location expression. */
103 _Unwind_Sword cfa_offset;
104 _Unwind_Word cfa_reg;
105 const unsigned char *cfa_exp;
106 enum {
107 CFA_UNSET,
108 CFA_REG_OFFSET,
109 CFA_EXP,
110 } cfa_how;
112 /* The PC described by the current frame state. */
113 void *pc;
115 /* The information we care about from the CIE/FDE. */
116 _Unwind_Personality_Fn personality;
117 _Unwind_Sword data_align;
118 _Unwind_Word code_align;
119 unsigned char retaddr_column;
120 unsigned char fde_encoding;
121 unsigned char lsda_encoding;
122 unsigned char saw_z;
123 void *eh_ptr;
124 } _Unwind_FrameState;
126 /* Read unaligned data from the instruction buffer. */
128 union unaligned
130 void *p;
131 unsigned u2 __attribute__ ((mode (HI)));
132 unsigned u4 __attribute__ ((mode (SI)));
133 unsigned u8 __attribute__ ((mode (DI)));
134 signed s2 __attribute__ ((mode (HI)));
135 signed s4 __attribute__ ((mode (SI)));
136 signed s8 __attribute__ ((mode (DI)));
137 } __attribute__ ((packed));
139 static inline void *
140 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
142 static inline int
143 read_1u (const void *p) { return *(const unsigned char *) p; }
145 static inline int
146 read_1s (const void *p) { return *(const signed char *) p; }
148 static inline int
149 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
151 static inline int
152 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
154 static inline unsigned int
155 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
157 static inline int
158 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
160 static inline unsigned long
161 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
163 static inline unsigned long
164 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
166 /* Get the value of register REG as saved in CONTEXT. */
168 inline _Unwind_Word
169 _Unwind_GetGR (struct _Unwind_Context *context, int index)
171 index = DWARF_REG_TO_UNWIND_COLUMN (index);
172 /* This will segfault if the register hasn't been saved. */
173 return * (_Unwind_Word *) context->reg[index];
176 /* Get the value of the CFA as saved in CONTEXT. */
178 _Unwind_Word
179 _Unwind_GetCFA (struct _Unwind_Context *context)
181 return (_Unwind_Ptr) context->cfa;
184 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
186 inline void
187 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
189 index = DWARF_REG_TO_UNWIND_COLUMN (index);
190 * (_Unwind_Word *) context->reg[index] = val;
193 /* Get the pointer to a register INDEX as saved in CONTEXT. */
195 static inline void *
196 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
198 index = DWARF_REG_TO_UNWIND_COLUMN (index);
199 return context->reg[index];
202 /* Set the pointer to a register INDEX as saved in CONTEXT. */
204 static inline void
205 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
207 index = DWARF_REG_TO_UNWIND_COLUMN (index);
208 context->reg[index] = p;
211 /* Retrieve the return address for CONTEXT. */
213 inline _Unwind_Ptr
214 _Unwind_GetIP (struct _Unwind_Context *context)
216 return (_Unwind_Ptr) context->ra;
219 /* Overwrite the return address for CONTEXT with VAL. */
221 inline void
222 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
224 context->ra = (void *) val;
227 void *
228 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
230 return context->lsda;
233 _Unwind_Ptr
234 _Unwind_GetRegionStart (struct _Unwind_Context *context)
236 return (_Unwind_Ptr) context->bases.func;
239 void *
240 _Unwind_FindEnclosingFunction (void *pc)
242 struct dwarf_eh_bases bases;
243 struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
244 if (fde)
245 return bases.func;
246 else
247 return NULL;
250 #ifndef __ia64__
251 _Unwind_Ptr
252 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
254 return (_Unwind_Ptr) context->bases.dbase;
257 _Unwind_Ptr
258 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
260 return (_Unwind_Ptr) context->bases.tbase;
262 #endif
264 /* Extract any interesting information from the CIE for the translation
265 unit F belongs to. Return a pointer to the byte after the augmentation,
266 or NULL if we encountered an undecipherable augmentation. */
268 static const unsigned char *
269 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
270 _Unwind_FrameState *fs)
272 const unsigned char *aug = cie->augmentation;
273 const unsigned char *p = aug + strlen (aug) + 1;
274 const unsigned char *ret = NULL;
275 _Unwind_Word utmp;
277 /* g++ v2 "eh" has pointer immediately following augmentation string,
278 so it must be handled first. */
279 if (aug[0] == 'e' && aug[1] == 'h')
281 fs->eh_ptr = read_pointer (p);
282 p += sizeof (void *);
283 aug += 2;
286 /* Immediately following the augmentation are the code and
287 data alignment and return address column. */
288 p = read_uleb128 (p, &fs->code_align);
289 p = read_sleb128 (p, &fs->data_align);
290 fs->retaddr_column = *p++;
291 fs->lsda_encoding = DW_EH_PE_omit;
293 /* If the augmentation starts with 'z', then a uleb128 immediately
294 follows containing the length of the augmentation field following
295 the size. */
296 if (*aug == 'z')
298 p = read_uleb128 (p, &utmp);
299 ret = p + utmp;
301 fs->saw_z = 1;
302 ++aug;
305 /* Iterate over recognized augmentation subsequences. */
306 while (*aug != '\0')
308 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
309 if (aug[0] == 'L')
311 fs->lsda_encoding = *p++;
312 aug += 1;
315 /* "R" indicates a byte indicating how FDE addresses are encoded. */
316 else if (aug[0] == 'R')
318 fs->fde_encoding = *p++;
319 aug += 1;
322 /* "P" indicates a personality routine in the CIE augmentation. */
323 else if (aug[0] == 'P')
325 p = read_encoded_value (context, *p, p + 1,
326 (_Unwind_Ptr *) &fs->personality);
327 aug += 1;
330 /* Otherwise we have an unknown augmentation string.
331 Bail unless we saw a 'z' prefix. */
332 else
333 return ret;
336 return ret ? ret : p;
340 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
341 onto the stack to start. */
343 static _Unwind_Word
344 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
345 struct _Unwind_Context *context, _Unwind_Word initial)
347 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
348 int stack_elt;
350 stack[0] = initial;
351 stack_elt = 1;
353 while (op_ptr < op_end)
355 enum dwarf_location_atom op = *op_ptr++;
356 _Unwind_Word result, reg, utmp;
357 _Unwind_Sword offset, stmp;
359 switch (op)
361 case DW_OP_lit0:
362 case DW_OP_lit1:
363 case DW_OP_lit2:
364 case DW_OP_lit3:
365 case DW_OP_lit4:
366 case DW_OP_lit5:
367 case DW_OP_lit6:
368 case DW_OP_lit7:
369 case DW_OP_lit8:
370 case DW_OP_lit9:
371 case DW_OP_lit10:
372 case DW_OP_lit11:
373 case DW_OP_lit12:
374 case DW_OP_lit13:
375 case DW_OP_lit14:
376 case DW_OP_lit15:
377 case DW_OP_lit16:
378 case DW_OP_lit17:
379 case DW_OP_lit18:
380 case DW_OP_lit19:
381 case DW_OP_lit20:
382 case DW_OP_lit21:
383 case DW_OP_lit22:
384 case DW_OP_lit23:
385 case DW_OP_lit24:
386 case DW_OP_lit25:
387 case DW_OP_lit26:
388 case DW_OP_lit27:
389 case DW_OP_lit28:
390 case DW_OP_lit29:
391 case DW_OP_lit30:
392 case DW_OP_lit31:
393 result = op - DW_OP_lit0;
394 break;
396 case DW_OP_addr:
397 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
398 op_ptr += sizeof (void *);
399 break;
401 case DW_OP_const1u:
402 result = read_1u (op_ptr);
403 op_ptr += 1;
404 break;
405 case DW_OP_const1s:
406 result = read_1s (op_ptr);
407 op_ptr += 1;
408 break;
409 case DW_OP_const2u:
410 result = read_2u (op_ptr);
411 op_ptr += 2;
412 break;
413 case DW_OP_const2s:
414 result = read_2s (op_ptr);
415 op_ptr += 2;
416 break;
417 case DW_OP_const4u:
418 result = read_4u (op_ptr);
419 op_ptr += 4;
420 break;
421 case DW_OP_const4s:
422 result = read_4s (op_ptr);
423 op_ptr += 4;
424 break;
425 case DW_OP_const8u:
426 result = read_8u (op_ptr);
427 op_ptr += 8;
428 break;
429 case DW_OP_const8s:
430 result = read_8s (op_ptr);
431 op_ptr += 8;
432 break;
433 case DW_OP_constu:
434 op_ptr = read_uleb128 (op_ptr, &result);
435 break;
436 case DW_OP_consts:
437 op_ptr = read_sleb128 (op_ptr, &stmp);
438 result = stmp;
439 break;
441 case DW_OP_reg0:
442 case DW_OP_reg1:
443 case DW_OP_reg2:
444 case DW_OP_reg3:
445 case DW_OP_reg4:
446 case DW_OP_reg5:
447 case DW_OP_reg6:
448 case DW_OP_reg7:
449 case DW_OP_reg8:
450 case DW_OP_reg9:
451 case DW_OP_reg10:
452 case DW_OP_reg11:
453 case DW_OP_reg12:
454 case DW_OP_reg13:
455 case DW_OP_reg14:
456 case DW_OP_reg15:
457 case DW_OP_reg16:
458 case DW_OP_reg17:
459 case DW_OP_reg18:
460 case DW_OP_reg19:
461 case DW_OP_reg20:
462 case DW_OP_reg21:
463 case DW_OP_reg22:
464 case DW_OP_reg23:
465 case DW_OP_reg24:
466 case DW_OP_reg25:
467 case DW_OP_reg26:
468 case DW_OP_reg27:
469 case DW_OP_reg28:
470 case DW_OP_reg29:
471 case DW_OP_reg30:
472 case DW_OP_reg31:
473 result = _Unwind_GetGR (context, op - DW_OP_reg0);
474 break;
475 case DW_OP_regx:
476 op_ptr = read_uleb128 (op_ptr, &reg);
477 result = _Unwind_GetGR (context, reg);
478 break;
480 case DW_OP_breg0:
481 case DW_OP_breg1:
482 case DW_OP_breg2:
483 case DW_OP_breg3:
484 case DW_OP_breg4:
485 case DW_OP_breg5:
486 case DW_OP_breg6:
487 case DW_OP_breg7:
488 case DW_OP_breg8:
489 case DW_OP_breg9:
490 case DW_OP_breg10:
491 case DW_OP_breg11:
492 case DW_OP_breg12:
493 case DW_OP_breg13:
494 case DW_OP_breg14:
495 case DW_OP_breg15:
496 case DW_OP_breg16:
497 case DW_OP_breg17:
498 case DW_OP_breg18:
499 case DW_OP_breg19:
500 case DW_OP_breg20:
501 case DW_OP_breg21:
502 case DW_OP_breg22:
503 case DW_OP_breg23:
504 case DW_OP_breg24:
505 case DW_OP_breg25:
506 case DW_OP_breg26:
507 case DW_OP_breg27:
508 case DW_OP_breg28:
509 case DW_OP_breg29:
510 case DW_OP_breg30:
511 case DW_OP_breg31:
512 op_ptr = read_sleb128 (op_ptr, &offset);
513 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
514 break;
515 case DW_OP_bregx:
516 op_ptr = read_uleb128 (op_ptr, &reg);
517 op_ptr = read_sleb128 (op_ptr, &offset);
518 result = _Unwind_GetGR (context, reg) + offset;
519 break;
521 case DW_OP_dup:
522 if (stack_elt < 1)
523 abort ();
524 result = stack[stack_elt - 1];
525 break;
527 case DW_OP_drop:
528 if (--stack_elt < 0)
529 abort ();
530 goto no_push;
532 case DW_OP_pick:
533 offset = *op_ptr++;
534 if (offset >= stack_elt - 1)
535 abort ();
536 result = stack[stack_elt - 1 - offset];
537 break;
539 case DW_OP_over:
540 if (stack_elt < 2)
541 abort ();
542 result = stack[stack_elt - 2];
543 break;
545 case DW_OP_rot:
547 _Unwind_Word t1, t2, t3;
549 if (stack_elt < 3)
550 abort ();
551 t1 = stack[stack_elt - 1];
552 t2 = stack[stack_elt - 2];
553 t3 = stack[stack_elt - 3];
554 stack[stack_elt - 1] = t2;
555 stack[stack_elt - 2] = t3;
556 stack[stack_elt - 3] = t1;
557 goto no_push;
560 case DW_OP_deref:
561 case DW_OP_deref_size:
562 case DW_OP_abs:
563 case DW_OP_neg:
564 case DW_OP_not:
565 case DW_OP_plus_uconst:
566 /* Unary operations. */
567 if (--stack_elt < 0)
568 abort ();
569 result = stack[stack_elt];
571 switch (op)
573 case DW_OP_deref:
575 void *ptr = (void *) (_Unwind_Ptr) result;
576 result = (_Unwind_Ptr) read_pointer (ptr);
578 break;
580 case DW_OP_deref_size:
582 void *ptr = (void *) (_Unwind_Ptr) result;
583 switch (*op_ptr++)
585 case 1:
586 result = read_1u (ptr);
587 break;
588 case 2:
589 result = read_2u (ptr);
590 break;
591 case 4:
592 result = read_4u (ptr);
593 break;
594 case 8:
595 result = read_8u (ptr);
596 break;
597 default:
598 abort ();
601 break;
603 case DW_OP_abs:
604 if ((_Unwind_Sword) result < 0)
605 result = -result;
606 break;
607 case DW_OP_neg:
608 result = -result;
609 break;
610 case DW_OP_not:
611 result = ~result;
612 break;
613 case DW_OP_plus_uconst:
614 op_ptr = read_uleb128 (op_ptr, &utmp);
615 result += utmp;
616 break;
618 default:
619 abort ();
621 break;
623 case DW_OP_and:
624 case DW_OP_div:
625 case DW_OP_minus:
626 case DW_OP_mod:
627 case DW_OP_mul:
628 case DW_OP_or:
629 case DW_OP_plus:
630 case DW_OP_le:
631 case DW_OP_ge:
632 case DW_OP_eq:
633 case DW_OP_lt:
634 case DW_OP_gt:
635 case DW_OP_ne:
637 /* Binary operations. */
638 _Unwind_Word first, second;
639 if ((stack_elt -= 2) < 0)
640 abort ();
641 second = stack[stack_elt];
642 first = stack[stack_elt + 1];
644 switch (op)
646 case DW_OP_and:
647 result = second & first;
648 break;
649 case DW_OP_div:
650 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
651 break;
652 case DW_OP_minus:
653 result = second - first;
654 break;
655 case DW_OP_mod:
656 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
657 break;
658 case DW_OP_mul:
659 result = second * first;
660 break;
661 case DW_OP_or:
662 result = second | first;
663 break;
664 case DW_OP_plus:
665 result = second + first;
666 break;
667 case DW_OP_shl:
668 result = second << first;
669 break;
670 case DW_OP_shr:
671 result = second >> first;
672 break;
673 case DW_OP_shra:
674 result = (_Unwind_Sword) second >> first;
675 break;
676 case DW_OP_xor:
677 result = second ^ first;
678 break;
679 case DW_OP_le:
680 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
681 break;
682 case DW_OP_ge:
683 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
684 break;
685 case DW_OP_eq:
686 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
687 break;
688 case DW_OP_lt:
689 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
690 break;
691 case DW_OP_gt:
692 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
693 break;
694 case DW_OP_ne:
695 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
696 break;
698 default:
699 abort ();
702 break;
704 case DW_OP_skip:
705 offset = read_2s (op_ptr);
706 op_ptr += 2;
707 op_ptr += offset;
708 goto no_push;
710 case DW_OP_bra:
711 if (--stack_elt < 0)
712 abort ();
713 offset = read_2s (op_ptr);
714 op_ptr += 2;
715 if (stack[stack_elt] != 0)
716 op_ptr += offset;
717 goto no_push;
719 case DW_OP_nop:
720 goto no_push;
722 default:
723 abort ();
726 /* Most things push a result value. */
727 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
728 abort ();
729 stack[stack_elt++] = result;
730 no_push:;
733 /* We were executing this program to get a value. It should be
734 at top of stack. */
735 if (--stack_elt < 0)
736 abort ();
737 return stack[stack_elt];
741 /* Decode DWARF 2 call frame information. Takes pointers the
742 instruction sequence to decode, current register information and
743 CIE info, and the PC range to evaluate. */
745 static void
746 execute_cfa_program (const unsigned char *insn_ptr,
747 const unsigned char *insn_end,
748 struct _Unwind_Context *context,
749 _Unwind_FrameState *fs)
751 struct frame_state_reg_info *unused_rs = NULL;
753 /* Don't allow remember/restore between CIE and FDE programs. */
754 fs->regs.prev = NULL;
756 /* The comparison with the return address uses < rather than <= because
757 we are only interested in the effects of code before the call; for a
758 noreturn function, the return address may point to unrelated code with
759 a different stack configuration that we are not interested in. We
760 assume that the call itself is unwind info-neutral; if not, or if
761 there are delay instructions that adjust the stack, these must be
762 reflected at the point immediately before the call insn. */
763 while (insn_ptr < insn_end && fs->pc < context->ra)
765 unsigned char insn = *insn_ptr++;
766 _Unwind_Word reg, utmp;
767 _Unwind_Sword offset, stmp;
769 if ((insn & 0xc0) == DW_CFA_advance_loc)
770 fs->pc += (insn & 0x3f) * fs->code_align;
771 else if ((insn & 0xc0) == DW_CFA_offset)
773 reg = insn & 0x3f;
774 insn_ptr = read_uleb128 (insn_ptr, &utmp);
775 offset = (_Unwind_Sword) utmp * fs->data_align;
776 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
777 = REG_SAVED_OFFSET;
778 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
780 else if ((insn & 0xc0) == DW_CFA_restore)
782 reg = insn & 0x3f;
783 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
785 else switch (insn)
787 case DW_CFA_set_loc:
788 insn_ptr = read_encoded_value (context, fs->fde_encoding,
789 insn_ptr, (_Unwind_Ptr *) &fs->pc);
790 break;
792 case DW_CFA_advance_loc1:
793 fs->pc += read_1u (insn_ptr) * fs->code_align;
794 insn_ptr += 1;
795 break;
796 case DW_CFA_advance_loc2:
797 fs->pc += read_2u (insn_ptr) * fs->code_align;
798 insn_ptr += 2;
799 break;
800 case DW_CFA_advance_loc4:
801 fs->pc += read_4u (insn_ptr) * fs->code_align;
802 insn_ptr += 4;
803 break;
805 case DW_CFA_offset_extended:
806 insn_ptr = read_uleb128 (insn_ptr, &reg);
807 insn_ptr = read_uleb128 (insn_ptr, &utmp);
808 offset = (_Unwind_Sword) utmp * fs->data_align;
809 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
810 = REG_SAVED_OFFSET;
811 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
812 break;
814 case DW_CFA_restore_extended:
815 insn_ptr = read_uleb128 (insn_ptr, &reg);
816 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
817 break;
819 case DW_CFA_undefined:
820 case DW_CFA_same_value:
821 insn_ptr = read_uleb128 (insn_ptr, &reg);
822 break;
824 case DW_CFA_nop:
825 break;
827 case DW_CFA_register:
829 _Unwind_Word reg2;
830 insn_ptr = read_uleb128 (insn_ptr, &reg);
831 insn_ptr = read_uleb128 (insn_ptr, &reg2);
832 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
833 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
835 break;
837 case DW_CFA_remember_state:
839 struct frame_state_reg_info *new_rs;
840 if (unused_rs)
842 new_rs = unused_rs;
843 unused_rs = unused_rs->prev;
845 else
846 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
848 *new_rs = fs->regs;
849 fs->regs.prev = new_rs;
851 break;
853 case DW_CFA_restore_state:
855 struct frame_state_reg_info *old_rs = fs->regs.prev;
856 fs->regs = *old_rs;
857 old_rs->prev = unused_rs;
858 unused_rs = old_rs;
860 break;
862 case DW_CFA_def_cfa:
863 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
864 insn_ptr = read_uleb128 (insn_ptr, &utmp);
865 fs->cfa_offset = utmp;
866 fs->cfa_how = CFA_REG_OFFSET;
867 break;
869 case DW_CFA_def_cfa_register:
870 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
871 fs->cfa_how = CFA_REG_OFFSET;
872 break;
874 case DW_CFA_def_cfa_offset:
875 insn_ptr = read_uleb128 (insn_ptr, &utmp);
876 fs->cfa_offset = utmp;
877 /* cfa_how deliberately not set. */
878 break;
880 case DW_CFA_def_cfa_expression:
881 fs->cfa_exp = insn_ptr;
882 fs->cfa_how = CFA_EXP;
883 insn_ptr = read_uleb128 (insn_ptr, &utmp);
884 insn_ptr += utmp;
885 break;
887 case DW_CFA_expression:
888 insn_ptr = read_uleb128 (insn_ptr, &reg);
889 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
890 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
891 insn_ptr = read_uleb128 (insn_ptr, &utmp);
892 insn_ptr += utmp;
893 break;
895 /* From the 2.1 draft. */
896 case DW_CFA_offset_extended_sf:
897 insn_ptr = read_uleb128 (insn_ptr, &reg);
898 insn_ptr = read_sleb128 (insn_ptr, &stmp);
899 offset = stmp * fs->data_align;
900 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
901 = REG_SAVED_OFFSET;
902 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
903 break;
905 case DW_CFA_def_cfa_sf:
906 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
907 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
908 fs->cfa_how = CFA_REG_OFFSET;
909 break;
911 case DW_CFA_def_cfa_offset_sf:
912 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
913 /* cfa_how deliberately not set. */
914 break;
916 case DW_CFA_GNU_window_save:
917 /* ??? Hardcoded for SPARC register window configuration. */
918 for (reg = 16; reg < 32; ++reg)
920 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
921 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
923 break;
925 case DW_CFA_GNU_args_size:
926 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
927 break;
929 case DW_CFA_GNU_negative_offset_extended:
930 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
931 older PowerPC code. */
932 insn_ptr = read_uleb128 (insn_ptr, &reg);
933 insn_ptr = read_uleb128 (insn_ptr, &utmp);
934 offset = (_Unwind_Word) utmp * fs->data_align;
935 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
936 = REG_SAVED_OFFSET;
937 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
938 break;
940 default:
941 abort ();
946 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
947 its caller and decode it into FS. This function also sets the
948 args_size and lsda members of CONTEXT, as they are really information
949 about the caller's frame. */
951 static _Unwind_Reason_Code
952 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
954 struct dwarf_fde *fde;
955 struct dwarf_cie *cie;
956 const unsigned char *aug, *insn, *end;
958 memset (fs, 0, sizeof (*fs));
959 context->args_size = 0;
960 context->lsda = 0;
962 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
963 if (fde == NULL)
965 /* Couldn't find frame unwind info for this function. Try a
966 target-specific fallback mechanism. This will necessarily
967 not provide a personality routine or LSDA. */
968 #ifdef MD_FALLBACK_FRAME_STATE_FOR
969 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
970 return _URC_END_OF_STACK;
971 success:
972 return _URC_NO_REASON;
973 #else
974 return _URC_END_OF_STACK;
975 #endif
978 fs->pc = context->bases.func;
980 cie = get_cie (fde);
981 insn = extract_cie_info (cie, context, fs);
982 if (insn == NULL)
983 /* CIE contained unknown augmentation. */
984 return _URC_FATAL_PHASE1_ERROR;
986 /* First decode all the insns in the CIE. */
987 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
988 execute_cfa_program (insn, end, context, fs);
990 /* Locate augmentation for the fde. */
991 aug = (unsigned char *) fde + sizeof (*fde);
992 aug += 2 * size_of_encoded_value (fs->fde_encoding);
993 insn = NULL;
994 if (fs->saw_z)
996 _Unwind_Word i;
997 aug = read_uleb128 (aug, &i);
998 insn = aug + i;
1000 if (fs->lsda_encoding != DW_EH_PE_omit)
1001 aug = read_encoded_value (context, fs->lsda_encoding, aug,
1002 (_Unwind_Ptr *) &context->lsda);
1004 /* Then the insns in the FDE up to our target PC. */
1005 if (insn == NULL)
1006 insn = aug;
1007 end = (unsigned char *) next_fde (fde);
1008 execute_cfa_program (insn, end, context, fs);
1010 return _URC_NO_REASON;
1013 typedef struct frame_state
1015 void *cfa;
1016 void *eh_ptr;
1017 long cfa_offset;
1018 long args_size;
1019 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1020 unsigned short cfa_reg;
1021 unsigned short retaddr_column;
1022 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1023 } frame_state;
1025 struct frame_state * __frame_state_for (void *, struct frame_state *);
1027 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1028 a given PC_TARGET. The caller should allocate a local variable of
1029 `struct frame_state' and pass its address to STATE_IN. */
1031 struct frame_state *
1032 __frame_state_for (void *pc_target, struct frame_state *state_in)
1034 struct _Unwind_Context context;
1035 _Unwind_FrameState fs;
1036 int reg;
1038 memset (&context, 0, sizeof (struct _Unwind_Context));
1039 context.ra = pc_target + 1;
1041 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1042 return 0;
1044 /* We have no way to pass a location expression for the CFA to our
1045 caller. It wouldn't understand it anyway. */
1046 if (fs.cfa_how == CFA_EXP)
1047 return 0;
1049 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1051 state_in->saved[reg] = fs.regs.reg[reg].how;
1052 switch (state_in->saved[reg])
1054 case REG_SAVED_REG:
1055 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1056 break;
1057 case REG_SAVED_OFFSET:
1058 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1059 break;
1060 default:
1061 state_in->reg_or_offset[reg] = 0;
1062 break;
1066 state_in->cfa_offset = fs.cfa_offset;
1067 state_in->cfa_reg = fs.cfa_reg;
1068 state_in->retaddr_column = fs.retaddr_column;
1069 state_in->args_size = context.args_size;
1070 state_in->eh_ptr = fs.eh_ptr;
1072 return state_in;
1075 static void
1076 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1078 struct _Unwind_Context orig_context = *context;
1079 void *cfa;
1080 long i;
1082 #ifdef EH_RETURN_STACKADJ_RTX
1083 /* Special handling here: Many machines do not use a frame pointer,
1084 and track the CFA only through offsets from the stack pointer from
1085 one frame to the next. In this case, the stack pointer is never
1086 stored, so it has no saved address in the context. What we do
1087 have is the CFA from the previous stack frame.
1089 In very special situations (such as unwind info for signal return),
1090 there may be location expressions that use the stack pointer as well.
1092 Do this conditionally for one frame. This allows the unwind info
1093 for one frame to save a copy of the stack pointer from the previous
1094 frame, and be able to use much easier CFA mechanisms to do it.
1095 Always zap the saved stack pointer value for the next frame; carrying
1096 the value over from one frame to another doesn't make sense. */
1098 _Unwind_Word tmp_sp;
1100 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1102 tmp_sp = (_Unwind_Ptr) context->cfa;
1103 _Unwind_SetGRPtr (&orig_context, __builtin_dwarf_sp_column (), &tmp_sp);
1105 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1106 #endif
1108 /* Compute this frame's CFA. */
1109 switch (fs->cfa_how)
1111 case CFA_REG_OFFSET:
1112 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
1113 cfa += fs->cfa_offset;
1114 break;
1116 case CFA_EXP:
1118 const unsigned char *exp = fs->cfa_exp;
1119 _Unwind_Word len;
1121 exp = read_uleb128 (exp, &len);
1122 cfa = (void *) (_Unwind_Ptr)
1123 execute_stack_op (exp, exp + len, &orig_context, 0);
1124 break;
1127 default:
1128 abort ();
1130 context->cfa = cfa;
1132 /* Compute the addresses of all registers saved in this frame. */
1133 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1134 switch (fs->regs.reg[i].how)
1136 case REG_UNSAVED:
1137 break;
1139 case REG_SAVED_OFFSET:
1140 _Unwind_SetGRPtr (context, i,
1141 (void *) (cfa + fs->regs.reg[i].loc.offset));
1142 break;
1144 case REG_SAVED_REG:
1145 _Unwind_SetGRPtr
1146 (context, i,
1147 _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
1148 break;
1150 case REG_SAVED_EXP:
1152 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1153 _Unwind_Word len;
1154 _Unwind_Ptr val;
1156 exp = read_uleb128 (exp, &len);
1157 val = execute_stack_op (exp, exp + len, &orig_context,
1158 (_Unwind_Ptr) cfa);
1159 _Unwind_SetGRPtr (context, i, (void *) val);
1161 break;
1165 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1166 of its caller. Update CONTEXT to refer to the caller as well. Note
1167 that the args_size and lsda members are not updated here, but later in
1168 uw_frame_state_for. */
1170 static void
1171 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1173 uw_update_context_1 (context, fs);
1175 /* Compute the return address now, since the return address column
1176 can change from frame to frame. */
1177 context->ra = __builtin_extract_return_addr
1178 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1181 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1182 level will be the return address and the CFA. */
1184 #define uw_init_context(CONTEXT) \
1185 do \
1187 /* Do any necessary initialization to access arbitrary stack frames. \
1188 On the SPARC, this means flushing the register windows. */ \
1189 __builtin_unwind_init (); \
1190 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1191 __builtin_return_address (0)); \
1193 while (0)
1195 static void
1196 uw_init_context_1 (struct _Unwind_Context *context,
1197 void *outer_cfa, void *outer_ra)
1199 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1200 _Unwind_FrameState fs;
1201 _Unwind_Word sp_slot;
1203 memset (context, 0, sizeof (struct _Unwind_Context));
1204 context->ra = ra;
1206 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1207 abort ();
1209 /* Force the frame state to use the known cfa value. */
1210 sp_slot = (_Unwind_Ptr) outer_cfa;
1211 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), &sp_slot);
1212 fs.cfa_how = CFA_REG_OFFSET;
1213 fs.cfa_reg = __builtin_dwarf_sp_column ();
1214 fs.cfa_offset = 0;
1216 uw_update_context_1 (context, &fs);
1218 /* If the return address column was saved in a register in the
1219 initialization context, then we can't see it in the given
1220 call frame data. So have the initialization context tell us. */
1221 context->ra = __builtin_extract_return_addr (outer_ra);
1225 /* Install TARGET into CURRENT so that we can return to it. This is a
1226 macro because __builtin_eh_return must be invoked in the context of
1227 our caller. */
1229 #define uw_install_context(CURRENT, TARGET) \
1230 do \
1232 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1233 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1234 __builtin_eh_return (offset, handler); \
1236 while (0)
1238 static inline void
1239 init_dwarf_reg_size_table (void)
1241 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1244 static long
1245 uw_install_context_1 (struct _Unwind_Context *current,
1246 struct _Unwind_Context *target)
1248 long i;
1250 #if __GTHREADS
1252 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1253 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1254 || dwarf_reg_size_table[0] == 0)
1255 init_dwarf_reg_size_table ();
1257 #else
1258 if (dwarf_reg_size_table[0] == 0)
1259 init_dwarf_reg_size_table ();
1260 #endif
1262 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1264 void *c = current->reg[i];
1265 void *t = target->reg[i];
1267 if (t && c && t != c)
1268 memcpy (c, t, dwarf_reg_size_table[i]);
1271 #ifdef EH_RETURN_STACKADJ_RTX
1273 void *target_cfa;
1275 /* If the last frame records a saved stack pointer, use it. */
1276 if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1277 target_cfa = (void *)(_Unwind_Ptr)
1278 _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
1279 else
1280 target_cfa = target->cfa;
1282 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1283 if (STACK_GROWS_DOWNWARD)
1284 return target_cfa - current->cfa + target->args_size;
1285 else
1286 return current->cfa - target_cfa - target->args_size;
1288 #else
1289 return 0;
1290 #endif
1293 static inline _Unwind_Ptr
1294 uw_identify_context (struct _Unwind_Context *context)
1296 return _Unwind_GetIP (context);
1300 #include "unwind.inc"
1302 #endif /* !USING_SJLJ_EXCEPTIONS */