X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=ffi%2Ftrap.c;h=c550658d5f5920d0cdc8a35f3520054ccf24163f;hb=dc7082de1fff3158da5682d683502128b5f6cc0b;hp=7871757811bf71128f1c29a814002cf3f8bf21f1;hpb=b25d636bdeaadc503cab14a9df7c1c8ec7b2c26c;p=mate.git diff --git a/ffi/trap.c b/ffi/trap.c index 7871757..c550658 100644 --- a/ffi/trap.c +++ b/ffi/trap.c @@ -1,5 +1,6 @@ #include #include +#include /* TODO(bernhard): use {u,}int* types */ @@ -19,114 +20,53 @@ #include -unsigned int getMethodEntry(unsigned int, unsigned int); -unsigned int getStaticFieldAddr(unsigned int, void*); +ptrdiff_t mateHandler(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); -#define NEW_MAP(prefix) \ - void* prefix ## _map = NULL; \ - void set_ ## prefix ## map(void *map) \ - { \ - printf("set_%s: 0x%08x\n", #prefix , (unsigned int) map); \ - prefix ## _map = map; \ - } \ - void *get_ ## prefix ## map() \ - { \ - printf("get_%s: 0x%08x\n", #prefix , (unsigned int) prefix ## _map); \ - return prefix ## _map; \ - } - -NEW_MAP(method) -NEW_MAP(trap) -NEW_MAP(class) -NEW_MAP(virtual) -NEW_MAP(strings) - - -void mainresult(unsigned int a) -{ - printf("mainresult: 0x%08x\n", a); -} - -void callertrap(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); - printf("callertrap(mctx) by 0x%08x\n", from); - if (*to_patch != 0x90ffff90) { - printf("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 - printf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - printf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = patchme - (from + 5); - printf("*to_patch: 0x%08x\n", *to_patch); - mctx->gregs[REG_EIP] = (unsigned long) insn; -} +#ifdef DBG_TRAP +#define dprintf(args...) do { printf (args); } while (0); +#else +#define dprintf(args...) +#endif -void staticfieldtrap(int nSignal, siginfo_t *info, void *ctx) +void chandler(int nSignal, siginfo_t *info, void *ctx) { - /* TODO(bernhard): more generic and cleaner please... */ mcontext_t *mctx = &((ucontext_t *) ctx)->uc_mcontext; - unsigned int from = (unsigned int) mctx->gregs[REG_EIP]; - if (from < 0x10000) { // invokevirtual - if (from > 0) { - printf("from: 0x%08x but should be 0 :-(\n", from); - } - unsigned int method_table_ptr = (unsigned int) mctx->gregs[REG_EAX]; - unsigned int *esp = (unsigned int *) mctx->gregs[REG_ESP]; - /* get actual eip from stack storage */ - unsigned int from = (*esp) - 3; - unsigned char offset = *((unsigned char *) (*esp) - 1); - /* method entry to patch */ - unsigned int *to_patch = (unsigned int*) (method_table_ptr + offset); - printf("invokevirtual by 0x%08x with offset 0x%08x\n", from, offset); - printf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - printf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = getMethodEntry(from, method_table_ptr); - mctx->gregs[REG_EIP] = *to_patch; - printf("*to_patch: 0x%08x\n", *to_patch); + greg_t *regs = mctx->gregs; + + ptrdiff_t eip = (ptrdiff_t) regs[REG_EIP]; + ptrdiff_t eax = (ptrdiff_t) regs[REG_EAX]; + ptrdiff_t ebx = (ptrdiff_t) regs[REG_EBX]; + ptrdiff_t esp = (ptrdiff_t) regs[REG_ESP]; + ptrdiff_t esi = (ptrdiff_t) regs[REG_ESI]; + ptrdiff_t ebp = (ptrdiff_t) regs[REG_EBP]; + dprintf("trap: type %d, eip 0x%08x, eax 0x%08x, ebx 0x%08x, \n" + "esp 0x%08x, *esp 0x%08x, *(ebp+8) 0x%08x\n", nSignal, eip, + eax, ebx, esp, *(ptrdiff_t*) esp, *(ptrdiff_t *) (ebp + 8)); + + ptrdiff_t ret = mateHandler(eip, eax, ebx, esi); + if (ret == -1) { + dprintf("regdump @ EIP: 0x%08x\n", regs[REG_EIP]); + dprintf("\tEAX: 0x%08lx EBX: 0x%08lx ECX: 0x%08lx EDX: 0x%08lx\n", + regs[REG_EAX], regs[REG_EBX], regs[REG_ECX], regs[REG_EDX]); + dprintf("\tESI: 0x%08lx EDI: 0x%08lx EBP: 0x%08lx ESP: 0x%08lx\n", + regs[REG_ESI], regs[REG_EDI], regs[REG_EBP], regs[REG_ESP]); + mctx->gregs[REG_EIP] = eip + 6; } else { - unsigned int *to_patch = (unsigned int *) (from + 2); - printf("staticfieldtrap by 0x%08x\n", from); - if (*to_patch != 0x00000000) { - printf("staticfieldtrap: something is wrong here. abort\n"); - exit(0); - } - unsigned int patchme = getStaticFieldAddr(from, trap_map); - - printf(" to_patch: 0x%08x\n", (unsigned int) to_patch); - printf("*to_patch: 0x%08x\n", *to_patch); - *to_patch = patchme; - printf("*to_patch: 0x%08x\n", *to_patch); + mctx->gregs[REG_EIP] = ret; } } void register_signal(void) { struct sigaction illaction; - illaction.sa_sigaction = callertrap; + 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 = staticfieldtrap; + 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 getMallocAddr(void) -{ - return (unsigned int) malloc; -}