refactor: s/C(aller)Map/T(rap)Map/g
[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 #define NEW_MAP(prefix) \
22         void* prefix ## _map = NULL; \
23         void set_ ## prefix ## map(void *map) \
24         { \
25                 printf("set_%s: 0x%08x\n", #prefix , (unsigned int) map); \
26                 prefix ## _map = map; \
27         } \
28         void *get_ ## prefix ## map() \
29         { \
30                 printf("get_%s: 0x%08x\n", #prefix , (unsigned int) prefix ## _map); \
31                 return prefix ## _map; \
32         }
33
34 NEW_MAP(method)
35 NEW_MAP(trap)
36 NEW_MAP(class)
37
38
39 void mainresult(unsigned int a)
40 {
41         printf("mainresult: 0x%08x\n", a);
42 }
43
44 void callertrap(int nSignal, siginfo_t *info, void *ctx)
45 {
46         struct ucontext *uctx = (struct ucontext *) ctx;
47         unsigned int from = (unsigned int) uctx->uc_mcontext.eip - 2;
48         unsigned int patchme = getMethodEntry(from, method_map, trap_map);
49
50         printf("callertrap(mctx)  by 0x%08x\n", from);
51
52         unsigned int *to_patch = (unsigned int *) (from + 1);
53         unsigned char *insn = (unsigned char *) from;
54         *insn = 0xe8; // call opcode
55         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
56         printf("*to_patch: 0x%08x\n", *to_patch);
57         if (*to_patch != 0x90ffff90) {
58                 printf("something is wrong here. abort\n");
59                 exit(0);
60         }
61         *to_patch = patchme - (from + 5);
62         printf("*to_patch: 0x%08x\n", *to_patch);
63         uctx->uc_mcontext.eip = (unsigned long) insn;
64         // while (1) ;
65 }
66
67 void register_signal(void)
68 {
69         struct sigaction segvaction;
70         segvaction.sa_sigaction = callertrap;
71         sigemptyset(&segvaction.sa_mask);
72         segvaction.sa_flags = SA_SIGINFO | SA_RESTART;
73         sigaction(SIGILL, &segvaction, NULL);
74 }
75
76 unsigned int getaddr(void)
77 {
78         return (unsigned int) mainresult;
79 }