X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fx86_64%2Flinux%2Fmd-os.c;h=aa81679c819f0efe948371c6c05d4665e8040fa3;hb=b76e356b0af200d2568e6fc55e82e233f1808eb9;hp=608add2f775fbda0c9f9d71c5eafe6e5ffa7b3a0;hpb=83879b304d381e289660d8c173b9eb42f3983818;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 608add2f7..aa81679c8 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. @@ -22,8 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md.c 7249 2007-01-29 19:32:52Z twisti $ - */ @@ -39,15 +35,16 @@ #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.h" +#include "vm/builtin.h" #include "vm/exceptions.h" #include "vm/signallocal.h" #include "vm/jit/asmpart.h" +#include "vm/jit/executionstate.h" #include "vm/jit/stacktrace.h" @@ -59,9 +56,9 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) { - stackframeinfo sfi; ucontext_t *_uc; mcontext_t *_mc; + void *pv; u1 *sp; u1 *ra; u1 *xpc; @@ -73,6 +70,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) int type; intptr_t val; void *p; + java_object_t *o; _uc = (ucontext_t *) _p; _mc = &_uc->uc_mcontext; @@ -80,9 +78,10 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) /* ATTENTION: Don't use CACAO's internal REG_* defines as they are different to the ones in . */ + pv = NULL; /* is resolved during stackframeinfo creation */ sp = (u1 *) _mc->gregs[REG_RSP]; xpc = (u1 *) _mc->gregs[REG_RIP]; - ra = xpc; /* return address is equal to xpc */ + ra = xpc; /* return address is equal to XPC */ #if 0 /* check for StackOverflowException */ @@ -152,6 +151,26 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) } val = _mc->gregs[d]; + + if (type == EXCEPTION_HARDWARE_COMPILER) { + /* The PV from the compiler stub is equal to the XPC. */ + + pv = xpc; + + /* We use a framesize of zero here because the call pushed + the return addres onto the stack. */ + + ra = md_stacktrace_get_returnaddress(sp, 0); + + /* Skip the RA on the stack. */ + + sp = sp + 1 * SIZEOF_VOID_P; + + /* The XPC is the RA minus 1, because the RA points to the + instruction after the call. */ + + xpc = ra - 3; + } } else { /* this was a normal NPE */ @@ -160,23 +179,31 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) val = 0; } - /* create stackframeinfo */ - - stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, xpc); - /* Handle the type. */ - p = signal_handle(xpc, type, val); + p = signal_handle(type, val, pv, sp, ra, xpc, _p); - /* remove stackframeinfo */ + /* Set registers. */ - stacktrace_remove_stackframeinfo(&sfi); + if (type == EXCEPTION_HARDWARE_COMPILER) { + if (p == NULL) { + o = builtin_retrieve_exception(); - /* set registers */ + _mc->gregs[REG_RSP] = (uintptr_t) sp; /* Remove RA from stack. */ - _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; + _mc->gregs[REG_RAX] = (uintptr_t) o; + _mc->gregs[REG_R10] = (uintptr_t) xpc; /* 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; + } } @@ -189,7 +216,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p) { - stackframeinfo sfi; ucontext_t *_uc; mcontext_t *_mc; u1 *pv; @@ -216,17 +242,9 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p) type = EXCEPTION_HARDWARE_ARITHMETIC; val = 0; - /* 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); + p = signal_handle(type, val, pv, sp, ra, xpc, _p); /* set registers */ @@ -236,6 +254,84 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p) } +/* md_signal_handler_sigill **************************************************** + + 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; + + /* 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]; + + /* now suspend the current thread */ + threads_suspend_ack(pc, sp); +} +#endif + + /* md_signal_handler_sigusr2 *************************************************** Signal handler for profiling sampling. @@ -265,6 +361,143 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p) #endif +/* md_executionstate_read ****************************************************** + + Read the given context into an executionstate. + +*******************************************************************************/ + +void md_executionstate_read(executionstate_t *es, void *context) +{ + ucontext_t *_uc; + mcontext_t *_mc; + s4 i; + s4 d; + + _uc = (ucontext_t *) context; + _mc = &_uc->uc_mcontext; + + /* read special registers */ + es->pc = (u1 *) _mc->gregs[REG_RIP]; + es->sp = (u1 *) _mc->gregs[REG_RSP]; + es->pv = NULL; + + /* read integer registers */ + for (i = 0; i < INT_REG_CNT; i++) { + /* XXX FIX ME! */ + + switch (i) { + 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 = i - 8; + break; + } + + es->intregs[i] = _mc->gregs[d]; + } + + /* read float registers */ + for (i = 0; i < FLT_REG_CNT; i++) + es->fltregs[i] = 0xdeadbeefdeadbeefL; +} + + +/* md_executionstate_write ***************************************************** + + Write the given executionstate back to the context. + +*******************************************************************************/ + +void md_executionstate_write(executionstate_t *es, void *context) +{ + ucontext_t *_uc; + mcontext_t *_mc; + s4 i; + s4 d; + + _uc = (ucontext_t *) context; + _mc = &_uc->uc_mcontext; + + /* write integer registers */ + for (i = 0; i < INT_REG_CNT; i++) { + /* XXX FIX ME! */ + + switch (i) { + 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 = i - 8; + break; + } + + _mc->gregs[d] = es->intregs[i]; + } + + /* write special registers */ + _mc->gregs[REG_RIP] = (ptrint) es->pc; + _mc->gregs[REG_RSP] = (ptrint) es->sp; +} + + /* md_critical_section_restart ************************************************* Search the critical sections tree for a matching section and set