1 /* src/vm/jit/trap.c - hardware traps
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
30 /* Include machine dependent trap stuff. */
34 #include "native/llni.h"
36 #include "toolbox/logging.h"
38 #include "vm/exceptions.h"
41 #include "vm/jit/code.h"
42 #include "vm/jit/disass.h"
43 #include "vm/jit/jit.h"
44 #include "vm/jit/methodtree.h"
45 #include "vm/jit/patcher-common.h"
46 #include "vm/jit/replace.h"
47 #include "vm/jit/stacktrace.h"
49 #include "vmcore/options.h"
50 #include "vmcore/system.h"
54 * Mmap the first memory page to support hardware exceptions and check
55 * the maximum hardware trap displacement on the architectures where
56 * it is required (TRAP_INSTRUCTION_IS_LOAD defined to 1).
60 #if !(defined(__ARM__) && defined(__LINUX__))
61 /* On arm-linux the first memory page can't be mmap'ed, as it
62 contains the exception vectors. */
66 /* mmap a memory page at address 0x0, so our hardware-exceptions
69 pagesize = system_getpagesize();
71 (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
74 TRACESUBSYSTEMINITIALIZATION("trap_init");
76 #if !defined(TRAP_INSTRUCTION_IS_LOAD)
77 # error TRAP_INSTRUCTION_IS_LOAD is not defined in your md-trap.h
80 #if TRAP_INSTRUCTION_IS_LOAD == 1
81 /* Check if we get into trouble with our hardware-exceptions. */
83 if (TRAP_END > OFFSET(java_bytearray_t, data))
84 vm_abort("trap_init: maximum hardware trap displacement is greater than the array-data offset: %d > %d", TRAP_END, OFFSET(java_bytearray_t, data));
90 * Handles the signal which is generated by trap instructions, caught
91 * by a signal handler and calls the correct function.
93 * @param type trap number
96 void* trap_handle(int type, intptr_t val, void *pv, void *sp, void *ra, void *xpc, void *context)
106 log_println("[signal_handle: trap %d]", type);
109 #if defined(ENABLE_VMLOG)
110 vmlog_cacao_signl_type(type);
113 /* Prevent compiler warnings. */
118 /* wrap the value into a handle if it is a reference */
119 /* BEFORE: creating stackframeinfo */
122 case TRAP_ClassCastException:
123 o = LLNI_WRAP((java_object_t *) val);
127 /* In this case the passed PV points to the compiler stub. We
128 get the methodinfo pointer here and set PV to NULL so
129 stacktrace_stackframeinfo_add determines the PV for the
130 parent Java method. */
132 m = code_get_methodinfo_for_pv(pv);
141 /* Fill and add a stackframeinfo. */
143 stacktrace_stackframeinfo_add(&sfi, pv, sp, ra, xpc);
146 case TRAP_NullPointerException:
147 p = exceptions_new_nullpointerexception();
150 case TRAP_ArithmeticException:
151 p = exceptions_new_arithmeticexception();
154 case TRAP_ArrayIndexOutOfBoundsException:
156 p = exceptions_new_arrayindexoutofboundsexception(index);
159 case TRAP_ArrayStoreException:
160 p = exceptions_new_arraystoreexception();
163 case TRAP_ClassCastException:
164 p = exceptions_new_classcastexception(o);
167 case TRAP_CHECK_EXCEPTION:
168 p = exceptions_fillinstacktrace();
172 #if defined(ENABLE_REPLACEMENT)
173 if (replace_me_wrapper(xpc, context)) {
178 p = patcher_handler(xpc);
182 p = jit_compile_handle(m, sfi.pv, ra, (void *) val);
186 /* Let's try to get a backtrace. */
188 (void) methodtree_find(xpc);
190 /* If that does not work, print more debug info. */
192 log_println("signal_handle: unknown hardware exception type %d", type);
194 #if SIZEOF_VOID_P == 8
195 log_println("PC=0x%016lx", xpc);
197 log_println("PC=0x%08x", xpc);
200 #if defined(ENABLE_DISASSEMBLER)
201 log_println("machine instruction at PC:");
205 vm_abort("Exiting...");
207 /* keep compiler happy */
212 /* Remove stackframeinfo. */
214 stacktrace_stackframeinfo_remove(&sfi);
216 /* unwrap and return the exception object */
217 /* AFTER: removing stackframeinfo */
219 if (type == TRAP_COMPILER)
222 return LLNI_UNWRAP(p);
227 * These are local overrides for various environment variables in Emacs.
228 * Please do not remove this and leave it at the end of the file, where
229 * Emacs will automagically detect them.
230 * ---------------------------------------------------------------------
233 * indent-tabs-mode: t