-/* src/vm/jit/powerpc64/linux/md-os.c - machine dependent PowerPC Linux functions
+/* 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 5081 2006-07-06 13:59:01Z tbfg $
+ $Id: md-os.c 8283 2007-08-09 15:10:05Z twisti $
*/
#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include <ucontext.h>
#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) {}
-void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) {}
-void thread_restartcriticalsection(ucontext_t *_uc) {}
-
-#if 0
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;
+ u1 *pv;
+ u1 *sp;
+ u1 *ra;
+ u1 *xpc;
+ u4 mcode;
+ int s1;
+ int16_t disp;
+ int d;
+ int type;
+ intptr_t addr;
+ intptr_t val;
+ void *p;
_uc = (ucontext_t *) _p;
- _mc = _uc->uc_mcontext.uc_regs;
+ _mc = &(_uc->uc_mcontext);
+
+ /* 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);
- instr = *((u4 *) _mc->gregs[PT_NIP]);
- reg = (instr >> 16) & 0x1f;
- addr = _mc->gregs[reg];
+ val = _mc->gp_regs[d];
- 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 (s1 == REG_ZERO) {
+ /* we use the exception type as load displacement */
+ type = disp;
+ }
+ else {
+ /* normal NPE */
+ addr = _mc->gp_regs[s1];
+ type = (s4) 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);
+
+ _mc->gp_regs[REG_ITMP1] = (intptr_t) p;
+ _mc->gp_regs[REG_ITMP2_XPC] = (intptr_t) xpc;
+ _mc->gp_regs[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;
tobj = THREADOBJECT;
_uc = (ucontext_t *) _p;
- _mc = _uc->uc_mcontext.uc_regs;
+ _mc = &(_uc->uc_mcontext);
- pc = (u1 *) _mc->gregs[PT_NIP];
+ pc = (u1 *) _mc->gp_regs[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;
+ u1 *npc;
- _mc = _uc->uc_mcontext.uc_regs;
+ _mc = &(_uc->uc_mcontext);
- pc = (u1 *) _mc->gregs[PT_NIP];
+ pc = (u1 *) _mc->gp_regs[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)
+ _mc->gp_regs[PT_NIP] = (ptrint) npc;
}
#endif
-#endif
/*
* These are local overrides for various environment variables in Emacs.