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