/* src/vm/jit/powerpc/linux/md-os.c - machine dependent PowerPC Linux 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 5038 2006-06-19 22:22:34Z twisti $
-
*/
#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include <ucontext.h>
#include "vm/types.h"
+#include "vm/jit/powerpc/codegen.h"
#include "vm/jit/powerpc/linux/md-abi.h"
#if defined(ENABLE_THREADS)
#include "vm/jit/asmpart.h"
#if defined(ENABLE_PROFILING)
-# include "vm/jit/profile/profile.h"
+# include "vm/jit/optimizing/profile.h"
#endif
#include "vm/jit/stacktrace.h"
/* md_signal_handler_sigsegv ***************************************************
- NullPointerException signal handler for hardware null pointer
- check.
+ Signal handler for hardware-exceptions.
*******************************************************************************/
void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
{
- ucontext_t *_uc;
- mcontext_t *_mc;
- u4 instr;
- s4 reg;
- ptrint addr;
- u1 *pv;
- u1 *sp;
- u1 *ra;
- u1 *xpc;
+ stackframeinfo sfi;
+ ucontext_t *_uc;
+ mcontext_t *_mc;
+ unsigned long *_gregs;
+ u1 *pv;
+ u1 *sp;
+ u1 *ra;
+ u1 *xpc;
+ 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.uc_regs;
- instr = *((u4 *) _mc->gregs[PT_NIP]);
- reg = (instr >> 16) & 0x1f;
- addr = _mc->gregs[reg];
+#if defined(__UCLIBC__)
+ _mc = &(_uc->uc_mcontext);
+ _gregs = _mc->regs->gpr;
+#else
+ _mc = _uc->uc_mcontext.uc_regs;
+ _gregs = _mc->gregs;
+#endif
+
+ pv = (u1 *) _gregs[REG_PV];
+ sp = (u1 *) _gregs[REG_SP];
+ ra = (u1 *) _gregs[PT_LNK]; /* this is correct for leafs */
+ xpc = (u1 *) _gregs[PT_NIP];
+
+ /* get exception-throwing instruction */
+
+ mcode = *((u4 *) xpc);
+
+ 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 {
+ /* This is a normal NPE: addr must be NULL and the NPE-type
+ define is 0. */
+
+ addr = _gregs[s1];
+ type = EXCEPTION_HARDWARE_NULLPOINTER;
- if (addr == 0) {
- pv = (u1 *) _mc->gregs[REG_PV];
- sp = (u1 *) _mc->gregs[REG_SP];
- ra = (u1 *) _mc->gregs[PT_LNK]; /* this is correct for leafs */
- xpc = (u1 *) _mc->gregs[PT_NIP];
+ if (addr != 0)
+ vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", addr);
+ }
- _mc->gregs[REG_ITMP1_XPTR] =
- (ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc);
+ /* create stackframeinfo */
- _mc->gregs[REG_ITMP2_XPC] = (ptrint) xpc;
- _mc->gregs[PT_NIP] = (ptrint) asm_handle_exception;
+ stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
- } else {
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Segmentation fault: 0x%08lx at 0x%08lx",
- addr, _mc->gregs[PT_NIP]);
- }
+ /* 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) {
+ _gregs[REG_ITMP1_XPTR] = (intptr_t) p;
+ _gregs[REG_ITMP2_XPC] = (intptr_t) xpc;
+ _gregs[PT_NIP] = (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;
+ unsigned long *_gregs;
+ u1 *pv;
+ u1 *sp;
+ u1 *ra;
+ u1 *xpc;
+ u4 mcode;
+ int s1;
+ intptr_t val;
+ int type;
+ void *p;
+
+ _uc = (ucontext_t *) _p;
+
+#if defined(__UCLIBC__)
+ _mc = &(_uc->uc_mcontext);
+ _gregs = _mc->regs->gpr;
+#else
+ _mc = _uc->uc_mcontext.uc_regs;
+ _gregs = _mc->gregs;
+#endif
+
+ pv = (u1 *) _gregs[REG_PV];
+ sp = (u1 *) _gregs[REG_SP];
+ ra = (u1 *) _gregs[PT_LNK]; /* this is correct for leafs */
+ xpc = (u1 *) _gregs[PT_NIP];
+
+ /* 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);
+
+ /* set registers */
+
+ _gregs[REG_ITMP1_XPTR] = (intptr_t) p;
+ _gregs[REG_ITMP2_XPC] = (intptr_t) xpc;
+ _gregs[PT_NIP] = (intptr_t) asm_handle_exception;
}
*******************************************************************************/
+#if defined(ENABLE_THREADS)
void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
{
- threadobject *tobj;
- ucontext_t *_uc;
- mcontext_t *_mc;
- u1 *pc;
+ threadobject *tobj;
+ ucontext_t *_uc;
+ mcontext_t *_mc;
+ unsigned long *_gregs;
+ u1 *pc;
tobj = THREADOBJECT;
_uc = (ucontext_t *) _p;
- _mc = _uc->uc_mcontext.uc_regs;
- pc = (u1 *) _mc->gregs[PT_NIP];
+#if defined(__UCLIBC__)
+ _mc = &(_uc->uc_mcontext);
+ _gregs = _mc->regs->gpr;
+#else
+ _mc = _uc->uc_mcontext.uc_regs;
+ _gregs = _mc->gregs;
+#endif
+
+ pc = (u1 *) _gregs[PT_NIP];
tobj->pc = pc;
}
+#endif
+/* 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;
- u1 *pc;
- void *critical;
-
- _mc = _uc->uc_mcontext.uc_regs;
+ mcontext_t *_mc;
+ unsigned long *_gregs;
+ u1 *pc;
+ u1 *npc;
+
+#if defined(__UCLIBC__)
+ _mc = &(_uc->uc_mcontext);
+ _gregs = _mc->regs->gpr;
+#else
+ _mc = _uc->uc_mcontext.uc_regs;
+ _gregs = _mc->gregs;
+#endif
- pc = (u1 *) _mc->gregs[PT_NIP];
+ pc = (u1 *) _gregs[PT_NIP];
- critical = critical_find_restart_point(pc);
+ npc = critical_find_restart_point(pc);
- if (critical)
- _mc->gregs[PT_NIP] = (ptrint) critical;
+ if (npc != NULL)
+ _gregs[PT_NIP] = (ptrint) npc;
}
#endif