OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [sparc/] [linux-unwind.h] - Blame information for rev 298

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
/* DWARF2 EH unwinding support for SPARC Linux.
2
   Copyright 2004, 2005, 2009 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
Under Section 7 of GPL version 3, you are granted additional
17
permissions described in the GCC Runtime Library Exception, version
18
3.1, as published by the Free Software Foundation.
19
 
20
You should have received a copy of the GNU General Public License and
21
a copy of the GCC Runtime Library Exception along with this program;
22
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
<http://www.gnu.org/licenses/>.  */
24
 
25
/* Do code reading to identify a signal frame, and set the frame
26
   state data appropriately.  See unwind-dw2.c for the structs.  */
27
 
28
#if defined(__arch64__)
29
 
30
/* 64-bit SPARC version */
31
#define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
32
 
33
static _Unwind_Reason_Code
34
sparc64_fallback_frame_state (struct _Unwind_Context *context,
35
                              _Unwind_FrameState *fs)
36
{
37
  unsigned int *pc = context->ra;
38
  long this_cfa = (long) context->cfa;
39
  long new_cfa, ra_location, shifted_ra_location;
40
  long regs_off, fpu_save_off;
41
  long fpu_save;
42
  int i;
43
 
44
  if (pc[0] != 0x82102065        /* mov NR_rt_sigreturn, %g1 */
45
      || pc[1] != 0x91d0206d)   /* ta 0x6d */
46
    return _URC_END_OF_STACK;
47
 
48
  regs_off = 192 + 128;
49
  fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4);
50
 
51
  new_cfa = *(long *)(this_cfa + regs_off + (14 * 8));
52
  new_cfa += 2047; /* Stack bias */
53
  fpu_save = *(long *)(this_cfa + fpu_save_off);
54
  fs->regs.cfa_how = CFA_REG_OFFSET;
55
  fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
56
  fs->regs.cfa_offset = new_cfa - this_cfa;
57
 
58
  for (i = 1; i < 16; i++)
59
    {
60
      /* We never restore %sp as everything is purely CFA-based.  */
61
      if ((unsigned int) i == __builtin_dwarf_sp_column ())
62
        continue;
63
 
64
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
65
      fs->regs.reg[i].loc.offset
66
        = this_cfa + regs_off + (i * 8) - new_cfa;
67
    }
68
  for (i = 0; i < 16; i++)
69
    {
70
      fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
71
      fs->regs.reg[i + 16].loc.offset
72
        = this_cfa + (i * 8) - new_cfa;
73
    }
74
  if (fpu_save)
75
    {
76
      for (i = 0; i < 64; i++)
77
        {
78
          if (i > 32 && (i & 0x1))
79
            continue;
80
          fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
81
          fs->regs.reg[i + 32].loc.offset
82
            = fpu_save + (i * 4) - new_cfa;
83
        }
84
    }
85
 
86
  /* State the rules to find the kernel's code "return address", which is
87
     the address of the active instruction when the signal was caught.
88
     On the SPARC, since RETURN_ADDR_OFFSET (essentially 8) is defined, we
89
     need to preventively subtract it from the purported return address.  */
90
  ra_location = this_cfa + regs_off + 17 * 8;
91
  shifted_ra_location = this_cfa + regs_off + 19 * 8; /* Y register */
92
  *(long *)shifted_ra_location = *(long *)ra_location - 8;
93
  fs->retaddr_column = 0;
94
  fs->regs.reg[0].how = REG_SAVED_OFFSET;
95
  fs->regs.reg[0].loc.offset = shifted_ra_location - new_cfa;
96
  fs->signal_frame = 1;
97
 
98
  return _URC_NO_REASON;
99
}
100
 
101
#define MD_FROB_UPDATE_CONTEXT sparc64_frob_update_context
102
 
103
static void
104
sparc64_frob_update_context (struct _Unwind_Context *context,
105
                             _Unwind_FrameState *fs)
106
{
107
  /* The column of %sp contains the old CFA, not the old value of %sp.
108
     The CFA offset already comprises the stack bias so, when %sp is the
109
     CFA register, we must avoid counting the stack bias twice.  Do not
110
     do that for signal frames as the offset is artificial for them.  */
111
  if (fs->regs.cfa_reg == __builtin_dwarf_sp_column ()
112
      && fs->regs.cfa_how == CFA_REG_OFFSET
113
      && fs->regs.cfa_offset != 0
114
      && !fs->signal_frame)
115
    context->cfa -= 2047;
116
}
117
 
118
#else
119
 
120
/* 32-bit SPARC version */
121
#define MD_FALLBACK_FRAME_STATE_FOR sparc_fallback_frame_state
122
 
123
static _Unwind_Reason_Code
124
sparc_fallback_frame_state (struct _Unwind_Context *context,
125
                            _Unwind_FrameState *fs)
126
{
127
  unsigned int *pc = context->ra;
128
  int this_cfa = (int) context->cfa;
129
  int new_cfa, ra_location, shifted_ra_location;
130
  int regs_off, fpu_save_off;
131
  int fpu_save;
132
  int old_style, i;
133
 
134
  if (pc[1] != 0x91d02010)      /* ta 0x10 */
135
    return _URC_END_OF_STACK;
136
 
137
  if (pc[0] == 0x821020d8)       /* mov NR_sigreturn, %g1 */
138
    old_style = 1;
139
  else if (pc[0] == 0x82102065)  /* mov NR_rt_sigreturn, %g1 */
140
    old_style = 0;
141
  else
142
    return _URC_END_OF_STACK;
143
 
144
  if (old_style)
145
    {
146
      regs_off = 96;
147
      fpu_save_off = regs_off + (4 * 4) + (16 * 4);
148
    }
149
  else
150
    {
151
      regs_off = 96 + 128;
152
      fpu_save_off = regs_off + (4 * 4) + (16 * 4) + (2 * 4);
153
    }
154
 
155
  new_cfa = *(int *)(this_cfa + regs_off + (4 * 4) + (14 * 4));
156
  fpu_save = *(int *)(this_cfa + fpu_save_off);
157
  fs->regs.cfa_how = CFA_REG_OFFSET;
158
  fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
159
  fs->regs.cfa_offset = new_cfa - this_cfa;
160
 
161
  for (i = 1; i < 16; i++)
162
    {
163
      /* We never restore %sp as everything is purely CFA-based.  */
164
      if ((unsigned int) i == __builtin_dwarf_sp_column ())
165
        continue;
166
 
167
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
168
      fs->regs.reg[i].loc.offset
169
        = this_cfa + regs_off + (4 * 4) + (i * 4) - new_cfa;
170
    }
171
  for (i = 0; i < 16; i++)
172
    {
173
      fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
174
      fs->regs.reg[i + 16].loc.offset
175
        = this_cfa + (i * 4) - new_cfa;
176
    }
177
  if (fpu_save)
178
    {
179
      for (i = 0; i < 32; i++)
180
        {
181
          fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
182
          fs->regs.reg[i + 32].loc.offset
183
            = fpu_save + (i * 4) - new_cfa;
184
        }
185
    }
186
 
187
  /* State the rules to find the kernel's code "return address", which is
188
     the address of the active instruction when the signal was caught.
189
     On the SPARC, since RETURN_ADDR_OFFSET (essentially 8) is defined, we
190
     need to preventively subtract it from the purported return address.  */
191
  ra_location = this_cfa + regs_off + 4;
192
  shifted_ra_location = this_cfa + regs_off + 3 * 4; /* Y register */
193
  *(int *)shifted_ra_location = *(int *)ra_location - 8;
194
  fs->retaddr_column = 0;
195
  fs->regs.reg[0].how = REG_SAVED_OFFSET;
196
  fs->regs.reg[0].loc.offset = shifted_ra_location - new_cfa;
197
  fs->signal_frame = 1;
198
 
199
  return _URC_NO_REASON;
200
}
201
 
202
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.