c356c5957708345fbfc65e2eedcc9a3fafa857a9
[cacao.git] / src / vm / jit / alpha / linux / md-os.c
1 /* src/vm/jit/alpha/linux/md-os.c - machine dependent Alpha Linux functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32 #include <ucontext.h>
33
34 #include "vm/types.h"
35
36 #include "vm/jit/alpha/codegen.h"
37 #include "vm/jit/alpha/md-abi.h"
38
39 #if defined(ENABLE_THREADS)
40 # include "threads/native/threads.h"
41 #endif
42
43 #include "vm/signallocal.h"
44
45 #include "vm/jit/asmpart.h"
46 #include "vm/jit/stacktrace.h"
47
48
49 /* md_signal_handler_sigsegv ***************************************************
50
51    NullPointerException signal handler for hardware null pointer
52    check.
53
54 *******************************************************************************/
55
56 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
57 {
58         ucontext_t     *_uc;
59         mcontext_t     *_mc;
60         u1             *pv;
61         u1             *sp;
62         u1             *ra;
63         u1             *xpc;
64         u4              mcode;
65         s4              d;
66         s4              s1;
67         s4              disp;
68         intptr_t        val;
69         intptr_t        addr;
70         int             type;
71         void           *p;
72
73         _uc = (ucontext_t *) _p;
74         _mc = &_uc->uc_mcontext;
75
76         pv  = (u1 *) _mc->sc_regs[REG_PV];
77         sp  = (u1 *) _mc->sc_regs[REG_SP];
78         ra  = (u1 *) _mc->sc_regs[REG_RA];           /* this is correct for leafs */
79         xpc = (u1 *) _mc->sc_pc;
80
81         /* get exception-throwing instruction */
82
83         mcode = *((u4 *) xpc);
84
85         d    = M_MEM_GET_Ra(mcode);
86         s1   = M_MEM_GET_Rb(mcode);
87         disp = M_MEM_GET_Memory_disp(mcode);
88
89         val  = _mc->sc_regs[d];
90
91         /* check for special-load */
92
93         if (s1 == REG_ZERO) {
94                 /* we use the exception type as load displacement */
95
96                 type = disp;
97         }
98         else {
99                 /* This is a normal NPE: addr must be NULL and the NPE-type
100                    define is 0. */
101
102                 addr = _mc->sc_regs[s1];
103                 type = (int) addr;
104         }
105
106         /* Handle the type. */
107
108         p = signal_handle(type, val, pv, sp, ra, xpc, _p);
109
110         /* set registers */
111
112         if (p != NULL) {
113                 _mc->sc_regs[REG_ITMP1_XPTR] = (intptr_t) p;
114                 _mc->sc_regs[REG_ITMP2_XPC]  = (intptr_t) xpc;
115                 _mc->sc_pc                   = (intptr_t) asm_handle_exception;
116         }
117 }
118
119
120 /* md_signal_handler_sigusr1 ***************************************************
121
122    Signal handler for suspending threads.
123
124 *******************************************************************************/
125
126 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
127 void md_signal_handler_sigusr1(int sig, siginfo_t *siginfo, void *_p)
128 {
129         ucontext_t *_uc;
130         mcontext_t *_mc;
131         u1         *pc;
132         u1         *sp;
133
134         _uc = (ucontext_t *) _p;
135         _mc = &_uc->uc_mcontext;
136
137         /* get the PC and SP for this thread */
138         pc = (u1 *) _mc->sc_pc;
139         sp = (u1 *) _mc->sc_regs[REG_SP];
140
141         /* now suspend the current thread */
142         threads_suspend_ack(pc, sp);
143 }
144 #endif
145
146
147 /* md_signal_handler_sigusr2 ***************************************************
148
149    Signal handler for profiling sampling.
150
151 *******************************************************************************/
152
153 #if defined(ENABLE_THREADS)
154 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
155 {
156         threadobject *tobj;
157         ucontext_t   *_uc;
158         mcontext_t   *_mc;
159         u1           *pc;
160
161         tobj = THREADOBJECT;
162
163         _uc = (ucontext_t *) _p;
164         _mc = &_uc->uc_mcontext;
165
166         pc = (u1 *) _mc->sc_pc;
167
168         tobj->pc = pc;
169 }
170 #endif
171
172
173 /* md_replace_executionstate_read **********************************************
174
175    Read the given context into an executionstate for Replacement.
176
177 *******************************************************************************/
178
179 #if defined(ENABLE_REPLACEMENT)
180 void md_replace_executionstate_read(executionstate_t *es, void *context)
181 {
182         ucontext_t *_uc;
183         mcontext_t *_mc;
184         s4          i;
185
186         _uc = (ucontext_t *) context;
187         _mc = &_uc->uc_mcontext;
188
189         /* read special registers */
190         es->pc = (u1 *) _mc->sc_pc;
191         es->sp = (u1 *) _mc->sc_regs[REG_SP];
192         es->pv = (u1 *) _mc->sc_regs[REG_PV];
193
194         /* read integer registers */
195         for (i = 0; i < INT_REG_CNT; i++)
196                 es->intregs[i] = _mc->sc_regs[i];
197
198         /* read float registers */
199         for (i = 0; i < FLT_REG_CNT; i++)
200                 es->fltregs[i] = _mc->sc_fpregs[i];
201 }
202 #endif
203
204
205 /* md_replace_executionstate_write *********************************************
206
207    Write the given executionstate back to the context for Replacement.
208
209 *******************************************************************************/
210
211 #if defined(ENABLE_REPLACEMENT)
212 void md_replace_executionstate_write(executionstate_t *es, void *context)
213 {
214         ucontext_t *_uc;
215         mcontext_t *_mc;
216         s4          i;
217
218         _uc = (ucontext_t *) context;
219         _mc = &_uc->uc_mcontext;
220
221         /* write integer registers */
222         for (i = 0; i < INT_REG_CNT; i++)
223                 _mc->sc_regs[i] = es->intregs[i];
224
225         /* write float registers */
226         for (i = 0; i < FLT_REG_CNT; i++)
227                 _mc->sc_fpregs[i] = es->fltregs[i];
228
229         /* write special registers */
230         _mc->sc_pc           = (ptrint) es->pc;
231         _mc->sc_regs[REG_SP] = (ptrint) es->sp;
232         _mc->sc_regs[REG_PV] = (ptrint) es->pv;
233 }
234 #endif
235
236
237 /* md_critical_section_restart *************************************************
238
239    Search the critical sections tree for a matching section and set
240    the PC to the restart point, if necessary.
241
242 *******************************************************************************/
243
244 #if defined(ENABLE_THREADS)
245 void md_critical_section_restart(ucontext_t *_uc)
246 {
247         mcontext_t *_mc;
248         u1         *pc;
249         u1         *npc;
250
251         _mc = &_uc->uc_mcontext;
252
253         pc = (u1 *) _mc->sc_pc;
254
255         npc = critical_find_restart_point(pc);
256
257         if (npc != NULL)
258                 _mc->sc_pc = (ptrint) npc;
259 }
260 #endif
261
262
263 /*
264  * These are local overrides for various environment variables in Emacs.
265  * Please do not remove this and leave it at the end of the file, where
266  * Emacs will automagically detect them.
267  * ---------------------------------------------------------------------
268  * Local variables:
269  * mode: c
270  * indent-tabs-mode: t
271  * c-basic-offset: 4
272  * tab-width: 4
273  * End:
274  */