X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fx86_64%2Flinux%2Fmd-os.c;h=6f3d2ce2d8785d46d300b0be5d2ab4f0fff352b1;hb=735bdda890a385d1fa9cc532faadbbc96f2d1218;hp=a814540e73701878e9283f7235a21d92652ae512;hpb=97183c85163cc1e2c0e5910a244527c25aece8a7;p=cacao.git diff --git a/src/vm/jit/x86_64/linux/md-os.c b/src/vm/jit/x86_64/linux/md-os.c index a814540e7..6f3d2ce2d 100644 --- a/src/vm/jit/x86_64/linux/md-os.c +++ b/src/vm/jit/x86_64/linux/md-os.c @@ -1,9 +1,7 @@ /* src/vm/jit/x86_64/linux/md-os.c - machine dependent x86_64 Linux functions - Copyright (C) 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) 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -37,291 +35,70 @@ #include "vm/types.h" #include "vm/jit/x86_64/codegen.h" +#include "vm/jit/x86_64/md.h" -#if defined(ENABLE_THREADS) -# include "threads/native/threads.h" -#endif +#include "threads/thread.hpp" -#include "vm/exceptions.h" -#include "vm/signallocal.h" +#include "vm/signallocal.hpp" #include "vm/jit/asmpart.h" -#include "vm/jit/stacktrace.h" - - -/* md_signal_handler_sigsegv *************************************************** - - Signal handler for hardware exception. +#include "vm/jit/executionstate.h" +#include "vm/jit/trap.hpp" -*******************************************************************************/ +/** + * Signal handler for hardware exception. + */ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) { - ucontext_t *_uc; - mcontext_t *_mc; - u1 *sp; - u1 *ra; - u1 *xpc; - u1 opc; - u1 mod; - u1 rm; - s4 d; - s4 disp; - int type; - intptr_t val; - void *p; - java_handle_t *o; - - _uc = (ucontext_t *) _p; - _mc = &_uc->uc_mcontext; + ucontext_t* _uc = (ucontext_t *) _p; + mcontext_t* _mc = &_uc->uc_mcontext; /* ATTENTION: Don't use CACAO's internal REG_* defines as they are different to the ones in . */ - sp = (u1 *) _mc->gregs[REG_RSP]; - xpc = (u1 *) _mc->gregs[REG_RIP]; - ra = xpc; /* return address is equal to xpc */ - -#if 0 - /* check for StackOverflowException */ - - threads_check_stackoverflow(sp); -#endif - - /* get exception-throwing instruction */ - - opc = M_ALD_MEM_GET_OPC(xpc); - mod = M_ALD_MEM_GET_MOD(xpc); - rm = M_ALD_MEM_GET_RM(xpc); - - /* for values see emit_mov_mem_reg and emit_mem */ - - if ((opc == 0x8b) && (mod == 0) && (rm == 4)) { - /* this was a hardware-exception */ - - d = M_ALD_MEM_GET_REG(xpc); - disp = M_ALD_MEM_GET_DISP(xpc); - - /* we use the exception type as load displacement */ - - type = disp; - - /* XXX FIX ME! */ - - /* ATTENTION: The _mc->gregs layout is even worse than on - i386! See /usr/include/sys/ucontext.h. We need a - switch-case here... */ - - switch (d) { - case 0: /* REG_RAX == 13 */ - d = REG_RAX; - break; - case 1: /* REG_RCX == 14 */ - d = REG_RCX; - break; - case 2: /* REG_RDX == 12 */ - d = REG_RDX; - break; - case 3: /* REG_RBX == 11 */ - d = REG_RBX; - break; - case 4: /* REG_RSP == 15 */ - d = REG_RSP; - break; - case 5: /* REG_RBP == 10 */ - d = REG_RBP; - break; - case 6: /* REG_RSI == 9 */ - d = REG_RSI; - break; - case 7: /* REG_RDI == 8 */ - d = REG_RDI; - break; - case 8: /* REG_R8 == 0 */ - case 9: /* REG_R9 == 1 */ - case 10: /* REG_R10 == 2 */ - case 11: /* REG_R11 == 3 */ - case 12: /* REG_R12 == 4 */ - case 13: /* REG_R13 == 5 */ - case 14: /* REG_R14 == 6 */ - case 15: /* REG_R15 == 7 */ - d = d - 8; - break; - } - - val = _mc->gregs[d]; - - if (type == EXCEPTION_HARDWARE_COMPILER) { - /* We use a framesize of zero here because the call pushed - the return addres onto the stack. */ - - ra = md_stacktrace_get_returnaddress(sp, 0); - - /* And remove the RA from the stack. */ - - sp = sp + 1 * SIZEOF_VOID_P; - } - } - else { - /* this was a normal NPE */ - - type = EXCEPTION_HARDWARE_NULLPOINTER; - val = 0; - } + void* xpc = (void*) _mc->gregs[REG_RIP]; - /* Handle the type. */ - - p = signal_handle(type, val, NULL, sp, ra, xpc, _p); - - /* Set registers. */ - - if (type == EXCEPTION_HARDWARE_COMPILER) { - if (p == NULL) { - o = exceptions_get_and_clear_exception(); - - ra = ra - 3; /* XPC is before the actual call */ - - _mc->gregs[REG_RSP] = (uintptr_t) sp; /* Remove RA from stack. */ - - _mc->gregs[REG_RAX] = (uintptr_t) o; - _mc->gregs[REG_R10] = (uintptr_t) ra; /* REG_ITMP2_XPC */ - _mc->gregs[REG_RIP] = (uintptr_t) asm_handle_exception; - } - else { - _mc->gregs[REG_RIP] = (uintptr_t) p; - } - } - else { - _mc->gregs[REG_RAX] = (uintptr_t) p; - _mc->gregs[REG_R10] = (uintptr_t) xpc; /* REG_ITMP2_XPC */ - _mc->gregs[REG_RIP] = (uintptr_t) asm_handle_exception; - } + // Handle the trap. + trap_handle(TRAP_SIGSEGV, xpc, _p); } -/* md_signal_handler_sigfpe **************************************************** - - ArithmeticException signal handler for hardware divide by zero - check. - -*******************************************************************************/ - +/** + * ArithmeticException signal handler for hardware divide by zero + * check. + */ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p) { - ucontext_t *_uc; - mcontext_t *_mc; - u1 *pv; - u1 *sp; - u1 *ra; - u1 *xpc; - int type; - intptr_t val; - void *p; - - _uc = (ucontext_t *) _p; - _mc = &_uc->uc_mcontext; + ucontext_t* _uc = (ucontext_t *) _p; + mcontext_t* _mc = &_uc->uc_mcontext; /* ATTENTION: Don't use CACAO's internal REG_* defines as they are different to the ones in . */ - pv = NULL; - sp = (u1 *) _mc->gregs[REG_RSP]; - xpc = (u1 *) _mc->gregs[REG_RIP]; - ra = xpc; /* return address is equal to xpc */ - - /* this is an ArithmeticException */ + void* xpc = (void*) _mc->gregs[REG_RIP]; - type = EXCEPTION_HARDWARE_ARITHMETIC; - val = 0; - - /* Handle the type. */ - - p = signal_handle(type, val, pv, sp, ra, xpc, _p); - - /* set registers */ - - _mc->gregs[REG_RAX] = (intptr_t) p; - _mc->gregs[REG_R10] = (intptr_t) xpc; /* REG_ITMP2_XPC */ - _mc->gregs[REG_RIP] = (intptr_t) asm_handle_exception; + // Handle the trap. + trap_handle(TRAP_SIGFPE, xpc, _p); } -/* md_signal_handler_sigill **************************************************** - - Signal handler for patchers. - -*******************************************************************************/ - +/** + * Signal handler for patchers. + */ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p) { - ucontext_t *_uc; - mcontext_t *_mc; - u1 *pv; - u1 *sp; - u1 *ra; - u1 *xpc; - int type; - intptr_t val; - void *p; - - _uc = (ucontext_t *) _p; - _mc = &_uc->uc_mcontext; - - /* ATTENTION: Don't use CACAO's internal REG_* defines as they are - different to the ones in . */ - - pv = NULL; - sp = (u1 *) _mc->gregs[REG_RSP]; - xpc = (u1 *) _mc->gregs[REG_RIP]; - ra = xpc; /* return address is equal to xpc */ - - /* This is a patcher. */ - - type = EXCEPTION_HARDWARE_PATCHER; - val = 0; - - /* Handle the type. */ - - p = signal_handle(type, val, pv, sp, ra, xpc, _p); - - /* set registers */ - - if (p != NULL) { - _mc->gregs[REG_RAX] = (intptr_t) p; - _mc->gregs[REG_R10] = (intptr_t) xpc; /* REG_ITMP2_XPC */ - _mc->gregs[REG_RIP] = (intptr_t) asm_handle_exception; - } -} - - -/* md_signal_handler_sigusr1 *************************************************** - - Signal handler for suspending threads. - -*******************************************************************************/ - -#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO) -void md_signal_handler_sigusr1(int sig, siginfo_t *siginfo, void *_p) -{ - ucontext_t *_uc; - mcontext_t *_mc; - u1 *pc; - u1 *sp; - - _uc = (ucontext_t *) _p; - _mc = &_uc->uc_mcontext; + ucontext_t* _uc = (ucontext_t *) _p; + mcontext_t* _mc = &_uc->uc_mcontext; /* ATTENTION: Don't use CACAO's internal REG_* defines as they are different to the ones in . */ - /* get the PC and SP for this thread */ - pc = (u1 *) _mc->gregs[REG_RIP]; - sp = (u1 *) _mc->gregs[REG_RSP]; + void* xpc = (void*) _mc->gregs[REG_RIP]; - /* now suspend the current thread */ - threads_suspend_ack(pc, sp); + // Handle the trap. + trap_handle(TRAP_SIGILL, xpc, _p); } -#endif /* md_signal_handler_sigusr2 *************************************************** @@ -353,14 +130,13 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) #endif -/* md_replace_executionstate_read ********************************************** +/* md_executionstate_read ****************************************************** - Read the given context into an executionstate for Replacement. + Read the given context into an executionstate. *******************************************************************************/ -#if defined(ENABLE_REPLACEMENT) -void md_replace_executionstate_read(executionstate_t *es, void *context) +void md_executionstate_read(executionstate_t *es, void *context) { ucontext_t *_uc; mcontext_t *_mc; @@ -370,8 +146,11 @@ void md_replace_executionstate_read(executionstate_t *es, void *context) _uc = (ucontext_t *) context; _mc = &_uc->uc_mcontext; + /* ATTENTION: Don't use CACAO's internal REG_* defines as they are + different to the ones in . */ + /* read special registers */ - es->pc = (u1 *) _mc->gregs[REG_RSP]; + es->pc = (u1 *) _mc->gregs[REG_RIP]; es->sp = (u1 *) _mc->gregs[REG_RSP]; es->pv = NULL; @@ -423,17 +202,15 @@ void md_replace_executionstate_read(executionstate_t *es, void *context) for (i = 0; i < FLT_REG_CNT; i++) es->fltregs[i] = 0xdeadbeefdeadbeefL; } -#endif -/* md_replace_executionstate_write ********************************************* +/* md_executionstate_write ***************************************************** - Write the given executionstate back to the context for Replacement. + Write the given executionstate back to the context. *******************************************************************************/ -#if defined(ENABLE_REPLACEMENT) -void md_replace_executionstate_write(executionstate_t *es, void *context) +void md_executionstate_write(executionstate_t *es, void *context) { ucontext_t *_uc; mcontext_t *_mc; @@ -443,6 +220,9 @@ void md_replace_executionstate_write(executionstate_t *es, void *context) _uc = (ucontext_t *) context; _mc = &_uc->uc_mcontext; + /* ATTENTION: Don't use CACAO's internal REG_* defines as they are + different to the ones in . */ + /* write integer registers */ for (i = 0; i < INT_REG_CNT; i++) { /* XXX FIX ME! */ @@ -491,36 +271,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context) _mc->gregs[REG_RIP] = (ptrint) es->pc; _mc->gregs[REG_RSP] = (ptrint) es->sp; } -#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 md_critical_section_restart(ucontext_t *_uc) -{ - mcontext_t *_mc; - u1 *pc; - u1 *npc; - - _mc = &_uc->uc_mcontext; - - /* ATTENTION: Don't use CACAO's internal REG_* defines as they are - different to the ones in . */ - - pc = (u1 *) _mc->gregs[REG_RIP]; - - npc = critical_find_restart_point(pc); - - if (npc != NULL) - _mc->gregs[REG_RIP] = (ptrint) npc; -} -#endif /*