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/] [sh/] [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 SH Linux.
2
   Copyright (C) 2004, 2005, 2006, 2007, 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
 
26
/* Do code reading to identify a signal frame, and set the frame
27
   state data appropriately.  See unwind-dw2.c for the structs.
28
   Don't use this at all if inhibit_libc is used.  */
29
 
30
#ifndef inhibit_libc
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      18
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->regs.cfa_how = CFA_REG_OFFSET;
98
  fs->regs.cfa_reg = 15;
99
  fs->regs.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->regs.cfa_how = CFA_REG_OFFSET;
195
  fs->regs.cfa_reg = 15;
196
  fs->regs.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[r+i].how = REG_SAVED_OFFSET;
234
      fs->regs.reg[r+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__) */
254
 
255
#endif /* inhibit_libc */

powered by: WebSVN 2.1.0

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