methodpool: save information in codegen context
[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(unsigned int, void *, void *);
7
8 void *method_map = NULL;
9 void *caller_map = NULL;
10
11 void set_mmap(void *mmap)
12 {
13         printf("set_mmap: 0x%08x\n", (unsigned int) mmap);
14         method_map = mmap;
15 }
16
17 void *get_mmap()
18 {
19         printf("get_mmap: 0x%08x\n", (unsigned int) method_map);
20         return method_map;
21 }
22
23 void set_cmap(void *cmap)
24 {
25         printf("set_cmap: 0x%08x\n", (unsigned int) cmap);
26         caller_map = cmap;
27 }
28
29 void *get_cmap()
30 {
31         printf("get_cmap: 0x%08x\n", (unsigned int) caller_map);
32         return caller_map;
33 }
34
35
36 void mainresult(unsigned int a)
37 {
38         printf("mainresult: 0x%08x\n", a);
39 }
40
41 void callertrap(int nSignal, siginfo_t *info, void *ctx)
42 {
43         struct ucontext *uctx = (struct ucontext *) ctx;
44         unsigned int from = (unsigned int) uctx->uc_mcontext.eip;
45         unsigned int patchme = getMethodEntry(from, method_map, caller_map);
46
47         printf("callertrap(mctx)  by 0x%08x\n", from);
48         // printf("callertrap(addr)  by 0x%08x\n", info->si_addr);
49         // printf("callertrap(*esp)  by 0x%08x\n", * (unsigned int *) uctx->uc_mcontext.esp);
50
51         unsigned int *to_patch = (unsigned int *) (uctx->uc_mcontext.eip + 2);
52         unsigned char *insn = (unsigned char *) (uctx->uc_mcontext.eip);
53         *insn = 0x90; // nop
54         insn++;
55         *insn = 0xe8; // call
56         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
57         printf("*to_patch: 0x%08x\n", *to_patch);
58         if (*to_patch != 0x00000000) {
59                 printf("something is wrong here. abort\n");
60                 exit(0);
61         }
62         *to_patch = (unsigned int) patchme - ((unsigned int) insn + 5);
63         printf("*to_patch: 0x%08x\n", *to_patch);
64         uctx->uc_mcontext.eip = (unsigned long) insn;
65         // while (1) ;
66 }
67
68 void register_signal(void)
69 {
70         struct sigaction segvaction;
71         segvaction.sa_sigaction = callertrap;
72         sigemptyset(&segvaction.sa_mask);
73         segvaction.sa_flags = SA_SIGINFO | SA_RESTART;
74         sigaction(SIGSEGV, &segvaction, NULL);
75 }
76
77 unsigned int getaddr(void)
78 {
79         return (unsigned int) mainresult;
80 }