X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=ffi%2Ftrap.c;h=301f2060ce47f5252bb4d2dfd73112efa069d9a7;hb=13cf9f65321881050edb99776f29eea8580ec457;hp=0302c5ea0667659c4ce21bd6728c31b49f574a8a;hpb=55d3b7af8c3a1fdef0c5e470e649d180dc0a3911;p=mate.git diff --git a/ffi/trap.c b/ffi/trap.c index 0302c5e..301f206 100644 --- a/ffi/trap.c +++ b/ffi/trap.c @@ -1,5 +1,6 @@ #include #include +#include #include "../debug.h" @@ -21,10 +22,7 @@ #include -unsigned int getMethodEntry(unsigned int, unsigned int); -unsigned int getStaticFieldAddr(unsigned int); -unsigned int getTrapType(unsigned int, unsigned int); -unsigned int mallocObject(int); +ptrdiff_t mateHandler(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); #ifdef DBG_TRAP #define dprintf(args...) do { printf (args); } while (0); @@ -32,126 +30,32 @@ unsigned int mallocObject(int); #define dprintf(args...) #endif -void *mate_ctx = NULL; - -void *get_mate_context() -{ - return mate_ctx; -} - -void *set_mate_context(void *ctx) -{ - mate_ctx = ctx; -} - -void mainresult(unsigned int a) -{ - dprintf("mainresult: 0x%08x\n", a); -} - -void staticcalltrap(int nSignal, siginfo_t *info, void *ctx) +void chandler(int nSignal, siginfo_t *info, void *ctx) { mcontext_t *mctx = &((ucontext_t *) ctx)->uc_mcontext; - unsigned int from = (unsigned int) mctx->gregs[REG_EIP] - 2; - unsigned int *to_patch = (unsigned int *) (from + 1); - dprintf("callertrap(mctx) by 0x%08x\n", from); - if (*to_patch != 0x90ffff90) { - dprintf("callertrap: something is wrong here. abort\n"); - exit(0); - } - unsigned int patchme = getMethodEntry(from, 0); - unsigned char *insn = (unsigned char *) from; - *insn = 0xe8; // call opcode - dprintf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - dprintf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = patchme - (from + 5); - dprintf("*to_patch: 0x%08x\n", *to_patch); - mctx->gregs[REG_EIP] = (unsigned long) insn; -} + ptrdiff_t eip = (ptrdiff_t) mctx->gregs[REG_EIP]; + ptrdiff_t eax = (ptrdiff_t) mctx->gregs[REG_EAX]; + ptrdiff_t ebx = (ptrdiff_t) mctx->gregs[REG_EBX]; + ptrdiff_t esp = (ptrdiff_t) mctx->gregs[REG_ESP]; + dprintf("trap: type %d, eip 0x%08x, eax 0x%08x, ebx 0x%08x, " + "esp 0x%08x, *esp 0x%08x\n", nSignal, eip, + eax, ebx, esp, *(ptrdiff_t*) esp); -void sigsegvtrap(int nSignal, siginfo_t *info, void *ctx) -{ - mcontext_t *mctx = &((ucontext_t *) ctx)->uc_mcontext; - unsigned int from = (unsigned int) mctx->gregs[REG_EIP]; - unsigned int *esp = (unsigned int *) mctx->gregs[REG_ESP]; - - /* if from is not *the* eip: get actual eip from stack storage */ - unsigned int from_stack = (*esp) - 3; - switch(getTrapType(from, from_stack)) { - default: case 0: { - dprintf("something is wrong here: abort\n"); - exit(1); - } break; - case 1: { // invokevirtual - if (from > 0) { - dprintf("from: 0x%08x but should be 0 :-(\n", from); - } - unsigned int method_table_ptr = (unsigned int) mctx->gregs[REG_EAX]; - unsigned char offset = *((unsigned char *) (*esp) - 1); - /* method entry to patch */ - unsigned int *to_patch = (unsigned int*) (method_table_ptr + offset); - dprintf("invokevirtual by 0x%08x with offset 0x%08x\n", from_stack, offset); - dprintf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - dprintf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = getMethodEntry(from_stack, method_table_ptr); - mctx->gregs[REG_EIP] = *to_patch; - dprintf("*to_patch: 0x%08x\n", *to_patch); - } break; - case 4: { // invokeinterface - if (from > 0) { - dprintf("from: 0x%08x but should be 0 :-(\n", from); - } - unsigned int method_table_ptr = (unsigned int) mctx->gregs[REG_EAX]; - unsigned int interface_table_ptr = (unsigned int) mctx->gregs[REG_EBX]; - unsigned char offset = *((unsigned char *) (*esp) - 1); - /* interface entry to patch */ - unsigned int *to_patch = (unsigned int*) (interface_table_ptr + offset); - dprintf("invokeinterface by 0x%08x with offset 0x%08x\n", from_stack, offset); - dprintf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - dprintf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = getMethodEntry(from_stack, method_table_ptr); - mctx->gregs[REG_EIP] = *to_patch; - dprintf("*to_patch: 0x%08x\n", *to_patch); - } break; - case 2: { // static field patch - unsigned int *to_patch = (unsigned int *) (from + 2); - dprintf("staticfieldtrap by 0x%08x\n", from); - if (*to_patch != 0x00000000) { - dprintf("staticfieldtrap: something is wrong here. abort\n"); - exit(0); - } - unsigned int patchme = getStaticFieldAddr(from); - - dprintf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - dprintf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = patchme; - dprintf("*to_patch: 0x%08x\n", *to_patch); - } break; - } + mctx->gregs[REG_EIP] = mateHandler(eip, eax, ebx, esp); } void register_signal(void) { struct sigaction illaction; - illaction.sa_sigaction = staticcalltrap; + illaction.sa_sigaction = chandler; sigemptyset(&illaction.sa_mask); illaction.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; sigaction(SIGILL, &illaction, NULL); struct sigaction segvaction; - segvaction.sa_sigaction = sigsegvtrap; + segvaction.sa_sigaction = chandler; sigemptyset(&segvaction.sa_mask); segvaction.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; sigaction(SIGSEGV, &segvaction, NULL); } - -unsigned int getaddr(void) -{ - return (unsigned int) mainresult; -} - -unsigned int getMallocObjectAddr(void) -{ - return (unsigned int) mallocObject; -}