* Removed all Id tags.
[cacao.git] / src / vm / jit / powerpc / darwin / md-os.c
index bd31e9775dd6e850ddd2f82025ad3fdf4111488b..2086b8eac341d7c1242b6cc4a2830aa1687081f2 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 4357 2006-01-22 23:33:38Z twisti $
-
 */
 
 
 #include "config.h"
 
+#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;
-       ptrint              addr;
        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;
        _ss = &_mc->ss;
 
-       /* check for NullPointerException */
+       /* immitate a gregs array */
 
        gregs = &_ss->r0;
 
-       instr = *((u4 *) _ss->srr0);
-       reg = (instr >> 16) & 31;
-       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;
+
+       /* 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)
+                       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);
 
-       if (addr == 0) {
-               pv  = (u1 *) _ss->r13;
-               sp  = (u1 *) _ss->r1;
-               ra  = (u1 *) _ss->lr;              /* this is correct for leafs */
-               xpc = (u1 *) _ss->srr0;
+       /* remove stackframeinfo */
 
-               _ss->r11 =
-                       (ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc);
+       stacktrace_remove_stackframeinfo(&sfi);
 
-               _ss->r12 = (ptrint) xpc;
-               _ss->srr0 = (ptrint) asm_handle_exception;
+       /* set registers (only if exception object ready) */
 
-       } else {
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                          "Segmentation fault: 0x%08lx at 0x%08lx",
-                                          addr, _ss->srr0);
+       if (p != NULL) {
+               _ss->r11  = (intptr_t) p;
+               _ss->r12  = (intptr_t) xpc;
+               _ss->srr0 = (intptr_t) asm_handle_exception;
        }
 }
 
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-void thread_restartcriticalsection(ucontext_t *uc)
+/* 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);
+
+       /* set registers */
+
+       _ss->r11  = (intptr_t) p;
+       _ss->r12  = (intptr_t) xpc;
+       _ss->srr0 = (intptr_t) asm_handle_exception;
+}
+
+
+/* md_signal_handler_sigusr2 ***************************************************
+
+   Signal handler for profiling sampling.
+
+*******************************************************************************/
+
+void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 {
-       /* XXX set pc to restart address */
+       threadobject       *t;
+       ucontext_t         *_uc;
+       mcontext_t          _mc;
+       ppc_thread_state_t *_ss;
+       u1                 *pc;
+
+       t = THREADOBJECT;
+
+       _uc = (ucontext_t *) _p;
+       _mc = _uc->uc_mcontext;
+       _ss = &_mc->ss;
+
+       pc = (u1 *) _ss->srr0;
+
+       t->pc = pc;
+}
+
+
+/* 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 md_critical_section_restart(ucontext_t *_uc)
+{
+       mcontext_t          _mc;
+       ppc_thread_state_t *_ss;
+       u1                 *pc;
+       u1                 *npc;
+
+       _mc = _uc->uc_mcontext;
+       _ss = &_mc->ss;
+
+       pc = (u1 *) _ss->srr0;
+
+       npc = critical_find_restart_point(pc);
+
+       if (npc != NULL)
+               _ss->srr0 = (ptrint) npc;
 }
 #endif