Line data Source code
1 : /* src/vm/jit/x86_64/linux/md-os.cpp - machine dependent x86_64 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 : #ifndef _GNU_SOURCE
27 : # define _GNU_SOURCE
28 : #endif
29 :
30 : #include "config.h"
31 :
32 : #include <cassert>
33 : #include <cstdlib>
34 : #include <stdint.h>
35 : #include <ucontext.h>
36 :
37 : #include "vm/types.hpp"
38 :
39 : #include "vm/jit/x86_64/codegen.hpp"
40 : #include "vm/jit/x86_64/md.hpp"
41 :
42 : #include "threads/thread.hpp"
43 :
44 : #include "vm/signallocal.hpp"
45 :
46 : #include "vm/jit/executionstate.hpp"
47 : #include "vm/jit/trap.hpp"
48 :
49 :
50 : /**
51 : * Signal handler for hardware exception.
52 : */
53 147223 : void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
54 : {
55 147223 : ucontext_t* _uc = (ucontext_t *) _p;
56 147223 : mcontext_t* _mc = &_uc->uc_mcontext;
57 :
58 : /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
59 : different to the ones in <ucontext.h>. */
60 :
61 147223 : void* xpc = (void*) _mc->gregs[REG_RIP];
62 :
63 : // Handle the trap.
64 147223 : trap_handle(TRAP_SIGSEGV, xpc, _p);
65 147223 : }
66 :
67 :
68 : /**
69 : * ArithmeticException signal handler for hardware divide by zero
70 : * check.
71 : */
72 8 : void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
73 : {
74 8 : ucontext_t* _uc = (ucontext_t *) _p;
75 8 : mcontext_t* _mc = &_uc->uc_mcontext;
76 :
77 : /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
78 : different to the ones in <ucontext.h>. */
79 :
80 8 : void* xpc = (void*) _mc->gregs[REG_RIP];
81 :
82 : // Handle the trap.
83 8 : trap_handle(TRAP_SIGFPE, xpc, _p);
84 8 : }
85 :
86 :
87 : /**
88 : * Signal handler for patchers.
89 : */
90 71147 : void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
91 : {
92 71147 : ucontext_t* _uc = (ucontext_t *) _p;
93 71147 : mcontext_t* _mc = &_uc->uc_mcontext;
94 :
95 : /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
96 : different to the ones in <ucontext.h>. */
97 :
98 71147 : void* xpc = (void*) _mc->gregs[REG_RIP];
99 :
100 : // Handle the trap.
101 71147 : trap_handle(TRAP_SIGILL, xpc, _p);
102 71147 : }
103 :
104 :
105 : /* md_signal_handler_sigusr2 ***************************************************
106 :
107 : Signal handler for profiling sampling.
108 :
109 : *******************************************************************************/
110 :
111 0 : void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
112 : {
113 : threadobject *t;
114 : ucontext_t *_uc;
115 : mcontext_t *_mc;
116 : u1 *pc;
117 :
118 0 : t = THREADOBJECT;
119 :
120 0 : _uc = (ucontext_t *) _p;
121 0 : _mc = &_uc->uc_mcontext;
122 :
123 : /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
124 : different to the ones in <ucontext.h>. */
125 :
126 0 : pc = (u1 *) _mc->gregs[REG_RIP];
127 :
128 0 : t->pc = pc;
129 0 : }
130 :
131 :
132 : /* md_executionstate_read ******************************************************
133 :
134 : Read the given context into an executionstate.
135 :
136 : *******************************************************************************/
137 :
138 655134 : void md_executionstate_read(executionstate_t *es, void *context)
139 : {
140 : ucontext_t *_uc;
141 : mcontext_t *_mc;
142 : s4 i;
143 : s4 d;
144 :
145 655134 : _uc = (ucontext_t *) context;
146 655134 : _mc = &_uc->uc_mcontext;
147 :
148 : /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
149 : different to the ones in <ucontext.h>. */
150 :
151 : /* read special registers */
152 655134 : es->pc = (u1 *) _mc->gregs[REG_RIP];
153 655134 : es->sp = (u1 *) _mc->gregs[REG_RSP];
154 655134 : es->pv = NULL;
155 :
156 : /* read integer registers */
157 11137217 : for (i = 0; i < INT_REG_CNT; i++) {
158 : /* XXX FIX ME! */
159 :
160 10482083 : switch (i) {
161 : case 0: /* REG_RAX == 13 */
162 655133 : d = REG_RAX;
163 655133 : break;
164 : case 1: /* REG_RCX == 14 */
165 655133 : d = REG_RCX;
166 655133 : break;
167 : case 2: /* REG_RDX == 12 */
168 655132 : d = REG_RDX;
169 655132 : break;
170 : case 3: /* REG_RBX == 11 */
171 655132 : d = REG_RBX;
172 655132 : break;
173 : case 4: /* REG_RSP == 15 */
174 655133 : d = REG_RSP;
175 655133 : break;
176 : case 5: /* REG_RBP == 10 */
177 655133 : d = REG_RBP;
178 655133 : break;
179 : case 6: /* REG_RSI == 9 */
180 655133 : d = REG_RSI;
181 655133 : break;
182 : case 7: /* REG_RDI == 8 */
183 655133 : d = REG_RDI;
184 655133 : break;
185 : case 8: /* REG_R8 == 0 */
186 : case 9: /* REG_R9 == 1 */
187 : case 10: /* REG_R10 == 2 */
188 : case 11: /* REG_R11 == 3 */
189 : case 12: /* REG_R12 == 4 */
190 : case 13: /* REG_R13 == 5 */
191 : case 14: /* REG_R14 == 6 */
192 : case 15: /* REG_R15 == 7 */
193 5241063 : d = i - 8;
194 : break;
195 : }
196 :
197 10482083 : es->intregs[i] = _mc->gregs[d];
198 : }
199 :
200 : /* read float registers */
201 11137268 : for (i = 0; i < FLT_REG_CNT; i++)
202 10482134 : es->fltregs[i] = 0xdeadbeefdeadbeefL;
203 655134 : }
204 :
205 :
206 : /* md_executionstate_write *****************************************************
207 :
208 : Write the given executionstate back to the context.
209 :
210 : *******************************************************************************/
211 :
212 436755 : void md_executionstate_write(executionstate_t *es, void *context)
213 : {
214 : ucontext_t *_uc;
215 : mcontext_t *_mc;
216 : s4 i;
217 : s4 d;
218 :
219 436755 : _uc = (ucontext_t *) context;
220 436755 : _mc = &_uc->uc_mcontext;
221 :
222 : /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
223 : different to the ones in <ucontext.h>. */
224 :
225 : /* write integer registers */
226 7424810 : for (i = 0; i < INT_REG_CNT; i++) {
227 : /* XXX FIX ME! */
228 :
229 6988055 : switch (i) {
230 : case 0: /* REG_RAX == 13 */
231 436755 : d = REG_RAX;
232 436755 : break;
233 : case 1: /* REG_RCX == 14 */
234 436755 : d = REG_RCX;
235 436755 : break;
236 : case 2: /* REG_RDX == 12 */
237 436755 : d = REG_RDX;
238 436755 : break;
239 : case 3: /* REG_RBX == 11 */
240 436755 : d = REG_RBX;
241 436755 : break;
242 : case 4: /* REG_RSP == 15 */
243 436755 : d = REG_RSP;
244 436755 : break;
245 : case 5: /* REG_RBP == 10 */
246 436755 : d = REG_RBP;
247 436755 : break;
248 : case 6: /* REG_RSI == 9 */
249 436755 : d = REG_RSI;
250 436755 : break;
251 : case 7: /* REG_RDI == 8 */
252 436755 : d = REG_RDI;
253 436755 : break;
254 : case 8: /* REG_R8 == 0 */
255 : case 9: /* REG_R9 == 1 */
256 : case 10: /* REG_R10 == 2 */
257 : case 11: /* REG_R11 == 3 */
258 : case 12: /* REG_R12 == 4 */
259 : case 13: /* REG_R13 == 5 */
260 : case 14: /* REG_R14 == 6 */
261 : case 15: /* REG_R15 == 7 */
262 3494033 : d = i - 8;
263 : break;
264 : }
265 :
266 6988055 : _mc->gregs[d] = es->intregs[i];
267 : }
268 :
269 : /* write special registers */
270 436755 : _mc->gregs[REG_RIP] = (ptrint) es->pc;
271 436755 : _mc->gregs[REG_RSP] = (ptrint) es->sp;
272 436755 : }
273 :
274 :
275 : /*
276 : * These are local overrides for various environment variables in Emacs.
277 : * Please do not remove this and leave it at the end of the file, where
278 : * Emacs will automagically detect them.
279 : * ---------------------------------------------------------------------
280 : * Local variables:
281 : * mode: c++
282 : * indent-tabs-mode: t
283 : * c-basic-offset: 4
284 : * tab-width: 4
285 : * End:
286 : * vim:noexpandtab:sw=4:ts=4:
287 : */
|