CACAO
md-os.cpp
Go to the documentation of this file.
1 /* src/vm/jit/mips/linux/md-os.cpp - machine dependent MIPS Linux functions
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <cassert>
29 #include <sgidefs.h> /* required for _MIPS_SIM_ABI* defines (before signal.h) */
30 #include <signal.h>
31 #include <stdint.h>
32 #include <ucontext.h>
33 
34 #include "vm/types.hpp"
35 
36 #include "vm/jit/mips/codegen.hpp"
37 #include "vm/jit/mips/md.hpp"
38 #include "vm/jit/mips/md-abi.hpp"
39 
40 #include "mm/gc.hpp"
41 #include "mm/memory.hpp"
42 
43 #include "vm/signallocal.hpp"
44 
46 #include "vm/jit/trap.hpp"
47 
48 
49 /* md_init *********************************************************************
50 
51  Do some machine dependent initialization.
52 
53 *******************************************************************************/
54 
55 void md_init(void)
56 {
57  /* The Boehm GC initialization blocks the SIGSEGV signal. So we do
58  a dummy allocation here to ensure that the GC is
59  initialized. */
60 
61 #if defined(ENABLE_GC_BOEHM)
62  (void) GCNEW(int);
63 #endif
64 
65 #if 0
66  /* Turn off flush-to-zero */
67 
68  {
69  union fpc_csr n;
70  n.fc_word = get_fpc_csr();
71  n.fc_struct.flush = 0;
72  set_fpc_csr(n.fc_word);
73  }
74 #endif
75 }
76 
77 
78 /**
79  * NullPointerException signal handler for hardware null pointer check.
80  */
81 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
82 {
83  ucontext_t* _uc = (struct ucontext *) _p;
84  mcontext_t* _mc = &_uc->uc_mcontext;
85  void *xpc;
86 
87 #if !defined(__UCLIBC__)
88 # if ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 5))
89  /* NOTE: We only need this for pre glibc-2.5. */
90 
91  int disp = 0;
92  int cause;
93 
94  /* get the cause of this exception */
95  cause = _mc->cause;
96 
97  /* check the cause to find the faulting instruction */
98 
99  /* TODO: use defines for that stuff */
100 
101  switch (cause & 0x0000003c) {
102  case 0x00000008:
103  /* TLBL: XPC is ok */
104  break;
105 
106  case 0x00000010:
107  /* AdEL: XPC is of the following instruction */
108  disp -= 4;
109  break;
110  }
111  xpc = (void*) (_mc->pc + disp);
112 # else
113  xpc = (void*) _mc->pc;
114 # endif
115 #else
116  xpc = (void*) _gregs[CTX_EPC];
117 #endif
118 
119  // Handle the trap.
120  trap_handle(TRAP_SIGSEGV, xpc, _p);
121 }
122 
123 
124 /**
125  * Illegal Instruction signal handler for hardware exception checks.
126  */
127 void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p)
128 {
129  ucontext_t* _uc = (struct ucontext *) _p;
130  mcontext_t* _mc = &_uc->uc_mcontext;
131 
132 #if !defined(__UCLIBC__)
133  void* xpc = (void*) _mc->pc;
134 #else
135  void* xpc = (void*) _gregs[CTX_EPC];
136 #endif
137 
138  // Handle the trap.
139  trap_handle(TRAP_SIGILL, xpc, _p);
140 }
141 
142 
143 /* md_signal_handler_sigusr2 ***************************************************
144 
145  DOCUMENT ME
146 
147 *******************************************************************************/
148 
149 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
150 {
151 }
152 
153 
154 /**
155  * Read the given context into an executionstate.
156  *
157  * @param es execution state
158  * @param context machine context
159  */
160 void md_executionstate_read(executionstate_t* es, void* context)
161 {
162  ucontext_t* _uc;
163  mcontext_t* _mc;
164  greg_t* _gregs;
165  int i;
166 
167  _uc = (ucontext_t*) context;
168  _mc = &_uc->uc_mcontext;
169 
170 #if defined(__UCLIBC__)
171  _gregs = _mc->gpregs;
172 #else
173  _gregs = _mc->gregs;
174 #endif
175 
176  /* Read special registers. */
177 
178  /* In glibc's ucontext.h the registers are defined as long long,
179  even for MIPS32, so we cast them. This is not the case for
180  uClibc. */
181 
182 #if defined(__UCLIBC__)
183  es->pc = _gregs[CTX_EPC];
184 #else
185  es->pc = (uint8_t*) (uintptr_t) _mc->pc;
186 #endif
187 
188  es->sp = (uint8_t*) (uintptr_t) _gregs[REG_SP];
189  es->pv = (uint8_t*) (uintptr_t) _gregs[REG_PV];
190  es->ra = (uint8_t*) (uintptr_t) _gregs[REG_RA];
191 
192  /* Read integer registers. */
193 
194  for (i = 0; i < INT_REG_CNT; i++)
195  es->intregs[i] = _gregs[i];
196 
197  /* Read float registers. */
198 
199  /* Do not use the assignment operator '=', as the type of the
200  _mc->fpregs[i] can cause invalid conversions. */
201 
202  assert(sizeof(_mc->fpregs.fp_r) == sizeof(es->fltregs));
203  os::memcpy(&es->fltregs, &_mc->fpregs.fp_r, sizeof(_mc->fpregs.fp_r));
204 }
205 
206 
207 /**
208  * Write the given executionstate back to the context.
209  *
210  * @param es execution state
211  * @param context machine context
212  */
214 {
215  ucontext_t* _uc;
216  mcontext_t* _mc;
217  greg_t* _gregs;
218  int i;
219 
220  _uc = (ucontext_t *) context;
221  _mc = &_uc->uc_mcontext;
222 
223 #if defined(__UCLIBC__)
224  _gregs = _mc->gpregs;
225 #else
226  _gregs = _mc->gregs;
227 #endif
228 
229  /* Write integer registers. */
230 
231  for (i = 0; i < INT_REG_CNT; i++)
232  _gregs[i] = es->intregs[i];
233 
234  /* Write float registers. */
235 
236  /* Do not use the assignment operator '=', as the type of the
237  _mc->fpregs[i] can cause invalid conversions. */
238 
239  assert(sizeof(_mc->fpregs.fp_r) == sizeof(es->fltregs));
240  os::memcpy(&_mc->fpregs.fp_r, &es->fltregs, sizeof(_mc->fpregs.fp_r));
241 
242  /* Write special registers. */
243 
244 #if defined(__UCLIBC__)
245  _gregs[CTX_EPC] = es->pc;
246 #else
247  _mc->pc = (uintptr_t) es->pc;
248 #endif
249 
250  _gregs[REG_SP] = (uintptr_t) es->sp;
251  _gregs[REG_PV] = (uintptr_t) es->pv;
252  _gregs[REG_RA] = (uintptr_t) es->ra;
253 }
254 
255 
256 /*
257  * These are local overrides for various environment variables in Emacs.
258  * Please do not remove this and leave it at the end of the file, where
259  * Emacs will automagically detect them.
260  * ---------------------------------------------------------------------
261  * Local variables:
262  * mode: c++
263  * indent-tabs-mode: t
264  * c-basic-offset: 4
265  * tab-width: 4
266  * End:
267  * vim:noexpandtab:sw=4:ts=4:
268  */
#define REG_SP
Definition: md-abi.hpp:53
#define REG_PV
Definition: md-abi.hpp:42
#define GCNEW(type)
Definition: memory.hpp:117
void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
NullPointerException signal handler for hardware null pointer check.
Definition: md-os.cpp:50
void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
Illegal Instruction signal handler for hardware exception checks.
Definition: md-os.cpp:65
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
struct sigcontext uc_mcontext
Definition: md-os.cpp:42
#define INT_REG_CNT
Definition: md-abi.hpp:72
#define xpc
Definition: md-asm.hpp:51
void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
Definition: md-os.cpp:83
MIIterator i
static void * memcpy(void *dest, const void *src, size_t n)
Definition: os.hpp:492
void md_executionstate_write(executionstate_t *es, void *context)
Definition: md-os.cpp:147
#define REG_RA
Definition: md-abi.hpp:41
CONTEXT mcontext_t
Definition: ucontext.h:27
void md_executionstate_read(executionstate_t *es, void *context)
Definition: md-os.cpp:107
void trap_handle(int sig, void *xpc, void *context)
Handles the signal which is generated by trap instructions, caught by a signal handler and calls the ...
Definition: trap.cpp:101
uintptr_t intregs[INT_REG_CNT]
void md_init(void)
Definition: md.cpp:48
double fltregs[FLT_REG_CNT]