Update.
[glibc.git] / sysdeps / generic / unwind-dw2.c
blobca0299468f7b49dcb1cbbe6a467f81f1e7431b0e
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #ifdef _LIBC
22 #include <stdlib.h>
23 #include <string.h>
24 #include <error.h>
25 #include <libintl.h>
26 #include <dwarf2.h>
27 #include <unwind.h>
28 #include <unwind-pe.h>
29 #include <unwind-dw2-fde.h>
30 #else
31 #include "tconfig.h"
32 #include "tsystem.h"
33 #include "dwarf2.h"
34 #include "unwind.h"
35 #include "unwind-pe.h"
36 #include "unwind-dw2-fde.h"
37 #include "gthr.h"
38 #endif
40 #if !USING_SJLJ_EXCEPTIONS
42 #ifndef STACK_GROWS_DOWNWARD
43 #define STACK_GROWS_DOWNWARD 0
44 #else
45 #undef STACK_GROWS_DOWNWARD
46 #define STACK_GROWS_DOWNWARD 1
47 #endif
49 /* A target can override (perhaps for backward compatibility) how
50 many dwarf2 columns are unwound. */
51 #ifndef DWARF_FRAME_REGISTERS
52 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
53 #endif
55 /* This is the register and unwind state for a particular frame. */
56 struct _Unwind_Context
58 void *reg[DWARF_FRAME_REGISTERS+1];
59 void *cfa;
60 void *ra;
61 void *lsda;
62 struct dwarf_eh_bases bases;
63 _Unwind_Word args_size;
66 #ifndef _LIBC
67 /* Byte size of every register managed by these routines. */
68 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
69 #endif
72 /* The result of interpreting the frame unwind info for a frame.
73 This is all symbolic at this point, as none of the values can
74 be resolved until the target pc is located. */
75 typedef struct
77 /* Each register save state can be described in terms of a CFA slot,
78 another register, or a location expression. */
79 struct frame_state_reg_info
81 struct {
82 union {
83 unsigned int reg;
84 _Unwind_Sword offset;
85 const unsigned char *exp;
86 } loc;
87 enum {
88 REG_UNSAVED,
89 REG_SAVED_OFFSET,
90 REG_SAVED_REG,
91 REG_SAVED_EXP,
92 } how;
93 } reg[DWARF_FRAME_REGISTERS+1];
95 /* Used to implement DW_CFA_remember_state. */
96 struct frame_state_reg_info *prev;
97 } regs;
99 /* The CFA can be described in terms of a reg+offset or a
100 location expression. */
101 _Unwind_Sword cfa_offset;
102 _Unwind_Word cfa_reg;
103 const unsigned char *cfa_exp;
104 enum {
105 CFA_UNSET,
106 CFA_REG_OFFSET,
107 CFA_EXP,
108 } cfa_how;
110 /* The PC described by the current frame state. */
111 void *pc;
113 /* The information we care about from the CIE/FDE. */
114 _Unwind_Personality_Fn personality;
115 signed int data_align;
116 unsigned int code_align;
117 unsigned char retaddr_column;
118 unsigned char fde_encoding;
119 unsigned char lsda_encoding;
120 unsigned char saw_z;
121 void *eh_ptr;
122 } _Unwind_FrameState;
124 /* Read unaligned data from the instruction buffer. */
126 union unaligned
128 void *p;
129 unsigned u2 __attribute__ ((mode (HI)));
130 unsigned u4 __attribute__ ((mode (SI)));
131 unsigned u8 __attribute__ ((mode (DI)));
132 signed s2 __attribute__ ((mode (HI)));
133 signed s4 __attribute__ ((mode (SI)));
134 signed s8 __attribute__ ((mode (DI)));
135 } __attribute__ ((packed));
137 static inline void *
138 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
140 static inline int
141 read_1u (const void *p) { return *(const unsigned char *)p; }
143 static inline int
144 read_1s (const void *p) { return *(const signed char *)p; }
146 static inline int
147 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
149 static inline int
150 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
152 static inline unsigned int
153 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
155 static inline int
156 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
158 static inline unsigned long
159 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
161 static inline unsigned long
162 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
164 /* Get the value of register REG as saved in CONTEXT. */
166 inline _Unwind_Word
167 _Unwind_GetGR (struct _Unwind_Context *context, int index)
169 /* This will segfault if the register hasn't been saved. */
170 return * (_Unwind_Word *) context->reg[index];
173 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
175 inline void
176 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
178 * (_Unwind_Word *) context->reg[index] = val;
181 /* Retrieve the return address for CONTEXT. */
183 inline _Unwind_Ptr
184 _Unwind_GetIP (struct _Unwind_Context *context)
186 return (_Unwind_Ptr) context->ra;
189 /* Overwrite the return address for CONTEXT with VAL. */
191 inline void
192 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
194 context->ra = (void *) val;
197 void *
198 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
200 return context->lsda;
203 _Unwind_Ptr
204 _Unwind_GetRegionStart (struct _Unwind_Context *context)
206 return (_Unwind_Ptr) context->bases.func;
209 #ifndef __ia64__
210 _Unwind_Ptr
211 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
213 return (_Unwind_Ptr) context->bases.dbase;
216 _Unwind_Ptr
217 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
219 return (_Unwind_Ptr) context->bases.tbase;
221 #endif
223 /* Extract any interesting information from the CIE for the translation
224 unit F belongs to. Return a pointer to the byte after the augmentation,
225 or NULL if we encountered an undecipherable augmentation. */
227 static const unsigned char *
228 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
229 _Unwind_FrameState *fs)
231 const unsigned char *aug = cie->augmentation;
232 const unsigned char *p = aug + strlen (aug) + 1;
233 const unsigned char *ret = NULL;
234 _Unwind_Ptr tmp;
236 /* g++ v2 "eh" has pointer immediately following augmentation string,
237 so it must be handled first. */
238 if (aug[0] == 'e' && aug[1] == 'h')
240 fs->eh_ptr = read_pointer (p);
241 p += sizeof (void *);
242 aug += 2;
245 /* Immediately following the augmentation are the code and
246 data alignment and return address column. */
247 p = read_uleb128 (p, &tmp); fs->code_align = tmp;
248 p = read_sleb128 (p, &tmp); fs->data_align = (saddr) tmp;
249 fs->retaddr_column = *p++;
250 fs->lsda_encoding = DW_EH_PE_omit;
252 /* If the augmentation starts with 'z', then a uleb128 immediately
253 follows containing the length of the augmentation field following
254 the size. */
255 if (*aug == 'z')
257 p = read_uleb128 (p, &tmp);
258 ret = p + tmp;
260 fs->saw_z = 1;
261 ++aug;
264 /* Iterate over recognized augmentation subsequences. */
265 while (*aug != '\0')
267 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
268 if (aug[0] == 'L')
270 fs->lsda_encoding = *p++;
271 aug += 1;
274 /* "R" indicates a byte indicating how FDE addresses are encoded. */
275 else if (aug[0] == 'R')
277 fs->fde_encoding = *p++;
278 aug += 1;
281 /* "P" indicates a personality routine in the CIE augmentation. */
282 else if (aug[0] == 'P')
284 p = read_encoded_value (context, *p, p + 1,
285 (_Unwind_Ptr *) &fs->personality);
286 aug += 1;
289 /* Otherwise we have an unknown augmentation string.
290 Bail unless we saw a 'z' prefix. */
291 else
292 return ret;
295 return ret ? ret : p;
298 #ifndef _LIBC
299 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
300 onto the stack to start. */
302 static _Unwind_Word
303 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
304 struct _Unwind_Context *context, _Unwind_Word initial)
306 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
307 int stack_elt;
309 stack[0] = initial;
310 stack_elt = 1;
312 while (op_ptr < op_end)
314 enum dwarf_location_atom op = *op_ptr++;
315 _Unwind_Word result = 0, reg;
316 _Unwind_Sword offset;
317 _Unwind_Ptr ptrtmp;
319 switch (op)
321 case DW_OP_lit0:
322 case DW_OP_lit1:
323 case DW_OP_lit2:
324 case DW_OP_lit3:
325 case DW_OP_lit4:
326 case DW_OP_lit5:
327 case DW_OP_lit6:
328 case DW_OP_lit7:
329 case DW_OP_lit8:
330 case DW_OP_lit9:
331 case DW_OP_lit10:
332 case DW_OP_lit11:
333 case DW_OP_lit12:
334 case DW_OP_lit13:
335 case DW_OP_lit14:
336 case DW_OP_lit15:
337 case DW_OP_lit16:
338 case DW_OP_lit17:
339 case DW_OP_lit18:
340 case DW_OP_lit19:
341 case DW_OP_lit20:
342 case DW_OP_lit21:
343 case DW_OP_lit22:
344 case DW_OP_lit23:
345 case DW_OP_lit24:
346 case DW_OP_lit25:
347 case DW_OP_lit26:
348 case DW_OP_lit27:
349 case DW_OP_lit28:
350 case DW_OP_lit29:
351 case DW_OP_lit30:
352 case DW_OP_lit31:
353 result = op - DW_OP_lit0;
354 break;
356 case DW_OP_addr:
357 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
358 op_ptr += sizeof (void *);
359 break;
361 case DW_OP_const1u:
362 result = read_1u (op_ptr);
363 op_ptr += 1;
364 break;
365 case DW_OP_const1s:
366 result = read_1s (op_ptr);
367 op_ptr += 1;
368 break;
369 case DW_OP_const2u:
370 result = read_2u (op_ptr);
371 op_ptr += 2;
372 break;
373 case DW_OP_const2s:
374 result = read_2s (op_ptr);
375 op_ptr += 2;
376 break;
377 case DW_OP_const4u:
378 result = read_4u (op_ptr);
379 op_ptr += 4;
380 break;
381 case DW_OP_const4s:
382 result = read_4s (op_ptr);
383 op_ptr += 4;
384 break;
385 case DW_OP_const8u:
386 result = read_8u (op_ptr);
387 op_ptr += 8;
388 break;
389 case DW_OP_const8s:
390 result = read_8s (op_ptr);
391 op_ptr += 8;
392 break;
393 case DW_OP_constu:
394 op_ptr = read_uleb128 (op_ptr, &ptrtmp);
395 result = ptrtmp;
396 break;
397 case DW_OP_consts:
398 op_ptr = read_sleb128 (op_ptr, &ptrtmp);
399 result = (saddr)ptrtmp;
400 break;
402 case DW_OP_reg0:
403 case DW_OP_reg1:
404 case DW_OP_reg2:
405 case DW_OP_reg3:
406 case DW_OP_reg4:
407 case DW_OP_reg5:
408 case DW_OP_reg6:
409 case DW_OP_reg7:
410 case DW_OP_reg8:
411 case DW_OP_reg9:
412 case DW_OP_reg10:
413 case DW_OP_reg11:
414 case DW_OP_reg12:
415 case DW_OP_reg13:
416 case DW_OP_reg14:
417 case DW_OP_reg15:
418 case DW_OP_reg16:
419 case DW_OP_reg17:
420 case DW_OP_reg18:
421 case DW_OP_reg19:
422 case DW_OP_reg20:
423 case DW_OP_reg21:
424 case DW_OP_reg22:
425 case DW_OP_reg23:
426 case DW_OP_reg24:
427 case DW_OP_reg25:
428 case DW_OP_reg26:
429 case DW_OP_reg27:
430 case DW_OP_reg28:
431 case DW_OP_reg29:
432 case DW_OP_reg30:
433 case DW_OP_reg31:
434 result = _Unwind_GetGR (context, op - DW_OP_reg0);
435 break;
436 case DW_OP_regx:
437 op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
438 result = _Unwind_GetGR (context, reg);
439 break;
441 case DW_OP_breg0:
442 case DW_OP_breg1:
443 case DW_OP_breg2:
444 case DW_OP_breg3:
445 case DW_OP_breg4:
446 case DW_OP_breg5:
447 case DW_OP_breg6:
448 case DW_OP_breg7:
449 case DW_OP_breg8:
450 case DW_OP_breg9:
451 case DW_OP_breg10:
452 case DW_OP_breg11:
453 case DW_OP_breg12:
454 case DW_OP_breg13:
455 case DW_OP_breg14:
456 case DW_OP_breg15:
457 case DW_OP_breg16:
458 case DW_OP_breg17:
459 case DW_OP_breg18:
460 case DW_OP_breg19:
461 case DW_OP_breg20:
462 case DW_OP_breg21:
463 case DW_OP_breg22:
464 case DW_OP_breg23:
465 case DW_OP_breg24:
466 case DW_OP_breg25:
467 case DW_OP_breg26:
468 case DW_OP_breg27:
469 case DW_OP_breg28:
470 case DW_OP_breg29:
471 case DW_OP_breg30:
472 case DW_OP_breg31:
473 op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
474 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
475 break;
476 case DW_OP_bregx:
477 op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
478 op_ptr = read_sleb128 (op_ptr, &ptrtmp); offset = (saddr)ptrtmp;
479 result = _Unwind_GetGR (context, reg) + offset;
480 break;
482 case DW_OP_dup:
483 if (stack_elt < 1)
484 abort ();
485 result = stack[stack_elt - 1];
486 break;
488 case DW_OP_drop:
489 if (--stack_elt < 0)
490 abort ();
491 goto no_push;
493 case DW_OP_pick:
494 offset = *op_ptr++;
495 if (offset >= stack_elt - 1)
496 abort ();
497 result = stack[stack_elt - 1 - offset];
498 break;
500 case DW_OP_over:
501 if (stack_elt < 2)
502 abort ();
503 result = stack[stack_elt - 2];
504 break;
506 case DW_OP_rot:
508 _Unwind_Word t1, t2, t3;
510 if (stack_elt < 3)
511 abort ();
512 t1 = stack[stack_elt - 1];
513 t2 = stack[stack_elt - 2];
514 t3 = stack[stack_elt - 3];
515 stack[stack_elt - 1] = t2;
516 stack[stack_elt - 2] = t3;
517 stack[stack_elt - 3] = t1;
518 goto no_push;
521 case DW_OP_deref:
522 case DW_OP_deref_size:
523 case DW_OP_abs:
524 case DW_OP_neg:
525 case DW_OP_not:
526 case DW_OP_plus_uconst:
527 /* Unary operations. */
528 if (--stack_elt < 0)
529 abort ();
530 result = stack[stack_elt];
532 switch (op)
534 case DW_OP_deref:
536 void *ptr = (void *)(_Unwind_Ptr) result;
537 result = (_Unwind_Ptr) read_pointer (ptr);
539 break;
541 case DW_OP_deref_size:
543 void *ptr = (void *)(_Unwind_Ptr) result;
544 switch (*op_ptr++)
546 case 1:
547 result = read_1u (ptr);
548 break;
549 case 2:
550 result = read_2u (ptr);
551 break;
552 case 4:
553 result = read_4u (ptr);
554 break;
555 case 8:
556 result = read_8u (ptr);
557 break;
558 default:
559 abort ();
562 break;
564 case DW_OP_abs:
565 if ((_Unwind_Sword) result < 0)
566 result = -result;
567 break;
568 case DW_OP_neg:
569 result = -result;
570 break;
571 case DW_OP_not:
572 result = ~result;
573 break;
574 case DW_OP_plus_uconst:
575 op_ptr = read_uleb128 (op_ptr, &ptrtmp); reg = ptrtmp;
576 result += reg;
577 break;
578 /* Avoid warnings. */
579 default:
580 break;
582 break;
584 case DW_OP_and:
585 case DW_OP_div:
586 case DW_OP_minus:
587 case DW_OP_mod:
588 case DW_OP_mul:
589 case DW_OP_or:
590 case DW_OP_plus:
591 case DW_OP_le:
592 case DW_OP_ge:
593 case DW_OP_eq:
594 case DW_OP_lt:
595 case DW_OP_gt:
596 case DW_OP_ne:
598 /* Binary operations. */
599 _Unwind_Word first, second;
600 if ((stack_elt -= 2) < 0)
601 abort ();
602 second = stack[stack_elt];
603 first = stack[stack_elt + 1];
605 switch (op)
607 case DW_OP_and:
608 result = second & first;
609 break;
610 case DW_OP_div:
611 result = (_Unwind_Sword)second / (_Unwind_Sword)first;
612 break;
613 case DW_OP_minus:
614 result = second - first;
615 break;
616 case DW_OP_mod:
617 result = (_Unwind_Sword)second % (_Unwind_Sword)first;
618 break;
619 case DW_OP_mul:
620 result = second * first;
621 break;
622 case DW_OP_or:
623 result = second | first;
624 break;
625 case DW_OP_plus:
626 result = second + first;
627 break;
628 case DW_OP_shl:
629 result = second << first;
630 break;
631 case DW_OP_shr:
632 result = second >> first;
633 break;
634 case DW_OP_shra:
635 result = (_Unwind_Sword)second >> first;
636 break;
637 case DW_OP_xor:
638 result = second ^ first;
639 break;
640 case DW_OP_le:
641 result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
642 break;
643 case DW_OP_ge:
644 result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
645 break;
646 case DW_OP_eq:
647 result = (_Unwind_Sword)first == (_Unwind_Sword)second;
648 break;
649 case DW_OP_lt:
650 result = (_Unwind_Sword)first < (_Unwind_Sword)second;
651 break;
652 case DW_OP_gt:
653 result = (_Unwind_Sword)first > (_Unwind_Sword)second;
654 break;
655 case DW_OP_ne:
656 result = (_Unwind_Sword)first != (_Unwind_Sword)second;
657 break;
658 default:
659 /* Avoid warnings. */
660 break;
663 break;
665 case DW_OP_skip:
666 offset = read_2s (op_ptr);
667 op_ptr += 2;
668 op_ptr += offset;
669 goto no_push;
671 case DW_OP_bra:
672 if (--stack_elt < 0)
673 abort ();
674 offset = read_2s (op_ptr);
675 op_ptr += 2;
676 if (stack[stack_elt] != 0)
677 op_ptr += offset;
678 goto no_push;
680 case DW_OP_nop:
681 goto no_push;
683 default:
684 abort ();
687 /* Most things push a result value. */
688 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
689 abort ();
690 stack[++stack_elt] = result;
691 no_push:;
694 /* We were executing this program to get a value. It should be
695 at top of stack. */
696 if (--stack_elt < 0)
697 abort ();
698 return stack[stack_elt];
700 #endif
702 /* Decode DWARF 2 call frame information. Takes pointers the
703 instruction sequence to decode, current register information and
704 CIE info, and the PC range to evaluate. */
706 static void
707 execute_cfa_program (const unsigned char *insn_ptr,
708 const unsigned char *insn_end,
709 struct _Unwind_Context *context,
710 _Unwind_FrameState *fs)
712 struct frame_state_reg_info *unused_rs = NULL;
714 /* Don't allow remember/restore between CIE and FDE programs. */
715 fs->regs.prev = NULL;
717 while (insn_ptr < insn_end && fs->pc < context->ra)
719 unsigned char insn = *insn_ptr++;
720 _Unwind_Word reg;
721 _Unwind_Sword offset;
722 _Unwind_Ptr ptrtmp;
724 if ((insn & 0xc0) == DW_CFA_advance_loc)
725 fs->pc += (insn & 0x3f) * fs->code_align;
726 else if ((insn & 0xc0) == DW_CFA_offset)
728 reg = insn & 0x3f;
729 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
730 offset = ptrtmp * fs->data_align;
731 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
732 fs->regs.reg[reg].loc.offset = offset;
734 else if ((insn & 0xc0) == DW_CFA_restore)
736 reg = insn & 0x3f;
737 fs->regs.reg[reg].how = REG_UNSAVED;
739 else switch (insn)
741 case DW_CFA_set_loc:
742 insn_ptr = read_encoded_value (context, fs->fde_encoding,
743 insn_ptr, (_Unwind_Ptr *) &fs->pc);
744 break;
746 case DW_CFA_advance_loc1:
747 fs->pc += read_1u (insn_ptr) * fs->code_align;
748 insn_ptr += 1;
749 break;
750 case DW_CFA_advance_loc2:
751 fs->pc += read_2u (insn_ptr) * fs->code_align;
752 insn_ptr += 2;
753 break;
754 case DW_CFA_advance_loc4:
755 fs->pc += read_4u (insn_ptr) * fs->code_align;
756 insn_ptr += 4;
757 break;
759 case DW_CFA_offset_extended:
760 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
761 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
762 offset = ptrtmp * fs->data_align;
763 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
764 fs->regs.reg[reg].loc.offset = offset;
765 break;
767 case DW_CFA_restore_extended:
768 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
769 fs->regs.reg[reg].how = REG_UNSAVED;
770 break;
772 case DW_CFA_undefined:
773 case DW_CFA_same_value:
774 case DW_CFA_nop:
775 break;
777 case DW_CFA_register:
779 _Unwind_Word reg2;
780 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
781 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
782 fs->regs.reg[reg].how = REG_SAVED_REG;
783 fs->regs.reg[reg].loc.reg = reg2;
785 break;
787 case DW_CFA_remember_state:
789 struct frame_state_reg_info *new_rs;
790 if (unused_rs)
792 new_rs = unused_rs;
793 unused_rs = unused_rs->prev;
795 else
796 new_rs = alloca (sizeof (struct frame_state_reg_info));
798 *new_rs = fs->regs;
799 fs->regs.prev = new_rs;
801 break;
803 case DW_CFA_restore_state:
805 struct frame_state_reg_info *old_rs = fs->regs.prev;
806 fs->regs = *old_rs;
807 old_rs->prev = unused_rs;
808 unused_rs = old_rs;
810 break;
812 case DW_CFA_def_cfa:
813 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
814 fs->cfa_reg = ptrtmp;
815 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
816 fs->cfa_offset = ptrtmp;
817 fs->cfa_how = CFA_REG_OFFSET;
818 break;
820 case DW_CFA_def_cfa_register:
821 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
822 fs->cfa_reg = ptrtmp;
823 fs->cfa_how = CFA_REG_OFFSET;
824 break;
826 case DW_CFA_def_cfa_offset:
827 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
828 fs->cfa_offset = ptrtmp;
829 /* cfa_how deliberately not set. */
830 break;
832 case DW_CFA_def_cfa_expression:
833 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
834 fs->cfa_exp = insn_ptr;
835 fs->cfa_how = CFA_EXP;
836 insn_ptr += ptrtmp;
837 break;
839 case DW_CFA_expression:
840 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
841 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
842 fs->regs.reg[reg].how = REG_SAVED_EXP;
843 fs->regs.reg[reg].loc.exp = insn_ptr;
844 insn_ptr += ptrtmp;
845 break;
847 /* From the 2.1 draft. */
848 case DW_CFA_offset_extended_sf:
849 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
850 insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
851 offset = (saddr)ptrtmp * fs->data_align;
852 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
853 fs->regs.reg[reg].loc.offset = offset;
854 break;
856 case DW_CFA_def_cfa_sf:
857 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
858 fs->cfa_reg = ptrtmp;
859 insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
860 fs->cfa_offset = (saddr)ptrtmp;
861 fs->cfa_how = CFA_REG_OFFSET;
862 break;
864 case DW_CFA_def_cfa_offset_sf:
865 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
866 fs->cfa_offset = ptrtmp;
867 /* cfa_how deliberately not set. */
868 break;
870 case DW_CFA_GNU_window_save:
871 /* ??? Hardcoded for SPARC register window configuration. */
872 for (reg = 16; reg < 32; ++reg)
874 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
875 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
877 break;
879 case DW_CFA_GNU_args_size:
880 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
881 context->args_size = ptrtmp;
882 break;
884 case DW_CFA_GNU_negative_offset_extended:
885 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
886 older PowerPC code. */
887 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
888 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
889 offset = ptrtmp * fs->data_align;
890 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
891 fs->regs.reg[reg].loc.offset = -offset;
892 break;
894 default:
895 abort ();
900 static _Unwind_Reason_Code
901 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
903 struct dwarf_fde *fde;
904 struct dwarf_cie *cie;
905 const unsigned char *aug, *insn, *end;
907 memset (fs, 0, sizeof (*fs));
908 context->args_size = 0;
909 context->lsda = 0;
911 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
912 if (fde == NULL)
914 /* Couldn't find frame unwind info for this function. Try a
915 target-specific fallback mechanism. This will necessarily
916 not profide a personality routine or LSDA. */
917 #ifdef MD_FALLBACK_FRAME_STATE_FOR
918 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
919 return _URC_END_OF_STACK;
920 success:
921 return _URC_NO_REASON;
922 #else
923 return _URC_END_OF_STACK;
924 #endif
927 fs->pc = context->bases.func;
929 cie = get_cie (fde);
930 insn = extract_cie_info (cie, context, fs);
931 if (insn == NULL)
932 /* CIE contained unknown augmentation. */
933 return _URC_FATAL_PHASE1_ERROR;
935 /* First decode all the insns in the CIE. */
936 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
937 execute_cfa_program (insn, end, context, fs);
939 /* Locate augmentation for the fde. */
940 aug = (unsigned char *)fde + sizeof (*fde);
941 aug += 2 * size_of_encoded_value (fs->fde_encoding);
942 insn = NULL;
943 if (fs->saw_z)
945 _Unwind_Ptr i;
946 aug = read_uleb128 (aug, &i);
947 insn = aug + i;
949 if (fs->lsda_encoding != DW_EH_PE_omit)
950 aug = read_encoded_value (context, fs->lsda_encoding, aug,
951 (_Unwind_Ptr *) &context->lsda);
953 /* Then the insns in the FDE up to our target PC. */
954 if (insn == NULL)
955 insn = aug;
956 end = (unsigned char *) next_fde (fde);
957 execute_cfa_program (insn, end, context, fs);
959 return _URC_NO_REASON;
962 typedef struct frame_state
964 void *cfa;
965 void *eh_ptr;
966 long cfa_offset;
967 long args_size;
968 long reg_or_offset[DWARF_FRAME_REGISTERS+1];
969 unsigned short cfa_reg;
970 unsigned short retaddr_column;
971 char saved[DWARF_FRAME_REGISTERS+1];
972 } frame_state;
974 struct frame_state * __frame_state_for (void *, struct frame_state *);
976 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
977 a given PC_TARGET. The caller should allocate a local variable of
978 `struct frame_state' and pass its address to STATE_IN. */
980 struct frame_state *
981 __frame_state_for (void *pc_target, struct frame_state *state_in)
983 struct _Unwind_Context context;
984 _Unwind_FrameState fs;
985 int reg;
987 memset (&context, 0, sizeof (struct _Unwind_Context));
988 context.ra = pc_target + 1;
990 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
991 return 0;
993 /* We have no way to pass a location expression for the CFA to our
994 caller. It wouldn't understand it anyway. */
995 if (fs.cfa_how == CFA_EXP)
996 return 0;
998 for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++)
1000 state_in->saved[reg] = fs.regs.reg[reg].how;
1001 switch (state_in->saved[reg])
1003 case REG_SAVED_REG:
1004 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1005 break;
1006 case REG_SAVED_OFFSET:
1007 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1008 break;
1009 default:
1010 state_in->reg_or_offset[reg] = 0;
1011 break;
1015 state_in->cfa_offset = fs.cfa_offset;
1016 state_in->cfa_reg = fs.cfa_reg;
1017 state_in->retaddr_column = fs.retaddr_column;
1018 state_in->args_size = context.args_size;
1019 state_in->eh_ptr = fs.eh_ptr;
1021 return state_in;
1024 #ifndef _LIBC
1026 static void
1027 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1029 struct _Unwind_Context orig_context = *context;
1030 void *cfa;
1031 long i;
1033 /* Compute this frame's CFA. */
1034 switch (fs->cfa_how)
1036 case CFA_REG_OFFSET:
1037 /* Special handling here: Many machines do not use a frame pointer,
1038 and track the CFA only through offsets from the stack pointer from
1039 one frame to the next. In this case, the stack pointer is never
1040 stored, so it has no saved address in the context. What we do
1041 have is the CFA from the previous stack frame. */
1042 if (context->reg[fs->cfa_reg] == NULL)
1043 cfa = context->cfa;
1044 else
1045 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1046 cfa += fs->cfa_offset;
1047 break;
1049 case CFA_EXP:
1050 /* ??? No way of knowing what register number is the stack pointer
1051 to do the same sort of handling as above. Assume that if the
1052 CFA calculation is so complicated as to require a stack program
1053 that this will not be a problem. */
1055 const unsigned char *exp = fs->cfa_exp;
1056 _Unwind_Ptr len;
1058 exp = read_uleb128 (exp, &len);
1059 cfa = (void *) (_Unwind_Ptr)
1060 execute_stack_op (exp, exp + len, context, 0);
1061 break;
1064 default:
1065 abort ();
1067 context->cfa = cfa;
1069 /* Compute the addresses of all registers saved in this frame. */
1070 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1071 switch (fs->regs.reg[i].how)
1073 case REG_UNSAVED:
1074 break;
1075 case REG_SAVED_OFFSET:
1076 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1077 break;
1078 case REG_SAVED_REG:
1079 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1080 break;
1081 case REG_SAVED_EXP:
1083 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1084 _Unwind_Ptr len;
1085 _Unwind_Ptr val;
1087 exp = read_uleb128 (exp, &len);
1088 val = execute_stack_op (exp, exp + len, &orig_context,
1089 (_Unwind_Ptr) cfa);
1090 context->reg[i] = (void *) val;
1092 break;
1096 static void
1097 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1099 uw_update_context_1 (context, fs);
1101 /* Compute the return address now, since the return address column
1102 can change from frame to frame. */
1103 context->ra = __builtin_extract_return_addr
1104 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1107 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1108 level will be the return address and the CFA. */
1110 #define uw_init_context(CONTEXT) \
1111 do { \
1112 /* Do any necessary initialization to access arbitrary stack frames. \
1113 On the SPARC, this means flushing the register windows. */ \
1114 __builtin_unwind_init (); \
1115 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1116 __builtin_return_address (0)); \
1117 } while (0)
1119 static void
1120 uw_init_context_1 (struct _Unwind_Context *context,
1121 void *outer_cfa, void *outer_ra)
1123 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1124 _Unwind_FrameState fs;
1126 memset (context, 0, sizeof (struct _Unwind_Context));
1127 context->ra = ra;
1129 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1130 abort ();
1132 /* Force the frame state to use the known cfa value. */
1133 context->cfa = outer_cfa;
1134 fs.cfa_how = CFA_REG_OFFSET;
1135 fs.cfa_reg = 0;
1136 fs.cfa_offset = 0;
1138 uw_update_context_1 (context, &fs);
1140 /* If the return address column was saved in a register in the
1141 initialization context, then we can't see it in the given
1142 call frame data. So have the initialization context tell us. */
1143 context->ra = __builtin_extract_return_addr (outer_ra);
1147 /* Install TARGET into CURRENT so that we can return to it. This is a
1148 macro because __builtin_eh_return must be invoked in the context of
1149 our caller. */
1151 #define uw_install_context(CURRENT, TARGET) \
1152 do { \
1153 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1154 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1155 __builtin_eh_return (offset, handler); \
1156 } while (0)
1158 static inline void
1159 init_dwarf_reg_size_table (void)
1161 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1164 static long
1165 uw_install_context_1 (struct _Unwind_Context *current,
1166 struct _Unwind_Context *target)
1168 long i;
1170 #if __GTHREADS
1172 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1173 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1174 || dwarf_reg_size_table[0] == 0)
1175 init_dwarf_reg_size_table ();
1177 #else
1178 if (dwarf_reg_size_table[0] == 0)
1179 init_dwarf_reg_size_table ();
1180 #endif
1182 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1184 void *c = current->reg[i];
1185 void *t = target->reg[i];
1186 if (t && c && t != c)
1187 memcpy (c, t, dwarf_reg_size_table[i]);
1190 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1191 if (STACK_GROWS_DOWNWARD)
1192 return target->cfa - current->cfa + target->args_size;
1193 else
1194 return current->cfa - target->cfa - target->args_size;
1197 static inline _Unwind_Ptr
1198 uw_identify_context (struct _Unwind_Context *context)
1200 return _Unwind_GetIP (context);
1204 #include "unwind.inc"
1206 #endif /* _LIBC */
1207 #endif /* !USING_SJLJ_EXCEPTIONS */