Makefile: GHCi still broken
[mate.git] / ffi / trap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <signal.h>
4 #include <asm/ucontext.h>
5
6 unsigned int getMethodEntry(void *, char *);
7 void *method_map = NULL;
8
9 void set_mmap(void *mmap)
10 {
11         printf("set_mmap: 0x%08x\n", (unsigned int) mmap);
12         method_map = mmap;
13 }
14
15 void *get_mmap()
16 {
17         printf("get_mmap: 0x%08x\n", (unsigned int) method_map);
18         return method_map;
19 }
20
21 void demo_mmap()
22 {
23         printf("mmap: 0x%08x\n", getMethodEntry(method_map, "fib"));
24 }
25
26
27 unsigned int patchme = 0;
28 void print_foo(unsigned int addr)
29 {
30         // printf("\n\nprint foo: 0x%08x\n", addr);
31         patchme = addr;
32 }
33
34 void callertrap(int nSignal, siginfo_t *info, void *ctx)
35 {
36         struct ucontext *uctx = (struct ucontext *) ctx;
37
38         printf("callertrap(mctx)  by 0x%08x\n", (unsigned int) uctx->uc_mcontext.eip);
39         // printf("callertrap(addr)  by 0x%08x\n", info->si_addr);
40         // printf("callertrap(*esp)  by 0x%08x\n", * (unsigned int *) uctx->uc_mcontext.esp);
41
42         unsigned int *to_patch = (unsigned int *) (uctx->uc_mcontext.eip + 2);
43         unsigned char *insn = (unsigned char *) (uctx->uc_mcontext.eip);
44         *insn = 0x90; // nop
45         insn++;
46         *insn = 0xe8; // call
47         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
48         printf("*to_patch: 0x%08x\n", *to_patch);
49         if (*to_patch != 0x00000000) {
50                 printf("something is wrong here. abort\n");
51                 exit(0);
52         }
53         *to_patch = (unsigned int) patchme - ((unsigned int) insn + 5);
54         printf("*to_patch: 0x%08x\n", *to_patch);
55         uctx->uc_mcontext.eip = (unsigned long) insn;
56         // while (1) ;
57 }
58
59 void register_signal(void)
60 {
61         struct sigaction segvaction;
62         segvaction.sa_sigaction = callertrap;
63         sigemptyset(&segvaction.sa_mask);
64         segvaction.sa_flags = SA_SIGINFO | SA_RESTART;
65         sigaction(SIGSEGV, &segvaction, NULL);
66 }
67
68 unsigned int getaddr(void)
69 {
70         return (unsigned int) print_foo;
71 }