Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/m68k/linux-unwind.h @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children |
rev | line source |
---|---|
0 | 1 /* DWARF2 EH unwinding support for Linux/m68k. |
2 Copyright (C) 2006, 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 Don't use this at all if inhibit_libc is used. */ | |
28 | |
29 #ifndef inhibit_libc | |
30 | |
31 #include <signal.h> | |
32 | |
33 /* <sys/ucontext.h> is unfortunately broken right now. */ | |
34 struct uw_ucontext { | |
35 unsigned long uc_flags; | |
36 struct ucontext *uc_link; | |
37 stack_t uc_stack; | |
38 mcontext_t uc_mcontext; | |
39 unsigned long uc_filler[80]; | |
40 __sigset_t uc_sigmask; | |
41 }; | |
42 | |
43 #define MD_FALLBACK_FRAME_STATE_FOR m68k_fallback_frame_state | |
44 | |
45 #ifdef __mcoldfire__ | |
46 #define M68K_FP_SIZE 8 | |
47 #else | |
48 #define M68K_FP_SIZE 12 | |
49 #endif | |
50 | |
51 static _Unwind_Reason_Code | |
52 m68k_fallback_frame_state (struct _Unwind_Context *context, | |
53 _Unwind_FrameState *fs) | |
54 { | |
55 unsigned short *pc = context->ra; | |
56 long cfa; | |
57 | |
58 /* moveq #__NR_sigreturn,%d0; trap #0 */ | |
59 if (pc[0] == 0x7077 && pc[1] == 0x4e40) | |
60 { | |
61 struct sigcontext *sc; | |
62 | |
63 /* Context is passed as the 3rd argument. */ | |
64 sc = *(struct sigcontext **) (context->cfa + 8); | |
65 | |
66 cfa = sc->sc_usp; | |
67 fs->regs.cfa_how = CFA_REG_OFFSET; | |
68 fs->regs.cfa_reg = 15; | |
69 fs->regs.cfa_offset = cfa - (long) context->cfa; | |
70 | |
71 fs->regs.reg[0].how = REG_SAVED_OFFSET; | |
72 fs->regs.reg[0].loc.offset = (long) &sc->sc_d0 - cfa; | |
73 fs->regs.reg[1].how = REG_SAVED_OFFSET; | |
74 fs->regs.reg[1].loc.offset = (long) &sc->sc_d1 - cfa; | |
75 fs->regs.reg[8].how = REG_SAVED_OFFSET; | |
76 fs->regs.reg[8].loc.offset = (long) &sc->sc_a0 - cfa; | |
77 fs->regs.reg[9].how = REG_SAVED_OFFSET; | |
78 fs->regs.reg[9].loc.offset = (long) &sc->sc_a1 - cfa; | |
79 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
80 #ifdef __uClinux__ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
81 fs->regs.reg[13].how = REG_SAVED_OFFSET; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
82 fs->regs.reg[13].loc.offset = (long) &sc->sc_a5 - cfa; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
83 #endif |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
84 |
0 | 85 fs->regs.reg[24].how = REG_SAVED_OFFSET; |
86 fs->regs.reg[24].loc.offset = (long) &sc->sc_pc - cfa; | |
87 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
88 #ifndef __uClinux__ |
0 | 89 if (*(int *) sc->sc_fpstate) |
90 { | |
91 int *fpregs = (int *) sc->sc_fpregs; | |
92 | |
93 fs->regs.reg[16].how = REG_SAVED_OFFSET; | |
94 fs->regs.reg[16].loc.offset = (long) &fpregs[0] - cfa; | |
95 fs->regs.reg[17].how = REG_SAVED_OFFSET; | |
96 fs->regs.reg[17].loc.offset = (long) &fpregs[M68K_FP_SIZE/4] - cfa; | |
97 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
98 #elif defined __mcffpu__ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
99 # error Implement this when uClinux kernel is ported to an FPU architecture |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
100 #endif |
0 | 101 } |
102 #ifdef __mcoldfire__ | |
103 /* move.l #__NR_rt_sigreturn,%d0; trap #0 */ | |
104 else if (pc[0] == 0x203c && pc[1] == 0x0000 && | |
105 pc[2] == 0x00ad && pc[3] == 0x4e40) | |
106 #else | |
107 /* moveq #~__NR_rt_sigreturn,%d0; not.b %d0; trap #0 */ | |
108 else if (pc[0] == 0x7052 && pc[1] == 0x4600 && pc[2] == 0x4e40) | |
109 #endif | |
110 { | |
111 struct uw_ucontext *uc; | |
112 greg_t *gregs; | |
113 int i; | |
114 | |
115 /* Context is passed as the 3rd argument. */ | |
116 uc = *(struct uw_ucontext **) (context->cfa + 8); | |
117 | |
118 gregs = uc->uc_mcontext.gregs; | |
119 cfa = gregs[15]; | |
120 fs->regs.cfa_how = CFA_REG_OFFSET; | |
121 fs->regs.cfa_reg = 15; | |
122 fs->regs.cfa_offset = cfa - (long) context->cfa; | |
123 | |
124 /* register %d0-%d7/%a0-%a6 */ | |
125 for (i = 0; i <= 14; i++) | |
126 { | |
127 fs->regs.reg[i].how = REG_SAVED_OFFSET; | |
128 fs->regs.reg[i].loc.offset = (long) &gregs[i] - cfa; | |
129 } | |
130 | |
131 /* return address */ | |
132 fs->regs.reg[24].how = REG_SAVED_OFFSET; | |
133 fs->regs.reg[24].loc.offset = (long) &gregs[16] - cfa; | |
134 | |
135 #define uc_fpstate uc_filler[0] | |
136 | |
137 if (uc->uc_fpstate) | |
138 { | |
139 long fpregs = (long) uc->uc_mcontext.fpregs.f_fpregs; | |
140 | |
141 /* register %fp0-%fp7 */ | |
142 for (i = 16; i <= 23; i++) | |
143 { | |
144 fs->regs.reg[i].how = REG_SAVED_OFFSET; | |
145 fs->regs.reg[i].loc.offset = fpregs - cfa; | |
146 fpregs += M68K_FP_SIZE; | |
147 } | |
148 } | |
149 } | |
150 else | |
151 return _URC_END_OF_STACK; | |
152 | |
153 fs->retaddr_column = 24; | |
154 fs->signal_frame = 1; | |
155 | |
156 return _URC_NO_REASON; | |
157 } | |
158 #endif /* ifdef inhibit_libc */ |