X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=ffi%2Ftrap.c;h=c550658d5f5920d0cdc8a35f3520054ccf24163f;hb=280c9c440fc6117911c329f9ce5556bac75b359b;hp=2073dae2ec285afe4c1a89343654d1a189882a00;hpb=efcf93f38698c9f8043f896007bfb9d40c72f0a5;p=mate.git diff --git a/ffi/trap.c b/ffi/trap.c index 2073dae..c550658 100644 --- a/ffi/trap.c +++ b/ffi/trap.c @@ -1,6 +1,10 @@ #include #include +#include +/* TODO(bernhard): use {u,}int* types */ + +#define __USE_GNU // Note by hs: my signal.h includes sys/uconctext which conflicts with // asm/ucontext - this hack kinda solves the problem for me ;-) // so feel free to blame me for that s**t @@ -14,76 +18,55 @@ #define __USE_XOPEN2K8 #endif -#include - -unsigned int getMethodEntry(unsigned int, void *, void *); - -void *method_map = NULL; -void *caller_map = NULL; - -void set_mmap(void *mmap) -{ - printf("set_mmap: 0x%08x\n", (unsigned int) mmap); - method_map = mmap; -} - -void *get_mmap() -{ - printf("get_mmap: 0x%08x\n", (unsigned int) method_map); - return method_map; -} - -void set_cmap(void *cmap) -{ - printf("set_cmap: 0x%08x\n", (unsigned int) cmap); - caller_map = cmap; -} - -void *get_cmap() -{ - printf("get_cmap: 0x%08x\n", (unsigned int) caller_map); - return caller_map; -} +#include +ptrdiff_t mateHandler(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); -void mainresult(unsigned int a) -{ - printf("mainresult: 0x%08x\n", a); -} +#ifdef DBG_TRAP +#define dprintf(args...) do { printf (args); } while (0); +#else +#define dprintf(args...) +#endif -void callertrap(int nSignal, siginfo_t *info, void *ctx) +void chandler(int nSignal, siginfo_t *info, void *ctx) { - struct ucontext *uctx = (struct ucontext *) ctx; - unsigned int from = (unsigned int) uctx->uc_mcontext.eip; - unsigned int patchme = getMethodEntry(from, method_map, caller_map); + mcontext_t *mctx = &((ucontext_t *) ctx)->uc_mcontext; + greg_t *regs = mctx->gregs; - printf("callertrap(mctx) by 0x%08x\n", from); + 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)); - unsigned int *to_patch = (unsigned int *) (from + 1); - 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); - if (*to_patch != 0x90ffffff) { - printf("something is wrong here. abort\n"); - exit(0); + 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 { + mctx->gregs[REG_EIP] = ret; } - *to_patch = patchme - (from + 5); - printf("*to_patch: 0x%08x\n", *to_patch); - uctx->uc_mcontext.eip = (unsigned long) insn; - // while (1) ; } void register_signal(void) { + struct sigaction illaction; + 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 = callertrap; + segvaction.sa_sigaction = chandler; sigemptyset(&segvaction.sa_mask); - segvaction.sa_flags = SA_SIGINFO | SA_RESTART; - sigaction(SIGILL, &segvaction, NULL); -} - -unsigned int getaddr(void) -{ - return (unsigned int) mainresult; + segvaction.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; + sigaction(SIGSEGV, &segvaction, NULL); }