1
2 /* This test tests whether registers are correctly restored after a
3 * signal handler is executed. The assembly file (test57loop.S) puts
4 * 'random' values in the registers, and the C code checks whether
5 * these values are the same, before and after the signal handler.
6 */
7
8 #define _POSIX_SOURCE 1
9
10 #include <stdio.h>
11 #include <signal.h>
12 #include <err.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15
16 #include <sys/types.h>
17 #include <sys/wait.h>
18
19 #define SIGNAL SIGUSR1
20
21 volatile int remaining_invocations = 2, handler_level = 0;
22
23 void check_context_loop(void);
24
25 #define REGS 8 /* how many registers pusha and popa save. */
26
27 #define ESP 3 /* where is esp saved? */
28
29 unsigned long newstate[REGS], origstate[REGS];
30
handler(int signal)31 static void handler(int signal)
32 {
33 int st;
34 sigset_t set, oset;
35 handler_level++;
36 remaining_invocations--;
37 if(remaining_invocations < 1)
38 return;
39 sigemptyset(&set);
40 sigaddset(&set, SIGNAL);
41 sigprocmask(SIG_UNBLOCK, &set, &oset);
42 wait(&st);
43 handler_level--;
44 }
45
main(int argc,char * argv[])46 int main(int argc, char *argv[])
47 {
48 pid_t child_pid;
49
50 printf("Test 57 ");
51
52 if(signal(SIGNAL, handler) == SIG_ERR)
53 err(1, "signal");
54
55 fflush(NULL);
56
57 if((child_pid=fork()) < 0)
58 err(1, "fork");
59
60 if(child_pid == 0) {
61 pid_t ppid = 0;
62
63 /* Keep signaling the parent until
64 * it disappears.
65 */
66 while((ppid = getppid()) > 1) {
67 if(kill(ppid, SIGNAL) < 0)
68 err(1, "kill");
69 sleep(1);
70 }
71
72 exit(0);
73 } else {
74 int i;
75 int err = 0;
76
77 check_context_loop();
78
79 /* correct 2nd esp for 'pusha' difference. */
80 newstate[ESP] += REGS*4;
81
82 for(i = 0; i < REGS; i++) {
83 #if 0
84 printf("%d %08lx %08lx diff ",
85 i, newstate[i], origstate[i]);
86 #endif
87 if(newstate[i] != origstate[i]) {
88 fprintf(stderr, "reg %d changed; "
89 "found 0x%lx, expected 0x%lx\n",
90 i, newstate[i], origstate[i]);
91 err = 1;
92 }
93 }
94
95 if(!err) printf("ok\n");
96
97 exit(err);
98 }
99
100 return 0;
101 }
102
103