ffi: added strange hack in order to build master on my machine:
[mate.git] / ffi / trap.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 // Note by hs: my signal.h includes sys/uconctext which conflicts with
5 // asm/ucontext - this hack kinda solves the problem for me ;-) 
6 // so feel free to blame me for that s**t
7 #if defined __USE_XOPEN2K8
8 #undef __USE_XOPEN2K8
9 #define RESTORE
10 #warning hs-hack: undefining __USE_XOPEN2K8 for signal.h
11 #endif
12 #include <signal.h>
13 #ifdef RESTORE
14 #define __USE_XOPEN2K8
15 #endif
16
17 #include <asm/ucontext.h>
18
19 unsigned int getMethodEntry(unsigned int, void *, void *);
20
21 void *method_map = NULL;
22 void *caller_map = NULL;
23
24 void set_mmap(void *mmap)
25 {
26         printf("set_mmap: 0x%08x\n", (unsigned int) mmap);
27         method_map = mmap;
28 }
29
30 void *get_mmap()
31 {
32         printf("get_mmap: 0x%08x\n", (unsigned int) method_map);
33         return method_map;
34 }
35
36 void set_cmap(void *cmap)
37 {
38         printf("set_cmap: 0x%08x\n", (unsigned int) cmap);
39         caller_map = cmap;
40 }
41
42 void *get_cmap()
43 {
44         printf("get_cmap: 0x%08x\n", (unsigned int) caller_map);
45         return caller_map;
46 }
47
48
49 void mainresult(unsigned int a)
50 {
51         printf("mainresult: 0x%08x\n", a);
52 }
53
54 void callertrap(int nSignal, siginfo_t *info, void *ctx)
55 {
56         struct ucontext *uctx = (struct ucontext *) ctx;
57         unsigned int from = (unsigned int) uctx->uc_mcontext.eip;
58         unsigned int patchme = getMethodEntry(from, method_map, caller_map);
59
60         printf("callertrap(mctx)  by 0x%08x\n", from);
61         // printf("callertrap(addr)  by 0x%08x\n", info->si_addr);
62         // printf("callertrap(*esp)  by 0x%08x\n", * (unsigned int *) uctx->uc_mcontext.esp);
63
64         unsigned int *to_patch = (unsigned int *) (uctx->uc_mcontext.eip + 2);
65         unsigned char *insn = (unsigned char *) (uctx->uc_mcontext.eip);
66         *insn = 0x90; // nop
67         insn++;
68         *insn = 0xe8; // call
69         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
70         printf("*to_patch: 0x%08x\n", *to_patch);
71         if (*to_patch != 0x00000000) {
72                 printf("something is wrong here. abort\n");
73                 exit(0);
74         }
75         *to_patch = (unsigned int) patchme - ((unsigned int) insn + 5);
76         printf("*to_patch: 0x%08x\n", *to_patch);
77         uctx->uc_mcontext.eip = (unsigned long) insn;
78         // while (1) ;
79 }
80
81 void register_signal(void)
82 {
83         struct sigaction segvaction;
84         segvaction.sa_sigaction = callertrap;
85         sigemptyset(&segvaction.sa_mask);
86         segvaction.sa_flags = SA_SIGINFO | SA_RESTART;
87         sigaction(SIGSEGV, &segvaction, NULL);
88 }
89
90 unsigned int getaddr(void)
91 {
92         return (unsigned int) mainresult;
93 }