* gcc.c-torture/execute/20020307-1.c: New test.
[official-gcc.git] / gcc / unwind-dw2.c
blobd3828e97ad4e3da4130fec68ec7a7144d7abff1a
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
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 "dwarf2.h"
25 #include "unwind.h"
26 #include "unwind-pe.h"
27 #include "unwind-dw2-fde.h"
28 #include "gthr.h"
31 #ifndef __USING_SJLJ_EXCEPTIONS__
33 #ifndef STACK_GROWS_DOWNWARD
34 #define STACK_GROWS_DOWNWARD 0
35 #else
36 #undef STACK_GROWS_DOWNWARD
37 #define STACK_GROWS_DOWNWARD 1
38 #endif
40 /* A target can override (perhaps for backward compatibility) how
41 many dwarf2 columns are unwound. */
42 #ifndef DWARF_FRAME_REGISTERS
43 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
44 #endif
46 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
47 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
48 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
49 #endif
51 /* This is the register and unwind state for a particular frame. */
52 struct _Unwind_Context
54 void *reg[DWARF_FRAME_REGISTERS+1];
55 void *cfa;
56 void *ra;
57 void *lsda;
58 struct dwarf_eh_bases bases;
59 _Unwind_Word args_size;
62 /* Byte size of every register managed by these routines. */
63 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
66 /* The result of interpreting the frame unwind info for a frame.
67 This is all symbolic at this point, as none of the values can
68 be resolved until the target pc is located. */
69 typedef struct
71 /* Each register save state can be described in terms of a CFA slot,
72 another register, or a location expression. */
73 struct frame_state_reg_info
75 struct {
76 union {
77 _Unwind_Word reg;
78 _Unwind_Sword offset;
79 const unsigned char *exp;
80 } loc;
81 enum {
82 REG_UNSAVED,
83 REG_SAVED_OFFSET,
84 REG_SAVED_REG,
85 REG_SAVED_EXP,
86 } how;
87 } reg[DWARF_FRAME_REGISTERS+1];
89 /* Used to implement DW_CFA_remember_state. */
90 struct frame_state_reg_info *prev;
91 } regs;
93 /* The CFA can be described in terms of a reg+offset or a
94 location expression. */
95 _Unwind_Sword cfa_offset;
96 _Unwind_Word cfa_reg;
97 const unsigned char *cfa_exp;
98 enum {
99 CFA_UNSET,
100 CFA_REG_OFFSET,
101 CFA_EXP,
102 } cfa_how;
104 /* The PC described by the current frame state. */
105 void *pc;
107 /* The information we care about from the CIE/FDE. */
108 _Unwind_Personality_Fn personality;
109 _Unwind_Sword data_align;
110 _Unwind_Word code_align;
111 unsigned char retaddr_column;
112 unsigned char fde_encoding;
113 unsigned char lsda_encoding;
114 unsigned char saw_z;
115 void *eh_ptr;
116 } _Unwind_FrameState;
118 /* Read unaligned data from the instruction buffer. */
120 union unaligned
122 void *p;
123 unsigned u2 __attribute__ ((mode (HI)));
124 unsigned u4 __attribute__ ((mode (SI)));
125 unsigned u8 __attribute__ ((mode (DI)));
126 signed s2 __attribute__ ((mode (HI)));
127 signed s4 __attribute__ ((mode (SI)));
128 signed s8 __attribute__ ((mode (DI)));
129 } __attribute__ ((packed));
131 static inline void *
132 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
134 static inline int
135 read_1u (const void *p) { return *(const unsigned char *) p; }
137 static inline int
138 read_1s (const void *p) { return *(const signed char *) p; }
140 static inline int
141 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
143 static inline int
144 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
146 static inline unsigned int
147 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
149 static inline int
150 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
152 static inline unsigned long
153 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
155 static inline unsigned long
156 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
158 /* Get the value of register REG as saved in CONTEXT. */
160 inline _Unwind_Word
161 _Unwind_GetGR (struct _Unwind_Context *context, int index)
163 /* This will segfault if the register hasn't been saved. */
164 return * (_Unwind_Word *) context->reg[index];
167 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
169 inline void
170 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
172 * (_Unwind_Word *) context->reg[index] = val;
175 /* Retrieve the return address for CONTEXT. */
177 inline _Unwind_Ptr
178 _Unwind_GetIP (struct _Unwind_Context *context)
180 return (_Unwind_Ptr) context->ra;
183 /* Overwrite the return address for CONTEXT with VAL. */
185 inline void
186 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
188 context->ra = (void *) val;
191 void *
192 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
194 return context->lsda;
197 _Unwind_Ptr
198 _Unwind_GetRegionStart (struct _Unwind_Context *context)
200 return (_Unwind_Ptr) context->bases.func;
203 #ifndef __ia64__
204 _Unwind_Ptr
205 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
207 return (_Unwind_Ptr) context->bases.dbase;
210 _Unwind_Ptr
211 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
213 return (_Unwind_Ptr) context->bases.tbase;
215 #endif
217 /* Extract any interesting information from the CIE for the translation
218 unit F belongs to. Return a pointer to the byte after the augmentation,
219 or NULL if we encountered an undecipherable augmentation. */
221 static const unsigned char *
222 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
223 _Unwind_FrameState *fs)
225 const unsigned char *aug = cie->augmentation;
226 const unsigned char *p = aug + strlen (aug) + 1;
227 const unsigned char *ret = NULL;
228 _Unwind_Word utmp;
230 /* g++ v2 "eh" has pointer immediately following augmentation string,
231 so it must be handled first. */
232 if (aug[0] == 'e' && aug[1] == 'h')
234 fs->eh_ptr = read_pointer (p);
235 p += sizeof (void *);
236 aug += 2;
239 /* Immediately following the augmentation are the code and
240 data alignment and return address column. */
241 p = read_uleb128 (p, &fs->code_align);
242 p = read_sleb128 (p, &fs->data_align);
243 fs->retaddr_column = *p++;
244 fs->lsda_encoding = DW_EH_PE_omit;
246 /* If the augmentation starts with 'z', then a uleb128 immediately
247 follows containing the length of the augmentation field following
248 the size. */
249 if (*aug == 'z')
251 p = read_uleb128 (p, &utmp);
252 ret = p + utmp;
254 fs->saw_z = 1;
255 ++aug;
258 /* Iterate over recognized augmentation subsequences. */
259 while (*aug != '\0')
261 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
262 if (aug[0] == 'L')
264 fs->lsda_encoding = *p++;
265 aug += 1;
268 /* "R" indicates a byte indicating how FDE addresses are encoded. */
269 else if (aug[0] == 'R')
271 fs->fde_encoding = *p++;
272 aug += 1;
275 /* "P" indicates a personality routine in the CIE augmentation. */
276 else if (aug[0] == 'P')
278 p = read_encoded_value (context, *p, p + 1,
279 (_Unwind_Ptr *) &fs->personality);
280 aug += 1;
283 /* Otherwise we have an unknown augmentation string.
284 Bail unless we saw a 'z' prefix. */
285 else
286 return ret;
289 return ret ? ret : p;
293 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
294 onto the stack to start. */
296 static _Unwind_Word
297 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
298 struct _Unwind_Context *context, _Unwind_Word initial)
300 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
301 int stack_elt;
303 stack[0] = initial;
304 stack_elt = 1;
306 while (op_ptr < op_end)
308 enum dwarf_location_atom op = *op_ptr++;
309 _Unwind_Word result, reg, utmp;
310 _Unwind_Sword offset, stmp;
312 switch (op)
314 case DW_OP_lit0:
315 case DW_OP_lit1:
316 case DW_OP_lit2:
317 case DW_OP_lit3:
318 case DW_OP_lit4:
319 case DW_OP_lit5:
320 case DW_OP_lit6:
321 case DW_OP_lit7:
322 case DW_OP_lit8:
323 case DW_OP_lit9:
324 case DW_OP_lit10:
325 case DW_OP_lit11:
326 case DW_OP_lit12:
327 case DW_OP_lit13:
328 case DW_OP_lit14:
329 case DW_OP_lit15:
330 case DW_OP_lit16:
331 case DW_OP_lit17:
332 case DW_OP_lit18:
333 case DW_OP_lit19:
334 case DW_OP_lit20:
335 case DW_OP_lit21:
336 case DW_OP_lit22:
337 case DW_OP_lit23:
338 case DW_OP_lit24:
339 case DW_OP_lit25:
340 case DW_OP_lit26:
341 case DW_OP_lit27:
342 case DW_OP_lit28:
343 case DW_OP_lit29:
344 case DW_OP_lit30:
345 case DW_OP_lit31:
346 result = op - DW_OP_lit0;
347 break;
349 case DW_OP_addr:
350 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
351 op_ptr += sizeof (void *);
352 break;
354 case DW_OP_const1u:
355 result = read_1u (op_ptr);
356 op_ptr += 1;
357 break;
358 case DW_OP_const1s:
359 result = read_1s (op_ptr);
360 op_ptr += 1;
361 break;
362 case DW_OP_const2u:
363 result = read_2u (op_ptr);
364 op_ptr += 2;
365 break;
366 case DW_OP_const2s:
367 result = read_2s (op_ptr);
368 op_ptr += 2;
369 break;
370 case DW_OP_const4u:
371 result = read_4u (op_ptr);
372 op_ptr += 4;
373 break;
374 case DW_OP_const4s:
375 result = read_4s (op_ptr);
376 op_ptr += 4;
377 break;
378 case DW_OP_const8u:
379 result = read_8u (op_ptr);
380 op_ptr += 8;
381 break;
382 case DW_OP_const8s:
383 result = read_8s (op_ptr);
384 op_ptr += 8;
385 break;
386 case DW_OP_constu:
387 op_ptr = read_uleb128 (op_ptr, &result);
388 break;
389 case DW_OP_consts:
390 op_ptr = read_sleb128 (op_ptr, &stmp);
391 result = stmp;
392 break;
394 case DW_OP_reg0:
395 case DW_OP_reg1:
396 case DW_OP_reg2:
397 case DW_OP_reg3:
398 case DW_OP_reg4:
399 case DW_OP_reg5:
400 case DW_OP_reg6:
401 case DW_OP_reg7:
402 case DW_OP_reg8:
403 case DW_OP_reg9:
404 case DW_OP_reg10:
405 case DW_OP_reg11:
406 case DW_OP_reg12:
407 case DW_OP_reg13:
408 case DW_OP_reg14:
409 case DW_OP_reg15:
410 case DW_OP_reg16:
411 case DW_OP_reg17:
412 case DW_OP_reg18:
413 case DW_OP_reg19:
414 case DW_OP_reg20:
415 case DW_OP_reg21:
416 case DW_OP_reg22:
417 case DW_OP_reg23:
418 case DW_OP_reg24:
419 case DW_OP_reg25:
420 case DW_OP_reg26:
421 case DW_OP_reg27:
422 case DW_OP_reg28:
423 case DW_OP_reg29:
424 case DW_OP_reg30:
425 case DW_OP_reg31:
426 result = _Unwind_GetGR (context, op - DW_OP_reg0);
427 break;
428 case DW_OP_regx:
429 op_ptr = read_uleb128 (op_ptr, &reg);
430 result = _Unwind_GetGR (context, reg);
431 break;
433 case DW_OP_breg0:
434 case DW_OP_breg1:
435 case DW_OP_breg2:
436 case DW_OP_breg3:
437 case DW_OP_breg4:
438 case DW_OP_breg5:
439 case DW_OP_breg6:
440 case DW_OP_breg7:
441 case DW_OP_breg8:
442 case DW_OP_breg9:
443 case DW_OP_breg10:
444 case DW_OP_breg11:
445 case DW_OP_breg12:
446 case DW_OP_breg13:
447 case DW_OP_breg14:
448 case DW_OP_breg15:
449 case DW_OP_breg16:
450 case DW_OP_breg17:
451 case DW_OP_breg18:
452 case DW_OP_breg19:
453 case DW_OP_breg20:
454 case DW_OP_breg21:
455 case DW_OP_breg22:
456 case DW_OP_breg23:
457 case DW_OP_breg24:
458 case DW_OP_breg25:
459 case DW_OP_breg26:
460 case DW_OP_breg27:
461 case DW_OP_breg28:
462 case DW_OP_breg29:
463 case DW_OP_breg30:
464 case DW_OP_breg31:
465 op_ptr = read_sleb128 (op_ptr, &offset);
466 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
467 break;
468 case DW_OP_bregx:
469 op_ptr = read_uleb128 (op_ptr, &reg);
470 op_ptr = read_sleb128 (op_ptr, &offset);
471 result = _Unwind_GetGR (context, reg) + offset;
472 break;
474 case DW_OP_dup:
475 if (stack_elt < 1)
476 abort ();
477 result = stack[stack_elt - 1];
478 break;
480 case DW_OP_drop:
481 if (--stack_elt < 0)
482 abort ();
483 goto no_push;
485 case DW_OP_pick:
486 offset = *op_ptr++;
487 if (offset >= stack_elt - 1)
488 abort ();
489 result = stack[stack_elt - 1 - offset];
490 break;
492 case DW_OP_over:
493 if (stack_elt < 2)
494 abort ();
495 result = stack[stack_elt - 2];
496 break;
498 case DW_OP_rot:
500 _Unwind_Word t1, t2, t3;
502 if (stack_elt < 3)
503 abort ();
504 t1 = stack[stack_elt - 1];
505 t2 = stack[stack_elt - 2];
506 t3 = stack[stack_elt - 3];
507 stack[stack_elt - 1] = t2;
508 stack[stack_elt - 2] = t3;
509 stack[stack_elt - 3] = t1;
510 goto no_push;
513 case DW_OP_deref:
514 case DW_OP_deref_size:
515 case DW_OP_abs:
516 case DW_OP_neg:
517 case DW_OP_not:
518 case DW_OP_plus_uconst:
519 /* Unary operations. */
520 if (--stack_elt < 0)
521 abort ();
522 result = stack[stack_elt];
524 switch (op)
526 case DW_OP_deref:
528 void *ptr = (void *) (_Unwind_Ptr) result;
529 result = (_Unwind_Ptr) read_pointer (ptr);
531 break;
533 case DW_OP_deref_size:
535 void *ptr = (void *) (_Unwind_Ptr) result;
536 switch (*op_ptr++)
538 case 1:
539 result = read_1u (ptr);
540 break;
541 case 2:
542 result = read_2u (ptr);
543 break;
544 case 4:
545 result = read_4u (ptr);
546 break;
547 case 8:
548 result = read_8u (ptr);
549 break;
550 default:
551 abort ();
554 break;
556 case DW_OP_abs:
557 if ((_Unwind_Sword) result < 0)
558 result = -result;
559 break;
560 case DW_OP_neg:
561 result = -result;
562 break;
563 case DW_OP_not:
564 result = ~result;
565 break;
566 case DW_OP_plus_uconst:
567 op_ptr = read_uleb128 (op_ptr, &utmp);
568 result += utmp;
569 break;
571 default:
572 abort ();
574 break;
576 case DW_OP_and:
577 case DW_OP_div:
578 case DW_OP_minus:
579 case DW_OP_mod:
580 case DW_OP_mul:
581 case DW_OP_or:
582 case DW_OP_plus:
583 case DW_OP_le:
584 case DW_OP_ge:
585 case DW_OP_eq:
586 case DW_OP_lt:
587 case DW_OP_gt:
588 case DW_OP_ne:
590 /* Binary operations. */
591 _Unwind_Word first, second;
592 if ((stack_elt -= 2) < 0)
593 abort ();
594 second = stack[stack_elt];
595 first = stack[stack_elt + 1];
597 switch (op)
599 case DW_OP_and:
600 result = second & first;
601 break;
602 case DW_OP_div:
603 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
604 break;
605 case DW_OP_minus:
606 result = second - first;
607 break;
608 case DW_OP_mod:
609 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
610 break;
611 case DW_OP_mul:
612 result = second * first;
613 break;
614 case DW_OP_or:
615 result = second | first;
616 break;
617 case DW_OP_plus:
618 result = second + first;
619 break;
620 case DW_OP_shl:
621 result = second << first;
622 break;
623 case DW_OP_shr:
624 result = second >> first;
625 break;
626 case DW_OP_shra:
627 result = (_Unwind_Sword) second >> first;
628 break;
629 case DW_OP_xor:
630 result = second ^ first;
631 break;
632 case DW_OP_le:
633 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
634 break;
635 case DW_OP_ge:
636 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
637 break;
638 case DW_OP_eq:
639 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
640 break;
641 case DW_OP_lt:
642 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
643 break;
644 case DW_OP_gt:
645 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
646 break;
647 case DW_OP_ne:
648 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
649 break;
651 default:
652 abort ();
655 break;
657 case DW_OP_skip:
658 offset = read_2s (op_ptr);
659 op_ptr += 2;
660 op_ptr += offset;
661 goto no_push;
663 case DW_OP_bra:
664 if (--stack_elt < 0)
665 abort ();
666 offset = read_2s (op_ptr);
667 op_ptr += 2;
668 if (stack[stack_elt] != 0)
669 op_ptr += offset;
670 goto no_push;
672 case DW_OP_nop:
673 goto no_push;
675 default:
676 abort ();
679 /* Most things push a result value. */
680 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
681 abort ();
682 stack[++stack_elt] = result;
683 no_push:;
686 /* We were executing this program to get a value. It should be
687 at top of stack. */
688 if (--stack_elt < 0)
689 abort ();
690 return stack[stack_elt];
694 /* Decode DWARF 2 call frame information. Takes pointers the
695 instruction sequence to decode, current register information and
696 CIE info, and the PC range to evaluate. */
698 static void
699 execute_cfa_program (const unsigned char *insn_ptr,
700 const unsigned char *insn_end,
701 struct _Unwind_Context *context,
702 _Unwind_FrameState *fs)
704 struct frame_state_reg_info *unused_rs = NULL;
706 /* Don't allow remember/restore between CIE and FDE programs. */
707 fs->regs.prev = NULL;
709 /* The comparison with the return address uses < rather than <= because
710 we are only interested in the effects of code before the call; for a
711 noreturn function, the return address may point to unrelated code with
712 a different stack configuration that we are not interested in. We
713 assume that the call itself is unwind info-neutral; if not, or if
714 there are delay instructions that adjust the stack, these must be
715 reflected at the point immediately before the call insn. */
716 while (insn_ptr < insn_end && fs->pc < context->ra)
718 unsigned char insn = *insn_ptr++;
719 _Unwind_Word reg, utmp;
720 _Unwind_Sword offset, stmp;
722 if ((insn & 0xc0) == DW_CFA_advance_loc)
723 fs->pc += (insn & 0x3f) * fs->code_align;
724 else if ((insn & 0xc0) == DW_CFA_offset)
726 reg = insn & 0x3f;
727 insn_ptr = read_uleb128 (insn_ptr, &utmp);
728 offset = (_Unwind_Sword) utmp * fs->data_align;
729 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
730 fs->regs.reg[reg].loc.offset = offset;
732 else if ((insn & 0xc0) == DW_CFA_restore)
734 reg = insn & 0x3f;
735 fs->regs.reg[reg].how = REG_UNSAVED;
737 else switch (insn)
739 case DW_CFA_set_loc:
740 insn_ptr = read_encoded_value (context, fs->fde_encoding,
741 insn_ptr, (_Unwind_Ptr *) &fs->pc);
742 break;
744 case DW_CFA_advance_loc1:
745 fs->pc += read_1u (insn_ptr) * fs->code_align;
746 insn_ptr += 1;
747 break;
748 case DW_CFA_advance_loc2:
749 fs->pc += read_2u (insn_ptr) * fs->code_align;
750 insn_ptr += 2;
751 break;
752 case DW_CFA_advance_loc4:
753 fs->pc += read_4u (insn_ptr) * fs->code_align;
754 insn_ptr += 4;
755 break;
757 case DW_CFA_offset_extended:
758 insn_ptr = read_uleb128 (insn_ptr, &reg);
759 insn_ptr = read_uleb128 (insn_ptr, &utmp);
760 offset = (_Unwind_Sword) utmp * fs->data_align;
761 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
762 fs->regs.reg[reg].loc.offset = offset;
763 break;
765 case DW_CFA_restore_extended:
766 insn_ptr = read_uleb128 (insn_ptr, &reg);
767 fs->regs.reg[reg].how = REG_UNSAVED;
768 break;
770 case DW_CFA_undefined:
771 case DW_CFA_same_value:
772 case DW_CFA_nop:
773 break;
775 case DW_CFA_register:
777 _Unwind_Word reg2;
778 insn_ptr = read_uleb128 (insn_ptr, &reg);
779 insn_ptr = read_uleb128 (insn_ptr, &reg2);
780 fs->regs.reg[reg].how = REG_SAVED_REG;
781 fs->regs.reg[reg].loc.reg = reg2;
783 break;
785 case DW_CFA_remember_state:
787 struct frame_state_reg_info *new_rs;
788 if (unused_rs)
790 new_rs = unused_rs;
791 unused_rs = unused_rs->prev;
793 else
794 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
796 *new_rs = fs->regs;
797 fs->regs.prev = new_rs;
799 break;
801 case DW_CFA_restore_state:
803 struct frame_state_reg_info *old_rs = fs->regs.prev;
804 fs->regs = *old_rs;
805 old_rs->prev = unused_rs;
806 unused_rs = old_rs;
808 break;
810 case DW_CFA_def_cfa:
811 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
812 insn_ptr = read_uleb128 (insn_ptr, &utmp);
813 fs->cfa_offset = utmp;
814 fs->cfa_how = CFA_REG_OFFSET;
815 break;
817 case DW_CFA_def_cfa_register:
818 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
819 fs->cfa_how = CFA_REG_OFFSET;
820 break;
822 case DW_CFA_def_cfa_offset:
823 insn_ptr = read_uleb128 (insn_ptr, &utmp);
824 fs->cfa_offset = utmp;
825 /* cfa_how deliberately not set. */
826 break;
828 case DW_CFA_def_cfa_expression:
829 insn_ptr = read_uleb128 (insn_ptr, &utmp);
830 fs->cfa_exp = insn_ptr;
831 fs->cfa_how = CFA_EXP;
832 insn_ptr += utmp;
833 break;
835 case DW_CFA_expression:
836 insn_ptr = read_uleb128 (insn_ptr, &reg);
837 insn_ptr = read_uleb128 (insn_ptr, &utmp);
838 fs->regs.reg[reg].how = REG_SAVED_EXP;
839 fs->regs.reg[reg].loc.exp = insn_ptr;
840 insn_ptr += utmp;
841 break;
843 /* From the 2.1 draft. */
844 case DW_CFA_offset_extended_sf:
845 insn_ptr = read_uleb128 (insn_ptr, &reg);
846 insn_ptr = read_sleb128 (insn_ptr, &stmp);
847 offset = stmp * fs->data_align;
848 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
849 fs->regs.reg[reg].loc.offset = offset;
850 break;
852 case DW_CFA_def_cfa_sf:
853 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
854 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
855 fs->cfa_how = CFA_REG_OFFSET;
856 break;
858 case DW_CFA_def_cfa_offset_sf:
859 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
860 /* cfa_how deliberately not set. */
861 break;
863 case DW_CFA_GNU_window_save:
864 /* ??? Hardcoded for SPARC register window configuration. */
865 for (reg = 16; reg < 32; ++reg)
867 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
868 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
870 break;
872 case DW_CFA_GNU_args_size:
873 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
874 break;
876 case DW_CFA_GNU_negative_offset_extended:
877 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
878 older PowerPC code. */
879 insn_ptr = read_uleb128 (insn_ptr, &reg);
880 insn_ptr = read_uleb128 (insn_ptr, &utmp);
881 offset = (_Unwind_Word) utmp * fs->data_align;
882 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
883 fs->regs.reg[reg].loc.offset = -offset;
884 break;
886 default:
887 abort ();
892 static _Unwind_Reason_Code
893 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
895 struct dwarf_fde *fde;
896 struct dwarf_cie *cie;
897 const unsigned char *aug, *insn, *end;
899 memset (fs, 0, sizeof (*fs));
900 context->args_size = 0;
901 context->lsda = 0;
903 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
904 if (fde == NULL)
906 /* Couldn't find frame unwind info for this function. Try a
907 target-specific fallback mechanism. This will necessarily
908 not provide a personality routine or LSDA. */
909 #ifdef MD_FALLBACK_FRAME_STATE_FOR
910 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
911 return _URC_END_OF_STACK;
912 success:
913 return _URC_NO_REASON;
914 #else
915 return _URC_END_OF_STACK;
916 #endif
919 fs->pc = context->bases.func;
921 cie = get_cie (fde);
922 insn = extract_cie_info (cie, context, fs);
923 if (insn == NULL)
924 /* CIE contained unknown augmentation. */
925 return _URC_FATAL_PHASE1_ERROR;
927 /* First decode all the insns in the CIE. */
928 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
929 execute_cfa_program (insn, end, context, fs);
931 /* Locate augmentation for the fde. */
932 aug = (unsigned char *) fde + sizeof (*fde);
933 aug += 2 * size_of_encoded_value (fs->fde_encoding);
934 insn = NULL;
935 if (fs->saw_z)
937 _Unwind_Word i;
938 aug = read_uleb128 (aug, &i);
939 insn = aug + i;
941 if (fs->lsda_encoding != DW_EH_PE_omit)
942 aug = read_encoded_value (context, fs->lsda_encoding, aug,
943 (_Unwind_Ptr *) &context->lsda);
945 /* Then the insns in the FDE up to our target PC. */
946 if (insn == NULL)
947 insn = aug;
948 end = (unsigned char *) next_fde (fde);
949 execute_cfa_program (insn, end, context, fs);
951 return _URC_NO_REASON;
954 typedef struct frame_state
956 void *cfa;
957 void *eh_ptr;
958 long cfa_offset;
959 long args_size;
960 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
961 unsigned short cfa_reg;
962 unsigned short retaddr_column;
963 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
964 } frame_state;
966 struct frame_state * __frame_state_for (void *, struct frame_state *);
968 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
969 a given PC_TARGET. The caller should allocate a local variable of
970 `struct frame_state' and pass its address to STATE_IN. */
972 struct frame_state *
973 __frame_state_for (void *pc_target, struct frame_state *state_in)
975 struct _Unwind_Context context;
976 _Unwind_FrameState fs;
977 int reg;
979 memset (&context, 0, sizeof (struct _Unwind_Context));
980 context.ra = pc_target + 1;
982 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
983 return 0;
985 /* We have no way to pass a location expression for the CFA to our
986 caller. It wouldn't understand it anyway. */
987 if (fs.cfa_how == CFA_EXP)
988 return 0;
990 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
992 state_in->saved[reg] = fs.regs.reg[reg].how;
993 switch (state_in->saved[reg])
995 case REG_SAVED_REG:
996 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
997 break;
998 case REG_SAVED_OFFSET:
999 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1000 break;
1001 default:
1002 state_in->reg_or_offset[reg] = 0;
1003 break;
1007 state_in->cfa_offset = fs.cfa_offset;
1008 state_in->cfa_reg = fs.cfa_reg;
1009 state_in->retaddr_column = fs.retaddr_column;
1010 state_in->args_size = context.args_size;
1011 state_in->eh_ptr = fs.eh_ptr;
1013 return state_in;
1016 static void
1017 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1019 struct _Unwind_Context orig_context = *context;
1020 void *cfa;
1021 long i;
1023 /* Compute this frame's CFA. */
1024 switch (fs->cfa_how)
1026 case CFA_REG_OFFSET:
1027 /* Special handling here: Many machines do not use a frame pointer,
1028 and track the CFA only through offsets from the stack pointer from
1029 one frame to the next. In this case, the stack pointer is never
1030 stored, so it has no saved address in the context. What we do
1031 have is the CFA from the previous stack frame. */
1032 if (context->reg[fs->cfa_reg] == NULL)
1033 cfa = context->cfa;
1034 else
1035 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1036 cfa += fs->cfa_offset;
1037 break;
1039 case CFA_EXP:
1040 /* ??? No way of knowing what register number is the stack pointer
1041 to do the same sort of handling as above. Assume that if the
1042 CFA calculation is so complicated as to require a stack program
1043 that this will not be a problem. */
1045 const unsigned char *exp = fs->cfa_exp;
1046 _Unwind_Word len;
1048 exp = read_uleb128 (exp, &len);
1049 cfa = (void *) (_Unwind_Ptr)
1050 execute_stack_op (exp, exp + len, context, 0);
1051 break;
1054 default:
1055 abort ();
1057 context->cfa = cfa;
1059 /* Compute the addresses of all registers saved in this frame. */
1060 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1061 switch (fs->regs.reg[i].how)
1063 case REG_UNSAVED:
1064 break;
1065 case REG_SAVED_OFFSET:
1066 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1067 break;
1068 case REG_SAVED_REG:
1069 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1070 break;
1071 case REG_SAVED_EXP:
1073 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1074 _Unwind_Word len;
1075 _Unwind_Ptr val;
1077 exp = read_uleb128 (exp, &len);
1078 val = execute_stack_op (exp, exp + len, &orig_context,
1079 (_Unwind_Ptr) cfa);
1080 context->reg[i] = (void *) val;
1082 break;
1086 static void
1087 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1089 uw_update_context_1 (context, fs);
1091 /* Compute the return address now, since the return address column
1092 can change from frame to frame. */
1093 context->ra = __builtin_extract_return_addr
1094 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1097 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1098 level will be the return address and the CFA. */
1100 #define uw_init_context(CONTEXT) \
1101 do \
1103 /* Do any necessary initialization to access arbitrary stack frames. \
1104 On the SPARC, this means flushing the register windows. */ \
1105 __builtin_unwind_init (); \
1106 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1107 __builtin_return_address (0)); \
1109 while (0)
1111 static void
1112 uw_init_context_1 (struct _Unwind_Context *context,
1113 void *outer_cfa, void *outer_ra)
1115 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1116 _Unwind_FrameState fs;
1118 memset (context, 0, sizeof (struct _Unwind_Context));
1119 context->ra = ra;
1121 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1122 abort ();
1124 /* Force the frame state to use the known cfa value. */
1125 context->cfa = outer_cfa;
1126 fs.cfa_how = CFA_REG_OFFSET;
1127 fs.cfa_reg = 0;
1128 fs.cfa_offset = 0;
1130 uw_update_context_1 (context, &fs);
1132 /* If the return address column was saved in a register in the
1133 initialization context, then we can't see it in the given
1134 call frame data. So have the initialization context tell us. */
1135 context->ra = __builtin_extract_return_addr (outer_ra);
1139 /* Install TARGET into CURRENT so that we can return to it. This is a
1140 macro because __builtin_eh_return must be invoked in the context of
1141 our caller. */
1143 #define uw_install_context(CURRENT, TARGET) \
1144 do \
1146 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1147 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1148 __builtin_eh_return (offset, handler); \
1150 while (0)
1152 static inline void
1153 init_dwarf_reg_size_table (void)
1155 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1158 static long
1159 uw_install_context_1 (struct _Unwind_Context *current,
1160 struct _Unwind_Context *target)
1162 long i;
1164 #if __GTHREADS
1166 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1167 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1168 || dwarf_reg_size_table[0] == 0)
1169 init_dwarf_reg_size_table ();
1171 #else
1172 if (dwarf_reg_size_table[0] == 0)
1173 init_dwarf_reg_size_table ();
1174 #endif
1176 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1178 void *c = current->reg[i];
1179 void *t = target->reg[i];
1180 if (t && c && t != c)
1181 memcpy (c, t, dwarf_reg_size_table[i]);
1184 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1185 if (STACK_GROWS_DOWNWARD)
1186 return target->cfa - current->cfa + target->args_size;
1187 else
1188 return current->cfa - target->cfa - target->args_size;
1191 static inline _Unwind_Ptr
1192 uw_identify_context (struct _Unwind_Context *context)
1194 return _Unwind_GetIP (context);
1198 #include "unwind.inc"
1200 #endif /* !USING_SJLJ_EXCEPTIONS */