X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc%2Fdarwin%2Fmd-os.c;h=2086b8eac341d7c1242b6cc4a2830aa1687081f2;hb=9f859ad50d3d5d98c185d40b86b2179bc4dc9aeb;hp=bd31e9775dd6e850ddd2f82025ad3fdf4111488b;hpb=ad92477479aeed17382996ab43a7ca0dfab2ba93;p=cacao.git diff --git a/src/vm/jit/powerpc/darwin/md-os.c b/src/vm/jit/powerpc/darwin/md-os.c index bd31e9775..2086b8eac 100644 --- a/src/vm/jit/powerpc/darwin/md-os.c +++ b/src/vm/jit/powerpc/darwin/md-os.c @@ -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 @@ -22,30 +22,30 @@ 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 #include +#include #include #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" @@ -59,54 +59,208 @@ 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