]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/unwind-dw2.c
Makefile.in, [...]: replace "GNU CC" with "GCC".
[thirdparty/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 GCC.
5
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.
10
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.
15
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. */
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 default:
568 abort ();
569 }
570 break;
571
572 case DW_OP_and:
573 case DW_OP_div:
574 case DW_OP_minus:
575 case DW_OP_mod:
576 case DW_OP_mul:
577 case DW_OP_or:
578 case DW_OP_plus:
579 case DW_OP_le:
580 case DW_OP_ge:
581 case DW_OP_eq:
582 case DW_OP_lt:
583 case DW_OP_gt:
584 case DW_OP_ne:
585 {
586 /* Binary operations. */
587 _Unwind_Word first, second;
588 if ((stack_elt -= 2) < 0)
589 abort ();
590 second = stack[stack_elt];
591 first = stack[stack_elt + 1];
592
593 switch (op)
594 {
595 case DW_OP_and:
596 result = second & first;
597 break;
598 case DW_OP_div:
599 result = (_Unwind_Sword)second / (_Unwind_Sword)first;
600 break;
601 case DW_OP_minus:
602 result = second - first;
603 break;
604 case DW_OP_mod:
605 result = (_Unwind_Sword)second % (_Unwind_Sword)first;
606 break;
607 case DW_OP_mul:
608 result = second * first;
609 break;
610 case DW_OP_or:
611 result = second | first;
612 break;
613 case DW_OP_plus:
614 result = second + first;
615 break;
616 case DW_OP_shl:
617 result = second << first;
618 break;
619 case DW_OP_shr:
620 result = second >> first;
621 break;
622 case DW_OP_shra:
623 result = (_Unwind_Sword)second >> first;
624 break;
625 case DW_OP_xor:
626 result = second ^ first;
627 break;
628 case DW_OP_le:
629 result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
630 break;
631 case DW_OP_ge:
632 result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
633 break;
634 case DW_OP_eq:
635 result = (_Unwind_Sword)first == (_Unwind_Sword)second;
636 break;
637 case DW_OP_lt:
638 result = (_Unwind_Sword)first < (_Unwind_Sword)second;
639 break;
640 case DW_OP_gt:
641 result = (_Unwind_Sword)first > (_Unwind_Sword)second;
642 break;
643 case DW_OP_ne:
644 result = (_Unwind_Sword)first != (_Unwind_Sword)second;
645 break;
646
647 default:
648 abort ();
649 }
650 }
651 break;
652
653 case DW_OP_skip:
654 offset = read_2s (op_ptr);
655 op_ptr += 2;
656 op_ptr += offset;
657 goto no_push;
658
659 case DW_OP_bra:
660 if (--stack_elt < 0)
661 abort ();
662 offset = read_2s (op_ptr);
663 op_ptr += 2;
664 if (stack[stack_elt] != 0)
665 op_ptr += offset;
666 goto no_push;
667
668 case DW_OP_nop:
669 goto no_push;
670
671 default:
672 abort ();
673 }
674
675 /* Most things push a result value. */
676 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
677 abort ();
678 stack[++stack_elt] = result;
679 no_push:;
680 }
681
682 /* We were executing this program to get a value. It should be
683 at top of stack. */
684 if (--stack_elt < 0)
685 abort ();
686 return stack[stack_elt];
687 }
688
689
690 /* Decode DWARF 2 call frame information. Takes pointers the
691 instruction sequence to decode, current register information and
692 CIE info, and the PC range to evaluate. */
693
694 static void
695 execute_cfa_program (const unsigned char *insn_ptr,
696 const unsigned char *insn_end,
697 struct _Unwind_Context *context,
698 _Unwind_FrameState *fs)
699 {
700 struct frame_state_reg_info *unused_rs = NULL;
701
702 /* Don't allow remember/restore between CIE and FDE programs. */
703 fs->regs.prev = NULL;
704
705 while (insn_ptr < insn_end && fs->pc < context->ra)
706 {
707 unsigned char insn = *insn_ptr++;
708 _Unwind_Word reg;
709 _Unwind_Sword offset;
710 _Unwind_Ptr ptrtmp;
711
712 if (insn & DW_CFA_advance_loc)
713 fs->pc += (insn & 0x3f) * fs->code_align;
714 else if (insn & DW_CFA_offset)
715 {
716 reg = insn & 0x3f;
717 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
718 offset = ptrtmp * fs->data_align;
719 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
720 fs->regs.reg[reg].loc.offset = offset;
721 }
722 else if (insn & DW_CFA_restore)
723 {
724 reg = insn & 0x3f;
725 fs->regs.reg[reg].how = REG_UNSAVED;
726 }
727 else switch (insn)
728 {
729 case DW_CFA_set_loc:
730 insn_ptr = read_encoded_value (context, fs->fde_encoding,
731 insn_ptr, (_Unwind_Ptr *) &fs->pc);
732 break;
733
734 case DW_CFA_advance_loc1:
735 fs->pc += read_1u (insn_ptr) * fs->code_align;
736 insn_ptr += 1;
737 break;
738 case DW_CFA_advance_loc2:
739 fs->pc += read_2u (insn_ptr) * fs->code_align;
740 insn_ptr += 2;
741 break;
742 case DW_CFA_advance_loc4:
743 fs->pc += read_4u (insn_ptr) * fs->code_align;
744 insn_ptr += 4;
745 break;
746
747 case DW_CFA_offset_extended:
748 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
749 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
750 offset = ptrtmp * fs->data_align;
751 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
752 fs->regs.reg[reg].loc.offset = offset;
753 break;
754
755 case DW_CFA_restore_extended:
756 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
757 fs->regs.reg[reg].how = REG_UNSAVED;
758 break;
759
760 case DW_CFA_undefined:
761 case DW_CFA_same_value:
762 case DW_CFA_nop:
763 break;
764
765 case DW_CFA_register:
766 {
767 _Unwind_Word reg2;
768 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
769 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;
770 fs->regs.reg[reg].how = REG_SAVED_REG;
771 fs->regs.reg[reg].loc.reg = reg2;
772 }
773 break;
774
775 case DW_CFA_remember_state:
776 {
777 struct frame_state_reg_info *new_rs;
778 if (unused_rs)
779 {
780 new_rs = unused_rs;
781 unused_rs = unused_rs->prev;
782 }
783 else
784 new_rs = alloca (sizeof (struct frame_state_reg_info));
785
786 *new_rs = fs->regs;
787 fs->regs.prev = new_rs;
788 }
789 break;
790
791 case DW_CFA_restore_state:
792 {
793 struct frame_state_reg_info *old_rs = fs->regs.prev;
794 fs->regs = *old_rs;
795 old_rs->prev = unused_rs;
796 unused_rs = old_rs;
797 }
798 break;
799
800 case DW_CFA_def_cfa:
801 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
802 fs->cfa_reg = ptrtmp;
803 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
804 fs->cfa_offset = ptrtmp;
805 fs->cfa_how = CFA_REG_OFFSET;
806 break;
807
808 case DW_CFA_def_cfa_register:
809 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
810 fs->cfa_reg = ptrtmp;
811 fs->cfa_how = CFA_REG_OFFSET;
812 break;
813
814 case DW_CFA_def_cfa_offset:
815 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
816 fs->cfa_offset = ptrtmp;
817 /* cfa_how deliberately not set. */
818 break;
819
820 case DW_CFA_def_cfa_expression:
821 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
822 fs->cfa_exp = insn_ptr;
823 fs->cfa_how = CFA_EXP;
824 insn_ptr += ptrtmp;
825 break;
826
827 case DW_CFA_expression:
828 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
829 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
830 fs->regs.reg[reg].how = REG_SAVED_EXP;
831 fs->regs.reg[reg].loc.exp = insn_ptr;
832 insn_ptr += ptrtmp;
833 break;
834
835 /* From the 2.1 draft. */
836 case DW_CFA_offset_extended_sf:
837 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
838 insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
839 offset = (saddr)ptrtmp * fs->data_align;
840 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
841 fs->regs.reg[reg].loc.offset = offset;
842 break;
843
844 case DW_CFA_def_cfa_sf:
845 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
846 fs->cfa_reg = ptrtmp;
847 insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);
848 fs->cfa_offset = (saddr)ptrtmp;
849 fs->cfa_how = CFA_REG_OFFSET;
850 break;
851
852 case DW_CFA_def_cfa_offset_sf:
853 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
854 fs->cfa_offset = ptrtmp;
855 /* cfa_how deliberately not set. */
856 break;
857
858 case DW_CFA_GNU_window_save:
859 /* ??? Hardcoded for SPARC register window configuration. */
860 for (reg = 16; reg < 32; ++reg)
861 {
862 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
863 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
864 }
865 break;
866
867 case DW_CFA_GNU_args_size:
868 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
869 context->args_size = ptrtmp;
870 break;
871
872 case DW_CFA_GNU_negative_offset_extended:
873 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
874 older PowerPC code. */
875 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;
876 insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);
877 offset = ptrtmp * fs->data_align;
878 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
879 fs->regs.reg[reg].loc.offset = -offset;
880 break;
881
882 default:
883 abort ();
884 }
885 }
886 }
887 \f
888 static _Unwind_Reason_Code
889 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
890 {
891 struct dwarf_fde *fde;
892 struct dwarf_cie *cie;
893 const unsigned char *aug, *insn, *end;
894
895 memset (fs, 0, sizeof (*fs));
896 context->args_size = 0;
897 context->lsda = 0;
898
899 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
900 if (fde == NULL)
901 {
902 /* Couldn't find frame unwind info for this function. Try a
903 target-specific fallback mechanism. This will necessarily
904 not profide a personality routine or LSDA. */
905 #ifdef MD_FALLBACK_FRAME_STATE_FOR
906 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
907 return _URC_END_OF_STACK;
908 success:
909 return _URC_NO_REASON;
910 #else
911 return _URC_END_OF_STACK;
912 #endif
913 }
914
915 fs->pc = context->bases.func;
916
917 cie = get_cie (fde);
918 insn = extract_cie_info (cie, context, fs);
919 if (insn == NULL)
920 /* CIE contained unknown augmentation. */
921 return _URC_FATAL_PHASE1_ERROR;
922
923 /* First decode all the insns in the CIE. */
924 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
925 execute_cfa_program (insn, end, context, fs);
926
927 /* Locate augmentation for the fde. */
928 aug = (unsigned char *)fde + sizeof (*fde);
929 aug += 2 * size_of_encoded_value (fs->fde_encoding);
930 insn = NULL;
931 if (fs->saw_z)
932 {
933 _Unwind_Ptr i;
934 aug = read_uleb128 (aug, &i);
935 insn = aug + i;
936 }
937 if (fs->lsda_encoding != DW_EH_PE_omit)
938 aug = read_encoded_value (context, fs->lsda_encoding, aug,
939 (_Unwind_Ptr *) &context->lsda);
940
941 /* Then the insns in the FDE up to our target PC. */
942 if (insn == NULL)
943 insn = aug;
944 end = (unsigned char *) next_fde (fde);
945 execute_cfa_program (insn, end, context, fs);
946
947 return _URC_NO_REASON;
948 }
949 \f
950 typedef struct frame_state
951 {
952 void *cfa;
953 void *eh_ptr;
954 long cfa_offset;
955 long args_size;
956 long reg_or_offset[DWARF_FRAME_REGISTERS+1];
957 unsigned short cfa_reg;
958 unsigned short retaddr_column;
959 char saved[DWARF_FRAME_REGISTERS+1];
960 } frame_state;
961
962 struct frame_state * __frame_state_for (void *, struct frame_state *);
963
964 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
965 a given PC_TARGET. The caller should allocate a local variable of
966 `struct frame_state' and pass its address to STATE_IN. */
967
968 struct frame_state *
969 __frame_state_for (void *pc_target, struct frame_state *state_in)
970 {
971 struct _Unwind_Context context;
972 _Unwind_FrameState fs;
973 int reg;
974
975 memset (&context, 0, sizeof (struct _Unwind_Context));
976 context.ra = pc_target + 1;
977
978 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
979 return 0;
980
981 /* We have no way to pass a location expression for the CFA to our
982 caller. It wouldn't understand it anyway. */
983 if (fs.cfa_how == CFA_EXP)
984 return 0;
985
986 for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++)
987 {
988 state_in->saved[reg] = fs.regs.reg[reg].how;
989 switch (state_in->saved[reg])
990 {
991 case REG_SAVED_REG:
992 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
993 break;
994 case REG_SAVED_OFFSET:
995 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
996 break;
997 default:
998 state_in->reg_or_offset[reg] = 0;
999 break;
1000 }
1001 }
1002
1003 state_in->cfa_offset = fs.cfa_offset;
1004 state_in->cfa_reg = fs.cfa_reg;
1005 state_in->retaddr_column = fs.retaddr_column;
1006 state_in->args_size = context.args_size;
1007 state_in->eh_ptr = fs.eh_ptr;
1008
1009 return state_in;
1010 }
1011 \f
1012 static void
1013 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1014 {
1015 struct _Unwind_Context orig_context = *context;
1016 void *cfa;
1017 long i;
1018
1019 /* Compute this frame's CFA. */
1020 switch (fs->cfa_how)
1021 {
1022 case CFA_REG_OFFSET:
1023 /* Special handling here: Many machines do not use a frame pointer,
1024 and track the CFA only through offsets from the stack pointer from
1025 one frame to the next. In this case, the stack pointer is never
1026 stored, so it has no saved address in the context. What we do
1027 have is the CFA from the previous stack frame. */
1028 if (context->reg[fs->cfa_reg] == NULL)
1029 cfa = context->cfa;
1030 else
1031 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1032 cfa += fs->cfa_offset;
1033 break;
1034
1035 case CFA_EXP:
1036 /* ??? No way of knowing what register number is the stack pointer
1037 to do the same sort of handling as above. Assume that if the
1038 CFA calculation is so complicated as to require a stack program
1039 that this will not be a problem. */
1040 {
1041 const unsigned char *exp = fs->cfa_exp;
1042 _Unwind_Ptr len;
1043
1044 exp = read_uleb128 (exp, &len);
1045 cfa = (void *) (_Unwind_Ptr)
1046 execute_stack_op (exp, exp + len, context, 0);
1047 break;
1048 }
1049
1050 default:
1051 abort ();
1052 }
1053 context->cfa = cfa;
1054
1055 /* Compute the addresses of all registers saved in this frame. */
1056 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1057 switch (fs->regs.reg[i].how)
1058 {
1059 case REG_UNSAVED:
1060 break;
1061 case REG_SAVED_OFFSET:
1062 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1063 break;
1064 case REG_SAVED_REG:
1065 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1066 break;
1067 case REG_SAVED_EXP:
1068 {
1069 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1070 _Unwind_Ptr len;
1071 _Unwind_Ptr val;
1072
1073 exp = read_uleb128 (exp, &len);
1074 val = execute_stack_op (exp, exp + len, &orig_context,
1075 (_Unwind_Ptr) cfa);
1076 context->reg[i] = (void *) val;
1077 }
1078 break;
1079 }
1080 }
1081
1082 static void
1083 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1084 {
1085 uw_update_context_1 (context, fs);
1086
1087 /* Compute the return address now, since the return address column
1088 can change from frame to frame. */
1089 context->ra = __builtin_extract_return_addr
1090 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1091 }
1092 \f
1093 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1094 level will be the return address and the CFA. */
1095
1096 #define uw_init_context(CONTEXT) \
1097 do { \
1098 /* Do any necessary initialization to access arbitrary stack frames. \
1099 On the SPARC, this means flushing the register windows. */ \
1100 __builtin_unwind_init (); \
1101 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1102 __builtin_return_address (0)); \
1103 } while (0)
1104
1105 static void
1106 uw_init_context_1 (struct _Unwind_Context *context,
1107 void *outer_cfa, void *outer_ra)
1108 {
1109 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1110 _Unwind_FrameState fs;
1111
1112 memset (context, 0, sizeof (struct _Unwind_Context));
1113 context->ra = ra;
1114
1115 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1116 abort ();
1117
1118 /* Force the frame state to use the known cfa value. */
1119 context->cfa = outer_cfa;
1120 fs.cfa_how = CFA_REG_OFFSET;
1121 fs.cfa_reg = 0;
1122 fs.cfa_offset = 0;
1123
1124 uw_update_context_1 (context, &fs);
1125
1126 /* If the return address column was saved in a register in the
1127 initialization context, then we can't see it in the given
1128 call frame data. So have the initialization context tell us. */
1129 context->ra = __builtin_extract_return_addr (outer_ra);
1130 }
1131
1132
1133 /* Install TARGET into CURRENT so that we can return to it. This is a
1134 macro because __builtin_eh_return must be invoked in the context of
1135 our caller. */
1136
1137 #define uw_install_context(CURRENT, TARGET) \
1138 do { \
1139 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1140 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1141 __builtin_eh_return (offset, handler); \
1142 } while (0)
1143
1144 static inline void
1145 init_dwarf_reg_size_table (void)
1146 {
1147 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1148 }
1149
1150 static long
1151 uw_install_context_1 (struct _Unwind_Context *current,
1152 struct _Unwind_Context *target)
1153 {
1154 long i;
1155
1156 #if __GTHREADS
1157 {
1158 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1159 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1160 || dwarf_reg_size_table[0] == 0)
1161 init_dwarf_reg_size_table ();
1162 }
1163 #else
1164 if (dwarf_reg_size_table[0] == 0)
1165 init_dwarf_reg_size_table ();
1166 #endif
1167
1168 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1169 {
1170 void *c = current->reg[i];
1171 void *t = target->reg[i];
1172 if (t && c && t != c)
1173 memcpy (c, t, dwarf_reg_size_table[i]);
1174 }
1175
1176 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1177 if (STACK_GROWS_DOWNWARD)
1178 return target->cfa - current->cfa + target->args_size;
1179 else
1180 return current->cfa - target->cfa - target->args_size;
1181 }
1182
1183 static inline _Unwind_Ptr
1184 uw_identify_context (struct _Unwind_Context *context)
1185 {
1186 return _Unwind_GetIP (context);
1187 }
1188
1189
1190 #include "unwind.inc"
1191
1192 #endif /* !USING_SJLJ_EXCEPTIONS */