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