Commit a69d83b60b9923784eaceccdb2dc07ca1e599494
1 parent
86840ae2
systematic exception test
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@122 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
93 additions
and
25 deletions
tests/testsig.c
@@ -26,13 +26,15 @@ void alarm_handler(int sig) | @@ -26,13 +26,15 @@ void alarm_handler(int sig) | ||
26 | #define REG_ESP ESP | 26 | #define REG_ESP ESP |
27 | #define REG_EIP EIP | 27 | #define REG_EIP EIP |
28 | #define REG_EFL EFL | 28 | #define REG_EFL EFL |
29 | +#define REG_TRAPNO TRAPNO | ||
30 | +#define REG_ERR ERR | ||
29 | #endif | 31 | #endif |
30 | 32 | ||
31 | void dump_regs(struct ucontext *uc) | 33 | void dump_regs(struct ucontext *uc) |
32 | { | 34 | { |
33 | printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" | 35 | printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" |
34 | "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" | 36 | "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" |
35 | - "EFL=%08x EIP=%08x\n", | 37 | + "EFL=%08x EIP=%08x trapno=%02x err=%08x\n", |
36 | uc->uc_mcontext.gregs[REG_EAX], | 38 | uc->uc_mcontext.gregs[REG_EAX], |
37 | uc->uc_mcontext.gregs[REG_EBX], | 39 | uc->uc_mcontext.gregs[REG_EBX], |
38 | uc->uc_mcontext.gregs[REG_ECX], | 40 | uc->uc_mcontext.gregs[REG_ECX], |
@@ -42,7 +44,9 @@ void dump_regs(struct ucontext *uc) | @@ -42,7 +44,9 @@ void dump_regs(struct ucontext *uc) | ||
42 | uc->uc_mcontext.gregs[REG_EBP], | 44 | uc->uc_mcontext.gregs[REG_EBP], |
43 | uc->uc_mcontext.gregs[REG_ESP], | 45 | uc->uc_mcontext.gregs[REG_ESP], |
44 | uc->uc_mcontext.gregs[REG_EFL], | 46 | uc->uc_mcontext.gregs[REG_EFL], |
45 | - uc->uc_mcontext.gregs[REG_EIP]); | 47 | + uc->uc_mcontext.gregs[REG_EIP], |
48 | + uc->uc_mcontext.gregs[REG_TRAPNO], | ||
49 | + uc->uc_mcontext.gregs[REG_ERR]); | ||
46 | } | 50 | } |
47 | 51 | ||
48 | void sig_handler(int sig, siginfo_t *info, void *puc) | 52 | void sig_handler(int sig, siginfo_t *info, void *puc) |
@@ -58,19 +62,22 @@ void sig_handler(int sig, siginfo_t *info, void *puc) | @@ -58,19 +62,22 @@ void sig_handler(int sig, siginfo_t *info, void *puc) | ||
58 | } | 62 | } |
59 | 63 | ||
60 | int v1; | 64 | int v1; |
65 | +int tab[2]; | ||
61 | 66 | ||
62 | int main(int argc, char **argv) | 67 | int main(int argc, char **argv) |
63 | { | 68 | { |
64 | struct sigaction act; | 69 | struct sigaction act; |
65 | - int i; | 70 | + int val; |
66 | 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 | + | ||
67 | /* test division by zero reporting */ | 79 | /* test division by zero reporting */ |
68 | if (setjmp(jmp_env) == 0) { | 80 | if (setjmp(jmp_env) == 0) { |
69 | - act.sa_sigaction = sig_handler; | ||
70 | - sigemptyset(&act.sa_mask); | ||
71 | - act.sa_flags = SA_SIGINFO | SA_ONESHOT; | ||
72 | - sigaction(SIGFPE, &act, NULL); | ||
73 | - | ||
74 | /* now divide by zero */ | 81 | /* now divide by zero */ |
75 | v1 = 0; | 82 | v1 = 0; |
76 | v1 = 2 / v1; | 83 | v1 = 2 / v1; |
@@ -78,33 +85,94 @@ int main(int argc, char **argv) | @@ -78,33 +85,94 @@ int main(int argc, char **argv) | ||
78 | 85 | ||
79 | /* test illegal instruction reporting */ | 86 | /* test illegal instruction reporting */ |
80 | if (setjmp(jmp_env) == 0) { | 87 | if (setjmp(jmp_env) == 0) { |
81 | - act.sa_sigaction = sig_handler; | ||
82 | - sigemptyset(&act.sa_mask); | ||
83 | - act.sa_flags = SA_SIGINFO | SA_ONESHOT; | ||
84 | - sigaction(SIGILL, &act, NULL); | ||
85 | - | ||
86 | /* now execute an invalid instruction */ | 88 | /* now execute an invalid instruction */ |
87 | asm volatile("ud2"); | 89 | asm volatile("ud2"); |
88 | } | 90 | } |
89 | 91 | ||
90 | /* test SEGV reporting */ | 92 | /* test SEGV reporting */ |
91 | if (setjmp(jmp_env) == 0) { | 93 | if (setjmp(jmp_env) == 0) { |
92 | - act.sa_sigaction = sig_handler; | ||
93 | - sigemptyset(&act.sa_mask); | ||
94 | - act.sa_flags = SA_SIGINFO | SA_ONESHOT; | ||
95 | - sigaction(SIGSEGV, &act, NULL); | ||
96 | - | ||
97 | /* now store in an invalid address */ | 94 | /* now store in an invalid address */ |
98 | *(char *)0x1234 = 1; | 95 | *(char *)0x1234 = 1; |
99 | } | 96 | } |
97 | + | ||
98 | + /* test SEGV reporting */ | ||
99 | + if (setjmp(jmp_env) == 0) { | ||
100 | + /* read from an invalid address */ | ||
101 | + v1 = *(char *)0x1234; | ||
102 | + } | ||
100 | 103 | ||
101 | - act.sa_handler = alarm_handler; | ||
102 | - sigemptyset(&act.sa_mask); | ||
103 | - act.sa_flags = 0; | ||
104 | - sigaction(SIGALRM, &act, NULL); | ||
105 | - alarm(1); | ||
106 | - for(i = 0;i < 2; i++) { | ||
107 | - sleep(1); | 104 | + printf("segment GPF exception:\n"); |
105 | + if (setjmp(jmp_env) == 0) { | ||
106 | + /* load an invalid segment */ | ||
107 | + asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); | ||
108 | + } | ||
109 | + | ||
110 | + printf("INT exception:\n"); | ||
111 | + if (setjmp(jmp_env) == 0) { | ||
112 | + asm volatile ("int $0xfd"); | ||
113 | + } | ||
114 | + | ||
115 | + printf("CLI exception:\n"); | ||
116 | + if (setjmp(jmp_env) == 0) { | ||
117 | + asm volatile ("cli"); | ||
118 | + } | ||
119 | + | ||
120 | + printf("STI exception:\n"); | ||
121 | + if (setjmp(jmp_env) == 0) { | ||
122 | + asm volatile ("cli"); | ||
123 | + } | ||
124 | + | ||
125 | + printf("INTO exception:\n"); | ||
126 | + if (setjmp(jmp_env) == 0) { | ||
127 | + /* overflow exception */ | ||
128 | + asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); | ||
129 | + } | ||
130 | + | ||
131 | + printf("BOUND exception:\n"); | ||
132 | + if (setjmp(jmp_env) == 0) { | ||
133 | + /* bound exception */ | ||
134 | + tab[0] = 1; | ||
135 | + tab[1] = 10; | ||
136 | + asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); | ||
137 | + } | ||
138 | + | ||
139 | + printf("OUTB exception:\n"); | ||
140 | + if (setjmp(jmp_env) == 0) { | ||
141 | + asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); | ||
142 | + } | ||
143 | + | ||
144 | + printf("INB exception:\n"); | ||
145 | + if (setjmp(jmp_env) == 0) { | ||
146 | + asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); | ||
108 | } | 147 | } |
148 | + | ||
149 | + printf("REP OUTSB exception:\n"); | ||
150 | + if (setjmp(jmp_env) == 0) { | ||
151 | + asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); | ||
152 | + } | ||
153 | + | ||
154 | + printf("REP INSB exception:\n"); | ||
155 | + if (setjmp(jmp_env) == 0) { | ||
156 | + asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); | ||
157 | + } | ||
158 | + | ||
159 | + printf("HLT exception:\n"); | ||
160 | + if (setjmp(jmp_env) == 0) { | ||
161 | + asm volatile ("hlt" : : "d" (0x4321), "D" (tab), "c" (1)); | ||
162 | + } | ||
163 | + | ||
164 | +#if 0 | ||
165 | + { | ||
166 | + int i; | ||
167 | + act.sa_handler = alarm_handler; | ||
168 | + sigemptyset(&act.sa_mask); | ||
169 | + act.sa_flags = 0; | ||
170 | + sigaction(SIGALRM, &act, NULL); | ||
171 | + alarm(1); | ||
172 | + for(i = 0;i < 2; i++) { | ||
173 | + sleep(1); | ||
174 | + } | ||
175 | + } | ||
176 | +#endif | ||
109 | return 0; | 177 | return 0; |
110 | } | 178 | } |