X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Flinux%2Fmd-os.c;h=f48ca785803a4468b54bd94fa0db3976747b3174;hb=735bdda890a385d1fa9cc532faadbbc96f2d1218;hp=8b6deac4a8db8b9e391145bd69ade437628a4768;hpb=75929e9ff50764b00d10154b97da698c936385e0;p=cacao.git diff --git a/src/vm/jit/mips/linux/md-os.c b/src/vm/jit/mips/linux/md-os.c index 8b6deac4a..f48ca7858 100644 --- a/src/vm/jit/mips/linux/md-os.c +++ b/src/vm/jit/mips/linux/md-os.c @@ -1,9 +1,7 @@ /* src/vm/jit/mips/linux/md-os.c - machine dependent MIPS Linux functions - 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 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2009 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,8 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md-os.c 7683 2007-04-10 21:37:03Z twisti $ - */ @@ -32,20 +28,22 @@ #include #include /* required for _MIPS_SIM_ABI* defines (before signal.h) */ #include +#include #include #include "vm/types.h" #include "vm/jit/mips/codegen.h" +#include "vm/jit/mips/md.h" #include "vm/jit/mips/md-abi.h" -#include "mm/gc-common.h" +#include "mm/gc.hpp" +#include "mm/memory.hpp" -#include "vm/exceptions.h" -#include "vm/stringlocal.h" +#include "vm/signallocal.hpp" -#include "vm/jit/asmpart.h" -#include "vm/jit/stacktrace.h" +#include "vm/jit/executionstate.h" +#include "vm/jit/trap.hpp" /* md_init ********************************************************************* @@ -56,11 +54,12 @@ void md_init(void) { - /* The Boehm GC initialization blocks the SIGSEGV signal. So we do a */ - /* dummy allocation here to ensure that the GC is initialized. */ + /* The Boehm GC initialization blocks the SIGSEGV signal. So we do + a dummy allocation here to ensure that the GC is + initialized. */ #if defined(ENABLE_GC_BOEHM) - heap_allocate(1, 0, NULL); + (void) GCNEW(int); #endif #if 0 @@ -76,54 +75,21 @@ void md_init(void) } -/* md_signal_handler_sigsegv *************************************************** - - NullPointerException signal handler for hardware null pointer - check. - -*******************************************************************************/ - +/** + * NullPointerException signal handler for hardware null pointer check. + */ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) { - ucontext_t *_uc; - mcontext_t *_mc; - greg_t *_gregs; - u1 *pv; - u1 *sp; - u1 *ra; - u1 *xpc; - unsigned int cause; - u4 mcode; - s4 d; - s4 s1; - s4 disp; - ptrint val; - ptrint addr; - s4 type; - java_objectheader *o; - - _uc = (struct ucontext *) _p; - _mc = &_uc->uc_mcontext; - -#if defined(__UCLIBC__) - _gregs = _mc->gpregs; -#else - _gregs = _mc->gregs; -#endif - - /* In glibc's ucontext.h the registers are defined as long long, - even for MIPS32, so we cast them. This is not the case for - uClibc. */ - - pv = (u1 *) (ptrint) _gregs[REG_PV]; - sp = (u1 *) (ptrint) _gregs[REG_SP]; - ra = (u1 *) (ptrint) _gregs[REG_RA]; /* this is correct for leafs */ - -#if !defined(__UCLIBC__) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 5)) + int disp = 0; + int cause; + ucontext_t* _uc = (struct ucontext *) _p; + mcontext_t* _mc = &_uc->uc_mcontext; + void *xpc; + +#if !defined(__UCLIBC__) +# if ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 5)) /* NOTE: We only need this for pre glibc-2.5. */ - xpc = (u1 *) (ptrint) _mc->pc; - /* get the cause of this exception */ cause = _mc->cause; @@ -139,92 +105,152 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) case 0x00000010: /* AdEL: XPC is of the following instruction */ - xpc = xpc - 4; + disp -= 4; break; } + xpc = (void*) (_mc->pc + disp); +# else + xpc = (void*) _mc->pc; +# endif #else - xpc = (u1 *) (ptrint) _gregs[CTX_EPC]; + xpc = (void*) _gregs[CTX_EPC]; #endif - /* get exception-throwing instruction */ + // Handle the trap. + trap_handle(TRAP_SIGSEGV, xpc, _p); +} - mcode = *((u4 *) xpc); - d = M_ITYPE_GET_RT(mcode); - s1 = M_ITYPE_GET_RS(mcode); - disp = M_ITYPE_GET_IMM(mcode); +/** + * Illegal Instruction signal handler for hardware exception checks. + */ +void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p) +{ + ucontext_t* _uc = (struct ucontext *) _p; + mcontext_t* _mc = &_uc->uc_mcontext; - /* check for special-load */ +#if !defined(__UCLIBC__) + void* xpc = (void*) _mc->pc; +#else + void* xpc = (void*) _gregs[CTX_EPC]; +#endif - if (s1 == REG_ZERO) { - /* we use the exception type as load displacement */ + // Handle the trap. + trap_handle(TRAP_SIGILL, xpc, _p); +} - type = disp; - val = _gregs[d]; - } - else { - /* This is a normal NPE: addr must be NULL and the NPE-type - define is 0. */ - addr = _gregs[s1]; - type = (s4) addr; - val = 0; - } +/* md_signal_handler_sigusr2 *************************************************** - /* generate appropriate exception */ + DOCUMENT ME - o = exceptions_new_hardware_exception(pv, sp, ra, xpc, type, val); +*******************************************************************************/ - /* set registers */ +void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) +{ +} - _gregs[REG_ITMP1_XPTR] = (ptrint) o; - _gregs[REG_ITMP2_XPC] = (ptrint) xpc; + +/** + * Read the given context into an executionstate. + * + * @param es execution state + * @param context machine context + */ +void md_executionstate_read(executionstate_t* es, void* context) +{ + ucontext_t* _uc; + mcontext_t* _mc; + greg_t* _gregs; + int i; + + _uc = (ucontext_t*) context; + _mc = &_uc->uc_mcontext; #if defined(__UCLIBC__) - _gregs[CTX_EPC] = (ptrint) asm_handle_exception; + _gregs = _mc->gpregs; +#else + _gregs = _mc->gregs; +#endif + + /* Read special registers. */ + + /* In glibc's ucontext.h the registers are defined as long long, + even for MIPS32, so we cast them. This is not the case for + uClibc. */ + +#if defined(__UCLIBC__) + es->pc = _gregs[CTX_EPC]; #else - _mc->pc = (ptrint) asm_handle_exception; + es->pc = (void*) (uintptr_t) _mc->pc; #endif -} + es->sp = (void*) (uintptr_t) _gregs[REG_SP]; + es->pv = (void*) (uintptr_t) _gregs[REG_PV]; + es->ra = (void*) (uintptr_t) _gregs[REG_RA]; -/* md_signal_handler_sigusr2 *************************************************** + /* Read integer registers. */ - DOCUMENT ME + for (i = 0; i < INT_REG_CNT; i++) + es->intregs[i] = _gregs[i]; -*******************************************************************************/ + /* Read float registers. */ -void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) -{ + /* Do not use the assignment operator '=', as the type of the + _mc->fpregs[i] can cause invalid conversions. */ + + assert(sizeof(_mc->fpregs.fp_r) == sizeof(es->fltregs)); + os_memcpy(&es->fltregs, &_mc->fpregs.fp_r, sizeof(_mc->fpregs.fp_r)); } -#if defined(ENABLE_THREADS) -void thread_restartcriticalsection(ucontext_t *_uc) +/** + * Write the given executionstate back to the context. + * + * @param es execution state + * @param context machine context + */ +void md_executionstate_write(executionstate_t* es, void* context) { - mcontext_t *_mc; - u1 *pc; - u1 *npc; + ucontext_t* _uc; + mcontext_t* _mc; + greg_t* _gregs; + int i; + _uc = (ucontext_t *) context; _mc = &_uc->uc_mcontext; #if defined(__UCLIBC__) - pc = (u1 *) (ptrint) _mc->gpregs[CTX_EPC]; -#else - pc = (u1 *) (ptrint) _mc->pc; + _gregs = _mc->gpregs; +#else + _gregs = _mc->gregs; #endif - npc = critical_find_restart_point(pc); + /* Write integer registers. */ + + for (i = 0; i < INT_REG_CNT; i++) + _gregs[i] = es->intregs[i]; + + /* Write float registers. */ + + /* Do not use the assignment operator '=', as the type of the + _mc->fpregs[i] can cause invalid conversions. */ + + assert(sizeof(_mc->fpregs.fp_r) == sizeof(es->fltregs)); + os_memcpy(&_mc->fpregs.fp_r, &es->fltregs, sizeof(_mc->fpregs.fp_r)); + + /* Write special registers. */ - if (npc != NULL) { #if defined(__UCLIBC__) - _mc->gpregs[CTX_EPC] = (ptrint) npc; + _gregs[CTX_EPC] = es->pc; #else - _mc->pc = (ptrint) npc; + _mc->pc = (uintptr_t) es->pc; #endif - } + + _gregs[REG_SP] = (uintptr_t) es->sp; + _gregs[REG_PV] = (uintptr_t) es->pv; + _gregs[REG_RA] = (uintptr_t) es->ra; } -#endif /*