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