fields: use offsets from ClassInfo in codegen
[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 getStaticFieldAddr(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 *to_patch = (unsigned int *) (from + 1);
50         printf("callertrap(mctx)  by 0x%08x\n", from);
51         if (*to_patch != 0x90ffff90) {
52                 printf("callertrap: something is wrong here. abort\n");
53                 exit(0);
54         }
55         unsigned int patchme = getMethodEntry(from, method_map, trap_map);
56
57         unsigned char *insn = (unsigned char *) from;
58         *insn = 0xe8; // call opcode
59         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
60         printf("*to_patch: 0x%08x\n", *to_patch);
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 staticfieldtrap(int nSignal, siginfo_t *info, void *ctx)
68 {
69         struct ucontext *uctx = (struct ucontext *) ctx;
70         unsigned int from = (unsigned int) uctx->uc_mcontext.eip;
71         unsigned int *to_patch = (unsigned int *) (from + 2);
72         printf("staticfieldtrap by 0x%08x\n", from);
73         if (*to_patch != 0x00000000) {
74                 printf("staticfieldtrap: something is wrong here. abort\n");
75                 exit(0);
76         }
77         unsigned int patchme = getStaticFieldAddr(from, trap_map);
78
79         printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
80         printf("*to_patch: 0x%08x\n", *to_patch);
81         *to_patch = patchme;
82         printf("*to_patch: 0x%08x\n", *to_patch);
83 }
84
85 void register_signal(void)
86 {
87         struct sigaction illaction;
88         illaction.sa_sigaction = callertrap;
89         sigemptyset(&illaction.sa_mask);
90         illaction.sa_flags = SA_SIGINFO | SA_RESTART;
91         sigaction(SIGILL, &illaction, NULL);
92
93         struct sigaction segvaction;
94         segvaction.sa_sigaction = staticfieldtrap;
95         sigemptyset(&segvaction.sa_mask);
96         segvaction.sa_flags = SA_SIGINFO | SA_RESTART;
97         sigaction(SIGSEGV, &segvaction, NULL);
98 }
99
100 unsigned int getaddr(void)
101 {
102         return (unsigned int) mainresult;
103 }
104
105 unsigned int getMallocAddr(void)
106 {
107         return (unsigned int) malloc;
108 }