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