X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc%2Flinux%2Fmd-os.c;h=edfc86d203085a4752ccbbdf3b399a56b9d04795;hb=167cdb4568b39860841183e6886bfc2bb0c28887;hp=d56123600db2948fe3902ca1974c3ef0688c7b46;hpb=7659949229c634784f7d27aa8b679fdd4c8351ab;p=cacao.git diff --git a/src/vm/jit/powerpc/linux/md-os.c b/src/vm/jit/powerpc/linux/md-os.c index d56123600..edfc86d20 100644 --- a/src/vm/jit/powerpc/linux/md-os.c +++ b/src/vm/jit/powerpc/linux/md-os.c @@ -2,6 +2,7 @@ Copyright (C) 1996-2005, 2006, 2007, 2008 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2008 Theobroma Systems Ltd. This file is part of CACAO. @@ -35,25 +36,23 @@ #include "vm/jit/powerpc/md.h" #include "vm/jit/powerpc/linux/md-abi.h" -#include "threads/thread.h" +#include "threads/thread.hpp" -#include "vm/builtin.h" -#include "vm/exceptions.h" +#include "vm/jit/builtin.hpp" #include "vm/signallocal.h" -#include "vm/stringlocal.h" +#include "vm/os.hpp" #include "vm/jit/asmpart.h" +#include "vm/jit/disass.h" #include "vm/jit/executionstate.h" #if defined(ENABLE_PROFILING) # include "vm/jit/optimizing/profile.h" #endif -#include "vm/jit/stacktrace.h" +#include "vm/jit/patcher-common.hpp" #include "vm/jit/trap.h" -#include "vmcore/system.h" - /* md_signal_handler_sigsegv *************************************************** @@ -154,12 +153,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) /* fall-through */ - case TRAP_PATCHER: - if (p == NULL) - break; - - /* fall-through */ - default: _gregs[REG_ITMP1_XPTR] = (uintptr_t) p; _gregs[REG_ITMP2_XPC] = (uintptr_t) xpc; @@ -168,6 +161,66 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) } +/** + * Signal handler for patcher calls. + */ +void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p) +{ + ucontext_t* _uc = (ucontext_t*) _p; + mcontext_t* _mc; + unsigned long* _gregs; + +#if defined(__UCLIBC__) + _mc = &(_uc->uc_mcontext); + _gregs = _mc->regs->gpr; +#else + _mc = _uc->uc_mcontext.uc_regs; + _gregs = _mc->gregs; +#endif + + /* get register values */ + + void* pv = (void*) _gregs[REG_PV]; + void* sp = (void*) _gregs[REG_SP]; + void* ra = (void*) _gregs[PT_LNK]; // The RA is correct for leag methods. + void* xpc =(void*) _gregs[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. + void* p = trap_handle(type, val, pv, sp, ra, xpc, _p); + + // Set registers if we have an exception, continue execution + // otherwise. + if (p != NULL) { + _gregs[REG_ITMP1_XPTR] = (uintptr_t) p; + _gregs[REG_ITMP2_XPC] = (uintptr_t) xpc; + _gregs[PT_NIP] = (uintptr_t) asm_handle_exception; + } +} + + /* md_signal_handler_sigtrap *************************************************** Signal handler for hardware-traps. @@ -335,7 +388,7 @@ void md_executionstate_read(executionstate_t *es, void *context) * the _mc->fpregs[i] can cause invalid conversions. */ assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs)); - system_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs)); + os_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs)); } @@ -370,7 +423,7 @@ void md_executionstate_write(executionstate_t *es, void *context) * the _mc->fpregs[i] can cause invalid conversions. */ assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs)); - system_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs)); + os_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs)); /* write special registers */ _gregs[PT_NIP] = (ptrint) es->pc;