/* src/vm/jit/powerpc/darwin/md-os.c - machine dependent PowerPC Darwin functions
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
J. Wenninger, Institut f. Computersprachen - TU Wien
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
- Changes:
-
- $Id: md-os.c 6123 2006-12-05 21:10:54Z twisti $
-
*/
#include <assert.h>
#include <signal.h>
+#include <stdint.h>
#include <ucontext.h>
#include "vm/types.h"
+#include "vm/jit/powerpc/codegen.h"
#include "vm/jit/powerpc/darwin/md-abi.h"
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#endif
+
#include "vm/exceptions.h"
#include "vm/global.h"
#include "vm/signallocal.h"
#include "vm/stringlocal.h"
+
#include "vm/jit/asmpart.h"
#include "vm/jit/stacktrace.h"
void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
{
+ stackframeinfo sfi;
ucontext_t *_uc;
mcontext_t _mc;
ppc_thread_state_t *_ss;
ptrint *gregs;
- u4 instr;
- s4 reg;
- s4 disp;
- ptrint addr;
u1 *pv;
u1 *sp;
u1 *ra;
u1 *xpc;
- stackframeinfo sfi;
- java_objectheader *o;
+ u4 mcode;
+ int s1;
+ int16_t disp;
+ int d;
+ intptr_t addr;
+ intptr_t val;
+ int type;
+ void *p;
_uc = (ucontext_t *) _p;
_mc = _uc->uc_mcontext;
_ss = &_mc->ss;
- /* check for NullPointerException */
+ /* immitate a gregs array */
gregs = &_ss->r0;
- instr = *((u4 *) _ss->srr0);
- reg = (instr >> 16) & 31;
- disp = (instr & 0xffff);
- addr = gregs[reg];
+ /* get register values */
pv = (u1 *) _ss->r13;
sp = (u1 *) _ss->r1;
ra = (u1 *) _ss->lr; /* this is correct for leafs */
xpc = (u1 *) _ss->srr0;
- /* create stackframeinfo */
+ /* get exception-throwing instruction */
- stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
+ mcode = *((u4 *) xpc);
- if (reg == REG_ZERO) {
- switch (disp) {
- case EXCEPTION_LOAD_DISP_ARITHMETIC:
- vm_abort("ArithmeticException");
- break;
- case EXCEPTION_LOAD_DISP_ARRAYINDEXOUTOFBOUNDS:
- log_println("ArrayIndexOutOfBoundsException");
- o = new_arrayindexoutofboundsexception(0);
- break;
- case EXCEPTION_LOAD_DISP_CLASSCAST:
- vm_abort("ClassCastException");
- break;
- default:
- vm_abort("unknown exception %d", disp);
- }
- }
- else if (addr == 0) {
- o = exceptions_new_nullpointerexception();
+ s1 = M_INSTR_OP2_IMM_A(mcode);
+ disp = M_INSTR_OP2_IMM_I(mcode);
+ d = M_INSTR_OP2_IMM_D(mcode);
+
+ val = gregs[d];
+
+ /* check for special-load */
+
+ if (s1 == REG_ZERO) {
+ /* we use the exception type as load displacement */
+
+ type = disp;
}
else {
- codegen_get_pv_from_pc(xpc);
+ /* This is a normal NPE: addr must be NULL and the NPE-type
+ define is 0. */
- /* this should not happen */
+ addr = gregs[s1];
+ type = EXCEPTION_HARDWARE_NULLPOINTER;
- assert(0);
+ if (addr != 0)
+ vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", addr);
}
+ /* create stackframeinfo */
+
+ stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
+
+ /* Handle the type. */
+
+ p = signal_handle(xpc, type, val);
+
+ /* remove stackframeinfo */
+
+ stacktrace_remove_stackframeinfo(&sfi);
+
+ /* set registers (only if exception object ready) */
+
+ if (p != NULL) {
+ _ss->r11 = (intptr_t) p;
+ _ss->r12 = (intptr_t) xpc;
+ _ss->srr0 = (intptr_t) asm_handle_exception;
+ }
+}
+
+
+/* md_signal_handler_sigtrap ***************************************************
+
+ Signal handler for hardware-traps.
+
+*******************************************************************************/
+
+void md_signal_handler_sigtrap(int sig, siginfo_t *siginfo, void *_p)
+{
+ stackframeinfo sfi;
+ ucontext_t *_uc;
+ mcontext_t _mc;
+ ppc_thread_state_t *_ss;
+ ptrint *gregs;
+ u1 *pv;
+ u1 *sp;
+ u1 *ra;
+ u1 *xpc;
+ u4 mcode;
+ int s1;
+ intptr_t val;
+ int type;
+ void *p;
+
+ _uc = (ucontext_t *) _p;
+ _mc = _uc->uc_mcontext;
+ _ss = &_mc->ss;
+
+ /* immitate a gregs array */
+
+ gregs = &_ss->r0;
+
+ /* get register values */
+
+ pv = (u1 *) _ss->r13;
+ sp = (u1 *) _ss->r1;
+ ra = (u1 *) _ss->lr; /* this is correct for leafs */
+ xpc = (u1 *) _ss->srr0;
+
+ /* get exception-throwing instruction */
+
+ mcode = *((u4 *) xpc);
+
+ s1 = M_OP3_GET_A(mcode);
+
+ /* for now we only handle ArrayIndexOutOfBoundsException */
+
+ type = EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS;
+ val = gregs[s1];
+
+ /* create stackframeinfo */
+
+ stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
+
+ /* Handle the type. */
+
+ p = signal_handle(xpc, type, val);
+
/* remove stackframeinfo */
stacktrace_remove_stackframeinfo(&sfi);
- _ss->r11 = (ptrint) o;
- _ss->r12 = (ptrint) xpc;
- _ss->srr0 = (ptrint) asm_handle_exception;
+ /* set registers */
+
+ _ss->r11 = (intptr_t) p;
+ _ss->r12 = (intptr_t) xpc;
+ _ss->srr0 = (intptr_t) asm_handle_exception;
}
}
+/* md_critical_section_restart *************************************************
+
+ Search the critical sections tree for a matching section and set
+ the PC to the restart point, if necessary.
+
+*******************************************************************************/
+
#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
+void md_critical_section_restart(ucontext_t *_uc)
{
mcontext_t _mc;
ppc_thread_state_t *_ss;
- void *critical;
+ u1 *pc;
+ u1 *npc;
_mc = _uc->uc_mcontext;
_ss = &_mc->ss;
- critical = critical_find_restart_point((void *) _ss->srr0);
+ pc = (u1 *) _ss->srr0;
+
+ npc = critical_find_restart_point(pc);
- if (critical)
- _ss->srr0 = (ptrint) critical;
+ if (npc != NULL)
+ _ss->srr0 = (ptrint) npc;
}
#endif