* Removed all Id tags.
[cacao.git] / src / vm / jit / powerpc / linux / md-os.c
index 5357ec91aba38ca91b4b86dbf995401b4fd202d4..1a9d6d98cf639d78eabec587e5cae083e29a6bc6 100644 (file)
@@ -1,6 +1,6 @@
 /* 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)
@@ -52,7 +46,7 @@
 #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;
 }
 
 
@@ -110,39 +216,63 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
 *******************************************************************************/
 
+#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