]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/unwind-dw2.c
re PR fortran/41586 ([OOP] Allocatable _scalars_ are never auto-deallocated)
[thirdparty/gcc.git] / gcc / unwind-dw2.c
CommitLineData
52a11cbf 1/* DWARF2 exception handling and frame unwind runtime interface routines.
66647d44 2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
54f5943c 3 2008, 2009 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
748086b7 9 the Free Software Foundation; either version 3, or (at your option)
52a11cbf
RH
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 16
748086b7
JJ
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
52a11cbf
RH
25
26#include "tconfig.h"
27#include "tsystem.h"
4977bab6
ZW
28#include "coretypes.h"
29#include "tm.h"
a80b0574 30#include "dwarf2.h"
52a11cbf 31#include "unwind.h"
525996eb
KG
32#ifdef __USING_SJLJ_EXCEPTIONS__
33# define NO_SIZE_OF_ENCODED_VALUE
34#endif
e1f9550a 35#include "unwind-pe.h"
52a11cbf
RH
36#include "unwind-dw2-fde.h"
37#include "gthr.h"
f8a57be8 38#include "unwind-dw2.h"
52a11cbf 39
0d24f4d1 40#ifndef __USING_SJLJ_EXCEPTIONS__
52a11cbf
RH
41
42#ifndef STACK_GROWS_DOWNWARD
43#define STACK_GROWS_DOWNWARD 0
44#else
45#undef STACK_GROWS_DOWNWARD
46#define STACK_GROWS_DOWNWARD 1
47#endif
48
919543ab
AH
49/* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
50#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
51#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
52#endif
53
41f3a930
AH
54#ifndef DWARF_REG_TO_UNWIND_COLUMN
55#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
56#endif
57
81a60e6c
JM
58/* This is the register and unwind state for a particular frame. This
59 provides the information necessary to unwind up past a frame and return
60 to its caller. */
52a11cbf
RH
61struct _Unwind_Context
62{
63 void *reg[DWARF_FRAME_REGISTERS+1];
64 void *cfa;
65 void *ra;
66 void *lsda;
67 struct dwarf_eh_bases bases;
f8e7718c
JJ
68 /* Signal frame context. */
69#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
70 /* Context which has version/args_size/by_value fields. */
71#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
72 _Unwind_Word flags;
73 /* 0 for now, can be increased when further fields are added to
74 struct _Unwind_Context. */
75 _Unwind_Word version;
52a11cbf 76 _Unwind_Word args_size;
4469af7a 77 char by_value[DWARF_FRAME_REGISTERS+1];
52a11cbf
RH
78};
79
80/* Byte size of every register managed by these routines. */
ed80cd68 81static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
52a11cbf 82
52a11cbf 83\f
52a11cbf
RH
84/* Read unaligned data from the instruction buffer. */
85
86union unaligned
87{
88 void *p;
89 unsigned u2 __attribute__ ((mode (HI)));
90 unsigned u4 __attribute__ ((mode (SI)));
91 unsigned u8 __attribute__ ((mode (DI)));
92 signed s2 __attribute__ ((mode (HI)));
93 signed s4 __attribute__ ((mode (SI)));
94 signed s8 __attribute__ ((mode (DI)));
95} __attribute__ ((packed));
96
edbaf6a2
JDA
97static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
98static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
99 _Unwind_FrameState *);
100
52a11cbf 101static inline void *
e1f9550a 102read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
52a11cbf
RH
103
104static inline int
e9d1b155 105read_1u (const void *p) { return *(const unsigned char *) p; }
52a11cbf
RH
106
107static inline int
e9d1b155 108read_1s (const void *p) { return *(const signed char *) p; }
52a11cbf
RH
109
110static inline int
e1f9550a 111read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
52a11cbf
RH
112
113static inline int
e1f9550a 114read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
52a11cbf
RH
115
116static inline unsigned int
e1f9550a 117read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
52a11cbf
RH
118
119static inline int
e1f9550a 120read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
52a11cbf
RH
121
122static inline unsigned long
e1f9550a 123read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
52a11cbf
RH
124
125static inline unsigned long
e1f9550a 126read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
52a11cbf 127\f
f8e7718c
JJ
128static inline _Unwind_Word
129_Unwind_IsSignalFrame (struct _Unwind_Context *context)
130{
131 return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
132}
133
134static inline void
135_Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
136{
137 if (val)
138 context->flags |= SIGNAL_FRAME_BIT;
139 else
140 context->flags &= ~SIGNAL_FRAME_BIT;
141}
142
143static inline _Unwind_Word
144_Unwind_IsExtendedContext (struct _Unwind_Context *context)
145{
146 return context->flags & EXTENDED_CONTEXT_BIT;
147}
148\f
4469af7a 149/* Get the value of register INDEX as saved in CONTEXT. */
52a11cbf
RH
150
151inline _Unwind_Word
152_Unwind_GetGR (struct _Unwind_Context *context, int index)
153{
71628aa0
R
154 int size;
155 void *ptr;
156
282efe1c
RH
157#ifdef DWARF_ZERO_REG
158 if (index == DWARF_ZERO_REG)
159 return 0;
160#endif
161
41f3a930 162 index = DWARF_REG_TO_UNWIND_COLUMN (index);
79d0dfa3 163 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
71628aa0
R
164 size = dwarf_reg_size_table[index];
165 ptr = context->reg[index];
166
f8e7718c 167 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
4469af7a
JJ
168 return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
169
52a11cbf 170 /* This will segfault if the register hasn't been saved. */
71628aa0
R
171 if (size == sizeof(_Unwind_Ptr))
172 return * (_Unwind_Ptr *) ptr;
79d0dfa3
NS
173 else
174 {
175 gcc_assert (size == sizeof(_Unwind_Word));
176 return * (_Unwind_Word *) ptr;
177 }
71628aa0
R
178}
179
180static inline void *
181_Unwind_GetPtr (struct _Unwind_Context *context, int index)
182{
183 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
52a11cbf
RH
184}
185
378683cf
RH
186/* Get the value of the CFA as saved in CONTEXT. */
187
188_Unwind_Word
189_Unwind_GetCFA (struct _Unwind_Context *context)
190{
9330e977 191 return (_Unwind_Ptr) context->cfa;
378683cf
RH
192}
193
4469af7a 194/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
52a11cbf
RH
195
196inline void
197_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
198{
71628aa0
R
199 int size;
200 void *ptr;
201
41f3a930 202 index = DWARF_REG_TO_UNWIND_COLUMN (index);
79d0dfa3 203 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
71628aa0 204 size = dwarf_reg_size_table[index];
4469af7a 205
f8e7718c 206 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
4469af7a
JJ
207 {
208 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
209 return;
210 }
211
71628aa0
R
212 ptr = context->reg[index];
213
214 if (size == sizeof(_Unwind_Ptr))
215 * (_Unwind_Ptr *) ptr = val;
71628aa0 216 else
79d0dfa3
NS
217 {
218 gcc_assert (size == sizeof(_Unwind_Word));
219 * (_Unwind_Word *) ptr = val;
220 }
52a11cbf
RH
221}
222
41f3a930
AH
223/* Get the pointer to a register INDEX as saved in CONTEXT. */
224
225static inline void *
226_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
227{
228 index = DWARF_REG_TO_UNWIND_COLUMN (index);
f8e7718c 229 if (_Unwind_IsExtendedContext (context) && context->by_value[index])
4469af7a 230 return &context->reg[index];
41f3a930
AH
231 return context->reg[index];
232}
233
234/* Set the pointer to a register INDEX as saved in CONTEXT. */
235
236static inline void
237_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
238{
239 index = DWARF_REG_TO_UNWIND_COLUMN (index);
f8e7718c
JJ
240 if (_Unwind_IsExtendedContext (context))
241 context->by_value[index] = 0;
41f3a930
AH
242 context->reg[index] = p;
243}
244
4469af7a
JJ
245/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
246
247static inline void
248_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
249 _Unwind_Word val)
250{
251 index = DWARF_REG_TO_UNWIND_COLUMN (index);
252 gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
253 gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
254
255 context->by_value[index] = 1;
256 context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
257}
258
c0220ea4 259/* Return nonzero if register INDEX is stored by value rather than
4469af7a
JJ
260 by reference. */
261
262static inline int
263_Unwind_GRByValue (struct _Unwind_Context *context, int index)
264{
265 index = DWARF_REG_TO_UNWIND_COLUMN (index);
266 return context->by_value[index];
267}
268
52a11cbf
RH
269/* Retrieve the return address for CONTEXT. */
270
271inline _Unwind_Ptr
272_Unwind_GetIP (struct _Unwind_Context *context)
273{
274 return (_Unwind_Ptr) context->ra;
275}
276
754e45a8
JJ
277/* Retrieve the return address and flag whether that IP is before
278 or after first not yet fully executed instruction. */
279
280inline _Unwind_Ptr
281_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
282{
f8e7718c 283 *ip_before_insn = _Unwind_IsSignalFrame (context);
754e45a8
JJ
284 return (_Unwind_Ptr) context->ra;
285}
286
52a11cbf
RH
287/* Overwrite the return address for CONTEXT with VAL. */
288
289inline void
290_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
291{
292 context->ra = (void *) val;
293}
294
295void *
296_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
297{
298 return context->lsda;
299}
300
301_Unwind_Ptr
302_Unwind_GetRegionStart (struct _Unwind_Context *context)
303{
304 return (_Unwind_Ptr) context->bases.func;
305}
306
5dafd282 307void *
5154b05d 308_Unwind_FindEnclosingFunction (void *pc)
5dafd282
AH
309{
310 struct dwarf_eh_bases bases;
f1518966 311 const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
5dafd282
AH
312 if (fde)
313 return bases.func;
314 else
315 return NULL;
316}
317
2a1ee410
RH
318#ifndef __ia64__
319_Unwind_Ptr
320_Unwind_GetDataRelBase (struct _Unwind_Context *context)
321{
322 return (_Unwind_Ptr) context->bases.dbase;
323}
324
325_Unwind_Ptr
326_Unwind_GetTextRelBase (struct _Unwind_Context *context)
327{
328 return (_Unwind_Ptr) context->bases.tbase;
329}
330#endif
8662eb14
AM
331
332#ifdef MD_UNWIND_SUPPORT
333#include MD_UNWIND_SUPPORT
334#endif
52a11cbf
RH
335\f
336/* Extract any interesting information from the CIE for the translation
337 unit F belongs to. Return a pointer to the byte after the augmentation,
338 or NULL if we encountered an undecipherable augmentation. */
339
e1f9550a 340static const unsigned char *
f1518966 341extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
52a11cbf
RH
342 _Unwind_FrameState *fs)
343{
e1f9550a 344 const unsigned char *aug = cie->augmentation;
ca29916b 345 const unsigned char *p = aug + strlen ((const char *)aug) + 1;
e1f9550a 346 const unsigned char *ret = NULL;
f767122b
AK
347 _uleb128_t utmp;
348 _sleb128_t stmp;
52a11cbf 349
5442cf15
MK
350 /* g++ v2 "eh" has pointer immediately following augmentation string,
351 so it must be handled first. */
352 if (aug[0] == 'e' && aug[1] == 'h')
353 {
354 fs->eh_ptr = read_pointer (p);
355 p += sizeof (void *);
356 aug += 2;
357 }
358
52a11cbf
RH
359 /* Immediately following the augmentation are the code and
360 data alignment and return address column. */
f767122b
AK
361 p = read_uleb128 (p, &utmp);
362 fs->code_align = (_Unwind_Word)utmp;
363 p = read_sleb128 (p, &stmp);
364 fs->data_align = (_Unwind_Sword)stmp;
0ef54a47
PB
365 if (cie->version == 1)
366 fs->retaddr_column = *p++;
367 else
f767122b
AK
368 {
369 p = read_uleb128 (p, &utmp);
370 fs->retaddr_column = (_Unwind_Word)utmp;
371 }
e1f9550a 372 fs->lsda_encoding = DW_EH_PE_omit;
52a11cbf
RH
373
374 /* If the augmentation starts with 'z', then a uleb128 immediately
375 follows containing the length of the augmentation field following
376 the size. */
377 if (*aug == 'z')
378 {
a9985a92
JM
379 p = read_uleb128 (p, &utmp);
380 ret = p + utmp;
52a11cbf
RH
381
382 fs->saw_z = 1;
383 ++aug;
384 }
385
386 /* Iterate over recognized augmentation subsequences. */
387 while (*aug != '\0')
388 {
e1f9550a 389 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
5442cf15 390 if (aug[0] == 'L')
e1f9550a
RH
391 {
392 fs->lsda_encoding = *p++;
393 aug += 1;
394 }
395
396 /* "R" indicates a byte indicating how FDE addresses are encoded. */
52a11cbf
RH
397 else if (aug[0] == 'R')
398 {
e1f9550a 399 fs->fde_encoding = *p++;
52a11cbf
RH
400 aug += 1;
401 }
402
e1f9550a 403 /* "P" indicates a personality routine in the CIE augmentation. */
52a11cbf
RH
404 else if (aug[0] == 'P')
405 {
950ccbc4
NS
406 _Unwind_Ptr personality;
407
408 p = read_encoded_value (context, *p, p + 1, &personality);
409 fs->personality = (_Unwind_Personality_Fn) personality;
52a11cbf
RH
410 aug += 1;
411 }
412
754e45a8
JJ
413 /* "S" indicates a signal frame. */
414 else if (aug[0] == 'S')
415 {
416 fs->signal_frame = 1;
417 aug += 1;
418 }
419
52a11cbf
RH
420 /* Otherwise we have an unknown augmentation string.
421 Bail unless we saw a 'z' prefix. */
422 else
423 return ret;
424 }
425
426 return ret ? ret : p;
427}
428
429
430/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
431 onto the stack to start. */
432
433static _Unwind_Word
e1f9550a 434execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
52a11cbf
RH
435 struct _Unwind_Context *context, _Unwind_Word initial)
436{
2d76cb1a 437 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
52a11cbf
RH
438 int stack_elt;
439
440 stack[0] = initial;
441 stack_elt = 1;
442
443 while (op_ptr < op_end)
444 {
445 enum dwarf_location_atom op = *op_ptr++;
f767122b
AK
446 _Unwind_Word result;
447 _uleb128_t reg, utmp;
448 _sleb128_t offset, stmp;
52a11cbf
RH
449
450 switch (op)
451 {
452 case DW_OP_lit0:
453 case DW_OP_lit1:
454 case DW_OP_lit2:
455 case DW_OP_lit3:
456 case DW_OP_lit4:
457 case DW_OP_lit5:
458 case DW_OP_lit6:
459 case DW_OP_lit7:
460 case DW_OP_lit8:
461 case DW_OP_lit9:
462 case DW_OP_lit10:
463 case DW_OP_lit11:
464 case DW_OP_lit12:
465 case DW_OP_lit13:
466 case DW_OP_lit14:
467 case DW_OP_lit15:
468 case DW_OP_lit16:
469 case DW_OP_lit17:
470 case DW_OP_lit18:
471 case DW_OP_lit19:
472 case DW_OP_lit20:
473 case DW_OP_lit21:
474 case DW_OP_lit22:
475 case DW_OP_lit23:
476 case DW_OP_lit24:
477 case DW_OP_lit25:
478 case DW_OP_lit26:
479 case DW_OP_lit27:
480 case DW_OP_lit28:
481 case DW_OP_lit29:
482 case DW_OP_lit30:
483 case DW_OP_lit31:
484 result = op - DW_OP_lit0;
485 break;
486
487 case DW_OP_addr:
488 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
489 op_ptr += sizeof (void *);
490 break;
491
b5e9dce1
RH
492 case DW_OP_GNU_encoded_addr:
493 {
494 _Unwind_Ptr presult;
495 op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
496 result = presult;
497 }
498 break;
499
52a11cbf
RH
500 case DW_OP_const1u:
501 result = read_1u (op_ptr);
502 op_ptr += 1;
503 break;
504 case DW_OP_const1s:
505 result = read_1s (op_ptr);
506 op_ptr += 1;
507 break;
508 case DW_OP_const2u:
509 result = read_2u (op_ptr);
510 op_ptr += 2;
511 break;
512 case DW_OP_const2s:
513 result = read_2s (op_ptr);
514 op_ptr += 2;
515 break;
516 case DW_OP_const4u:
517 result = read_4u (op_ptr);
518 op_ptr += 4;
519 break;
520 case DW_OP_const4s:
521 result = read_4s (op_ptr);
522 op_ptr += 4;
523 break;
524 case DW_OP_const8u:
525 result = read_8u (op_ptr);
526 op_ptr += 8;
527 break;
528 case DW_OP_const8s:
529 result = read_8s (op_ptr);
530 op_ptr += 8;
531 break;
532 case DW_OP_constu:
f767122b
AK
533 op_ptr = read_uleb128 (op_ptr, &utmp);
534 result = (_Unwind_Word)utmp;
52a11cbf
RH
535 break;
536 case DW_OP_consts:
a9985a92 537 op_ptr = read_sleb128 (op_ptr, &stmp);
f767122b 538 result = (_Unwind_Sword)stmp;
52a11cbf
RH
539 break;
540
541 case DW_OP_reg0:
542 case DW_OP_reg1:
543 case DW_OP_reg2:
544 case DW_OP_reg3:
545 case DW_OP_reg4:
546 case DW_OP_reg5:
547 case DW_OP_reg6:
548 case DW_OP_reg7:
549 case DW_OP_reg8:
550 case DW_OP_reg9:
551 case DW_OP_reg10:
552 case DW_OP_reg11:
553 case DW_OP_reg12:
554 case DW_OP_reg13:
555 case DW_OP_reg14:
556 case DW_OP_reg15:
557 case DW_OP_reg16:
558 case DW_OP_reg17:
559 case DW_OP_reg18:
560 case DW_OP_reg19:
561 case DW_OP_reg20:
562 case DW_OP_reg21:
563 case DW_OP_reg22:
564 case DW_OP_reg23:
565 case DW_OP_reg24:
566 case DW_OP_reg25:
567 case DW_OP_reg26:
568 case DW_OP_reg27:
569 case DW_OP_reg28:
570 case DW_OP_reg29:
571 case DW_OP_reg30:
572 case DW_OP_reg31:
573 result = _Unwind_GetGR (context, op - DW_OP_reg0);
574 break;
575 case DW_OP_regx:
a9985a92 576 op_ptr = read_uleb128 (op_ptr, &reg);
52a11cbf
RH
577 result = _Unwind_GetGR (context, reg);
578 break;
579
580 case DW_OP_breg0:
581 case DW_OP_breg1:
582 case DW_OP_breg2:
583 case DW_OP_breg3:
584 case DW_OP_breg4:
585 case DW_OP_breg5:
586 case DW_OP_breg6:
587 case DW_OP_breg7:
588 case DW_OP_breg8:
589 case DW_OP_breg9:
590 case DW_OP_breg10:
591 case DW_OP_breg11:
592 case DW_OP_breg12:
593 case DW_OP_breg13:
594 case DW_OP_breg14:
595 case DW_OP_breg15:
596 case DW_OP_breg16:
597 case DW_OP_breg17:
598 case DW_OP_breg18:
599 case DW_OP_breg19:
600 case DW_OP_breg20:
601 case DW_OP_breg21:
602 case DW_OP_breg22:
603 case DW_OP_breg23:
604 case DW_OP_breg24:
605 case DW_OP_breg25:
606 case DW_OP_breg26:
607 case DW_OP_breg27:
608 case DW_OP_breg28:
609 case DW_OP_breg29:
610 case DW_OP_breg30:
611 case DW_OP_breg31:
a9985a92 612 op_ptr = read_sleb128 (op_ptr, &offset);
52a11cbf
RH
613 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
614 break;
615 case DW_OP_bregx:
a9985a92
JM
616 op_ptr = read_uleb128 (op_ptr, &reg);
617 op_ptr = read_sleb128 (op_ptr, &offset);
f767122b 618 result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
52a11cbf
RH
619 break;
620
621 case DW_OP_dup:
79d0dfa3 622 gcc_assert (stack_elt);
52a11cbf
RH
623 result = stack[stack_elt - 1];
624 break;
625
626 case DW_OP_drop:
79d0dfa3
NS
627 gcc_assert (stack_elt);
628 stack_elt -= 1;
52a11cbf
RH
629 goto no_push;
630
631 case DW_OP_pick:
632 offset = *op_ptr++;
79d0dfa3 633 gcc_assert (offset < stack_elt - 1);
52a11cbf
RH
634 result = stack[stack_elt - 1 - offset];
635 break;
636
637 case DW_OP_over:
79d0dfa3 638 gcc_assert (stack_elt >= 2);
52a11cbf
RH
639 result = stack[stack_elt - 2];
640 break;
641
9dc5c4f5
GK
642 case DW_OP_swap:
643 {
644 _Unwind_Word t;
645 gcc_assert (stack_elt >= 2);
646 t = stack[stack_elt - 1];
647 stack[stack_elt - 1] = stack[stack_elt - 2];
648 stack[stack_elt - 2] = t;
649 goto no_push;
650 }
651
52a11cbf
RH
652 case DW_OP_rot:
653 {
654 _Unwind_Word t1, t2, t3;
655
79d0dfa3 656 gcc_assert (stack_elt >= 3);
52a11cbf
RH
657 t1 = stack[stack_elt - 1];
658 t2 = stack[stack_elt - 2];
659 t3 = stack[stack_elt - 3];
660 stack[stack_elt - 1] = t2;
661 stack[stack_elt - 2] = t3;
662 stack[stack_elt - 3] = t1;
663 goto no_push;
664 }
665
666 case DW_OP_deref:
667 case DW_OP_deref_size:
668 case DW_OP_abs:
669 case DW_OP_neg:
670 case DW_OP_not:
671 case DW_OP_plus_uconst:
672 /* Unary operations. */
79d0dfa3
NS
673 gcc_assert (stack_elt);
674 stack_elt -= 1;
675
52a11cbf
RH
676 result = stack[stack_elt];
677
678 switch (op)
679 {
680 case DW_OP_deref:
681 {
a01da83b 682 void *ptr = (void *) (_Unwind_Ptr) result;
52a11cbf
RH
683 result = (_Unwind_Ptr) read_pointer (ptr);
684 }
685 break;
686
687 case DW_OP_deref_size:
688 {
a01da83b 689 void *ptr = (void *) (_Unwind_Ptr) result;
52a11cbf
RH
690 switch (*op_ptr++)
691 {
692 case 1:
693 result = read_1u (ptr);
694 break;
695 case 2:
696 result = read_2u (ptr);
697 break;
698 case 4:
699 result = read_4u (ptr);
700 break;
701 case 8:
702 result = read_8u (ptr);
703 break;
704 default:
79d0dfa3 705 gcc_unreachable ();
52a11cbf
RH
706 }
707 }
708 break;
709
710 case DW_OP_abs:
711 if ((_Unwind_Sword) result < 0)
712 result = -result;
713 break;
714 case DW_OP_neg:
715 result = -result;
716 break;
717 case DW_OP_not:
718 result = ~result;
719 break;
720 case DW_OP_plus_uconst:
a9985a92 721 op_ptr = read_uleb128 (op_ptr, &utmp);
f767122b 722 result += (_Unwind_Word)utmp;
52a11cbf 723 break;
5ed3149c
ZW
724
725 default:
79d0dfa3 726 gcc_unreachable ();
52a11cbf
RH
727 }
728 break;
729
730 case DW_OP_and:
731 case DW_OP_div:
732 case DW_OP_minus:
733 case DW_OP_mod:
734 case DW_OP_mul:
735 case DW_OP_or:
736 case DW_OP_plus:
7a706738
AM
737 case DW_OP_shl:
738 case DW_OP_shr:
739 case DW_OP_shra:
740 case DW_OP_xor:
52a11cbf
RH
741 case DW_OP_le:
742 case DW_OP_ge:
743 case DW_OP_eq:
744 case DW_OP_lt:
745 case DW_OP_gt:
746 case DW_OP_ne:
747 {
748 /* Binary operations. */
749 _Unwind_Word first, second;
79d0dfa3
NS
750 gcc_assert (stack_elt >= 2);
751 stack_elt -= 2;
752
41077ce4
KH
753 second = stack[stack_elt];
754 first = stack[stack_elt + 1];
755
756 switch (op)
757 {
758 case DW_OP_and:
759 result = second & first;
760 break;
761 case DW_OP_div:
762 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
763 break;
764 case DW_OP_minus:
765 result = second - first;
766 break;
767 case DW_OP_mod:
768 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
769 break;
770 case DW_OP_mul:
771 result = second * first;
772 break;
773 case DW_OP_or:
774 result = second | first;
775 break;
776 case DW_OP_plus:
777 result = second + first;
778 break;
779 case DW_OP_shl:
780 result = second << first;
781 break;
782 case DW_OP_shr:
783 result = second >> first;
784 break;
785 case DW_OP_shra:
786 result = (_Unwind_Sword) second >> first;
787 break;
788 case DW_OP_xor:
789 result = second ^ first;
790 break;
791 case DW_OP_le:
792 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
793 break;
794 case DW_OP_ge:
795 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
796 break;
797 case DW_OP_eq:
798 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
799 break;
800 case DW_OP_lt:
801 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
802 break;
803 case DW_OP_gt:
804 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
805 break;
806 case DW_OP_ne:
807 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
808 break;
809
810 default:
79d0dfa3 811 gcc_unreachable ();
41077ce4 812 }
52a11cbf
RH
813 }
814 break;
815
816 case DW_OP_skip:
817 offset = read_2s (op_ptr);
818 op_ptr += 2;
819 op_ptr += offset;
820 goto no_push;
821
822 case DW_OP_bra:
79d0dfa3
NS
823 gcc_assert (stack_elt);
824 stack_elt -= 1;
825
52a11cbf
RH
826 offset = read_2s (op_ptr);
827 op_ptr += 2;
828 if (stack[stack_elt] != 0)
829 op_ptr += offset;
830 goto no_push;
831
832 case DW_OP_nop:
833 goto no_push;
834
835 default:
79d0dfa3 836 gcc_unreachable ();
52a11cbf
RH
837 }
838
839 /* Most things push a result value. */
79d0dfa3 840 gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
9c80ff25 841 stack[stack_elt++] = result;
52a11cbf
RH
842 no_push:;
843 }
844
845 /* We were executing this program to get a value. It should be
846 at top of stack. */
79d0dfa3
NS
847 gcc_assert (stack_elt);
848 stack_elt -= 1;
52a11cbf
RH
849 return stack[stack_elt];
850}
851
852
853/* Decode DWARF 2 call frame information. Takes pointers the
854 instruction sequence to decode, current register information and
855 CIE info, and the PC range to evaluate. */
856
857static void
e1f9550a
RH
858execute_cfa_program (const unsigned char *insn_ptr,
859 const unsigned char *insn_end,
860 struct _Unwind_Context *context,
861 _Unwind_FrameState *fs)
52a11cbf
RH
862{
863 struct frame_state_reg_info *unused_rs = NULL;
864
865 /* Don't allow remember/restore between CIE and FDE programs. */
866 fs->regs.prev = NULL;
867
7d8ac293
JM
868 /* The comparison with the return address uses < rather than <= because
869 we are only interested in the effects of code before the call; for a
870 noreturn function, the return address may point to unrelated code with
871 a different stack configuration that we are not interested in. We
872 assume that the call itself is unwind info-neutral; if not, or if
873 there are delay instructions that adjust the stack, these must be
754e45a8
JJ
874 reflected at the point immediately before the call insn.
875 In signal frames, return address is after last completed instruction,
876 so we add 1 to return address to make the comparison <=. */
f8e7718c
JJ
877 while (insn_ptr < insn_end
878 && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
52a11cbf
RH
879 {
880 unsigned char insn = *insn_ptr++;
f767122b
AK
881 _uleb128_t reg, utmp;
882 _sleb128_t offset, stmp;
52a11cbf 883
f0451e26 884 if ((insn & 0xc0) == DW_CFA_advance_loc)
52a11cbf 885 fs->pc += (insn & 0x3f) * fs->code_align;
f0451e26 886 else if ((insn & 0xc0) == DW_CFA_offset)
52a11cbf
RH
887 {
888 reg = insn & 0x3f;
a9985a92 889 insn_ptr = read_uleb128 (insn_ptr, &utmp);
e9d1b155 890 offset = (_Unwind_Sword) utmp * fs->data_align;
41f3a930
AH
891 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
892 = REG_SAVED_OFFSET;
893 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
52a11cbf 894 }
f0451e26 895 else if ((insn & 0xc0) == DW_CFA_restore)
52a11cbf
RH
896 {
897 reg = insn & 0x3f;
41f3a930 898 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
52a11cbf
RH
899 }
900 else switch (insn)
901 {
902 case DW_CFA_set_loc:
950ccbc4
NS
903 {
904 _Unwind_Ptr pc;
905
906 insn_ptr = read_encoded_value (context, fs->fde_encoding,
907 insn_ptr, &pc);
908 fs->pc = (void *) pc;
909 }
52a11cbf
RH
910 break;
911
912 case DW_CFA_advance_loc1:
9e800206 913 fs->pc += read_1u (insn_ptr) * fs->code_align;
52a11cbf
RH
914 insn_ptr += 1;
915 break;
916 case DW_CFA_advance_loc2:
9e800206 917 fs->pc += read_2u (insn_ptr) * fs->code_align;
52a11cbf
RH
918 insn_ptr += 2;
919 break;
920 case DW_CFA_advance_loc4:
9e800206 921 fs->pc += read_4u (insn_ptr) * fs->code_align;
52a11cbf
RH
922 insn_ptr += 4;
923 break;
924
925 case DW_CFA_offset_extended:
a9985a92
JM
926 insn_ptr = read_uleb128 (insn_ptr, &reg);
927 insn_ptr = read_uleb128 (insn_ptr, &utmp);
e9d1b155 928 offset = (_Unwind_Sword) utmp * fs->data_align;
41f3a930
AH
929 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
930 = REG_SAVED_OFFSET;
931 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
52a11cbf
RH
932 break;
933
934 case DW_CFA_restore_extended:
a9985a92 935 insn_ptr = read_uleb128 (insn_ptr, &reg);
f8a57be8
GK
936 /* FIXME, this is wrong; the CIE might have said that the
937 register was saved somewhere. */
41f3a930 938 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
52a11cbf
RH
939 break;
940
52a11cbf 941 case DW_CFA_same_value:
cb25b0ce 942 insn_ptr = read_uleb128 (insn_ptr, &reg);
f8a57be8 943 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
cb25b0ce
BK
944 break;
945
54f5943c
JJ
946 case DW_CFA_undefined:
947 insn_ptr = read_uleb128 (insn_ptr, &reg);
948 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNDEFINED;
949 break;
950
52a11cbf
RH
951 case DW_CFA_nop:
952 break;
953
954 case DW_CFA_register:
955 {
f767122b 956 _uleb128_t reg2;
a9985a92
JM
957 insn_ptr = read_uleb128 (insn_ptr, &reg);
958 insn_ptr = read_uleb128 (insn_ptr, &reg2);
41f3a930 959 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
f767122b
AK
960 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg =
961 (_Unwind_Word)reg2;
52a11cbf
RH
962 }
963 break;
41077ce4 964
52a11cbf
RH
965 case DW_CFA_remember_state:
966 {
967 struct frame_state_reg_info *new_rs;
968 if (unused_rs)
969 {
970 new_rs = unused_rs;
971 unused_rs = unused_rs->prev;
972 }
973 else
2c82eecc 974 new_rs = alloca (sizeof (struct frame_state_reg_info));
52a11cbf
RH
975
976 *new_rs = fs->regs;
977 fs->regs.prev = new_rs;
978 }
979 break;
980
981 case DW_CFA_restore_state:
982 {
983 struct frame_state_reg_info *old_rs = fs->regs.prev;
984 fs->regs = *old_rs;
985 old_rs->prev = unused_rs;
986 unused_rs = old_rs;
987 }
988 break;
989
990 case DW_CFA_def_cfa:
a9985a92 991 insn_ptr = read_uleb128 (insn_ptr, &utmp);
f767122b
AK
992 fs->regs.cfa_reg = (_Unwind_Word)utmp;
993 insn_ptr = read_uleb128 (insn_ptr, &utmp);
994 fs->regs.cfa_offset = (_Unwind_Word)utmp;
6673f90b 995 fs->regs.cfa_how = CFA_REG_OFFSET;
52a11cbf
RH
996 break;
997
998 case DW_CFA_def_cfa_register:
f767122b
AK
999 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1000 fs->regs.cfa_reg = (_Unwind_Word)utmp;
6673f90b 1001 fs->regs.cfa_how = CFA_REG_OFFSET;
52a11cbf
RH
1002 break;
1003
1004 case DW_CFA_def_cfa_offset:
a9985a92 1005 insn_ptr = read_uleb128 (insn_ptr, &utmp);
6673f90b 1006 fs->regs.cfa_offset = utmp;
52a11cbf
RH
1007 /* cfa_how deliberately not set. */
1008 break;
1009
1010 case DW_CFA_def_cfa_expression:
6673f90b
NF
1011 fs->regs.cfa_exp = insn_ptr;
1012 fs->regs.cfa_how = CFA_EXP;
9c80ff25 1013 insn_ptr = read_uleb128 (insn_ptr, &utmp);
a9985a92 1014 insn_ptr += utmp;
52a11cbf
RH
1015 break;
1016
1017 case DW_CFA_expression:
a9985a92 1018 insn_ptr = read_uleb128 (insn_ptr, &reg);
41f3a930
AH
1019 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
1020 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
9c80ff25 1021 insn_ptr = read_uleb128 (insn_ptr, &utmp);
a9985a92 1022 insn_ptr += utmp;
52a11cbf
RH
1023 break;
1024
4469af7a 1025 /* Dwarf3. */
52a11cbf 1026 case DW_CFA_offset_extended_sf:
a9985a92
JM
1027 insn_ptr = read_uleb128 (insn_ptr, &reg);
1028 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1029 offset = stmp * fs->data_align;
41f3a930
AH
1030 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1031 = REG_SAVED_OFFSET;
1032 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
52a11cbf 1033 break;
41077ce4 1034
52a11cbf 1035 case DW_CFA_def_cfa_sf:
f767122b
AK
1036 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1037 fs->regs.cfa_reg = (_Unwind_Word)utmp;
1038 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1039 fs->regs.cfa_offset = (_Unwind_Sword)stmp;
6673f90b
NF
1040 fs->regs.cfa_how = CFA_REG_OFFSET;
1041 fs->regs.cfa_offset *= fs->data_align;
52a11cbf
RH
1042 break;
1043
1044 case DW_CFA_def_cfa_offset_sf:
f767122b
AK
1045 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1046 fs->regs.cfa_offset = (_Unwind_Sword)stmp;
6673f90b 1047 fs->regs.cfa_offset *= fs->data_align;
52a11cbf
RH
1048 /* cfa_how deliberately not set. */
1049 break;
1050
4469af7a
JJ
1051 case DW_CFA_val_offset:
1052 insn_ptr = read_uleb128 (insn_ptr, &reg);
1053 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1054 offset = (_Unwind_Sword) utmp * fs->data_align;
1055 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1056 = REG_SAVED_VAL_OFFSET;
1057 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1058 break;
1059
1060 case DW_CFA_val_offset_sf:
1061 insn_ptr = read_uleb128 (insn_ptr, &reg);
1062 insn_ptr = read_sleb128 (insn_ptr, &stmp);
1063 offset = stmp * fs->data_align;
1064 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1065 = REG_SAVED_VAL_OFFSET;
1066 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1067 break;
1068
1069 case DW_CFA_val_expression:
1070 insn_ptr = read_uleb128 (insn_ptr, &reg);
1071 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1072 = REG_SAVED_VAL_EXP;
1073 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1074 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1075 insn_ptr += utmp;
1076 break;
1077
52a11cbf
RH
1078 case DW_CFA_GNU_window_save:
1079 /* ??? Hardcoded for SPARC register window configuration. */
1080 for (reg = 16; reg < 32; ++reg)
1081 {
1082 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1083 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1084 }
1085 break;
1086
1087 case DW_CFA_GNU_args_size:
f767122b
AK
1088 insn_ptr = read_uleb128 (insn_ptr, &utmp);
1089 context->args_size = (_Unwind_Word)utmp;
52a11cbf
RH
1090 break;
1091
1092 case DW_CFA_GNU_negative_offset_extended:
1093 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1094 older PowerPC code. */
a9985a92
JM
1095 insn_ptr = read_uleb128 (insn_ptr, &reg);
1096 insn_ptr = read_uleb128 (insn_ptr, &utmp);
e9d1b155 1097 offset = (_Unwind_Word) utmp * fs->data_align;
41f3a930
AH
1098 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1099 = REG_SAVED_OFFSET;
1100 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
52a11cbf
RH
1101 break;
1102
1103 default:
79d0dfa3 1104 gcc_unreachable ();
52a11cbf
RH
1105 }
1106 }
1107}
1108\f
81a60e6c
JM
1109/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1110 its caller and decode it into FS. This function also sets the
1111 args_size and lsda members of CONTEXT, as they are really information
1112 about the caller's frame. */
1113
52a11cbf
RH
1114static _Unwind_Reason_Code
1115uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1116{
f1518966
AJ
1117 const struct dwarf_fde *fde;
1118 const struct dwarf_cie *cie;
e1f9550a 1119 const unsigned char *aug, *insn, *end;
52a11cbf
RH
1120
1121 memset (fs, 0, sizeof (*fs));
1122 context->args_size = 0;
1123 context->lsda = 0;
1124
ed80cd68
RH
1125 if (context->ra == 0)
1126 return _URC_END_OF_STACK;
1127
f8e7718c 1128 fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
754e45a8 1129 &context->bases);
52a11cbf
RH
1130 if (fde == NULL)
1131 {
8662eb14 1132#ifdef MD_FALLBACK_FRAME_STATE_FOR
52a11cbf
RH
1133 /* Couldn't find frame unwind info for this function. Try a
1134 target-specific fallback mechanism. This will necessarily
e3aafbad 1135 not provide a personality routine or LSDA. */
8662eb14 1136 return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
52a11cbf
RH
1137#else
1138 return _URC_END_OF_STACK;
1139#endif
1140 }
1141
e1f9550a 1142 fs->pc = context->bases.func;
52a11cbf
RH
1143
1144 cie = get_cie (fde);
1145 insn = extract_cie_info (cie, context, fs);
1146 if (insn == NULL)
1147 /* CIE contained unknown augmentation. */
1148 return _URC_FATAL_PHASE1_ERROR;
1149
1150 /* First decode all the insns in the CIE. */
5f754896 1151 end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
52a11cbf
RH
1152 execute_cfa_program (insn, end, context, fs);
1153
1154 /* Locate augmentation for the fde. */
5f754896 1155 aug = (const unsigned char *) fde + sizeof (*fde);
e1f9550a 1156 aug += 2 * size_of_encoded_value (fs->fde_encoding);
52a11cbf
RH
1157 insn = NULL;
1158 if (fs->saw_z)
1159 {
f767122b 1160 _uleb128_t i;
52a11cbf
RH
1161 aug = read_uleb128 (aug, &i);
1162 insn = aug + i;
1163 }
e1f9550a 1164 if (fs->lsda_encoding != DW_EH_PE_omit)
950ccbc4
NS
1165 {
1166 _Unwind_Ptr lsda;
1167
1168 aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1169 context->lsda = (void *) lsda;
1170 }
52a11cbf
RH
1171
1172 /* Then the insns in the FDE up to our target PC. */
1173 if (insn == NULL)
1174 insn = aug;
5f754896 1175 end = (const unsigned char *) next_fde (fde);
52a11cbf
RH
1176 execute_cfa_program (insn, end, context, fs);
1177
1178 return _URC_NO_REASON;
1179}
5442cf15
MK
1180\f
1181typedef struct frame_state
1182{
1183 void *cfa;
1184 void *eh_ptr;
1185 long cfa_offset;
1186 long args_size;
919543ab 1187 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
5442cf15
MK
1188 unsigned short cfa_reg;
1189 unsigned short retaddr_column;
919543ab 1190 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
5442cf15
MK
1191} frame_state;
1192
1193struct frame_state * __frame_state_for (void *, struct frame_state *);
1194
1195/* Called from pre-G++ 3.0 __throw to find the registers to restore for
1196 a given PC_TARGET. The caller should allocate a local variable of
1197 `struct frame_state' and pass its address to STATE_IN. */
1198
1199struct frame_state *
1200__frame_state_for (void *pc_target, struct frame_state *state_in)
1201{
1202 struct _Unwind_Context context;
1203 _Unwind_FrameState fs;
1204 int reg;
1205
1206 memset (&context, 0, sizeof (struct _Unwind_Context));
f8e7718c 1207 context.flags = EXTENDED_CONTEXT_BIT;
5442cf15
MK
1208 context.ra = pc_target + 1;
1209
1210 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1211 return 0;
52a11cbf 1212
5442cf15
MK
1213 /* We have no way to pass a location expression for the CFA to our
1214 caller. It wouldn't understand it anyway. */
6673f90b 1215 if (fs.regs.cfa_how == CFA_EXP)
5442cf15 1216 return 0;
52a11cbf 1217
919543ab 1218 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
5442cf15
MK
1219 {
1220 state_in->saved[reg] = fs.regs.reg[reg].how;
1221 switch (state_in->saved[reg])
1222 {
1223 case REG_SAVED_REG:
1224 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1225 break;
1226 case REG_SAVED_OFFSET:
1227 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1228 break;
1229 default:
1230 state_in->reg_or_offset[reg] = 0;
1231 break;
1232 }
1233 }
1234
6673f90b
NF
1235 state_in->cfa_offset = fs.regs.cfa_offset;
1236 state_in->cfa_reg = fs.regs.cfa_reg;
5442cf15
MK
1237 state_in->retaddr_column = fs.retaddr_column;
1238 state_in->args_size = context.args_size;
1239 state_in->eh_ptr = fs.eh_ptr;
1240
1241 return state_in;
1242}
1243\f
71628aa0
R
1244typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1245
1246static inline void
1247_Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
4469af7a 1248 _Unwind_SpTmp *tmp_sp)
71628aa0
R
1249{
1250 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1251
1252 if (size == sizeof(_Unwind_Ptr))
1253 tmp_sp->ptr = (_Unwind_Ptr) cfa;
71628aa0 1254 else
79d0dfa3
NS
1255 {
1256 gcc_assert (size == sizeof(_Unwind_Word));
1257 tmp_sp->word = (_Unwind_Ptr) cfa;
1258 }
71628aa0
R
1259 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1260}
1261
52a11cbf
RH
1262static void
1263uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1264{
1265 struct _Unwind_Context orig_context = *context;
1266 void *cfa;
1267 long i;
1268
34dc173c 1269#ifdef EH_RETURN_STACKADJ_RTX
9c80ff25
RH
1270 /* Special handling here: Many machines do not use a frame pointer,
1271 and track the CFA only through offsets from the stack pointer from
1272 one frame to the next. In this case, the stack pointer is never
1273 stored, so it has no saved address in the context. What we do
1274 have is the CFA from the previous stack frame.
1275
1276 In very special situations (such as unwind info for signal return),
1277 there may be location expressions that use the stack pointer as well.
1278
8b689196
RH
1279 Do this conditionally for one frame. This allows the unwind info
1280 for one frame to save a copy of the stack pointer from the previous
1281 frame, and be able to use much easier CFA mechanisms to do it.
1282 Always zap the saved stack pointer value for the next frame; carrying
1283 the value over from one frame to another doesn't make sense. */
34dc173c 1284
71628aa0 1285 _Unwind_SpTmp tmp_sp;
34dc173c 1286
8b689196 1287 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
71628aa0 1288 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
8b689196 1289 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
34dc173c 1290#endif
9c80ff25 1291
52a11cbf 1292 /* Compute this frame's CFA. */
6673f90b 1293 switch (fs->regs.cfa_how)
52a11cbf
RH
1294 {
1295 case CFA_REG_OFFSET:
6673f90b
NF
1296 cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1297 cfa += fs->regs.cfa_offset;
52a11cbf
RH
1298 break;
1299
1300 case CFA_EXP:
52a11cbf 1301 {
6673f90b 1302 const unsigned char *exp = fs->regs.cfa_exp;
f767122b 1303 _uleb128_t len;
52a11cbf
RH
1304
1305 exp = read_uleb128 (exp, &len);
1306 cfa = (void *) (_Unwind_Ptr)
9c80ff25 1307 execute_stack_op (exp, exp + len, &orig_context, 0);
52a11cbf
RH
1308 break;
1309 }
1310
1311 default:
79d0dfa3 1312 gcc_unreachable ();
52a11cbf
RH
1313 }
1314 context->cfa = cfa;
1315
1316 /* Compute the addresses of all registers saved in this frame. */
1317 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1318 switch (fs->regs.reg[i].how)
1319 {
1320 case REG_UNSAVED:
54f5943c 1321 case REG_UNDEFINED:
52a11cbf 1322 break;
9c80ff25 1323
52a11cbf 1324 case REG_SAVED_OFFSET:
9c80ff25
RH
1325 _Unwind_SetGRPtr (context, i,
1326 (void *) (cfa + fs->regs.reg[i].loc.offset));
52a11cbf 1327 break;
9c80ff25 1328
52a11cbf 1329 case REG_SAVED_REG:
4469af7a
JJ
1330 if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1331 _Unwind_SetGRValue (context, i,
1332 _Unwind_GetGR (&orig_context,
1333 fs->regs.reg[i].loc.reg));
1334 else
1335 _Unwind_SetGRPtr (context, i,
1336 _Unwind_GetGRPtr (&orig_context,
1337 fs->regs.reg[i].loc.reg));
52a11cbf 1338 break;
9c80ff25 1339
52a11cbf
RH
1340 case REG_SAVED_EXP:
1341 {
e1f9550a 1342 const unsigned char *exp = fs->regs.reg[i].loc.exp;
f767122b 1343 _uleb128_t len;
52a11cbf
RH
1344 _Unwind_Ptr val;
1345
1346 exp = read_uleb128 (exp, &len);
1347 val = execute_stack_op (exp, exp + len, &orig_context,
1348 (_Unwind_Ptr) cfa);
41f3a930 1349 _Unwind_SetGRPtr (context, i, (void *) val);
52a11cbf
RH
1350 }
1351 break;
4469af7a
JJ
1352
1353 case REG_SAVED_VAL_OFFSET:
1354 _Unwind_SetGRValue (context, i,
1355 (_Unwind_Internal_Ptr)
1356 (cfa + fs->regs.reg[i].loc.offset));
1357 break;
1358
1359 case REG_SAVED_VAL_EXP:
1360 {
1361 const unsigned char *exp = fs->regs.reg[i].loc.exp;
f767122b 1362 _uleb128_t len;
4469af7a
JJ
1363 _Unwind_Ptr val;
1364
1365 exp = read_uleb128 (exp, &len);
1366 val = execute_stack_op (exp, exp + len, &orig_context,
1367 (_Unwind_Ptr) cfa);
1368 _Unwind_SetGRValue (context, i, val);
1369 }
1370 break;
52a11cbf 1371 }
fc4767bb 1372
f8e7718c 1373 _Unwind_SetSignalFrame (context, fs->signal_frame);
754e45a8 1374
8662eb14 1375#ifdef MD_FROB_UPDATE_CONTEXT
fc4767bb 1376 MD_FROB_UPDATE_CONTEXT (context, fs);
8662eb14 1377#endif
52a11cbf
RH
1378}
1379
81a60e6c
JM
1380/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1381 of its caller. Update CONTEXT to refer to the caller as well. Note
1382 that the args_size and lsda members are not updated here, but later in
1383 uw_frame_state_for. */
1384
52a11cbf
RH
1385static void
1386uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1387{
1388 uw_update_context_1 (context, fs);
1389
54f5943c
JJ
1390 /* In general this unwinder doesn't make any distinction between
1391 undefined and same_value rule. Call-saved registers are assumed
1392 to have same_value rule by default and explicit undefined
1393 rule is handled like same_value. The only exception is
1394 DW_CFA_undefined on retaddr_column which is supposed to
1395 mark outermost frame in DWARF 3. */
1396 if (fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)].how
1397 == REG_UNDEFINED)
1398 /* uw_frame_state_for uses context->ra == 0 check to find outermost
1399 stack frame. */
1400 context->ra = 0;
1401 else
1402 /* Compute the return address now, since the return address column
1403 can change from frame to frame. */
1404 context->ra = __builtin_extract_return_addr
1405 (_Unwind_GetPtr (context, fs->retaddr_column));
52a11cbf 1406}
60aef23e
DJ
1407
1408static void
1409uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1410{
1411 uw_update_context (context, fs);
1412}
52a11cbf
RH
1413\f
1414/* Fill in CONTEXT for top-of-stack. The only valid registers at this
1415 level will be the return address and the CFA. */
41077ce4 1416
a01da83b
KH
1417#define uw_init_context(CONTEXT) \
1418 do \
1419 { \
1420 /* Do any necessary initialization to access arbitrary stack frames. \
1421 On the SPARC, this means flushing the register windows. */ \
1422 __builtin_unwind_init (); \
1423 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1424 __builtin_return_address (0)); \
1425 } \
1426 while (0)
52a11cbf 1427
71628aa0
R
1428static inline void
1429init_dwarf_reg_size_table (void)
1430{
1431 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1432}
1433
e5b258a4 1434static void __attribute__((noinline))
52a11cbf
RH
1435uw_init_context_1 (struct _Unwind_Context *context,
1436 void *outer_cfa, void *outer_ra)
1437{
1438 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1439 _Unwind_FrameState fs;
71628aa0 1440 _Unwind_SpTmp sp_slot;
79d0dfa3 1441 _Unwind_Reason_Code code;
52a11cbf
RH
1442
1443 memset (context, 0, sizeof (struct _Unwind_Context));
1444 context->ra = ra;
f8e7718c 1445 context->flags = EXTENDED_CONTEXT_BIT;
52a11cbf 1446
79d0dfa3
NS
1447 code = uw_frame_state_for (context, &fs);
1448 gcc_assert (code == _URC_NO_REASON);
52a11cbf 1449
71628aa0
R
1450#if __GTHREADS
1451 {
1452 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1453 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
7bec3e84 1454 && dwarf_reg_size_table[0] == 0)
71628aa0
R
1455 init_dwarf_reg_size_table ();
1456 }
1457#else
1458 if (dwarf_reg_size_table[0] == 0)
1459 init_dwarf_reg_size_table ();
1460#endif
1461
52a11cbf 1462 /* Force the frame state to use the known cfa value. */
71628aa0 1463 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
6673f90b
NF
1464 fs.regs.cfa_how = CFA_REG_OFFSET;
1465 fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1466 fs.regs.cfa_offset = 0;
52a11cbf
RH
1467
1468 uw_update_context_1 (context, &fs);
1469
1470 /* If the return address column was saved in a register in the
1471 initialization context, then we can't see it in the given
1472 call frame data. So have the initialization context tell us. */
1473 context->ra = __builtin_extract_return_addr (outer_ra);
1474}
1475
e455776a
TT
1476static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
1477
1478/* This function is called during unwinding. It is intended as a hook
1479 for a debugger to intercept exceptions. CFA is the CFA of the
1480 target frame. HANDLER is the PC to which control will be
1481 transferred. */
1482static void
1483_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1484 void *handler __attribute__ ((__unused__)))
1485{
1486 asm ("");
1487}
52a11cbf
RH
1488
1489/* Install TARGET into CURRENT so that we can return to it. This is a
1490 macro because __builtin_eh_return must be invoked in the context of
1491 our caller. */
1492
e455776a
TT
1493#define uw_install_context(CURRENT, TARGET) \
1494 do \
1495 { \
1496 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1497 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1498 _Unwind_DebugHook ((TARGET)->cfa, handler); \
1499 __builtin_eh_return (offset, handler); \
1500 } \
a01da83b 1501 while (0)
52a11cbf 1502
52a11cbf
RH
1503static long
1504uw_install_context_1 (struct _Unwind_Context *current,
1505 struct _Unwind_Context *target)
1506{
1507 long i;
9d8646d7
PB
1508 _Unwind_SpTmp sp_slot;
1509
1510 /* If the target frame does not have a saved stack pointer,
1511 then set up the target's CFA. */
1512 if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
4469af7a 1513 _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
52a11cbf 1514
52a11cbf
RH
1515 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1516 {
1517 void *c = current->reg[i];
1518 void *t = target->reg[i];
41f3a930 1519
4469af7a
JJ
1520 gcc_assert (current->by_value[i] == 0);
1521 if (target->by_value[i] && c)
1522 {
1523 _Unwind_Word w;
1524 _Unwind_Ptr p;
1525 if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1526 {
1527 w = (_Unwind_Internal_Ptr) t;
1528 memcpy (c, &w, sizeof (_Unwind_Word));
1529 }
1530 else
1531 {
1532 gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1533 p = (_Unwind_Internal_Ptr) t;
1534 memcpy (c, &p, sizeof (_Unwind_Ptr));
1535 }
1536 }
1537 else if (t && c && t != c)
52a11cbf
RH
1538 memcpy (c, t, dwarf_reg_size_table[i]);
1539 }
1540
9d8646d7
PB
1541 /* If the current frame doesn't have a saved stack pointer, then we
1542 need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1543 pointer value reloaded. */
1544 if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1545 {
1546 void *target_cfa;
34dc173c 1547
71628aa0 1548 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
9d8646d7
PB
1549
1550 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1551 if (STACK_GROWS_DOWNWARD)
1552 return target_cfa - current->cfa + target->args_size;
1553 else
1554 return current->cfa - target_cfa - target->args_size;
1555 }
34dc173c 1556 return 0;
52a11cbf
RH
1557}
1558
1559static inline _Unwind_Ptr
1560uw_identify_context (struct _Unwind_Context *context)
1561{
ca0d5e02 1562 return _Unwind_GetCFA (context);
52a11cbf
RH
1563}
1564
1565
1566#include "unwind.inc"
1567
443728bb
L
1568#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1569alias (_Unwind_Backtrace);
1570alias (_Unwind_DeleteException);
1571alias (_Unwind_FindEnclosingFunction);
443728bb
L
1572alias (_Unwind_ForcedUnwind);
1573alias (_Unwind_GetDataRelBase);
1574alias (_Unwind_GetTextRelBase);
1575alias (_Unwind_GetCFA);
1576alias (_Unwind_GetGR);
1577alias (_Unwind_GetIP);
1578alias (_Unwind_GetLanguageSpecificData);
1579alias (_Unwind_GetRegionStart);
1580alias (_Unwind_RaiseException);
1581alias (_Unwind_Resume);
1582alias (_Unwind_Resume_or_Rethrow);
1583alias (_Unwind_SetGR);
1584alias (_Unwind_SetIP);
1585#endif
1586
52a11cbf 1587#endif /* !USING_SJLJ_EXCEPTIONS */