[BZ #2172]
[glibc.git] / sysdeps / generic / unwind-dw2.c
blob301b53176e380af05d8263749aefcd7daa5c1c61
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005
3 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA. */
22 #ifdef _LIBC
23 #include <stdlib.h>
24 #include <string.h>
25 #include <error.h>
26 #include <libintl.h>
27 #include <dwarf2.h>
28 #include <unwind.h>
29 #include <unwind-pe.h>
30 #include <unwind-dw2-fde.h>
31 #else
32 #include "tconfig.h"
33 #include "tsystem.h"
34 #include "dwarf2.h"
35 #include "unwind.h"
36 #include "unwind-pe.h"
37 #include "unwind-dw2-fde.h"
38 #include "gthr.h"
39 #endif
43 #ifndef STACK_GROWS_DOWNWARD
44 #define STACK_GROWS_DOWNWARD 0
45 #else
46 #undef STACK_GROWS_DOWNWARD
47 #define STACK_GROWS_DOWNWARD 1
48 #endif
50 /* A target can override (perhaps for backward compatibility) how
51 many dwarf2 columns are unwound. */
52 #ifndef DWARF_FRAME_REGISTERS
53 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
54 #endif
56 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
57 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
58 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
59 #endif
61 /* This is the register and unwind state for a particular frame. This
62 provides the information necessary to unwind up past a frame and return
63 to its caller. */
64 struct _Unwind_Context
66 void *reg[DWARF_FRAME_REGISTERS+1];
67 void *cfa;
68 void *ra;
69 void *lsda;
70 struct dwarf_eh_bases bases;
71 _Unwind_Word args_size;
74 #ifndef _LIBC
75 /* Byte size of every register managed by these routines. */
76 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
77 #endif
80 /* The result of interpreting the frame unwind info for a frame.
81 This is all symbolic at this point, as none of the values can
82 be resolved until the target pc is located. */
83 typedef struct
85 /* Each register save state can be described in terms of a CFA slot,
86 another register, or a location expression. */
87 struct frame_state_reg_info
89 struct {
90 union {
91 _Unwind_Word reg;
92 _Unwind_Sword offset;
93 const unsigned char *exp;
94 } loc;
95 enum {
96 REG_UNSAVED,
97 REG_SAVED_OFFSET,
98 REG_SAVED_REG,
99 REG_SAVED_EXP,
100 } how;
101 } reg[DWARF_FRAME_REGISTERS+1];
103 /* Used to implement DW_CFA_remember_state. */
104 struct frame_state_reg_info *prev;
105 } regs;
107 /* The CFA can be described in terms of a reg+offset or a
108 location expression. */
109 _Unwind_Sword cfa_offset;
110 _Unwind_Word cfa_reg;
111 const unsigned char *cfa_exp;
112 enum {
113 CFA_UNSET,
114 CFA_REG_OFFSET,
115 CFA_EXP,
116 } cfa_how;
118 /* The PC described by the current frame state. */
119 void *pc;
121 /* The information we care about from the CIE/FDE. */
122 _Unwind_Personality_Fn personality;
123 _Unwind_Sword data_align;
124 _Unwind_Word code_align;
125 unsigned char retaddr_column;
126 unsigned char fde_encoding;
127 unsigned char lsda_encoding;
128 unsigned char saw_z;
129 void *eh_ptr;
130 } _Unwind_FrameState;
132 /* Read unaligned data from the instruction buffer. */
134 union unaligned
136 void *p;
137 unsigned u2 __attribute__ ((mode (HI)));
138 unsigned u4 __attribute__ ((mode (SI)));
139 unsigned u8 __attribute__ ((mode (DI)));
140 signed s2 __attribute__ ((mode (HI)));
141 signed s4 __attribute__ ((mode (SI)));
142 signed s8 __attribute__ ((mode (DI)));
143 } __attribute__ ((packed));
145 static inline void *
146 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
148 static inline int
149 read_1u (const void *p) { return *(const unsigned char *) p; }
151 static inline int
152 read_1s (const void *p) { return *(const signed char *) p; }
154 static inline int
155 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
157 static inline int
158 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
160 static inline unsigned int
161 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
163 static inline int
164 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
166 static inline unsigned long
167 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
169 static inline unsigned long
170 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
172 /* Get the value of register REG as saved in CONTEXT. */
174 inline _Unwind_Word
175 _Unwind_GetGR (struct _Unwind_Context *context, int index)
177 /* This will segfault if the register hasn't been saved. */
178 return * (_Unwind_Word *) context->reg[index];
181 /* Get the value of the CFA as saved in CONTEXT. */
183 _Unwind_Word
184 _Unwind_GetCFA (struct _Unwind_Context *context)
186 return (_Unwind_Ptr) context->cfa;
189 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
191 inline void
192 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
194 * (_Unwind_Word *) context->reg[index] = val;
197 /* Retrieve the return address for CONTEXT. */
199 inline _Unwind_Ptr
200 _Unwind_GetIP (struct _Unwind_Context *context)
202 return (_Unwind_Ptr) context->ra;
205 /* Overwrite the return address for CONTEXT with VAL. */
207 inline void
208 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
210 context->ra = (void *) val;
213 void *
214 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
216 return context->lsda;
219 _Unwind_Ptr
220 _Unwind_GetRegionStart (struct _Unwind_Context *context)
222 return (_Unwind_Ptr) context->bases.func;
225 void *
226 _Unwind_FindEnclosingFunction (void *pc)
228 struct dwarf_eh_bases bases;
229 struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
230 if (fde)
231 return bases.func;
232 else
233 return NULL;
236 #ifndef __ia64__
237 _Unwind_Ptr
238 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
240 return (_Unwind_Ptr) context->bases.dbase;
243 _Unwind_Ptr
244 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
246 return (_Unwind_Ptr) context->bases.tbase;
248 #endif
250 /* Extract any interesting information from the CIE for the translation
251 unit F belongs to. Return a pointer to the byte after the augmentation,
252 or NULL if we encountered an undecipherable augmentation. */
254 static const unsigned char *
255 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
256 _Unwind_FrameState *fs)
258 const unsigned char *aug = cie->augmentation;
259 const unsigned char *p = aug + strlen ((const char *) aug) + 1;
260 const unsigned char *ret = NULL;
261 _Unwind_Word utmp;
263 /* g++ v2 "eh" has pointer immediately following augmentation string,
264 so it must be handled first. */
265 if (aug[0] == 'e' && aug[1] == 'h')
267 fs->eh_ptr = read_pointer (p);
268 p += sizeof (void *);
269 aug += 2;
272 /* Immediately following the augmentation are the code and
273 data alignment and return address column. */
274 p = read_uleb128 (p, &fs->code_align);
275 p = read_sleb128 (p, &fs->data_align);
276 fs->retaddr_column = *p++;
277 fs->lsda_encoding = DW_EH_PE_omit;
279 /* If the augmentation starts with 'z', then a uleb128 immediately
280 follows containing the length of the augmentation field following
281 the size. */
282 if (*aug == 'z')
284 p = read_uleb128 (p, &utmp);
285 ret = p + utmp;
287 fs->saw_z = 1;
288 ++aug;
291 /* Iterate over recognized augmentation subsequences. */
292 while (*aug != '\0')
294 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
295 if (aug[0] == 'L')
297 fs->lsda_encoding = *p++;
298 aug += 1;
301 /* "R" indicates a byte indicating how FDE addresses are encoded. */
302 else if (aug[0] == 'R')
304 fs->fde_encoding = *p++;
305 aug += 1;
308 /* "P" indicates a personality routine in the CIE augmentation. */
309 else if (aug[0] == 'P')
311 p = read_encoded_value (context, *p, p + 1,
312 (_Unwind_Ptr *) &fs->personality);
313 aug += 1;
316 /* Otherwise we have an unknown augmentation string.
317 Bail unless we saw a 'z' prefix. */
318 else
319 return ret;
322 return ret ? ret : p;
325 #ifndef _LIBC
326 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
327 onto the stack to start. */
329 static _Unwind_Word
330 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
331 struct _Unwind_Context *context, _Unwind_Word initial)
333 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
334 int stack_elt;
336 stack[0] = initial;
337 stack_elt = 1;
339 while (op_ptr < op_end)
341 enum dwarf_location_atom op = *op_ptr++;
342 _Unwind_Word result, reg, utmp;
343 _Unwind_Sword offset, stmp;
345 switch (op)
347 case DW_OP_lit0:
348 case DW_OP_lit1:
349 case DW_OP_lit2:
350 case DW_OP_lit3:
351 case DW_OP_lit4:
352 case DW_OP_lit5:
353 case DW_OP_lit6:
354 case DW_OP_lit7:
355 case DW_OP_lit8:
356 case DW_OP_lit9:
357 case DW_OP_lit10:
358 case DW_OP_lit11:
359 case DW_OP_lit12:
360 case DW_OP_lit13:
361 case DW_OP_lit14:
362 case DW_OP_lit15:
363 case DW_OP_lit16:
364 case DW_OP_lit17:
365 case DW_OP_lit18:
366 case DW_OP_lit19:
367 case DW_OP_lit20:
368 case DW_OP_lit21:
369 case DW_OP_lit22:
370 case DW_OP_lit23:
371 case DW_OP_lit24:
372 case DW_OP_lit25:
373 case DW_OP_lit26:
374 case DW_OP_lit27:
375 case DW_OP_lit28:
376 case DW_OP_lit29:
377 case DW_OP_lit30:
378 case DW_OP_lit31:
379 result = op - DW_OP_lit0;
380 break;
382 case DW_OP_addr:
383 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
384 op_ptr += sizeof (void *);
385 break;
387 case DW_OP_const1u:
388 result = read_1u (op_ptr);
389 op_ptr += 1;
390 break;
391 case DW_OP_const1s:
392 result = read_1s (op_ptr);
393 op_ptr += 1;
394 break;
395 case DW_OP_const2u:
396 result = read_2u (op_ptr);
397 op_ptr += 2;
398 break;
399 case DW_OP_const2s:
400 result = read_2s (op_ptr);
401 op_ptr += 2;
402 break;
403 case DW_OP_const4u:
404 result = read_4u (op_ptr);
405 op_ptr += 4;
406 break;
407 case DW_OP_const4s:
408 result = read_4s (op_ptr);
409 op_ptr += 4;
410 break;
411 case DW_OP_const8u:
412 result = read_8u (op_ptr);
413 op_ptr += 8;
414 break;
415 case DW_OP_const8s:
416 result = read_8s (op_ptr);
417 op_ptr += 8;
418 break;
419 case DW_OP_constu:
420 op_ptr = read_uleb128 (op_ptr, &result);
421 break;
422 case DW_OP_consts:
423 op_ptr = read_sleb128 (op_ptr, &stmp);
424 result = stmp;
425 break;
427 case DW_OP_reg0:
428 case DW_OP_reg1:
429 case DW_OP_reg2:
430 case DW_OP_reg3:
431 case DW_OP_reg4:
432 case DW_OP_reg5:
433 case DW_OP_reg6:
434 case DW_OP_reg7:
435 case DW_OP_reg8:
436 case DW_OP_reg9:
437 case DW_OP_reg10:
438 case DW_OP_reg11:
439 case DW_OP_reg12:
440 case DW_OP_reg13:
441 case DW_OP_reg14:
442 case DW_OP_reg15:
443 case DW_OP_reg16:
444 case DW_OP_reg17:
445 case DW_OP_reg18:
446 case DW_OP_reg19:
447 case DW_OP_reg20:
448 case DW_OP_reg21:
449 case DW_OP_reg22:
450 case DW_OP_reg23:
451 case DW_OP_reg24:
452 case DW_OP_reg25:
453 case DW_OP_reg26:
454 case DW_OP_reg27:
455 case DW_OP_reg28:
456 case DW_OP_reg29:
457 case DW_OP_reg30:
458 case DW_OP_reg31:
459 result = _Unwind_GetGR (context, op - DW_OP_reg0);
460 break;
461 case DW_OP_regx:
462 op_ptr = read_uleb128 (op_ptr, &reg);
463 result = _Unwind_GetGR (context, reg);
464 break;
466 case DW_OP_breg0:
467 case DW_OP_breg1:
468 case DW_OP_breg2:
469 case DW_OP_breg3:
470 case DW_OP_breg4:
471 case DW_OP_breg5:
472 case DW_OP_breg6:
473 case DW_OP_breg7:
474 case DW_OP_breg8:
475 case DW_OP_breg9:
476 case DW_OP_breg10:
477 case DW_OP_breg11:
478 case DW_OP_breg12:
479 case DW_OP_breg13:
480 case DW_OP_breg14:
481 case DW_OP_breg15:
482 case DW_OP_breg16:
483 case DW_OP_breg17:
484 case DW_OP_breg18:
485 case DW_OP_breg19:
486 case DW_OP_breg20:
487 case DW_OP_breg21:
488 case DW_OP_breg22:
489 case DW_OP_breg23:
490 case DW_OP_breg24:
491 case DW_OP_breg25:
492 case DW_OP_breg26:
493 case DW_OP_breg27:
494 case DW_OP_breg28:
495 case DW_OP_breg29:
496 case DW_OP_breg30:
497 case DW_OP_breg31:
498 op_ptr = read_sleb128 (op_ptr, &offset);
499 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
500 break;
501 case DW_OP_bregx:
502 op_ptr = read_uleb128 (op_ptr, &reg);
503 op_ptr = read_sleb128 (op_ptr, &offset);
504 result = _Unwind_GetGR (context, reg) + offset;
505 break;
507 case DW_OP_dup:
508 if (stack_elt < 1)
509 abort ();
510 result = stack[stack_elt - 1];
511 break;
513 case DW_OP_drop:
514 if (--stack_elt < 0)
515 abort ();
516 goto no_push;
518 case DW_OP_pick:
519 offset = *op_ptr++;
520 if (offset >= stack_elt - 1)
521 abort ();
522 result = stack[stack_elt - 1 - offset];
523 break;
525 case DW_OP_over:
526 if (stack_elt < 2)
527 abort ();
528 result = stack[stack_elt - 2];
529 break;
531 case DW_OP_rot:
533 _Unwind_Word t1, t2, t3;
535 if (stack_elt < 3)
536 abort ();
537 t1 = stack[stack_elt - 1];
538 t2 = stack[stack_elt - 2];
539 t3 = stack[stack_elt - 3];
540 stack[stack_elt - 1] = t2;
541 stack[stack_elt - 2] = t3;
542 stack[stack_elt - 3] = t1;
543 goto no_push;
546 case DW_OP_deref:
547 case DW_OP_deref_size:
548 case DW_OP_abs:
549 case DW_OP_neg:
550 case DW_OP_not:
551 case DW_OP_plus_uconst:
552 /* Unary operations. */
553 if (--stack_elt < 0)
554 abort ();
555 result = stack[stack_elt];
557 switch (op)
559 case DW_OP_deref:
561 void *ptr = (void *) (_Unwind_Ptr) result;
562 result = (_Unwind_Ptr) read_pointer (ptr);
564 break;
566 case DW_OP_deref_size:
568 void *ptr = (void *) (_Unwind_Ptr) result;
569 switch (*op_ptr++)
571 case 1:
572 result = read_1u (ptr);
573 break;
574 case 2:
575 result = read_2u (ptr);
576 break;
577 case 4:
578 result = read_4u (ptr);
579 break;
580 case 8:
581 result = read_8u (ptr);
582 break;
583 default:
584 abort ();
587 break;
589 case DW_OP_abs:
590 if ((_Unwind_Sword) result < 0)
591 result = -result;
592 break;
593 case DW_OP_neg:
594 result = -result;
595 break;
596 case DW_OP_not:
597 result = ~result;
598 break;
599 case DW_OP_plus_uconst:
600 op_ptr = read_uleb128 (op_ptr, &utmp);
601 result += utmp;
602 break;
604 default:
605 abort ();
607 break;
609 case DW_OP_and:
610 case DW_OP_div:
611 case DW_OP_minus:
612 case DW_OP_mod:
613 case DW_OP_mul:
614 case DW_OP_or:
615 case DW_OP_plus:
616 case DW_OP_le:
617 case DW_OP_ge:
618 case DW_OP_eq:
619 case DW_OP_lt:
620 case DW_OP_gt:
621 case DW_OP_ne:
623 /* Binary operations. */
624 _Unwind_Word first, second;
625 if ((stack_elt -= 2) < 0)
626 abort ();
627 second = stack[stack_elt];
628 first = stack[stack_elt + 1];
630 switch (op)
632 case DW_OP_and:
633 result = second & first;
634 break;
635 case DW_OP_div:
636 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
637 break;
638 case DW_OP_minus:
639 result = second - first;
640 break;
641 case DW_OP_mod:
642 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
643 break;
644 case DW_OP_mul:
645 result = second * first;
646 break;
647 case DW_OP_or:
648 result = second | first;
649 break;
650 case DW_OP_plus:
651 result = second + first;
652 break;
653 case DW_OP_shl:
654 result = second << first;
655 break;
656 case DW_OP_shr:
657 result = second >> first;
658 break;
659 case DW_OP_shra:
660 result = (_Unwind_Sword) second >> first;
661 break;
662 case DW_OP_xor:
663 result = second ^ first;
664 break;
665 case DW_OP_le:
666 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
667 break;
668 case DW_OP_ge:
669 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
670 break;
671 case DW_OP_eq:
672 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
673 break;
674 case DW_OP_lt:
675 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
676 break;
677 case DW_OP_gt:
678 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
679 break;
680 case DW_OP_ne:
681 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
682 break;
684 default:
685 abort ();
688 break;
690 case DW_OP_skip:
691 offset = read_2s (op_ptr);
692 op_ptr += 2;
693 op_ptr += offset;
694 goto no_push;
696 case DW_OP_bra:
697 if (--stack_elt < 0)
698 abort ();
699 offset = read_2s (op_ptr);
700 op_ptr += 2;
701 if (stack[stack_elt] != 0)
702 op_ptr += offset;
703 goto no_push;
705 case DW_OP_nop:
706 goto no_push;
708 default:
709 abort ();
712 /* Most things push a result value. */
713 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
714 abort ();
715 stack[stack_elt++] = result;
716 no_push:;
719 /* We were executing this program to get a value. It should be
720 at top of stack. */
721 if (--stack_elt < 0)
722 abort ();
723 return stack[stack_elt];
725 #endif
727 /* Decode DWARF 2 call frame information. Takes pointers the
728 instruction sequence to decode, current register information and
729 CIE info, and the PC range to evaluate. */
731 static void
732 execute_cfa_program (const unsigned char *insn_ptr,
733 const unsigned char *insn_end,
734 struct _Unwind_Context *context,
735 _Unwind_FrameState *fs)
737 struct frame_state_reg_info *unused_rs = NULL;
739 /* Don't allow remember/restore between CIE and FDE programs. */
740 fs->regs.prev = NULL;
742 /* The comparison with the return address uses < rather than <= because
743 we are only interested in the effects of code before the call; for a
744 noreturn function, the return address may point to unrelated code with
745 a different stack configuration that we are not interested in. We
746 assume that the call itself is unwind info-neutral; if not, or if
747 there are delay instructions that adjust the stack, these must be
748 reflected at the point immediately before the call insn. */
749 while (insn_ptr < insn_end && fs->pc < context->ra)
751 unsigned char insn = *insn_ptr++;
752 _Unwind_Word reg, utmp;
753 _Unwind_Sword offset, stmp;
755 if ((insn & 0xc0) == DW_CFA_advance_loc)
756 fs->pc += (insn & 0x3f) * fs->code_align;
757 else if ((insn & 0xc0) == DW_CFA_offset)
759 reg = insn & 0x3f;
760 insn_ptr = read_uleb128 (insn_ptr, &utmp);
761 offset = (_Unwind_Sword) utmp * fs->data_align;
762 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
763 fs->regs.reg[reg].loc.offset = offset;
765 else if ((insn & 0xc0) == DW_CFA_restore)
767 reg = insn & 0x3f;
768 fs->regs.reg[reg].how = REG_UNSAVED;
770 else switch (insn)
772 case DW_CFA_set_loc:
773 insn_ptr = read_encoded_value (context, fs->fde_encoding,
774 insn_ptr, (_Unwind_Ptr *) &fs->pc);
775 break;
777 case DW_CFA_advance_loc1:
778 fs->pc += read_1u (insn_ptr) * fs->code_align;
779 insn_ptr += 1;
780 break;
781 case DW_CFA_advance_loc2:
782 fs->pc += read_2u (insn_ptr) * fs->code_align;
783 insn_ptr += 2;
784 break;
785 case DW_CFA_advance_loc4:
786 fs->pc += read_4u (insn_ptr) * fs->code_align;
787 insn_ptr += 4;
788 break;
790 case DW_CFA_offset_extended:
791 insn_ptr = read_uleb128 (insn_ptr, &reg);
792 insn_ptr = read_uleb128 (insn_ptr, &utmp);
793 offset = (_Unwind_Sword) utmp * fs->data_align;
794 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
795 fs->regs.reg[reg].loc.offset = offset;
796 break;
798 case DW_CFA_restore_extended:
799 insn_ptr = read_uleb128 (insn_ptr, &reg);
800 fs->regs.reg[reg].how = REG_UNSAVED;
801 break;
803 case DW_CFA_undefined:
804 case DW_CFA_same_value:
805 insn_ptr = read_uleb128 (insn_ptr, &reg);
806 break;
808 case DW_CFA_nop:
809 break;
811 case DW_CFA_register:
813 _Unwind_Word reg2;
814 insn_ptr = read_uleb128 (insn_ptr, &reg);
815 insn_ptr = read_uleb128 (insn_ptr, &reg2);
816 fs->regs.reg[reg].how = REG_SAVED_REG;
817 fs->regs.reg[reg].loc.reg = reg2;
819 break;
821 case DW_CFA_remember_state:
823 struct frame_state_reg_info *new_rs;
824 if (unused_rs)
826 new_rs = unused_rs;
827 unused_rs = unused_rs->prev;
829 else
830 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
832 *new_rs = fs->regs;
833 fs->regs.prev = new_rs;
835 break;
837 case DW_CFA_restore_state:
839 struct frame_state_reg_info *old_rs = fs->regs.prev;
840 fs->regs = *old_rs;
841 old_rs->prev = unused_rs;
842 unused_rs = old_rs;
844 break;
846 case DW_CFA_def_cfa:
847 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
848 insn_ptr = read_uleb128 (insn_ptr, &utmp);
849 fs->cfa_offset = utmp;
850 fs->cfa_how = CFA_REG_OFFSET;
851 break;
853 case DW_CFA_def_cfa_register:
854 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
855 fs->cfa_how = CFA_REG_OFFSET;
856 break;
858 case DW_CFA_def_cfa_offset:
859 insn_ptr = read_uleb128 (insn_ptr, &utmp);
860 fs->cfa_offset = utmp;
861 /* cfa_how deliberately not set. */
862 break;
864 case DW_CFA_def_cfa_expression:
865 fs->cfa_exp = insn_ptr;
866 fs->cfa_how = CFA_EXP;
867 insn_ptr = read_uleb128 (insn_ptr, &utmp);
868 insn_ptr += utmp;
869 break;
871 case DW_CFA_expression:
872 insn_ptr = read_uleb128 (insn_ptr, &reg);
873 fs->regs.reg[reg].how = REG_SAVED_EXP;
874 fs->regs.reg[reg].loc.exp = insn_ptr;
875 insn_ptr = read_uleb128 (insn_ptr, &utmp);
876 insn_ptr += utmp;
877 break;
879 /* From the 2.1 draft. */
880 case DW_CFA_offset_extended_sf:
881 insn_ptr = read_uleb128 (insn_ptr, &reg);
882 insn_ptr = read_sleb128 (insn_ptr, &stmp);
883 offset = stmp * fs->data_align;
884 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
885 fs->regs.reg[reg].loc.offset = offset;
886 break;
888 case DW_CFA_def_cfa_sf:
889 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
890 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
891 fs->cfa_how = CFA_REG_OFFSET;
892 break;
894 case DW_CFA_def_cfa_offset_sf:
895 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
896 /* cfa_how deliberately not set. */
897 break;
899 case DW_CFA_GNU_window_save:
900 /* ??? Hardcoded for SPARC register window configuration. */
901 for (reg = 16; reg < 32; ++reg)
903 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
904 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
906 break;
908 case DW_CFA_GNU_args_size:
909 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
910 break;
912 case DW_CFA_GNU_negative_offset_extended:
913 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
914 older PowerPC code. */
915 insn_ptr = read_uleb128 (insn_ptr, &reg);
916 insn_ptr = read_uleb128 (insn_ptr, &utmp);
917 offset = (_Unwind_Word) utmp * fs->data_align;
918 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
919 fs->regs.reg[reg].loc.offset = -offset;
920 break;
922 default:
923 abort ();
928 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
929 its caller and decode it into FS. This function also sets the
930 args_size and lsda members of CONTEXT, as they are really information
931 about the caller's frame. */
933 static _Unwind_Reason_Code
934 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
936 struct dwarf_fde *fde;
937 struct dwarf_cie *cie;
938 const unsigned char *aug, *insn, *end;
940 memset (fs, 0, sizeof (*fs));
941 context->args_size = 0;
942 context->lsda = 0;
944 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
945 if (fde == NULL)
947 /* Couldn't find frame unwind info for this function. Try a
948 target-specific fallback mechanism. This will necessarily
949 not provide a personality routine or LSDA. */
950 #ifdef MD_FALLBACK_FRAME_STATE_FOR
951 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
952 return _URC_END_OF_STACK;
953 success:
954 return _URC_NO_REASON;
955 #else
956 return _URC_END_OF_STACK;
957 #endif
960 fs->pc = context->bases.func;
962 cie = get_cie (fde);
963 insn = extract_cie_info (cie, context, fs);
964 if (insn == NULL)
965 /* CIE contained unknown augmentation. */
966 return _URC_FATAL_PHASE1_ERROR;
968 /* First decode all the insns in the CIE. */
969 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
970 execute_cfa_program (insn, end, context, fs);
972 /* Locate augmentation for the fde. */
973 aug = (unsigned char *) fde + sizeof (*fde);
974 aug += 2 * size_of_encoded_value (fs->fde_encoding);
975 insn = NULL;
976 if (fs->saw_z)
978 _Unwind_Word i;
979 aug = read_uleb128 (aug, &i);
980 insn = aug + i;
982 if (fs->lsda_encoding != DW_EH_PE_omit)
983 aug = read_encoded_value (context, fs->lsda_encoding, aug,
984 (_Unwind_Ptr *) &context->lsda);
986 /* Then the insns in the FDE up to our target PC. */
987 if (insn == NULL)
988 insn = aug;
989 end = (unsigned char *) next_fde (fde);
990 execute_cfa_program (insn, end, context, fs);
992 return _URC_NO_REASON;
995 typedef struct frame_state
997 void *cfa;
998 void *eh_ptr;
999 long cfa_offset;
1000 long args_size;
1001 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1002 unsigned short cfa_reg;
1003 unsigned short retaddr_column;
1004 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1005 } frame_state;
1007 #ifndef STATIC
1008 # define STATIC
1009 #endif
1011 STATIC
1012 struct frame_state * __frame_state_for (void *, struct frame_state *);
1014 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1015 a given PC_TARGET. The caller should allocate a local variable of
1016 `struct frame_state' and pass its address to STATE_IN. */
1018 STATIC
1019 struct frame_state *
1020 __frame_state_for (void *pc_target, struct frame_state *state_in)
1022 struct _Unwind_Context context;
1023 _Unwind_FrameState fs;
1024 int reg;
1026 memset (&context, 0, sizeof (struct _Unwind_Context));
1027 context.ra = pc_target + 1;
1029 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1030 return 0;
1032 /* We have no way to pass a location expression for the CFA to our
1033 caller. It wouldn't understand it anyway. */
1034 if (fs.cfa_how == CFA_EXP)
1035 return 0;
1037 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1039 state_in->saved[reg] = fs.regs.reg[reg].how;
1040 switch (state_in->saved[reg])
1042 case REG_SAVED_REG:
1043 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1044 break;
1045 case REG_SAVED_OFFSET:
1046 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1047 break;
1048 default:
1049 state_in->reg_or_offset[reg] = 0;
1050 break;
1054 state_in->cfa_offset = fs.cfa_offset;
1055 state_in->cfa_reg = fs.cfa_reg;
1056 state_in->retaddr_column = fs.retaddr_column;
1057 state_in->args_size = context.args_size;
1058 state_in->eh_ptr = fs.eh_ptr;
1060 return state_in;
1063 #ifndef _LIBC
1065 static void
1066 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1068 struct _Unwind_Context orig_context = *context;
1069 void *cfa;
1070 long i;
1072 #ifdef EH_RETURN_STACKADJ_RTX
1073 /* Special handling here: Many machines do not use a frame pointer,
1074 and track the CFA only through offsets from the stack pointer from
1075 one frame to the next. In this case, the stack pointer is never
1076 stored, so it has no saved address in the context. What we do
1077 have is the CFA from the previous stack frame.
1079 In very special situations (such as unwind info for signal return),
1080 there may be location expressions that use the stack pointer as well.
1082 Do this conditionally for one frame. This allows the unwind info
1083 for one frame to save a copy of the stack pointer from the previous
1084 frame, and be able to use much easier CFA mechanisms to do it.
1085 Always zap the saved stack pointer value for the next frame; carrying
1086 the value over from one frame to another doesn't make sense. */
1088 _Unwind_Word tmp_sp;
1090 if (!orig_context.reg[__builtin_dwarf_sp_column ()])
1092 tmp_sp = (_Unwind_Ptr) context->cfa;
1093 orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
1095 context->reg[__builtin_dwarf_sp_column ()] = NULL;
1096 #endif
1098 /* Compute this frame's CFA. */
1099 switch (fs->cfa_how)
1101 case CFA_REG_OFFSET:
1102 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
1103 cfa += fs->cfa_offset;
1104 break;
1106 case CFA_EXP:
1108 const unsigned char *exp = fs->cfa_exp;
1109 _Unwind_Word len;
1111 exp = read_uleb128 (exp, &len);
1112 cfa = (void *) (_Unwind_Ptr)
1113 execute_stack_op (exp, exp + len, &orig_context, 0);
1114 break;
1117 default:
1118 abort ();
1120 context->cfa = cfa;
1122 /* Compute the addresses of all registers saved in this frame. */
1123 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1124 switch (fs->regs.reg[i].how)
1126 case REG_UNSAVED:
1127 break;
1129 case REG_SAVED_OFFSET:
1130 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1131 break;
1133 case REG_SAVED_REG:
1134 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1135 break;
1137 case REG_SAVED_EXP:
1139 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1140 _Unwind_Word len;
1141 _Unwind_Ptr val;
1143 exp = read_uleb128 (exp, &len);
1144 val = execute_stack_op (exp, exp + len, &orig_context,
1145 (_Unwind_Ptr) cfa);
1146 context->reg[i] = (void *) val;
1148 break;
1152 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1153 of its caller. Update CONTEXT to refer to the caller as well. Note
1154 that the args_size and lsda members are not updated here, but later in
1155 uw_frame_state_for. */
1157 static void
1158 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1160 uw_update_context_1 (context, fs);
1162 /* Compute the return address now, since the return address column
1163 can change from frame to frame. */
1164 context->ra = __builtin_extract_return_addr
1165 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1168 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1169 level will be the return address and the CFA. */
1171 #define uw_init_context(CONTEXT) \
1172 do \
1174 /* Do any necessary initialization to access arbitrary stack frames. \
1175 On the SPARC, this means flushing the register windows. */ \
1176 __builtin_unwind_init (); \
1177 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1178 __builtin_return_address (0)); \
1180 while (0)
1182 static void
1183 uw_init_context_1 (struct _Unwind_Context *context,
1184 void *outer_cfa, void *outer_ra)
1186 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1187 _Unwind_FrameState fs;
1188 _Unwind_Word sp_slot;
1190 memset (context, 0, sizeof (struct _Unwind_Context));
1191 context->ra = ra;
1193 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1194 abort ();
1196 /* Force the frame state to use the known cfa value. */
1197 sp_slot = (_Unwind_Ptr) outer_cfa;
1198 context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
1199 fs.cfa_how = CFA_REG_OFFSET;
1200 fs.cfa_reg = __builtin_dwarf_sp_column ();
1201 fs.cfa_offset = 0;
1203 uw_update_context_1 (context, &fs);
1205 /* If the return address column was saved in a register in the
1206 initialization context, then we can't see it in the given
1207 call frame data. So have the initialization context tell us. */
1208 context->ra = __builtin_extract_return_addr (outer_ra);
1212 /* Install TARGET into CURRENT so that we can return to it. This is a
1213 macro because __builtin_eh_return must be invoked in the context of
1214 our caller. */
1216 #define uw_install_context(CURRENT, TARGET) \
1217 do \
1219 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1220 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1221 __builtin_eh_return (offset, handler); \
1223 while (0)
1225 static inline void
1226 init_dwarf_reg_size_table (void)
1228 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1231 static long
1232 uw_install_context_1 (struct _Unwind_Context *current,
1233 struct _Unwind_Context *target)
1235 long i;
1237 #if __GTHREADS
1239 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1240 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1241 || dwarf_reg_size_table[0] == 0)
1242 init_dwarf_reg_size_table ();
1244 #else
1245 if (dwarf_reg_size_table[0] == 0)
1246 init_dwarf_reg_size_table ();
1247 #endif
1249 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1251 void *c = current->reg[i];
1252 void *t = target->reg[i];
1253 if (t && c && t != c)
1254 memcpy (c, t, dwarf_reg_size_table[i]);
1257 #ifdef EH_RETURN_STACKADJ_RTX
1259 void *target_cfa;
1261 /* If the last frame records a saved stack pointer, use it. */
1262 if (target->reg[__builtin_dwarf_sp_column ()])
1263 target_cfa = (void *)(_Unwind_Ptr)
1264 _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
1265 else
1266 target_cfa = target->cfa;
1268 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1269 if (STACK_GROWS_DOWNWARD)
1270 return target_cfa - current->cfa + target->args_size;
1271 else
1272 return current->cfa - target_cfa - target->args_size;
1274 #else
1275 return 0;
1276 #endif
1279 static inline _Unwind_Ptr
1280 uw_identify_context (struct _Unwind_Context *context)
1282 return _Unwind_GetIP (context);
1286 #include "unwind.inc"
1288 #endif /* _LIBC */