* xref.c (FILE_NAME_ABSOLUTE_P): Add parenthesis.
[official-gcc.git] / gcc / unwind-dw2.c
blobef9b33bddbf33497a5304d6b7c7a78d0026fe621
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 GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 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 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include "tconfig.h"
22 #include "tsystem.h"
23 #include "dwarf2.h"
24 #include "unwind.h"
25 #include "unwind-pe.h"
26 #include "unwind-dw2-fde.h"
27 #include "gthr.h"
30 #if !USING_SJLJ_EXCEPTIONS
32 #ifndef STACK_GROWS_DOWNWARD
33 #define STACK_GROWS_DOWNWARD 0
34 #else
35 #undef STACK_GROWS_DOWNWARD
36 #define STACK_GROWS_DOWNWARD 1
37 #endif
39 /* A target can override (perhaps for backward compatibility) how
40 many dwarf2 columns are unwound. */
41 #ifndef DWARF_FRAME_REGISTERS
42 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
43 #endif
45 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
46 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
47 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
48 #endif
50 /* This is the register and unwind state for a particular frame. */
51 struct _Unwind_Context
53 void *reg[DWARF_FRAME_REGISTERS+1];
54 void *cfa;
55 void *ra;
56 void *lsda;
57 struct dwarf_eh_bases bases;
58 _Unwind_Word args_size;
61 /* Byte size of every register managed by these routines. */
62 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
65 /* The result of interpreting the frame unwind info for a frame.
66 This is all symbolic at this point, as none of the values can
67 be resolved until the target pc is located. */
68 typedef struct
70 /* Each register save state can be described in terms of a CFA slot,
71 another register, or a location expression. */
72 struct frame_state_reg_info
74 struct {
75 union {
76 _Unwind_Word reg;
77 _Unwind_Sword offset;
78 const unsigned char *exp;
79 } loc;
80 enum {
81 REG_UNSAVED,
82 REG_SAVED_OFFSET,
83 REG_SAVED_REG,
84 REG_SAVED_EXP,
85 } how;
86 } reg[DWARF_FRAME_REGISTERS+1];
88 /* Used to implement DW_CFA_remember_state. */
89 struct frame_state_reg_info *prev;
90 } regs;
92 /* The CFA can be described in terms of a reg+offset or a
93 location expression. */
94 _Unwind_Sword cfa_offset;
95 _Unwind_Word cfa_reg;
96 const unsigned char *cfa_exp;
97 enum {
98 CFA_UNSET,
99 CFA_REG_OFFSET,
100 CFA_EXP,
101 } cfa_how;
103 /* The PC described by the current frame state. */
104 void *pc;
106 /* The information we care about from the CIE/FDE. */
107 _Unwind_Personality_Fn personality;
108 _Unwind_Sword data_align;
109 _Unwind_Word code_align;
110 unsigned char retaddr_column;
111 unsigned char fde_encoding;
112 unsigned char lsda_encoding;
113 unsigned char saw_z;
114 void *eh_ptr;
115 } _Unwind_FrameState;
117 /* Read unaligned data from the instruction buffer. */
119 union unaligned
121 void *p;
122 unsigned u2 __attribute__ ((mode (HI)));
123 unsigned u4 __attribute__ ((mode (SI)));
124 unsigned u8 __attribute__ ((mode (DI)));
125 signed s2 __attribute__ ((mode (HI)));
126 signed s4 __attribute__ ((mode (SI)));
127 signed s8 __attribute__ ((mode (DI)));
128 } __attribute__ ((packed));
130 static inline void *
131 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
133 static inline int
134 read_1u (const void *p) { return *(const unsigned char *)p; }
136 static inline int
137 read_1s (const void *p) { return *(const signed char *)p; }
139 static inline int
140 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
142 static inline int
143 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
145 static inline unsigned int
146 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
148 static inline int
149 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
151 static inline unsigned long
152 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
154 static inline unsigned long
155 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
157 /* Get the value of register REG as saved in CONTEXT. */
159 inline _Unwind_Word
160 _Unwind_GetGR (struct _Unwind_Context *context, int index)
162 /* This will segfault if the register hasn't been saved. */
163 return * (_Unwind_Word *) context->reg[index];
166 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
168 inline void
169 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
171 * (_Unwind_Word *) context->reg[index] = val;
174 /* Retrieve the return address for CONTEXT. */
176 inline _Unwind_Ptr
177 _Unwind_GetIP (struct _Unwind_Context *context)
179 return (_Unwind_Ptr) context->ra;
182 /* Overwrite the return address for CONTEXT with VAL. */
184 inline void
185 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
187 context->ra = (void *) val;
190 void *
191 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
193 return context->lsda;
196 _Unwind_Ptr
197 _Unwind_GetRegionStart (struct _Unwind_Context *context)
199 return (_Unwind_Ptr) context->bases.func;
202 #ifndef __ia64__
203 _Unwind_Ptr
204 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
206 return (_Unwind_Ptr) context->bases.dbase;
209 _Unwind_Ptr
210 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
212 return (_Unwind_Ptr) context->bases.tbase;
214 #endif
216 /* Extract any interesting information from the CIE for the translation
217 unit F belongs to. Return a pointer to the byte after the augmentation,
218 or NULL if we encountered an undecipherable augmentation. */
220 static const unsigned char *
221 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
222 _Unwind_FrameState *fs)
224 const unsigned char *aug = cie->augmentation;
225 const unsigned char *p = aug + strlen (aug) + 1;
226 const unsigned char *ret = NULL;
227 _Unwind_Word utmp;
229 /* g++ v2 "eh" has pointer immediately following augmentation string,
230 so it must be handled first. */
231 if (aug[0] == 'e' && aug[1] == 'h')
233 fs->eh_ptr = read_pointer (p);
234 p += sizeof (void *);
235 aug += 2;
238 /* Immediately following the augmentation are the code and
239 data alignment and return address column. */
240 p = read_uleb128 (p, &fs->code_align);
241 p = read_sleb128 (p, &fs->data_align);
242 fs->retaddr_column = *p++;
243 fs->lsda_encoding = DW_EH_PE_omit;
245 /* If the augmentation starts with 'z', then a uleb128 immediately
246 follows containing the length of the augmentation field following
247 the size. */
248 if (*aug == 'z')
250 p = read_uleb128 (p, &utmp);
251 ret = p + utmp;
253 fs->saw_z = 1;
254 ++aug;
257 /* Iterate over recognized augmentation subsequences. */
258 while (*aug != '\0')
260 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
261 if (aug[0] == 'L')
263 fs->lsda_encoding = *p++;
264 aug += 1;
267 /* "R" indicates a byte indicating how FDE addresses are encoded. */
268 else if (aug[0] == 'R')
270 fs->fde_encoding = *p++;
271 aug += 1;
274 /* "P" indicates a personality routine in the CIE augmentation. */
275 else if (aug[0] == 'P')
277 p = read_encoded_value (context, *p, p + 1,
278 (_Unwind_Ptr *) &fs->personality);
279 aug += 1;
282 /* Otherwise we have an unknown augmentation string.
283 Bail unless we saw a 'z' prefix. */
284 else
285 return ret;
288 return ret ? ret : p;
292 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
293 onto the stack to start. */
295 static _Unwind_Word
296 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
297 struct _Unwind_Context *context, _Unwind_Word initial)
299 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
300 int stack_elt;
302 stack[0] = initial;
303 stack_elt = 1;
305 while (op_ptr < op_end)
307 enum dwarf_location_atom op = *op_ptr++;
308 _Unwind_Word result, reg, utmp;
309 _Unwind_Sword offset, stmp;
311 switch (op)
313 case DW_OP_lit0:
314 case DW_OP_lit1:
315 case DW_OP_lit2:
316 case DW_OP_lit3:
317 case DW_OP_lit4:
318 case DW_OP_lit5:
319 case DW_OP_lit6:
320 case DW_OP_lit7:
321 case DW_OP_lit8:
322 case DW_OP_lit9:
323 case DW_OP_lit10:
324 case DW_OP_lit11:
325 case DW_OP_lit12:
326 case DW_OP_lit13:
327 case DW_OP_lit14:
328 case DW_OP_lit15:
329 case DW_OP_lit16:
330 case DW_OP_lit17:
331 case DW_OP_lit18:
332 case DW_OP_lit19:
333 case DW_OP_lit20:
334 case DW_OP_lit21:
335 case DW_OP_lit22:
336 case DW_OP_lit23:
337 case DW_OP_lit24:
338 case DW_OP_lit25:
339 case DW_OP_lit26:
340 case DW_OP_lit27:
341 case DW_OP_lit28:
342 case DW_OP_lit29:
343 case DW_OP_lit30:
344 case DW_OP_lit31:
345 result = op - DW_OP_lit0;
346 break;
348 case DW_OP_addr:
349 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
350 op_ptr += sizeof (void *);
351 break;
353 case DW_OP_const1u:
354 result = read_1u (op_ptr);
355 op_ptr += 1;
356 break;
357 case DW_OP_const1s:
358 result = read_1s (op_ptr);
359 op_ptr += 1;
360 break;
361 case DW_OP_const2u:
362 result = read_2u (op_ptr);
363 op_ptr += 2;
364 break;
365 case DW_OP_const2s:
366 result = read_2s (op_ptr);
367 op_ptr += 2;
368 break;
369 case DW_OP_const4u:
370 result = read_4u (op_ptr);
371 op_ptr += 4;
372 break;
373 case DW_OP_const4s:
374 result = read_4s (op_ptr);
375 op_ptr += 4;
376 break;
377 case DW_OP_const8u:
378 result = read_8u (op_ptr);
379 op_ptr += 8;
380 break;
381 case DW_OP_const8s:
382 result = read_8s (op_ptr);
383 op_ptr += 8;
384 break;
385 case DW_OP_constu:
386 op_ptr = read_uleb128 (op_ptr, &result);
387 break;
388 case DW_OP_consts:
389 op_ptr = read_sleb128 (op_ptr, &stmp);
390 result = stmp;
391 break;
393 case DW_OP_reg0:
394 case DW_OP_reg1:
395 case DW_OP_reg2:
396 case DW_OP_reg3:
397 case DW_OP_reg4:
398 case DW_OP_reg5:
399 case DW_OP_reg6:
400 case DW_OP_reg7:
401 case DW_OP_reg8:
402 case DW_OP_reg9:
403 case DW_OP_reg10:
404 case DW_OP_reg11:
405 case DW_OP_reg12:
406 case DW_OP_reg13:
407 case DW_OP_reg14:
408 case DW_OP_reg15:
409 case DW_OP_reg16:
410 case DW_OP_reg17:
411 case DW_OP_reg18:
412 case DW_OP_reg19:
413 case DW_OP_reg20:
414 case DW_OP_reg21:
415 case DW_OP_reg22:
416 case DW_OP_reg23:
417 case DW_OP_reg24:
418 case DW_OP_reg25:
419 case DW_OP_reg26:
420 case DW_OP_reg27:
421 case DW_OP_reg28:
422 case DW_OP_reg29:
423 case DW_OP_reg30:
424 case DW_OP_reg31:
425 result = _Unwind_GetGR (context, op - DW_OP_reg0);
426 break;
427 case DW_OP_regx:
428 op_ptr = read_uleb128 (op_ptr, &reg);
429 result = _Unwind_GetGR (context, reg);
430 break;
432 case DW_OP_breg0:
433 case DW_OP_breg1:
434 case DW_OP_breg2:
435 case DW_OP_breg3:
436 case DW_OP_breg4:
437 case DW_OP_breg5:
438 case DW_OP_breg6:
439 case DW_OP_breg7:
440 case DW_OP_breg8:
441 case DW_OP_breg9:
442 case DW_OP_breg10:
443 case DW_OP_breg11:
444 case DW_OP_breg12:
445 case DW_OP_breg13:
446 case DW_OP_breg14:
447 case DW_OP_breg15:
448 case DW_OP_breg16:
449 case DW_OP_breg17:
450 case DW_OP_breg18:
451 case DW_OP_breg19:
452 case DW_OP_breg20:
453 case DW_OP_breg21:
454 case DW_OP_breg22:
455 case DW_OP_breg23:
456 case DW_OP_breg24:
457 case DW_OP_breg25:
458 case DW_OP_breg26:
459 case DW_OP_breg27:
460 case DW_OP_breg28:
461 case DW_OP_breg29:
462 case DW_OP_breg30:
463 case DW_OP_breg31:
464 op_ptr = read_sleb128 (op_ptr, &offset);
465 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
466 break;
467 case DW_OP_bregx:
468 op_ptr = read_uleb128 (op_ptr, &reg);
469 op_ptr = read_sleb128 (op_ptr, &offset);
470 result = _Unwind_GetGR (context, reg) + offset;
471 break;
473 case DW_OP_dup:
474 if (stack_elt < 1)
475 abort ();
476 result = stack[stack_elt - 1];
477 break;
479 case DW_OP_drop:
480 if (--stack_elt < 0)
481 abort ();
482 goto no_push;
484 case DW_OP_pick:
485 offset = *op_ptr++;
486 if (offset >= stack_elt - 1)
487 abort ();
488 result = stack[stack_elt - 1 - offset];
489 break;
491 case DW_OP_over:
492 if (stack_elt < 2)
493 abort ();
494 result = stack[stack_elt - 2];
495 break;
497 case DW_OP_rot:
499 _Unwind_Word t1, t2, t3;
501 if (stack_elt < 3)
502 abort ();
503 t1 = stack[stack_elt - 1];
504 t2 = stack[stack_elt - 2];
505 t3 = stack[stack_elt - 3];
506 stack[stack_elt - 1] = t2;
507 stack[stack_elt - 2] = t3;
508 stack[stack_elt - 3] = t1;
509 goto no_push;
512 case DW_OP_deref:
513 case DW_OP_deref_size:
514 case DW_OP_abs:
515 case DW_OP_neg:
516 case DW_OP_not:
517 case DW_OP_plus_uconst:
518 /* Unary operations. */
519 if (--stack_elt < 0)
520 abort ();
521 result = stack[stack_elt];
523 switch (op)
525 case DW_OP_deref:
527 void *ptr = (void *)(_Unwind_Ptr) result;
528 result = (_Unwind_Ptr) read_pointer (ptr);
530 break;
532 case DW_OP_deref_size:
534 void *ptr = (void *)(_Unwind_Ptr) result;
535 switch (*op_ptr++)
537 case 1:
538 result = read_1u (ptr);
539 break;
540 case 2:
541 result = read_2u (ptr);
542 break;
543 case 4:
544 result = read_4u (ptr);
545 break;
546 case 8:
547 result = read_8u (ptr);
548 break;
549 default:
550 abort ();
553 break;
555 case DW_OP_abs:
556 if ((_Unwind_Sword) result < 0)
557 result = -result;
558 break;
559 case DW_OP_neg:
560 result = -result;
561 break;
562 case DW_OP_not:
563 result = ~result;
564 break;
565 case DW_OP_plus_uconst:
566 op_ptr = read_uleb128 (op_ptr, &utmp);
567 result += utmp;
568 break;
570 default:
571 abort ();
573 break;
575 case DW_OP_and:
576 case DW_OP_div:
577 case DW_OP_minus:
578 case DW_OP_mod:
579 case DW_OP_mul:
580 case DW_OP_or:
581 case DW_OP_plus:
582 case DW_OP_le:
583 case DW_OP_ge:
584 case DW_OP_eq:
585 case DW_OP_lt:
586 case DW_OP_gt:
587 case DW_OP_ne:
589 /* Binary operations. */
590 _Unwind_Word first, second;
591 if ((stack_elt -= 2) < 0)
592 abort ();
593 second = stack[stack_elt];
594 first = stack[stack_elt + 1];
596 switch (op)
598 case DW_OP_and:
599 result = second & first;
600 break;
601 case DW_OP_div:
602 result = (_Unwind_Sword)second / (_Unwind_Sword)first;
603 break;
604 case DW_OP_minus:
605 result = second - first;
606 break;
607 case DW_OP_mod:
608 result = (_Unwind_Sword)second % (_Unwind_Sword)first;
609 break;
610 case DW_OP_mul:
611 result = second * first;
612 break;
613 case DW_OP_or:
614 result = second | first;
615 break;
616 case DW_OP_plus:
617 result = second + first;
618 break;
619 case DW_OP_shl:
620 result = second << first;
621 break;
622 case DW_OP_shr:
623 result = second >> first;
624 break;
625 case DW_OP_shra:
626 result = (_Unwind_Sword)second >> first;
627 break;
628 case DW_OP_xor:
629 result = second ^ first;
630 break;
631 case DW_OP_le:
632 result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
633 break;
634 case DW_OP_ge:
635 result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
636 break;
637 case DW_OP_eq:
638 result = (_Unwind_Sword)first == (_Unwind_Sword)second;
639 break;
640 case DW_OP_lt:
641 result = (_Unwind_Sword)first < (_Unwind_Sword)second;
642 break;
643 case DW_OP_gt:
644 result = (_Unwind_Sword)first > (_Unwind_Sword)second;
645 break;
646 case DW_OP_ne:
647 result = (_Unwind_Sword)first != (_Unwind_Sword)second;
648 break;
650 default:
651 abort ();
654 break;
656 case DW_OP_skip:
657 offset = read_2s (op_ptr);
658 op_ptr += 2;
659 op_ptr += offset;
660 goto no_push;
662 case DW_OP_bra:
663 if (--stack_elt < 0)
664 abort ();
665 offset = read_2s (op_ptr);
666 op_ptr += 2;
667 if (stack[stack_elt] != 0)
668 op_ptr += offset;
669 goto no_push;
671 case DW_OP_nop:
672 goto no_push;
674 default:
675 abort ();
678 /* Most things push a result value. */
679 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
680 abort ();
681 stack[++stack_elt] = result;
682 no_push:;
685 /* We were executing this program to get a value. It should be
686 at top of stack. */
687 if (--stack_elt < 0)
688 abort ();
689 return stack[stack_elt];
693 /* Decode DWARF 2 call frame information. Takes pointers the
694 instruction sequence to decode, current register information and
695 CIE info, and the PC range to evaluate. */
697 static void
698 execute_cfa_program (const unsigned char *insn_ptr,
699 const unsigned char *insn_end,
700 struct _Unwind_Context *context,
701 _Unwind_FrameState *fs)
703 struct frame_state_reg_info *unused_rs = NULL;
705 /* Don't allow remember/restore between CIE and FDE programs. */
706 fs->regs.prev = NULL;
708 /* The comparison with the return address uses < rather than <= because
709 we are only interested in the effects of code before the call; for a
710 noreturn function, the return address may point to unrelated code with
711 a different stack configuration that we are not interested in. We
712 assume that the call itself is unwind info-neutral; if not, or if
713 there are delay instructions that adjust the stack, these must be
714 reflected at the point immediately before the call insn. */
715 while (insn_ptr < insn_end && fs->pc < context->ra)
717 unsigned char insn = *insn_ptr++;
718 _Unwind_Word reg, utmp;
719 _Unwind_Sword offset, stmp;
721 if ((insn & 0xc0) == DW_CFA_advance_loc)
722 fs->pc += (insn & 0x3f) * fs->code_align;
723 else if ((insn & 0xc0) == DW_CFA_offset)
725 reg = insn & 0x3f;
726 insn_ptr = read_uleb128 (insn_ptr, &utmp);
727 offset = (_Unwind_Sword)utmp * fs->data_align;
728 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
729 fs->regs.reg[reg].loc.offset = offset;
731 else if ((insn & 0xc0) == DW_CFA_restore)
733 reg = insn & 0x3f;
734 fs->regs.reg[reg].how = REG_UNSAVED;
736 else switch (insn)
738 case DW_CFA_set_loc:
739 insn_ptr = read_encoded_value (context, fs->fde_encoding,
740 insn_ptr, (_Unwind_Ptr *) &fs->pc);
741 break;
743 case DW_CFA_advance_loc1:
744 fs->pc += read_1u (insn_ptr) * fs->code_align;
745 insn_ptr += 1;
746 break;
747 case DW_CFA_advance_loc2:
748 fs->pc += read_2u (insn_ptr) * fs->code_align;
749 insn_ptr += 2;
750 break;
751 case DW_CFA_advance_loc4:
752 fs->pc += read_4u (insn_ptr) * fs->code_align;
753 insn_ptr += 4;
754 break;
756 case DW_CFA_offset_extended:
757 insn_ptr = read_uleb128 (insn_ptr, &reg);
758 insn_ptr = read_uleb128 (insn_ptr, &utmp);
759 offset = (_Unwind_Sword)utmp * fs->data_align;
760 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
761 fs->regs.reg[reg].loc.offset = offset;
762 break;
764 case DW_CFA_restore_extended:
765 insn_ptr = read_uleb128 (insn_ptr, &reg);
766 fs->regs.reg[reg].how = REG_UNSAVED;
767 break;
769 case DW_CFA_undefined:
770 case DW_CFA_same_value:
771 case DW_CFA_nop:
772 break;
774 case DW_CFA_register:
776 _Unwind_Word reg2;
777 insn_ptr = read_uleb128 (insn_ptr, &reg);
778 insn_ptr = read_uleb128 (insn_ptr, &reg2);
779 fs->regs.reg[reg].how = REG_SAVED_REG;
780 fs->regs.reg[reg].loc.reg = reg2;
782 break;
784 case DW_CFA_remember_state:
786 struct frame_state_reg_info *new_rs;
787 if (unused_rs)
789 new_rs = unused_rs;
790 unused_rs = unused_rs->prev;
792 else
793 new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
795 *new_rs = fs->regs;
796 fs->regs.prev = new_rs;
798 break;
800 case DW_CFA_restore_state:
802 struct frame_state_reg_info *old_rs = fs->regs.prev;
803 fs->regs = *old_rs;
804 old_rs->prev = unused_rs;
805 unused_rs = old_rs;
807 break;
809 case DW_CFA_def_cfa:
810 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
811 insn_ptr = read_uleb128 (insn_ptr, &utmp);
812 fs->cfa_offset = utmp;
813 fs->cfa_how = CFA_REG_OFFSET;
814 break;
816 case DW_CFA_def_cfa_register:
817 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
818 fs->cfa_how = CFA_REG_OFFSET;
819 break;
821 case DW_CFA_def_cfa_offset:
822 insn_ptr = read_uleb128 (insn_ptr, &utmp);
823 fs->cfa_offset = utmp;
824 /* cfa_how deliberately not set. */
825 break;
827 case DW_CFA_def_cfa_expression:
828 insn_ptr = read_uleb128 (insn_ptr, &utmp);
829 fs->cfa_exp = insn_ptr;
830 fs->cfa_how = CFA_EXP;
831 insn_ptr += utmp;
832 break;
834 case DW_CFA_expression:
835 insn_ptr = read_uleb128 (insn_ptr, &reg);
836 insn_ptr = read_uleb128 (insn_ptr, &utmp);
837 fs->regs.reg[reg].how = REG_SAVED_EXP;
838 fs->regs.reg[reg].loc.exp = insn_ptr;
839 insn_ptr += utmp;
840 break;
842 /* From the 2.1 draft. */
843 case DW_CFA_offset_extended_sf:
844 insn_ptr = read_uleb128 (insn_ptr, &reg);
845 insn_ptr = read_sleb128 (insn_ptr, &stmp);
846 offset = stmp * fs->data_align;
847 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
848 fs->regs.reg[reg].loc.offset = offset;
849 break;
851 case DW_CFA_def_cfa_sf:
852 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
853 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
854 fs->cfa_how = CFA_REG_OFFSET;
855 break;
857 case DW_CFA_def_cfa_offset_sf:
858 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
859 /* cfa_how deliberately not set. */
860 break;
862 case DW_CFA_GNU_window_save:
863 /* ??? Hardcoded for SPARC register window configuration. */
864 for (reg = 16; reg < 32; ++reg)
866 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
867 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
869 break;
871 case DW_CFA_GNU_args_size:
872 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
873 break;
875 case DW_CFA_GNU_negative_offset_extended:
876 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
877 older PowerPC code. */
878 insn_ptr = read_uleb128 (insn_ptr, &reg);
879 insn_ptr = read_uleb128 (insn_ptr, &utmp);
880 offset = (_Unwind_Word)utmp * fs->data_align;
881 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
882 fs->regs.reg[reg].loc.offset = -offset;
883 break;
885 default:
886 abort ();
891 static _Unwind_Reason_Code
892 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
894 struct dwarf_fde *fde;
895 struct dwarf_cie *cie;
896 const unsigned char *aug, *insn, *end;
898 memset (fs, 0, sizeof (*fs));
899 context->args_size = 0;
900 context->lsda = 0;
902 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
903 if (fde == NULL)
905 /* Couldn't find frame unwind info for this function. Try a
906 target-specific fallback mechanism. This will necessarily
907 not provide a personality routine or LSDA. */
908 #ifdef MD_FALLBACK_FRAME_STATE_FOR
909 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
910 return _URC_END_OF_STACK;
911 success:
912 return _URC_NO_REASON;
913 #else
914 return _URC_END_OF_STACK;
915 #endif
918 fs->pc = context->bases.func;
920 cie = get_cie (fde);
921 insn = extract_cie_info (cie, context, fs);
922 if (insn == NULL)
923 /* CIE contained unknown augmentation. */
924 return _URC_FATAL_PHASE1_ERROR;
926 /* First decode all the insns in the CIE. */
927 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
928 execute_cfa_program (insn, end, context, fs);
930 /* Locate augmentation for the fde. */
931 aug = (unsigned char *)fde + sizeof (*fde);
932 aug += 2 * size_of_encoded_value (fs->fde_encoding);
933 insn = NULL;
934 if (fs->saw_z)
936 _Unwind_Word i;
937 aug = read_uleb128 (aug, &i);
938 insn = aug + i;
940 if (fs->lsda_encoding != DW_EH_PE_omit)
941 aug = read_encoded_value (context, fs->lsda_encoding, aug,
942 (_Unwind_Ptr *) &context->lsda);
944 /* Then the insns in the FDE up to our target PC. */
945 if (insn == NULL)
946 insn = aug;
947 end = (unsigned char *) next_fde (fde);
948 execute_cfa_program (insn, end, context, fs);
950 return _URC_NO_REASON;
953 typedef struct frame_state
955 void *cfa;
956 void *eh_ptr;
957 long cfa_offset;
958 long args_size;
959 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
960 unsigned short cfa_reg;
961 unsigned short retaddr_column;
962 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
963 } frame_state;
965 struct frame_state * __frame_state_for (void *, struct frame_state *);
967 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
968 a given PC_TARGET. The caller should allocate a local variable of
969 `struct frame_state' and pass its address to STATE_IN. */
971 struct frame_state *
972 __frame_state_for (void *pc_target, struct frame_state *state_in)
974 struct _Unwind_Context context;
975 _Unwind_FrameState fs;
976 int reg;
978 memset (&context, 0, sizeof (struct _Unwind_Context));
979 context.ra = pc_target + 1;
981 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
982 return 0;
984 /* We have no way to pass a location expression for the CFA to our
985 caller. It wouldn't understand it anyway. */
986 if (fs.cfa_how == CFA_EXP)
987 return 0;
989 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
991 state_in->saved[reg] = fs.regs.reg[reg].how;
992 switch (state_in->saved[reg])
994 case REG_SAVED_REG:
995 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
996 break;
997 case REG_SAVED_OFFSET:
998 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
999 break;
1000 default:
1001 state_in->reg_or_offset[reg] = 0;
1002 break;
1006 state_in->cfa_offset = fs.cfa_offset;
1007 state_in->cfa_reg = fs.cfa_reg;
1008 state_in->retaddr_column = fs.retaddr_column;
1009 state_in->args_size = context.args_size;
1010 state_in->eh_ptr = fs.eh_ptr;
1012 return state_in;
1015 static void
1016 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1018 struct _Unwind_Context orig_context = *context;
1019 void *cfa;
1020 long i;
1022 /* Compute this frame's CFA. */
1023 switch (fs->cfa_how)
1025 case CFA_REG_OFFSET:
1026 /* Special handling here: Many machines do not use a frame pointer,
1027 and track the CFA only through offsets from the stack pointer from
1028 one frame to the next. In this case, the stack pointer is never
1029 stored, so it has no saved address in the context. What we do
1030 have is the CFA from the previous stack frame. */
1031 if (context->reg[fs->cfa_reg] == NULL)
1032 cfa = context->cfa;
1033 else
1034 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1035 cfa += fs->cfa_offset;
1036 break;
1038 case CFA_EXP:
1039 /* ??? No way of knowing what register number is the stack pointer
1040 to do the same sort of handling as above. Assume that if the
1041 CFA calculation is so complicated as to require a stack program
1042 that this will not be a problem. */
1044 const unsigned char *exp = fs->cfa_exp;
1045 _Unwind_Word len;
1047 exp = read_uleb128 (exp, &len);
1048 cfa = (void *) (_Unwind_Ptr)
1049 execute_stack_op (exp, exp + len, context, 0);
1050 break;
1053 default:
1054 abort ();
1056 context->cfa = cfa;
1058 /* Compute the addresses of all registers saved in this frame. */
1059 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1060 switch (fs->regs.reg[i].how)
1062 case REG_UNSAVED:
1063 break;
1064 case REG_SAVED_OFFSET:
1065 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1066 break;
1067 case REG_SAVED_REG:
1068 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1069 break;
1070 case REG_SAVED_EXP:
1072 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1073 _Unwind_Word len;
1074 _Unwind_Ptr val;
1076 exp = read_uleb128 (exp, &len);
1077 val = execute_stack_op (exp, exp + len, &orig_context,
1078 (_Unwind_Ptr) cfa);
1079 context->reg[i] = (void *) val;
1081 break;
1085 static void
1086 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1088 uw_update_context_1 (context, fs);
1090 /* Compute the return address now, since the return address column
1091 can change from frame to frame. */
1092 context->ra = __builtin_extract_return_addr
1093 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1096 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1097 level will be the return address and the CFA. */
1099 #define uw_init_context(CONTEXT) \
1100 do { \
1101 /* Do any necessary initialization to access arbitrary stack frames. \
1102 On the SPARC, this means flushing the register windows. */ \
1103 __builtin_unwind_init (); \
1104 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1105 __builtin_return_address (0)); \
1106 } while (0)
1108 static void
1109 uw_init_context_1 (struct _Unwind_Context *context,
1110 void *outer_cfa, void *outer_ra)
1112 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1113 _Unwind_FrameState fs;
1115 memset (context, 0, sizeof (struct _Unwind_Context));
1116 context->ra = ra;
1118 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1119 abort ();
1121 /* Force the frame state to use the known cfa value. */
1122 context->cfa = outer_cfa;
1123 fs.cfa_how = CFA_REG_OFFSET;
1124 fs.cfa_reg = 0;
1125 fs.cfa_offset = 0;
1127 uw_update_context_1 (context, &fs);
1129 /* If the return address column was saved in a register in the
1130 initialization context, then we can't see it in the given
1131 call frame data. So have the initialization context tell us. */
1132 context->ra = __builtin_extract_return_addr (outer_ra);
1136 /* Install TARGET into CURRENT so that we can return to it. This is a
1137 macro because __builtin_eh_return must be invoked in the context of
1138 our caller. */
1140 #define uw_install_context(CURRENT, TARGET) \
1141 do { \
1142 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1143 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1144 __builtin_eh_return (offset, handler); \
1145 } while (0)
1147 static inline void
1148 init_dwarf_reg_size_table (void)
1150 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1153 static long
1154 uw_install_context_1 (struct _Unwind_Context *current,
1155 struct _Unwind_Context *target)
1157 long i;
1159 #if __GTHREADS
1161 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1162 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1163 || dwarf_reg_size_table[0] == 0)
1164 init_dwarf_reg_size_table ();
1166 #else
1167 if (dwarf_reg_size_table[0] == 0)
1168 init_dwarf_reg_size_table ();
1169 #endif
1171 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1173 void *c = current->reg[i];
1174 void *t = target->reg[i];
1175 if (t && c && t != c)
1176 memcpy (c, t, dwarf_reg_size_table[i]);
1179 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1180 if (STACK_GROWS_DOWNWARD)
1181 return target->cfa - current->cfa + target->args_size;
1182 else
1183 return current->cfa - target->cfa - target->args_size;
1186 static inline _Unwind_Ptr
1187 uw_identify_context (struct _Unwind_Context *context)
1189 return _Unwind_GetIP (context);
1193 #include "unwind.inc"
1195 #endif /* !USING_SJLJ_EXCEPTIONS */