codegen: {put,get}static for static field access
[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 unsigned int getFieldAddr(unsigned int, void*);
21
22 #define NEW_MAP(prefix) \
23         void* prefix ## _map = NULL; \
24         void set_ ## prefix ## map(void *map) \
25         { \
26                 printf("set_%s: 0x%08x\n", #prefix , (unsigned int) map); \
27                 prefix ## _map = map; \
28         } \
29         void *get_ ## prefix ## map() \
30         { \
31                 printf("get_%s: 0x%08x\n", #prefix , (unsigned int) prefix ## _map); \
32                 return prefix ## _map; \
33         }
34
35 NEW_MAP(method)
36 NEW_MAP(trap)
37 NEW_MAP(class)
38
39
40 void mainresult(unsigned int a)
41 {
42         printf("mainresult: 0x%08x\n", a);
43 }
44
45 void callertrap(int nSignal, siginfo_t *info, void *ctx)
46 {
47         struct ucontext *uctx = (struct ucontext *) ctx;
48         unsigned int from = (unsigned int) uctx->uc_mcontext.eip - 2;
49         unsigned int patchme = getMethodEntry(from, method_map, trap_map);
50
51         printf("callertrap(mctx)  by 0x%08x\n", from);
52
53         unsigned int *to_patch = (unsigned int *) (from + 1);
54         unsigned char *insn = (unsigned char *) from;
55         *insn = 0xe8; // call opcode
56         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
57         printf("*to_patch: 0x%08x\n", *to_patch);
58         if (*to_patch != 0x90ffff90) {
59                 printf("something is wrong here. abort\n");
60                 exit(0);
61         }
62         *to_patch = patchme - (from + 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 staticfieldtrap(int nSignal, siginfo_t *info, void *ctx)
69 {
70         struct ucontext *uctx = (struct ucontext *) ctx;
71         unsigned int from = (unsigned int) uctx->uc_mcontext.eip;
72         unsigned int patchme = getFieldAddr(from, trap_map);
73         unsigned int *to_patch = (unsigned int *) (from + 2);
74
75         printf("staticfieldtrap by 0x%08x\n", from);
76         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
77         printf("*to_patch: 0x%08x\n", *to_patch);
78         if (*to_patch != 0x00000000) {
79                 printf("something is wrong here. abort\n");
80                 exit(0);
81         }
82         *to_patch = patchme;
83         printf("*to_patch: 0x%08x\n", *to_patch);
84 }
85
86 void register_signal(void)
87 {
88         struct sigaction illaction;
89         illaction.sa_sigaction = callertrap;
90         sigemptyset(&illaction.sa_mask);
91         illaction.sa_flags = SA_SIGINFO | SA_RESTART;
92         sigaction(SIGILL, &illaction, NULL);
93
94         struct sigaction segvaction;
95         segvaction.sa_sigaction = staticfieldtrap;
96         sigemptyset(&segvaction.sa_mask);
97         segvaction.sa_flags = SA_SIGINFO | SA_RESTART;
98         sigaction(SIGSEGV, &segvaction, NULL);
99 }
100
101 unsigned int getaddr(void)
102 {
103         return (unsigned int) mainresult;
104 }