2eb2bfc4ac60e44c8fed1cc49a2414f4687a91d1
[qemu] / tests / testsig.c
1 #define _GNU_SOURCE
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <signal.h>
6 #include <unistd.h>
7 #include <setjmp.h>
8 #include <sys/ucontext.h>
9
10 jmp_buf jmp_env;
11
12 void alarm_handler(int sig)
13 {
14     printf("alarm signal=%d\n", sig);
15     alarm(1);
16 }
17
18 #ifndef REG_EAX
19 #define REG_EAX EAX
20 #define REG_EBX EBX
21 #define REG_ECX ECX
22 #define REG_EDX EDX
23 #define REG_ESI ESI
24 #define REG_EDI EDI
25 #define REG_EBP EBP
26 #define REG_ESP ESP
27 #define REG_EIP EIP
28 #define REG_EFL EFL
29 #define REG_TRAPNO TRAPNO
30 #define REG_ERR ERR
31 #endif
32
33 void dump_regs(struct ucontext *uc)
34 {
35     printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
36            "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
37            "EFL=%08x EIP=%08x trapno=%02x err=%08x\n",
38            uc->uc_mcontext.gregs[REG_EAX],
39            uc->uc_mcontext.gregs[REG_EBX],
40            uc->uc_mcontext.gregs[REG_ECX],
41            uc->uc_mcontext.gregs[REG_EDX],
42            uc->uc_mcontext.gregs[REG_ESI],
43            uc->uc_mcontext.gregs[REG_EDI],
44            uc->uc_mcontext.gregs[REG_EBP],
45            uc->uc_mcontext.gregs[REG_ESP],
46            uc->uc_mcontext.gregs[REG_EFL],
47            uc->uc_mcontext.gregs[REG_EIP],
48            uc->uc_mcontext.gregs[REG_TRAPNO],
49            uc->uc_mcontext.gregs[REG_ERR]);
50 }
51
52 void sig_handler(int sig, siginfo_t *info, void *puc)
53 {
54     struct ucontext *uc = puc;
55
56     printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n",
57            strsignal(info->si_signo),
58            info->si_signo, info->si_errno, info->si_code, 
59            (unsigned long)info->si_addr);
60     dump_regs(uc);
61     longjmp(jmp_env, 1);
62 }
63
64 int v1;
65 int tab[2];
66
67 int main(int argc, char **argv)
68 {
69     struct sigaction act;
70     volatile int val;
71     
72     act.sa_sigaction = sig_handler;
73     sigemptyset(&act.sa_mask);
74     act.sa_flags = SA_SIGINFO;
75     sigaction(SIGFPE, &act, NULL);
76     sigaction(SIGILL, &act, NULL);
77     sigaction(SIGSEGV, &act, NULL);
78     sigaction(SIGTRAP, &act, NULL);
79
80     /* test division by zero reporting */
81     if (setjmp(jmp_env) == 0) {
82         /* now divide by zero */
83         v1 = 0;
84         v1 = 2 / v1;
85     }
86
87     /* test illegal instruction reporting */
88     if (setjmp(jmp_env) == 0) {
89         /* now execute an invalid instruction */
90         asm volatile("ud2");
91     }
92     
93     /* test SEGV reporting */
94     if (setjmp(jmp_env) == 0) {
95         /* now store in an invalid address */
96         *(char *)0x1234 = 1;
97     }
98
99     /* test SEGV reporting */
100     if (setjmp(jmp_env) == 0) {
101         /* read from an invalid address */
102         v1 = *(char *)0x1234;
103     }
104     
105     printf("segment GPF exception:\n");
106     if (setjmp(jmp_env) == 0) {
107         /* load an invalid segment */
108         asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0));
109     }
110
111     printf("INT exception:\n");
112     if (setjmp(jmp_env) == 0) {
113         asm volatile ("int $0xfd");
114     }
115
116     printf("INT3 exception:\n");
117     if (setjmp(jmp_env) == 0) {
118         asm volatile ("int3");
119     }
120
121     printf("CLI exception:\n");
122     if (setjmp(jmp_env) == 0) {
123         asm volatile ("cli");
124     }
125
126     printf("STI exception:\n");
127     if (setjmp(jmp_env) == 0) {
128         asm volatile ("cli");
129     }
130
131     printf("INTO exception:\n");
132     if (setjmp(jmp_env) == 0) {
133         /* overflow exception */
134         asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
135     }
136
137     printf("BOUND exception:\n");
138     if (setjmp(jmp_env) == 0) {
139         /* bound exception */
140         tab[0] = 1;
141         tab[1] = 10;
142         asm volatile ("bound %0, %1" : : "r" (11), "m" (tab));
143     }
144
145     printf("OUTB exception:\n");
146     if (setjmp(jmp_env) == 0) {
147         asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
148     }
149
150     printf("INB exception:\n");
151     if (setjmp(jmp_env) == 0) {
152         asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
153     }
154
155     printf("REP OUTSB exception:\n");
156     if (setjmp(jmp_env) == 0) {
157         asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
158     }
159
160     printf("REP INSB exception:\n");
161     if (setjmp(jmp_env) == 0) {
162         asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
163     }
164
165     printf("HLT exception:\n");
166     if (setjmp(jmp_env) == 0) {
167         asm volatile ("hlt");
168     }
169
170     printf("single step exception:\n");
171     val = 0;
172     if (setjmp(jmp_env) == 0) {
173         asm volatile ("pushf\n"
174                       "orl $0x00100, (%%esp)\n"
175                       "popf\n"
176                       "movl $0xabcd, %0\n" : "=m" (val) : : "cc", "memory");
177     }
178     printf("val=0x%x\n", val);
179     
180 #if 1
181     {
182         int i;
183         act.sa_handler = alarm_handler;
184         sigemptyset(&act.sa_mask);
185         act.sa_flags = 0;
186         sigaction(SIGALRM, &act, NULL);
187         alarm(1);
188         for(i = 0;i < 2; i++) {
189             sleep(1);
190         }
191     }
192 #endif
193     return 0;
194 }