* config/mn10300/mn10300-protos.h (mn10300_va_arg): Remove.
[official-gcc.git] / gcc / unwind-dw2.c
blob11b94b123d0f72d4b20d5708e5c1e817c6cb4b70
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"
43 #include "unwind-dw2.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 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
55 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
56 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
57 #endif
59 #ifndef DWARF_REG_TO_UNWIND_COLUMN
60 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
61 #endif
63 /* A target can do some update context frobbing. */
64 #ifndef MD_FROB_UPDATE_CONTEXT
65 #define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
66 #endif
68 /* This is the register and unwind state for a particular frame. This
69 provides the information necessary to unwind up past a frame and return
70 to its caller. */
71 struct _Unwind_Context
73 void *reg[DWARF_FRAME_REGISTERS+1];
74 void *cfa;
75 void *ra;
76 void *lsda;
77 struct dwarf_eh_bases bases;
78 _Unwind_Word args_size;
81 /* Byte size of every register managed by these routines. */
82 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
85 /* Read unaligned data from the instruction buffer. */
87 union unaligned
89 void *p;
90 unsigned u2 __attribute__ ((mode (HI)));
91 unsigned u4 __attribute__ ((mode (SI)));
92 unsigned u8 __attribute__ ((mode (DI)));
93 signed s2 __attribute__ ((mode (HI)));
94 signed s4 __attribute__ ((mode (SI)));
95 signed s8 __attribute__ ((mode (DI)));
96 } __attribute__ ((packed));
98 static inline void *
99 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
101 static inline int
102 read_1u (const void *p) { return *(const unsigned char *) p; }
104 static inline int
105 read_1s (const void *p) { return *(const signed char *) p; }
107 static inline int
108 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
110 static inline int
111 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
113 static inline unsigned int
114 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
116 static inline int
117 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
119 static inline unsigned long
120 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
122 static inline unsigned long
123 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
125 /* Get the value of register REG as saved in CONTEXT. */
127 inline _Unwind_Word
128 _Unwind_GetGR (struct _Unwind_Context *context, int index)
130 int size;
131 void *ptr;
133 index = DWARF_REG_TO_UNWIND_COLUMN (index);
134 if (index >= (int) sizeof(dwarf_reg_size_table))
135 abort ();
136 size = dwarf_reg_size_table[index];
137 ptr = context->reg[index];
139 /* This will segfault if the register hasn't been saved. */
140 if (size == sizeof(_Unwind_Ptr))
141 return * (_Unwind_Ptr *) ptr;
143 if (size == sizeof(_Unwind_Word))
144 return * (_Unwind_Word *) ptr;
146 abort ();
149 static inline void *
150 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
152 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
155 /* Get the value of the CFA as saved in CONTEXT. */
157 _Unwind_Word
158 _Unwind_GetCFA (struct _Unwind_Context *context)
160 return (_Unwind_Ptr) context->cfa;
163 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
165 inline void
166 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
168 int size;
169 void *ptr;
171 index = DWARF_REG_TO_UNWIND_COLUMN (index);
172 if (index >= (int) sizeof(dwarf_reg_size_table))
173 abort ();
174 size = dwarf_reg_size_table[index];
175 ptr = context->reg[index];
177 if (size == sizeof(_Unwind_Ptr))
178 * (_Unwind_Ptr *) ptr = val;
179 else if (size == sizeof(_Unwind_Word))
180 * (_Unwind_Word *) ptr = val;
181 else
182 abort ();
185 /* Get the pointer to a register INDEX as saved in CONTEXT. */
187 static inline void *
188 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
190 index = DWARF_REG_TO_UNWIND_COLUMN (index);
191 return context->reg[index];
194 /* Set the pointer to a register INDEX as saved in CONTEXT. */
196 static inline void
197 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
199 index = DWARF_REG_TO_UNWIND_COLUMN (index);
200 context->reg[index] = p;
203 /* Retrieve the return address for CONTEXT. */
205 inline _Unwind_Ptr
206 _Unwind_GetIP (struct _Unwind_Context *context)
208 return (_Unwind_Ptr) context->ra;
211 /* Overwrite the return address for CONTEXT with VAL. */
213 inline void
214 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
216 context->ra = (void *) val;
219 void *
220 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
222 return context->lsda;
225 _Unwind_Ptr
226 _Unwind_GetRegionStart (struct _Unwind_Context *context)
228 return (_Unwind_Ptr) context->bases.func;
231 void *
232 _Unwind_FindEnclosingFunction (void *pc)
234 struct dwarf_eh_bases bases;
235 const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
236 if (fde)
237 return bases.func;
238 else
239 return NULL;
242 #ifndef __ia64__
243 _Unwind_Ptr
244 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
246 return (_Unwind_Ptr) context->bases.dbase;
249 _Unwind_Ptr
250 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
252 return (_Unwind_Ptr) context->bases.tbase;
254 #endif
256 /* Extract any interesting information from the CIE for the translation
257 unit F belongs to. Return a pointer to the byte after the augmentation,
258 or NULL if we encountered an undecipherable augmentation. */
260 static const unsigned char *
261 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
262 _Unwind_FrameState *fs)
264 const unsigned char *aug = cie->augmentation;
265 const unsigned char *p = aug + strlen (aug) + 1;
266 const unsigned char *ret = NULL;
267 _Unwind_Word utmp;
269 /* g++ v2 "eh" has pointer immediately following augmentation string,
270 so it must be handled first. */
271 if (aug[0] == 'e' && aug[1] == 'h')
273 fs->eh_ptr = read_pointer (p);
274 p += sizeof (void *);
275 aug += 2;
278 /* Immediately following the augmentation are the code and
279 data alignment and return address column. */
280 p = read_uleb128 (p, &fs->code_align);
281 p = read_sleb128 (p, &fs->data_align);
282 if (cie->version == 1)
283 fs->retaddr_column = *p++;
284 else
285 p = read_uleb128 (p, &fs->retaddr_column);
286 fs->lsda_encoding = DW_EH_PE_omit;
288 /* If the augmentation starts with 'z', then a uleb128 immediately
289 follows containing the length of the augmentation field following
290 the size. */
291 if (*aug == 'z')
293 p = read_uleb128 (p, &utmp);
294 ret = p + utmp;
296 fs->saw_z = 1;
297 ++aug;
300 /* Iterate over recognized augmentation subsequences. */
301 while (*aug != '\0')
303 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
304 if (aug[0] == 'L')
306 fs->lsda_encoding = *p++;
307 aug += 1;
310 /* "R" indicates a byte indicating how FDE addresses are encoded. */
311 else if (aug[0] == 'R')
313 fs->fde_encoding = *p++;
314 aug += 1;
317 /* "P" indicates a personality routine in the CIE augmentation. */
318 else if (aug[0] == 'P')
320 p = read_encoded_value (context, *p, p + 1,
321 (_Unwind_Ptr *) &fs->personality);
322 aug += 1;
325 /* Otherwise we have an unknown augmentation string.
326 Bail unless we saw a 'z' prefix. */
327 else
328 return ret;
331 return ret ? ret : p;
335 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
336 onto the stack to start. */
338 static _Unwind_Word
339 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
340 struct _Unwind_Context *context, _Unwind_Word initial)
342 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
343 int stack_elt;
345 stack[0] = initial;
346 stack_elt = 1;
348 while (op_ptr < op_end)
350 enum dwarf_location_atom op = *op_ptr++;
351 _Unwind_Word result, reg, utmp;
352 _Unwind_Sword offset, stmp;
354 switch (op)
356 case DW_OP_lit0:
357 case DW_OP_lit1:
358 case DW_OP_lit2:
359 case DW_OP_lit3:
360 case DW_OP_lit4:
361 case DW_OP_lit5:
362 case DW_OP_lit6:
363 case DW_OP_lit7:
364 case DW_OP_lit8:
365 case DW_OP_lit9:
366 case DW_OP_lit10:
367 case DW_OP_lit11:
368 case DW_OP_lit12:
369 case DW_OP_lit13:
370 case DW_OP_lit14:
371 case DW_OP_lit15:
372 case DW_OP_lit16:
373 case DW_OP_lit17:
374 case DW_OP_lit18:
375 case DW_OP_lit19:
376 case DW_OP_lit20:
377 case DW_OP_lit21:
378 case DW_OP_lit22:
379 case DW_OP_lit23:
380 case DW_OP_lit24:
381 case DW_OP_lit25:
382 case DW_OP_lit26:
383 case DW_OP_lit27:
384 case DW_OP_lit28:
385 case DW_OP_lit29:
386 case DW_OP_lit30:
387 case DW_OP_lit31:
388 result = op - DW_OP_lit0;
389 break;
391 case DW_OP_addr:
392 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
393 op_ptr += sizeof (void *);
394 break;
396 case DW_OP_const1u:
397 result = read_1u (op_ptr);
398 op_ptr += 1;
399 break;
400 case DW_OP_const1s:
401 result = read_1s (op_ptr);
402 op_ptr += 1;
403 break;
404 case DW_OP_const2u:
405 result = read_2u (op_ptr);
406 op_ptr += 2;
407 break;
408 case DW_OP_const2s:
409 result = read_2s (op_ptr);
410 op_ptr += 2;
411 break;
412 case DW_OP_const4u:
413 result = read_4u (op_ptr);
414 op_ptr += 4;
415 break;
416 case DW_OP_const4s:
417 result = read_4s (op_ptr);
418 op_ptr += 4;
419 break;
420 case DW_OP_const8u:
421 result = read_8u (op_ptr);
422 op_ptr += 8;
423 break;
424 case DW_OP_const8s:
425 result = read_8s (op_ptr);
426 op_ptr += 8;
427 break;
428 case DW_OP_constu:
429 op_ptr = read_uleb128 (op_ptr, &result);
430 break;
431 case DW_OP_consts:
432 op_ptr = read_sleb128 (op_ptr, &stmp);
433 result = stmp;
434 break;
436 case DW_OP_reg0:
437 case DW_OP_reg1:
438 case DW_OP_reg2:
439 case DW_OP_reg3:
440 case DW_OP_reg4:
441 case DW_OP_reg5:
442 case DW_OP_reg6:
443 case DW_OP_reg7:
444 case DW_OP_reg8:
445 case DW_OP_reg9:
446 case DW_OP_reg10:
447 case DW_OP_reg11:
448 case DW_OP_reg12:
449 case DW_OP_reg13:
450 case DW_OP_reg14:
451 case DW_OP_reg15:
452 case DW_OP_reg16:
453 case DW_OP_reg17:
454 case DW_OP_reg18:
455 case DW_OP_reg19:
456 case DW_OP_reg20:
457 case DW_OP_reg21:
458 case DW_OP_reg22:
459 case DW_OP_reg23:
460 case DW_OP_reg24:
461 case DW_OP_reg25:
462 case DW_OP_reg26:
463 case DW_OP_reg27:
464 case DW_OP_reg28:
465 case DW_OP_reg29:
466 case DW_OP_reg30:
467 case DW_OP_reg31:
468 result = _Unwind_GetGR (context, op - DW_OP_reg0);
469 break;
470 case DW_OP_regx:
471 op_ptr = read_uleb128 (op_ptr, &reg);
472 result = _Unwind_GetGR (context, reg);
473 break;
475 case DW_OP_breg0:
476 case DW_OP_breg1:
477 case DW_OP_breg2:
478 case DW_OP_breg3:
479 case DW_OP_breg4:
480 case DW_OP_breg5:
481 case DW_OP_breg6:
482 case DW_OP_breg7:
483 case DW_OP_breg8:
484 case DW_OP_breg9:
485 case DW_OP_breg10:
486 case DW_OP_breg11:
487 case DW_OP_breg12:
488 case DW_OP_breg13:
489 case DW_OP_breg14:
490 case DW_OP_breg15:
491 case DW_OP_breg16:
492 case DW_OP_breg17:
493 case DW_OP_breg18:
494 case DW_OP_breg19:
495 case DW_OP_breg20:
496 case DW_OP_breg21:
497 case DW_OP_breg22:
498 case DW_OP_breg23:
499 case DW_OP_breg24:
500 case DW_OP_breg25:
501 case DW_OP_breg26:
502 case DW_OP_breg27:
503 case DW_OP_breg28:
504 case DW_OP_breg29:
505 case DW_OP_breg30:
506 case DW_OP_breg31:
507 op_ptr = read_sleb128 (op_ptr, &offset);
508 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
509 break;
510 case DW_OP_bregx:
511 op_ptr = read_uleb128 (op_ptr, &reg);
512 op_ptr = read_sleb128 (op_ptr, &offset);
513 result = _Unwind_GetGR (context, reg) + offset;
514 break;
516 case DW_OP_dup:
517 if (stack_elt < 1)
518 abort ();
519 result = stack[stack_elt - 1];
520 break;
522 case DW_OP_drop:
523 if (--stack_elt < 0)
524 abort ();
525 goto no_push;
527 case DW_OP_pick:
528 offset = *op_ptr++;
529 if (offset >= stack_elt - 1)
530 abort ();
531 result = stack[stack_elt - 1 - offset];
532 break;
534 case DW_OP_over:
535 if (stack_elt < 2)
536 abort ();
537 result = stack[stack_elt - 2];
538 break;
540 case DW_OP_rot:
542 _Unwind_Word t1, t2, t3;
544 if (stack_elt < 3)
545 abort ();
546 t1 = stack[stack_elt - 1];
547 t2 = stack[stack_elt - 2];
548 t3 = stack[stack_elt - 3];
549 stack[stack_elt - 1] = t2;
550 stack[stack_elt - 2] = t3;
551 stack[stack_elt - 3] = t1;
552 goto no_push;
555 case DW_OP_deref:
556 case DW_OP_deref_size:
557 case DW_OP_abs:
558 case DW_OP_neg:
559 case DW_OP_not:
560 case DW_OP_plus_uconst:
561 /* Unary operations. */
562 if (--stack_elt < 0)
563 abort ();
564 result = stack[stack_elt];
566 switch (op)
568 case DW_OP_deref:
570 void *ptr = (void *) (_Unwind_Ptr) result;
571 result = (_Unwind_Ptr) read_pointer (ptr);
573 break;
575 case DW_OP_deref_size:
577 void *ptr = (void *) (_Unwind_Ptr) result;
578 switch (*op_ptr++)
580 case 1:
581 result = read_1u (ptr);
582 break;
583 case 2:
584 result = read_2u (ptr);
585 break;
586 case 4:
587 result = read_4u (ptr);
588 break;
589 case 8:
590 result = read_8u (ptr);
591 break;
592 default:
593 abort ();
596 break;
598 case DW_OP_abs:
599 if ((_Unwind_Sword) result < 0)
600 result = -result;
601 break;
602 case DW_OP_neg:
603 result = -result;
604 break;
605 case DW_OP_not:
606 result = ~result;
607 break;
608 case DW_OP_plus_uconst:
609 op_ptr = read_uleb128 (op_ptr, &utmp);
610 result += utmp;
611 break;
613 default:
614 abort ();
616 break;
618 case DW_OP_and:
619 case DW_OP_div:
620 case DW_OP_minus:
621 case DW_OP_mod:
622 case DW_OP_mul:
623 case DW_OP_or:
624 case DW_OP_plus:
625 case DW_OP_le:
626 case DW_OP_ge:
627 case DW_OP_eq:
628 case DW_OP_lt:
629 case DW_OP_gt:
630 case DW_OP_ne:
632 /* Binary operations. */
633 _Unwind_Word first, second;
634 if ((stack_elt -= 2) < 0)
635 abort ();
636 second = stack[stack_elt];
637 first = stack[stack_elt + 1];
639 switch (op)
641 case DW_OP_and:
642 result = second & first;
643 break;
644 case DW_OP_div:
645 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
646 break;
647 case DW_OP_minus:
648 result = second - first;
649 break;
650 case DW_OP_mod:
651 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
652 break;
653 case DW_OP_mul:
654 result = second * first;
655 break;
656 case DW_OP_or:
657 result = second | first;
658 break;
659 case DW_OP_plus:
660 result = second + first;
661 break;
662 case DW_OP_shl:
663 result = second << first;
664 break;
665 case DW_OP_shr:
666 result = second >> first;
667 break;
668 case DW_OP_shra:
669 result = (_Unwind_Sword) second >> first;
670 break;
671 case DW_OP_xor:
672 result = second ^ first;
673 break;
674 case DW_OP_le:
675 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
676 break;
677 case DW_OP_ge:
678 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
679 break;
680 case DW_OP_eq:
681 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
682 break;
683 case DW_OP_lt:
684 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
685 break;
686 case DW_OP_gt:
687 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
688 break;
689 case DW_OP_ne:
690 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
691 break;
693 default:
694 abort ();
697 break;
699 case DW_OP_skip:
700 offset = read_2s (op_ptr);
701 op_ptr += 2;
702 op_ptr += offset;
703 goto no_push;
705 case DW_OP_bra:
706 if (--stack_elt < 0)
707 abort ();
708 offset = read_2s (op_ptr);
709 op_ptr += 2;
710 if (stack[stack_elt] != 0)
711 op_ptr += offset;
712 goto no_push;
714 case DW_OP_nop:
715 goto no_push;
717 default:
718 abort ();
721 /* Most things push a result value. */
722 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
723 abort ();
724 stack[stack_elt++] = result;
725 no_push:;
728 /* We were executing this program to get a value. It should be
729 at top of stack. */
730 if (--stack_elt < 0)
731 abort ();
732 return stack[stack_elt];
736 /* Decode DWARF 2 call frame information. Takes pointers the
737 instruction sequence to decode, current register information and
738 CIE info, and the PC range to evaluate. */
740 static void
741 execute_cfa_program (const unsigned char *insn_ptr,
742 const unsigned char *insn_end,
743 struct _Unwind_Context *context,
744 _Unwind_FrameState *fs)
746 struct frame_state_reg_info *unused_rs = NULL;
748 /* Don't allow remember/restore between CIE and FDE programs. */
749 fs->regs.prev = NULL;
751 /* The comparison with the return address uses < rather than <= because
752 we are only interested in the effects of code before the call; for a
753 noreturn function, the return address may point to unrelated code with
754 a different stack configuration that we are not interested in. We
755 assume that the call itself is unwind info-neutral; if not, or if
756 there are delay instructions that adjust the stack, these must be
757 reflected at the point immediately before the call insn. */
758 while (insn_ptr < insn_end && fs->pc < context->ra)
760 unsigned char insn = *insn_ptr++;
761 _Unwind_Word reg, utmp;
762 _Unwind_Sword offset, stmp;
764 if ((insn & 0xc0) == DW_CFA_advance_loc)
765 fs->pc += (insn & 0x3f) * fs->code_align;
766 else if ((insn & 0xc0) == DW_CFA_offset)
768 reg = insn & 0x3f;
769 insn_ptr = read_uleb128 (insn_ptr, &utmp);
770 offset = (_Unwind_Sword) utmp * fs->data_align;
771 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
772 = REG_SAVED_OFFSET;
773 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
775 else if ((insn & 0xc0) == DW_CFA_restore)
777 reg = insn & 0x3f;
778 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
780 else switch (insn)
782 case DW_CFA_set_loc:
783 insn_ptr = read_encoded_value (context, fs->fde_encoding,
784 insn_ptr, (_Unwind_Ptr *) &fs->pc);
785 break;
787 case DW_CFA_advance_loc1:
788 fs->pc += read_1u (insn_ptr) * fs->code_align;
789 insn_ptr += 1;
790 break;
791 case DW_CFA_advance_loc2:
792 fs->pc += read_2u (insn_ptr) * fs->code_align;
793 insn_ptr += 2;
794 break;
795 case DW_CFA_advance_loc4:
796 fs->pc += read_4u (insn_ptr) * fs->code_align;
797 insn_ptr += 4;
798 break;
800 case DW_CFA_offset_extended:
801 insn_ptr = read_uleb128 (insn_ptr, &reg);
802 insn_ptr = read_uleb128 (insn_ptr, &utmp);
803 offset = (_Unwind_Sword) utmp * fs->data_align;
804 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
805 = REG_SAVED_OFFSET;
806 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
807 break;
809 case DW_CFA_restore_extended:
810 insn_ptr = read_uleb128 (insn_ptr, &reg);
811 /* FIXME, this is wrong; the CIE might have said that the
812 register was saved somewhere. */
813 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
814 break;
816 case DW_CFA_undefined:
817 case DW_CFA_same_value:
818 insn_ptr = read_uleb128 (insn_ptr, &reg);
819 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
820 break;
822 case DW_CFA_nop:
823 break;
825 case DW_CFA_register:
827 _Unwind_Word reg2;
828 insn_ptr = read_uleb128 (insn_ptr, &reg);
829 insn_ptr = read_uleb128 (insn_ptr, &reg2);
830 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
831 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
833 break;
835 case DW_CFA_remember_state:
837 struct frame_state_reg_info *new_rs;
838 if (unused_rs)
840 new_rs = unused_rs;
841 unused_rs = unused_rs->prev;
843 else
844 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
846 *new_rs = fs->regs;
847 fs->regs.prev = new_rs;
849 break;
851 case DW_CFA_restore_state:
853 struct frame_state_reg_info *old_rs = fs->regs.prev;
854 fs->regs = *old_rs;
855 old_rs->prev = unused_rs;
856 unused_rs = old_rs;
858 break;
860 case DW_CFA_def_cfa:
861 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
862 insn_ptr = read_uleb128 (insn_ptr, &utmp);
863 fs->cfa_offset = utmp;
864 fs->cfa_how = CFA_REG_OFFSET;
865 break;
867 case DW_CFA_def_cfa_register:
868 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
869 fs->cfa_how = CFA_REG_OFFSET;
870 break;
872 case DW_CFA_def_cfa_offset:
873 insn_ptr = read_uleb128 (insn_ptr, &utmp);
874 fs->cfa_offset = utmp;
875 /* cfa_how deliberately not set. */
876 break;
878 case DW_CFA_def_cfa_expression:
879 fs->cfa_exp = insn_ptr;
880 fs->cfa_how = CFA_EXP;
881 insn_ptr = read_uleb128 (insn_ptr, &utmp);
882 insn_ptr += utmp;
883 break;
885 case DW_CFA_expression:
886 insn_ptr = read_uleb128 (insn_ptr, &reg);
887 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
888 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
889 insn_ptr = read_uleb128 (insn_ptr, &utmp);
890 insn_ptr += utmp;
891 break;
893 /* From the 2.1 draft. */
894 case DW_CFA_offset_extended_sf:
895 insn_ptr = read_uleb128 (insn_ptr, &reg);
896 insn_ptr = read_sleb128 (insn_ptr, &stmp);
897 offset = stmp * fs->data_align;
898 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
899 = REG_SAVED_OFFSET;
900 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
901 break;
903 case DW_CFA_def_cfa_sf:
904 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
905 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
906 fs->cfa_how = CFA_REG_OFFSET;
907 break;
909 case DW_CFA_def_cfa_offset_sf:
910 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
911 /* cfa_how deliberately not set. */
912 break;
914 case DW_CFA_GNU_window_save:
915 /* ??? Hardcoded for SPARC register window configuration. */
916 for (reg = 16; reg < 32; ++reg)
918 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
919 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
921 break;
923 case DW_CFA_GNU_args_size:
924 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
925 break;
927 case DW_CFA_GNU_negative_offset_extended:
928 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
929 older PowerPC code. */
930 insn_ptr = read_uleb128 (insn_ptr, &reg);
931 insn_ptr = read_uleb128 (insn_ptr, &utmp);
932 offset = (_Unwind_Word) utmp * fs->data_align;
933 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
934 = REG_SAVED_OFFSET;
935 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
936 break;
938 default:
939 abort ();
944 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
945 its caller and decode it into FS. This function also sets the
946 args_size and lsda members of CONTEXT, as they are really information
947 about the caller's frame. */
949 static _Unwind_Reason_Code
950 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
952 const struct dwarf_fde *fde;
953 const struct dwarf_cie *cie;
954 const unsigned char *aug, *insn, *end;
956 memset (fs, 0, sizeof (*fs));
957 context->args_size = 0;
958 context->lsda = 0;
960 if (context->ra == 0)
961 return _URC_END_OF_STACK;
963 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
964 if (fde == NULL)
966 /* Couldn't find frame unwind info for this function. Try a
967 target-specific fallback mechanism. This will necessarily
968 not provide a personality routine or LSDA. */
969 #ifdef MD_FALLBACK_FRAME_STATE_FOR
970 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
971 return _URC_END_OF_STACK;
972 success:
973 return _URC_NO_REASON;
974 #else
975 return _URC_END_OF_STACK;
976 #endif
979 fs->pc = context->bases.func;
981 cie = get_cie (fde);
982 insn = extract_cie_info (cie, context, fs);
983 if (insn == NULL)
984 /* CIE contained unknown augmentation. */
985 return _URC_FATAL_PHASE1_ERROR;
987 /* First decode all the insns in the CIE. */
988 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
989 execute_cfa_program (insn, end, context, fs);
991 /* Locate augmentation for the fde. */
992 aug = (unsigned char *) fde + sizeof (*fde);
993 aug += 2 * size_of_encoded_value (fs->fde_encoding);
994 insn = NULL;
995 if (fs->saw_z)
997 _Unwind_Word i;
998 aug = read_uleb128 (aug, &i);
999 insn = aug + i;
1001 if (fs->lsda_encoding != DW_EH_PE_omit)
1002 aug = read_encoded_value (context, fs->lsda_encoding, aug,
1003 (_Unwind_Ptr *) &context->lsda);
1005 /* Then the insns in the FDE up to our target PC. */
1006 if (insn == NULL)
1007 insn = aug;
1008 end = (unsigned char *) next_fde (fde);
1009 execute_cfa_program (insn, end, context, fs);
1011 return _URC_NO_REASON;
1014 typedef struct frame_state
1016 void *cfa;
1017 void *eh_ptr;
1018 long cfa_offset;
1019 long args_size;
1020 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1021 unsigned short cfa_reg;
1022 unsigned short retaddr_column;
1023 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1024 } frame_state;
1026 struct frame_state * __frame_state_for (void *, struct frame_state *);
1028 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1029 a given PC_TARGET. The caller should allocate a local variable of
1030 `struct frame_state' and pass its address to STATE_IN. */
1032 struct frame_state *
1033 __frame_state_for (void *pc_target, struct frame_state *state_in)
1035 struct _Unwind_Context context;
1036 _Unwind_FrameState fs;
1037 int reg;
1039 memset (&context, 0, sizeof (struct _Unwind_Context));
1040 context.ra = pc_target + 1;
1042 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1043 return 0;
1045 /* We have no way to pass a location expression for the CFA to our
1046 caller. It wouldn't understand it anyway. */
1047 if (fs.cfa_how == CFA_EXP)
1048 return 0;
1050 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1052 state_in->saved[reg] = fs.regs.reg[reg].how;
1053 switch (state_in->saved[reg])
1055 case REG_SAVED_REG:
1056 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1057 break;
1058 case REG_SAVED_OFFSET:
1059 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1060 break;
1061 default:
1062 state_in->reg_or_offset[reg] = 0;
1063 break;
1067 state_in->cfa_offset = fs.cfa_offset;
1068 state_in->cfa_reg = fs.cfa_reg;
1069 state_in->retaddr_column = fs.retaddr_column;
1070 state_in->args_size = context.args_size;
1071 state_in->eh_ptr = fs.eh_ptr;
1073 return state_in;
1076 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1078 static inline void
1079 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1080 _Unwind_SpTmp *tmp_sp)
1082 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1084 if (size == sizeof(_Unwind_Ptr))
1085 tmp_sp->ptr = (_Unwind_Ptr) cfa;
1086 else if (size == sizeof(_Unwind_Word))
1087 tmp_sp->word = (_Unwind_Ptr) cfa;
1088 else
1089 abort ();
1090 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1093 static void
1094 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1096 struct _Unwind_Context orig_context = *context;
1097 void *cfa;
1098 long i;
1100 #ifdef EH_RETURN_STACKADJ_RTX
1101 /* Special handling here: Many machines do not use a frame pointer,
1102 and track the CFA only through offsets from the stack pointer from
1103 one frame to the next. In this case, the stack pointer is never
1104 stored, so it has no saved address in the context. What we do
1105 have is the CFA from the previous stack frame.
1107 In very special situations (such as unwind info for signal return),
1108 there may be location expressions that use the stack pointer as well.
1110 Do this conditionally for one frame. This allows the unwind info
1111 for one frame to save a copy of the stack pointer from the previous
1112 frame, and be able to use much easier CFA mechanisms to do it.
1113 Always zap the saved stack pointer value for the next frame; carrying
1114 the value over from one frame to another doesn't make sense. */
1116 _Unwind_SpTmp tmp_sp;
1118 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1119 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1120 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1121 #endif
1123 /* Compute this frame's CFA. */
1124 switch (fs->cfa_how)
1126 case CFA_REG_OFFSET:
1127 cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
1128 cfa += fs->cfa_offset;
1129 break;
1131 case CFA_EXP:
1133 const unsigned char *exp = fs->cfa_exp;
1134 _Unwind_Word len;
1136 exp = read_uleb128 (exp, &len);
1137 cfa = (void *) (_Unwind_Ptr)
1138 execute_stack_op (exp, exp + len, &orig_context, 0);
1139 break;
1142 default:
1143 abort ();
1145 context->cfa = cfa;
1147 /* Compute the addresses of all registers saved in this frame. */
1148 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1149 switch (fs->regs.reg[i].how)
1151 case REG_UNSAVED:
1152 break;
1154 case REG_SAVED_OFFSET:
1155 _Unwind_SetGRPtr (context, i,
1156 (void *) (cfa + fs->regs.reg[i].loc.offset));
1157 break;
1159 case REG_SAVED_REG:
1160 _Unwind_SetGRPtr
1161 (context, i,
1162 _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
1163 break;
1165 case REG_SAVED_EXP:
1167 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1168 _Unwind_Word len;
1169 _Unwind_Ptr val;
1171 exp = read_uleb128 (exp, &len);
1172 val = execute_stack_op (exp, exp + len, &orig_context,
1173 (_Unwind_Ptr) cfa);
1174 _Unwind_SetGRPtr (context, i, (void *) val);
1176 break;
1179 MD_FROB_UPDATE_CONTEXT (context, fs);
1182 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1183 of its caller. Update CONTEXT to refer to the caller as well. Note
1184 that the args_size and lsda members are not updated here, but later in
1185 uw_frame_state_for. */
1187 static void
1188 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1190 uw_update_context_1 (context, fs);
1192 /* Compute the return address now, since the return address column
1193 can change from frame to frame. */
1194 context->ra = __builtin_extract_return_addr
1195 (_Unwind_GetPtr (context, fs->retaddr_column));
1198 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1199 level will be the return address and the CFA. */
1201 #define uw_init_context(CONTEXT) \
1202 do \
1204 /* Do any necessary initialization to access arbitrary stack frames. \
1205 On the SPARC, this means flushing the register windows. */ \
1206 __builtin_unwind_init (); \
1207 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1208 __builtin_return_address (0)); \
1210 while (0)
1212 static inline void
1213 init_dwarf_reg_size_table (void)
1215 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1218 static void
1219 uw_init_context_1 (struct _Unwind_Context *context,
1220 void *outer_cfa, void *outer_ra)
1222 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1223 _Unwind_FrameState fs;
1224 _Unwind_SpTmp sp_slot;
1226 memset (context, 0, sizeof (struct _Unwind_Context));
1227 context->ra = ra;
1229 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1230 abort ();
1232 #if __GTHREADS
1234 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1235 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1236 || dwarf_reg_size_table[0] == 0)
1237 init_dwarf_reg_size_table ();
1239 #else
1240 if (dwarf_reg_size_table[0] == 0)
1241 init_dwarf_reg_size_table ();
1242 #endif
1244 /* Force the frame state to use the known cfa value. */
1245 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1246 fs.cfa_how = CFA_REG_OFFSET;
1247 fs.cfa_reg = __builtin_dwarf_sp_column ();
1248 fs.cfa_offset = 0;
1250 uw_update_context_1 (context, &fs);
1252 /* If the return address column was saved in a register in the
1253 initialization context, then we can't see it in the given
1254 call frame data. So have the initialization context tell us. */
1255 context->ra = __builtin_extract_return_addr (outer_ra);
1259 /* Install TARGET into CURRENT so that we can return to it. This is a
1260 macro because __builtin_eh_return must be invoked in the context of
1261 our caller. */
1263 #define uw_install_context(CURRENT, TARGET) \
1264 do \
1266 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1267 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1268 __builtin_eh_return (offset, handler); \
1270 while (0)
1272 static long
1273 uw_install_context_1 (struct _Unwind_Context *current,
1274 struct _Unwind_Context *target)
1276 long i;
1278 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1280 void *c = current->reg[i];
1281 void *t = target->reg[i];
1283 if (t && c && t != c)
1284 memcpy (c, t, dwarf_reg_size_table[i]);
1287 #ifdef EH_RETURN_STACKADJ_RTX
1289 void *target_cfa;
1291 /* If the last frame records a saved stack pointer, use it. */
1292 if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1293 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1294 else
1295 target_cfa = target->cfa;
1297 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1298 if (STACK_GROWS_DOWNWARD)
1299 return target_cfa - current->cfa + target->args_size;
1300 else
1301 return current->cfa - target_cfa - target->args_size;
1303 #else
1304 return 0;
1305 #endif
1308 static inline _Unwind_Ptr
1309 uw_identify_context (struct _Unwind_Context *context)
1311 return _Unwind_GetIP (context);
1315 #include "unwind.inc"
1317 #endif /* !USING_SJLJ_EXCEPTIONS */