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