0
|
1 /* DWARF2 EH unwinding support for Alpha VMS.
|
|
2 Copyright (C) 2004, 2007 Free Software Foundation, Inc.
|
|
3
|
|
4 This file is part of GCC.
|
|
5
|
|
6 GCC is free software; you can redistribute it and/or modify
|
|
7 it under the terms of the GNU General Public License as published by
|
|
8 the Free Software Foundation; either version 3, or (at your option)
|
|
9 any later version.
|
|
10
|
|
11 GCC is distributed in the hope that it will be useful,
|
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 GNU General Public License for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with GCC; see the file COPYING3. If not see
|
|
18 <http://www.gnu.org/licenses/>. */
|
|
19
|
|
20 #include <pdscdef.h>
|
|
21
|
|
22 #define MD_FALLBACK_FRAME_STATE_FOR alpha_fallback_frame_state
|
|
23
|
|
24 static _Unwind_Reason_Code
|
|
25 alpha_fallback_frame_state (struct _Unwind_Context *context,
|
|
26 _Unwind_FrameState *fs)
|
|
27 {
|
|
28 PDSCDEF *pv = *((PDSCDEF **) context->reg [29]);
|
|
29
|
|
30 if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */
|
|
31 pv = *(PDSCDEF **) pv;
|
|
32
|
|
33 if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK))
|
|
34 {
|
|
35 int i, j;
|
|
36
|
|
37 fs->regs.cfa_offset = pv->pdsc$l_size;
|
|
38 fs->regs.cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
|
|
39 fs->retaddr_column = 26;
|
|
40 fs->regs.cfa_how = CFA_REG_OFFSET;
|
|
41 fs->regs.reg[27].loc.offset = -pv->pdsc$l_size;
|
|
42 fs->regs.reg[27].how = REG_SAVED_OFFSET;
|
|
43 fs->regs.reg[26].loc.offset
|
|
44 = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset);
|
|
45 fs->regs.reg[26].how = REG_SAVED_OFFSET;
|
|
46
|
|
47 for (i = 0, j = 0; i < 32; i++)
|
|
48 if (1<<i & pv->pdsc$l_ireg_mask)
|
|
49 {
|
|
50 fs->regs.reg[i].loc.offset
|
|
51 = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j);
|
|
52 fs->regs.reg[i].how = REG_SAVED_OFFSET;
|
|
53 }
|
|
54
|
|
55 return _URC_NO_REASON;
|
|
56 }
|
|
57 else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER))
|
|
58 {
|
|
59 fs->regs.cfa_offset = pv->pdsc$l_size;
|
|
60 fs->regs.cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
|
|
61 fs->retaddr_column = 26;
|
|
62 fs->regs.cfa_how = CFA_REG_OFFSET;
|
|
63 fs->regs.reg[26].loc.reg = pv->pdsc$b_save_ra;
|
|
64 fs->regs.reg[26].how = REG_SAVED_REG;
|
|
65 fs->regs.reg[29].loc.reg = pv->pdsc$b_save_fp;
|
|
66 fs->regs.reg[29].how = REG_SAVED_REG;
|
|
67
|
|
68 return _URC_NO_REASON;
|
|
69 }
|
|
70 return _URC_END_OF_STACK;
|
|
71 }
|