* Merged in twisti-branch.
[cacao.git] / src / vm / jit / powerpc64 / linux / md-os.c
index c726f59b8fbc4f05c8b5385e959cc858e2d660f4..ef265d2c44f87a2010d9ee25e3b99f60ae830b28 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc64/linux/md-os.c - machine dependent PowerPC64 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 5279 2006-08-25 11:55:21Z tbfg $
+   $Id: md-os.c 7582 2007-03-26 09:27:10Z tbfg $
 
 */
 
@@ -40,6 +34,7 @@
 
 #include "vm/types.h"
 
+#include "vm/jit/powerpc64/codegen.h"
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
 #if defined(ENABLE_THREADS)
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
+
 #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;
+       ucontext_t      *_uc;
+       mcontext_t      *_mc;
+       u1              *pv;
+       u1              *sp;
+       u1              *ra;
+       u1              *xpc;
+       u4              mcode;
+       s4              s1;
+       s4              disp;
+       s4              d;
+       s4              type;
+       ptrint          addr;
+       ptrint          val;
+       java_objectheader *e;
 
        _uc = (ucontext_t *) _p;
        _mc = &(_uc->uc_mcontext);
-       
-
-       instr = *((u4 *) _mc->gp_regs[PT_NIP]);
-       reg = (instr >> 16) & 0x1f;
-       addr = _mc->gp_regs[reg];
-
-       if (addr == 0) {
-               pv  = (u1 *) _mc->gp_regs[REG_PV];
-               sp  = (u1 *) _mc->gp_regs[REG_SP];
-               ra  = (u1 *) _mc->gp_regs[PT_LNK];         /* this is correct for leafs */
-               xpc = (u1 *) _mc->gp_regs[PT_NIP];
-
-               _mc->gp_regs[REG_ITMP1_XPTR] =
-                       (ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc);
-
-               _mc->gp_regs[REG_ITMP2_XPC] = (ptrint) xpc;
-               _mc->gp_regs[PT_NIP] = (ptrint) asm_handle_exception;
 
-       } else {
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Segmentation fault: 0x%08lx at 0x%08lx",
-                                                                  addr, _mc->gp_regs[PT_NIP]);
-       }               
+       /* get register values */
+       pv = (u1*) _mc->gp_regs[REG_PV];
+       sp = (u1*) _mc->gp_regs[REG_SP];
+       ra = (u1*) _mc->gp_regs[PT_LNK];                     /* correct for leafs */
+       xpc =(u1*) _mc->gp_regs[PT_NIP];
+
+       /* get the 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  = _mc->gp_regs[d];
+
+       if (s1 == REG_ZERO)     {
+               /* we use the exception type as load displacement */
+               type = disp;
+       } else  {
+               /* normal NPE */
+               addr = _mc->gp_regs[s1];
+               type = (s4) addr;
+       }
+       e = exceptions_new_hardware_exception(pv, sp, ra, xpc, type, val);
+
+       _mc->gp_regs[REG_ITMP1]     = (ptrint) e;
+       _mc->gp_regs[REG_ITMP2_XPC] = (ptrint) xpc;
+       _mc->gp_regs[PT_NIP]        = (ptrint) asm_handle_exception;
 }
 
 
@@ -142,7 +147,7 @@ void thread_restartcriticalsection(ucontext_t *_uc)
 
        critical = critical_find_restart_point(pc);
 
-       if (critical)
+       if (critical != NULL)
                _mc->gp_regs[PT_NIP] = (ptrint) critical;
 }
 #endif