From: Michael Starzinger Date: Fri, 13 Mar 2009 15:01:44 +0000 (+0100) Subject: * src/vm/jit/powerpc64/linux/md-os.c: Simplified signal handlers. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=0c8a46702f4d12bcb93d8c74a644e107fa71540d * src/vm/jit/powerpc64/linux/md-os.c: Simplified signal handlers. * src/vm/jit/powerpc64/md-trap.h (MD_TRAP_COMPILER_FIXUP): Implemented. * src/vm/jit/powerpc64/md.c (md_trap_decode): Implemented. * src/vm/jit/powerpc64/patcher.c (patcher_is_valid_trap_instruction_at): Removed obsolete method. --HG-- branch : new-trap-decoding --- diff --git a/src/vm/jit/powerpc64/linux/md-os.c b/src/vm/jit/powerpc64/linux/md-os.c index 25d0b1bf4..23b1a5415 100644 --- a/src/vm/jit/powerpc64/linux/md-os.c +++ b/src/vm/jit/powerpc64/linux/md-os.c @@ -1,6 +1,6 @@ /* src/vm/jit/powerpc64/linux/md-os.c - machine dependent PowerPC64 Linux functions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2009 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO Copyright (C) 2008 Theobroma Systems Ltd. @@ -38,83 +38,25 @@ #include "threads/thread.hpp" -#include "vm/jit/builtin.hpp" #include "vm/signallocal.hpp" -#include "vm/os.hpp" #include "vm/jit/asmpart.h" #include "vm/jit/executionstate.h" - -#if defined(ENABLE_PROFILING) -# include "vm/jit/optimizing/profile.h" -#endif - -#include "vm/jit/disass.h" #include "vm/jit/trap.hpp" -/* md_signal_handler_sigsegv *************************************************** - - Signal handler for hardware-exceptions. - -*******************************************************************************/ - +/** + * Signal handler for hardware-exceptions. + */ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) { - 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; - - _uc = (ucontext_t *) _p; - _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]; + ucontext_t* _uc = (ucontext_t *) _p; + mcontext_t* _mc = &(_uc->uc_mcontext); - /* get the throwing instruction */ + void* xpc = (void*) _mc->gp_regs[PT_NIP]; - 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; - - if (type == TRAP_COMPILER) { - /* The XPC is the RA minus 1, because the RA points to the - instruction after the call. */ - - xpc = ra - 4; - } - } - else { - /* Normal NPE. */ - addr = _mc->gp_regs[s1]; - type = (int) addr; - } - - /* Handle the trap. */ - - trap_handle(type, val, pv, sp, ra, xpc, _p); + // Handle the trap. + trap_handle(TRAP_SIGSEGV, xpc, _p); } @@ -126,38 +68,10 @@ void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p) ucontext_t* _uc = (ucontext_t*) _p; mcontext_t* _mc = &(_uc->uc_mcontext); - /* get register values */ - - void* pv = (void*) _mc->gp_regs[REG_PV]; - void* sp = (void*) _mc->gp_regs[REG_SP]; - void* ra = (void*) _mc->gp_regs[PT_LNK]; // The RA is correct for leag methods. void* xpc =(void*) _mc->gp_regs[PT_NIP]; - // Get the illegal-instruction. - uint32_t mcode = *((uint32_t*) xpc); - - // Check if the trap instruction is valid. - // TODO Move this into patcher_handler. - if (patcher_is_valid_trap_instruction_at(xpc) == false) { - // Check if the PC has been patched during our way to this - // signal handler (see PR85). - if (patcher_is_patched_at(xpc) == true) - return; - - // We have a problem... - log_println("md_signal_handler_sigill: Unknown illegal instruction 0x%x at 0x%lx", mcode, xpc); -#if defined(ENABLE_DISASSEMBLER) - (void) disassinstr(xpc); -#endif - vm_abort("Aborting..."); - } - - // This signal is always a patcher. - int type = TRAP_PATCHER; - intptr_t val = 0; - // Handle the trap. - trap_handle(type, val, pv, sp, ra, xpc, _p); + trap_handle(TRAP_SIGILL, xpc, _p); } diff --git a/src/vm/jit/powerpc64/md-trap.h b/src/vm/jit/powerpc64/md-trap.h index 3830d1598..aeac454da 100644 --- a/src/vm/jit/powerpc64/md-trap.h +++ b/src/vm/jit/powerpc64/md-trap.h @@ -64,6 +64,17 @@ enum { TRAP_PATCHER = 99 // A large number. }; + +/** + * Macro to fixup a compiler stub. The XPC is the RA minus 4, + * because the RA points to the instruction after the call. + */ +#define MD_TRAP_COMPILER_FIXUP(xpc, ra, sp, pv) \ + do { \ + (xpc) = (void*) (((uintptr_t) (ra)) - 4); \ + } while(0) + + #endif /* _MD_TRAP_H */ diff --git a/src/vm/jit/powerpc64/md.c b/src/vm/jit/powerpc64/md.c index fd1019400..0b61ced6a 100644 --- a/src/vm/jit/powerpc64/md.c +++ b/src/vm/jit/powerpc64/md.c @@ -1,9 +1,7 @@ /* src/vm/jit/powerpc64/md.c - machine dependent PowerPC 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, 2009 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -157,6 +155,60 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr) } +/** + * Decode the trap instruction at the given PC. + * + * @param trp information about trap to be filled + * @param sig signal number + * @param xpc exception PC + * @param es execution state of the machine + * @return true if trap was decoded successfully, false otherwise. + */ +bool md_trap_decode(trapinfo_t* trp, int sig, void* xpc, executionstate_t* es) +{ + // Get the throwing instruction. + uint32_t mcode = *((uint32_t*) xpc); + + switch (sig) { + case TRAP_SIGILL: + // Check for valid trap instruction. + if (mcode == 0x00000000) { + trp->type = TRAP_PATCHER; + trp->value = 0; + return true; + } + return false; + + case TRAP_SIGSEGV: + { + // Decode the throwing instruction. + int s1 = M_INSTR_OP2_IMM_A(mcode); + int16_t disp = M_INSTR_OP2_IMM_I(mcode); + int d = M_INSTR_OP2_IMM_D(mcode); + + // We use the exception type as load displacement. + if (s1 == REG_ZERO) { + trp->type = disp; + trp->value = es->intregs[d]; + return true; + } + + // Default case is a normal NullPointerException. + if (es->intregs[s1] == 0) { + trp->type = TRAP_NullPointerException; + trp->value = 0; + return true; + } + + return false; + } + + default: + return false; + } +} + + /* md_patch_replacement_point ************************************************** Patch the given replacement point. diff --git a/src/vm/jit/powerpc64/patcher.c b/src/vm/jit/powerpc64/patcher.c index c923f8448..f5875a04e 100644 --- a/src/vm/jit/powerpc64/patcher.c +++ b/src/vm/jit/powerpc64/patcher.c @@ -66,22 +66,6 @@ void patcher_patch_code(patchref_t *pr) } -/** - * Check if the trap instruction at the given PC is valid. - * - * @param pc Program counter. - * - * @return true if valid, false otherwise. - */ -bool patcher_is_valid_trap_instruction_at(void* pc) -{ - uint32_t mcode = *((uint32_t*) pc); - - // Check for the undefined instruction we use. - return (mcode == 0x00000000); -} - - /* patcher_get_putstatic ******************************************************* Machine code: