revert to oldcode
[snitchaser:mainline.git] / checkpoint / rt_sigaction.c
1
2 #include "syscalls.h"
3 #ifndef SYSCALL_PRINTER
4
5 /* 
6  * in the loader, those 2 vars are defined in snitchaser.c;
7  * in the injector, those 2 vars are defined in wrapper.c;
8  */
9
10 #ifndef IN_INJECTOR
11 extern SCOPE uint32_t wrapped_sigreturn;
12 extern SCOPE uint32_t wrapped_rt_sigreturn;
13 extern SCOPE uint32_t wrapped_sighandler;
14 #else
15 extern void wrapped_sigreturn(void);
16 extern void wrapped_rt_sigreturn(void);
17 extern void wrapped_sighandler(void);
18 #endif
19
20 #define SIG_DFL ((void*)(0))    /* default signal handling */
21 #define SIG_IGN ((void*)(1))    /* ignore signal */
22 #define SIG_ERR ((void*)(-1))   /* error return from signal */
23
24 #define SA_NOCLDSTOP    0x00000001u
25 #define SA_NOCLDWAIT    0x00000002u
26 #define SA_SIGINFO      0x00000004u
27 #define SA_ONSTACK      0x08000000u
28 #define SA_RESTART      0x10000000u
29 #define SA_NODEFER      0x40000000u
30 #define SA_RESETHAND    0x80000000u
31
32 #define SA_NOMASK       SA_NODEFER
33 #define SA_ONESHOT      SA_RESETHAND
34
35 #define SA_RESTORER     0x04000000
36
37 int SCOPE
38 pre_rt_sigaction(const struct syscall_regs * regs)
39 {
40         /* if the signal handler is not the SIG_DFL or SIG_IGN, we need to
41          * reset the handler entry, make the target call my wrapper. */
42         uintptr_t act = regs->ecx;
43         struct k_sigaction d;
44
45         /* check sig */
46         int signo = regs->ebx;
47         if ((signo == SIGKILL) || (signo == SIGSTOP)) {
48                 /* sigaction should fail, do nothing */
49                 return 0;
50         }
51
52         if ((signo < 1) || (signo > K_NSIG))
53                 return 0;
54
55         /* check act */
56         if (act == 0)
57                 return 0;
58         __dup_mem(&d, act, sizeof(d));
59
60         /* save new handler */
61         state_vector.sigactions[signo] = d;
62
63         if ((d.sa_handler == SIG_IGN) || (d.sa_handler == SIG_DFL))
64                 return 0;
65
66         /* check sa_flags, whether the handler use itself restorer */
67         ASSERT(!(d.sa_flags & SA_RESTORER) || (d.sa_restorer == (void*)wrapped_rt_sigreturn),
68                         regs, "handler for signal %d use itself's restorer, doesn't support\n");
69
70         /* update sa_handler */
71         d.sa_handler = (void*)wrapped_sighandler;
72         /* disable all signals */
73         memset(&d.sa_mask, 0xff, sizeof(d.sa_mask));
74         __upd_mem(act, &d, sizeof(d));
75
76         /* we don't set restorer, we do it in wrapped_sighandler */
77         return 0;
78 }
79
80 int SCOPE
81 post_rt_sigaction(const struct syscall_regs * regs)
82 {
83         write_eax(regs);
84         int signo = regs->ebx;
85         if ((signo == SIGKILL) || (signo == SIGSTOP))
86                 return 0;
87         if ((signo < 1) || (signo > K_NSIG))
88                 return 0;
89
90         /* rt_sigaction should not fail... */
91         ASSERT(regs->eax >= 0, regs, "rt_sigaction failed, we cannot handle...\n");
92
93         uintptr_t act = regs->ecx;
94         uintptr_t oact = regs->edx;
95         int sigsetsize = regs->esi;
96
97         write_obj(sigsetsize);
98         write_obj(oact);
99         write_obj(act);
100
101         /* we need copy modified act back */
102         struct k_sigaction * s = &state_vector.sigactions[regs->ebx];
103         if (act != 0)
104                 __upd_mem(act, s, sizeof(*s));
105
106         if (sigsetsize != sizeof(k_sigset_t)) {
107                 INJ_WARNING("esi (%d) != %d\n",
108                                 sigsetsize, sizeof(k_sigset_t));
109                 return 0;
110         }
111
112         if (oact != 0) {
113                 /* we modify the result */
114                 struct k_sigaction d;
115                 __dup_mem(&d, oact, sizeof(d));
116                 if (d.sa_handler == (void*)wrapped_sighandler) {
117                         struct k_sigaction * p = &(state_vector.sigactions[regs->ebx]);
118                         d = *p;
119                         __upd_mem(oact, &d, sizeof(d));
120                 }
121                 write_mem(oact, sizeof(struct k_sigaction));
122         }
123         return 0;
124 }
125
126 int SCOPE
127 replay_rt_sigaction(const struct syscall_regs * regs)
128 {
129         int32_t eax = read_int32();
130         if (eax == 0) {
131                 int sigsetsize = read_int32();
132                 ASSERT(sigsetsize == regs->esi, regs, "");
133                 ASSERT(sigsetsize == sizeof(k_sigset_t), regs, "!@@#1\n");
134
135                 uintptr_t oact = read_uint32();
136                 ASSERT(oact == regs->edx, regs, "oact inconsistent: 0x%x != 0x%x\n",
137                                 regs->edx, oact);
138                 
139                 uintptr_t act = read_uint32();
140                 ASSERT(act == regs->ecx, regs, "act inconsistent: 0x%x != 0x%x\n",
141                                 regs->ecx, act);
142
143                 if (oact != 0)
144                         read_mem(oact, sizeof(struct k_sigaction));
145
146                 /* we need trace sighandler even in replay */
147                 if (act != 0)
148                         __dup_mem(&state_vector.sigactions[regs->ebx], act,
149                                         sizeof(struct k_sigaction));
150         }
151         return eax;
152 }
153
154 #else
155
156 extern int finished;
157 void
158 output_rt_sigaction(int nr)
159 {
160         int32_t ret = read_eax();
161         if (ret == 0) {
162                 int sigsetsize;
163                 uintptr_t act;
164                 uintptr_t oact;
165                 read_obj(sigsetsize);
166                 read_obj(oact);
167                 read_obj(act);
168
169                 if (sigsetsize == sizeof(k_sigset_t)) {
170                         if (oact != 0)
171                                 skip(sizeof(struct k_sigaction));
172                 }
173                 printf("rt_sigaction(act=0x%x, oact=0x%x):\t%d\n",
174                                 act, oact, ret);
175         } else {
176                 printf("rt_sigaction:\t%d\n", ret);
177         }
178 }
179 #endif
180