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