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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [sh/] [linux-unwind.h] - Blame information for rev 827

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

Line No. Rev Author Line
1 38 julius
/* DWARF2 EH unwinding support for SH Linux.
2
   Copyright (C) 2004, 2005, 2006 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 2, or (at your option)
9
any later version.
10
 
11
In addition to the permissions in the GNU General Public License, the
12
Free Software Foundation gives you unlimited permission to link the
13
compiled version of this file with other programs, and to distribute
14
those programs without any restriction coming from the use of this
15
file.  (The General Public License restrictions do apply in other
16
respects; for example, they cover modification of the file, and
17
distribution when not linked into another program.)
18
 
19
GCC is distributed in the hope that it will be useful,
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
GNU General Public License for more details.
23
 
24
You should have received a copy of the GNU General Public License
25
along with this program; see the file COPYING.  If not, write to
26
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27
Boston, MA 02110-1301, USA.  */
28
 
29
/* Do code reading to identify a signal frame, and set the frame
30
   state data appropriately.  See unwind-dw2.c for the structs.  */
31
 
32
#include <signal.h>
33
#include <sys/ucontext.h>
34
#include "insn-constants.h"
35
 
36
# if defined (__SH5__)
37
#define SH_DWARF_FRAME_GP0      0
38
#define SH_DWARF_FRAME_FP0      77
39
#define SH_DWARF_FRAME_BT0      68
40
#define SH_DWARF_FRAME_PR_MEDIA 18
41
#define SH_DWARF_FRAME_SR       65
42
#define SH_DWARF_FRAME_FPSCR    76
43
#else
44
#define SH_DWARF_FRAME_GP0      0
45
#define SH_DWARF_FRAME_FP0      25
46
#define SH_DWARF_FRAME_XD0      87
47
#define SH_DWARF_FRAME_PR       17
48
#define SH_DWARF_FRAME_GBR      19
49
#define SH_DWARF_FRAME_MACH     20
50
#define SH_DWARF_FRAME_MACL     21
51
#define SH_DWARF_FRAME_PC       16
52
#define SH_DWARF_FRAME_SR       22
53
#define SH_DWARF_FRAME_FPUL     23
54
#define SH_DWARF_FRAME_FPSCR    24
55
#endif /* defined (__SH5__) */
56
 
57
#if defined (__SH5__)
58
 
59
#define MD_FALLBACK_FRAME_STATE_FOR shmedia_fallback_frame_state
60
 
61
static _Unwind_Reason_Code
62
shmedia_fallback_frame_state (struct _Unwind_Context *context,
63
                              _Unwind_FrameState *fs)
64
{
65
  unsigned char *pc = context->ra;
66
  struct sigcontext *sc;
67
  long new_cfa;
68
  int i, r;
69
 
70
  /* movi 0x10,r9; shori 0x77,r9; trapa r9; nop (sigreturn)  */
71
  /* movi 0x10,r9; shori 0xad,r9; trapa r9; nop (rt_sigreturn)  */
72
  if ((*(unsigned long *) (pc-1)  == 0xcc004090)
73
      && (*(unsigned long *) (pc+3)  == 0xc801dc90)
74
      && (*(unsigned long *) (pc+7)  == 0x6c91fff0)
75
      && (*(unsigned long *) (pc+11)  == 0x6ff0fff0))
76
    sc = context->cfa;
77
  else if ((*(unsigned long *) (pc-1)  == 0xcc004090)
78
           && (*(unsigned long *) (pc+3)  == 0xc802b490)
79
           && (*(unsigned long *) (pc+7)  == 0x6c91fff0)
80
           && (*(unsigned long *) (pc+11)  == 0x6ff0fff0))
81
    {
82
      struct rt_sigframe {
83
        struct siginfo *pinfo;
84
        void *puc;
85
        struct siginfo info;
86
        struct ucontext uc;
87
      } *rt_ = context->cfa;
88
      /* The void * cast is necessary to avoid an aliasing warning.
89
         The aliasing warning is correct, but should not be a problem
90
         because it does not alias anything.  */
91
      sc = (struct sigcontext *) (void *) &rt_->uc.uc_mcontext;
92
    }
93
  else
94
    return _URC_END_OF_STACK;
95
 
96
  new_cfa = sc->sc_regs[15];
97
  fs->cfa_how = CFA_REG_OFFSET;
98
  fs->cfa_reg = 15;
99
  fs->cfa_offset = new_cfa - (long) context->cfa;
100
 
101
  for (i = 0; i < 63; i++)
102
    {
103
      if (i == 15)
104
        continue;
105
 
106
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
107
      fs->regs.reg[i].loc.offset
108
        = (long)&(sc->sc_regs[i]) - new_cfa;
109
    }
110
 
111
  fs->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET;
112
  fs->regs.reg[SH_DWARF_FRAME_SR].loc.offset
113
    = (long)&(sc->sc_sr) - new_cfa;
114
 
115
  r = SH_DWARF_FRAME_BT0;
116
  for (i = 0; i < 8; i++)
117
    {
118
      fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
119
      fs->regs.reg[r+i].loc.offset
120
        = (long)&(sc->sc_tregs[i]) - new_cfa;
121
    }
122
 
123
  r = SH_DWARF_FRAME_FP0;
124
  for (i = 0; i < 32; i++)
125
    {
126
      fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
127
      fs->regs.reg[r+i].loc.offset
128
        = (long)&(sc->sc_fpregs[i]) - new_cfa;
129
    }
130
 
131
  fs->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET;
132
  fs->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset
133
    = (long)&(sc->sc_fpscr) - new_cfa;
134
 
135
  /* We use the slot for the zero register to save return address.  */
136
  fs->regs.reg[63].how = REG_SAVED_OFFSET;
137
  fs->regs.reg[63].loc.offset
138
    = (long)&(sc->sc_pc) - new_cfa;
139
  fs->retaddr_column = 63;
140
  fs->signal_frame = 1;
141
  return _URC_NO_REASON;
142
}
143
 
144
#else /* defined (__SH5__) */
145
 
146
#define MD_FALLBACK_FRAME_STATE_FOR sh_fallback_frame_state
147
 
148
static _Unwind_Reason_Code
149
sh_fallback_frame_state (struct _Unwind_Context *context,
150
                         _Unwind_FrameState *fs)
151
{
152
  unsigned char *pc = context->ra;
153
  struct sigcontext *sc;
154
  long new_cfa;
155
  int i;
156
#if defined (__SH3E__) || defined (__SH4__)
157
  int r;
158
#endif
159
 
160
  /* mov.w 1f,r3; trapa #0x10; 1: .short 0x77  (sigreturn)  */
161
  /* mov.w 1f,r3; trapa #0x10; 1: .short 0xad  (rt_sigreturn)  */
162
  /* Newer kernel uses pad instructions to avoid an SH-4 core bug.  */
163
  /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
164
     or r0,r0; 1: .short 0x77  (sigreturn)  */
165
  /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
166
     or r0,r0; 1: .short 0xad  (rt_sigreturn)  */
167
  if (((*(unsigned short *) (pc+0)  == 0x9300)
168
       && (*(unsigned short *) (pc+2)  == 0xc310)
169
       && (*(unsigned short *) (pc+4)  == 0x0077))
170
      || (((*(unsigned short *) (pc+0)  == 0x9305)
171
           && (*(unsigned short *) (pc+2)  == 0xc310)
172
           && (*(unsigned short *) (pc+14)  == 0x0077))))
173
    sc = context->cfa;
174
  else if (((*(unsigned short *) (pc+0) == 0x9300)
175
            && (*(unsigned short *) (pc+2)  == 0xc310)
176
            && (*(unsigned short *) (pc+4)  == 0x00ad))
177
           || (((*(unsigned short *) (pc+0) == 0x9305)
178
                && (*(unsigned short *) (pc+2)  == 0xc310)
179
                && (*(unsigned short *) (pc+14)  == 0x00ad))))
180
    {
181
      struct rt_sigframe {
182
        struct siginfo info;
183
        struct ucontext uc;
184
      } *rt_ = context->cfa;
185
      /* The void * cast is necessary to avoid an aliasing warning.
186
         The aliasing warning is correct, but should not be a problem
187
         because it does not alias anything.  */
188
      sc = (struct sigcontext *) (void *) &rt_->uc.uc_mcontext;
189
    }
190
  else
191
    return _URC_END_OF_STACK;
192
 
193
  new_cfa = sc->sc_regs[15];
194
  fs->cfa_how = CFA_REG_OFFSET;
195
  fs->cfa_reg = 15;
196
  fs->cfa_offset = new_cfa - (long) context->cfa;
197
 
198
  for (i = 0; i < 15; i++)
199
    {
200
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
201
      fs->regs.reg[i].loc.offset
202
        = (long)&(sc->sc_regs[i]) - new_cfa;
203
    }
204
 
205
  fs->regs.reg[SH_DWARF_FRAME_PR].how = REG_SAVED_OFFSET;
206
  fs->regs.reg[SH_DWARF_FRAME_PR].loc.offset
207
    = (long)&(sc->sc_pr) - new_cfa;
208
  fs->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET;
209
  fs->regs.reg[SH_DWARF_FRAME_SR].loc.offset
210
    = (long)&(sc->sc_sr) - new_cfa;
211
  fs->regs.reg[SH_DWARF_FRAME_GBR].how = REG_SAVED_OFFSET;
212
  fs->regs.reg[SH_DWARF_FRAME_GBR].loc.offset
213
    = (long)&(sc->sc_gbr) - new_cfa;
214
  fs->regs.reg[SH_DWARF_FRAME_MACH].how = REG_SAVED_OFFSET;
215
  fs->regs.reg[SH_DWARF_FRAME_MACH].loc.offset
216
    = (long)&(sc->sc_mach) - new_cfa;
217
  fs->regs.reg[SH_DWARF_FRAME_MACL].how = REG_SAVED_OFFSET;
218
  fs->regs.reg[SH_DWARF_FRAME_MACL].loc.offset
219
    = (long)&(sc->sc_macl) - new_cfa;
220
 
221
#if defined (__SH3E__) || defined (__SH4__)
222
  r = SH_DWARF_FRAME_FP0;
223
  for (i = 0; i < 16; i++)
224
    {
225
      fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
226
      fs->regs.reg[r+i].loc.offset
227
        = (long)&(sc->sc_fpregs[i]) - new_cfa;
228
    }
229
 
230
  r = SH_DWARF_FRAME_XD0;
231
  for (i = 0; i < 8; i++)
232
    {
233
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
234
      fs->regs.reg[i].loc.offset
235
        = (long)&(sc->sc_xfpregs[2*i]) - new_cfa;
236
    }
237
 
238
  fs->regs.reg[SH_DWARF_FRAME_FPUL].how = REG_SAVED_OFFSET;
239
  fs->regs.reg[SH_DWARF_FRAME_FPUL].loc.offset
240
    = (long)&(sc->sc_fpul) - new_cfa;
241
  fs->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET;
242
  fs->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset
243
    = (long)&(sc->sc_fpscr) - new_cfa;
244
#endif
245
 
246
  fs->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET;
247
  fs->regs.reg[SH_DWARF_FRAME_PC].loc.offset
248
    = (long)&(sc->sc_pc) - new_cfa;
249
  fs->retaddr_column = SH_DWARF_FRAME_PC;
250
  fs->signal_frame = 1;
251
  return _URC_NO_REASON;
252
}
253
#endif /* defined (__SH5__) */

powered by: WebSVN 2.1.0

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