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