xref: /minix/minix/tests/test9.c (revision 7f5f010b)
1 /* Test 9 setjmp with register variables.	Author: Ceriel Jacobs */
2 
3 #include <sys/types.h>
4 #include <setjmp.h>
5 #include <signal.h>
6 
7 int max_error = 4;
8 #include "common.h"
9 
10 
11 
12 char *tmpa;
13 
14 int main(int argc, char *argv []);
15 void test9a(void);
16 void test9b(void);
17 void test9c(void);
18 void test9d(void);
19 void test9e(void);
20 void test9f(void);
21 char *addr(void);
22 void garbage(void);
23 void level1(void);
24 void level2(void);
25 void dolev(void);
26 void catch(int s);
27 void hard(void);
28 
29 int main(argc, argv)
30 int argc;
31 char *argv[];
32 {
33   jmp_buf envm;
34   int i, j, m = 0xFFFF;
35 
36   start(9);
37   if (argc == 2) m = atoi(argv[1]);
38   for (j = 0; j < 100; j++) {
39 	if (m & 00001) test9a();
40 	if (m & 00002) test9b();
41 	if (m & 00004) test9c();
42 	if (m & 00010) test9d();
43 	if (m & 00020) test9e();
44 	if (m & 00040) test9f();
45   }
46   if (errct) quit();
47   i = 1;
48   if (setjmp(envm) == 0) {
49 	i = 2;
50 	longjmp(envm, 1);
51   } else {
52 	if (i == 2) {
53 		/* Correct */
54 	} else if (i == 1) {
55 		printf("WARNING: The setjmp/longjmp of this machine restore register variables\n\
56 to the value they had at the time of the Setjmp\n");
57 	} else {
58 		printf("Aha, I just found one last error\n");
59 		return 1;
60 	}
61   }
62   quit();
63   return(-1);			/* impossible */
64 }
65 
66 void test9a()
67 {
68   register int p;
69 
70   subtest = 1;
71   p = 200;
72   garbage();
73   if (p != 200) e(1);
74 }
75 
76 void test9b()
77 {
78   register int p, q;
79 
80   subtest = 2;
81   p = 200;
82   q = 300;
83   garbage();
84   if (p != 200) e(1);
85   if (q != 300) e(2);
86 }
87 
88 void test9c()
89 {
90   register int p, q, r;
91 
92   subtest = 3;
93   p = 200;
94   q = 300;
95   r = 400;
96   garbage();
97   if (p != 200) e(1);
98   if (q != 300) e(2);
99   if (r != 400) e(3);
100 }
101 
102 char buf[512];
103 
104 void test9d()
105 {
106   register char *p;
107 
108   subtest = 4;
109   p = &buf[100];
110   garbage();
111   if (p != &buf[100]) e(1);
112 }
113 
114 void test9e()
115 {
116   register char *p, *q;
117 
118   subtest = 5;
119   p = &buf[100];
120   q = &buf[200];
121   garbage();
122   if (p != &buf[100]) e(1);
123   if (q != &buf[200]) e(2);
124 }
125 
126 void test9f()
127 {
128   register char *p, *q, *r;
129 
130   subtest = 6;
131   p = &buf[100];
132   q = &buf[200];
133   r = &buf[300];
134   garbage();
135   if (p != &buf[100]) e(1);
136   if (q != &buf[200]) e(2);
137   if (r != &buf[300]) e(3);
138 }
139 
140 jmp_buf env;
141 
142 /*	return address of local variable.
143   This way we can check that the stack is not polluted.
144 */
145 char *
146  addr()
147 {
148   char a, *ret;
149 
150   ret = &a;
151   return(ret);
152 }
153 
154 void garbage()
155 {
156   register int i, j, k;
157   register char *p, *q, *r;
158   char *a = NULL;
159 
160   p = &buf[300];
161   q = &buf[400];
162   r = &buf[500];
163   i = 10;
164   j = 20;
165   k = 30;
166   switch (setjmp(env)) {
167       case 0:
168 	a = addr();
169 #ifdef __GNUC__
170 	/*
171 	 * to defeat the smartness of the GNU C optimizer we pretend we
172 	 * use 'a'. Otherwise the optimizer will not detect the looping
173 	 * effectuated by setjmp/longjmp, so that it thinks it can get
174 	 * rid of the assignment to 'a'.
175 	 */
176 	srand((unsigned)&a);
177 #endif
178 	longjmp(env, 1);
179 	break;
180       case 1:
181 	if (i != 10) e(11);
182 	if (j != 20) e(12);
183 	if (k != 30) e(13);
184 	if (p != &buf[300]) e(14);
185 	if (q != &buf[400]) e(15);
186 	if (r != &buf[500]) e(16);
187 	tmpa = addr();
188 	if (a != tmpa) e(17);
189 	level1();
190 	break;
191       case 2:
192 	if (i != 10) e(21);
193 	if (j != 20) e(22);
194 	if (k != 30) e(23);
195 	if (p != &buf[300]) e(24);
196 	if (q != &buf[400]) e(25);
197 	if (r != &buf[500]) e(26);
198 	tmpa = addr();
199 	if (a != tmpa) e(27);
200 	level2();
201 	break;
202       case 3:
203 	if (i != 10) e(31);
204 	if (j != 20) e(32);
205 	if (k != 30) e(33);
206 	if (p != &buf[300]) e(34);
207 	if (q != &buf[400]) e(35);
208 	if (r != &buf[500]) e(36);
209 	tmpa = addr();
210 	if (a != tmpa) e(37);
211 	hard();
212       case 4:
213 	if (i != 10) e(41);
214 	if (j != 20) e(42);
215 	if (k != 30) e(43);
216 	if (p != &buf[300]) e(44);
217 	if (q != &buf[400]) e(45);
218 	if (r != &buf[500]) e(46);
219 	tmpa = addr();
220 	if (a != tmpa) e(47);
221 	return;
222 	break;
223       default:	e(100);
224   }
225   e(200);
226 }
227 
228 void level1()
229 {
230   register char *p;
231   register int i;
232 
233   i = 1000;
234   p = &buf[10];
235   i = 200;
236   p = &buf[20];
237 
238 #ifdef __GNUC__
239 	/*
240 	 * to defeat the smartness of the GNU C optimizer we pretend we
241 	 * use 'a'. Otherwise the optimizer will not detect the looping
242 	 * effectuated by setjmp/longjmp, so that it thinks it can get
243 	 * rid of the assignment to 'a'.
244 	 */
245   srand(i);
246   srand((int)*p);
247 #endif
248 
249   longjmp(env, 2);
250 }
251 
252 void level2()
253 {
254   register char *p;
255   register int i;
256 
257   i = 0200;
258   p = &buf[2];
259   *p = i;
260   dolev();
261 }
262 
263 void dolev()
264 {
265   register char *p;
266   register int i;
267 
268   i = 010;
269   p = &buf[3];
270   *p = i;
271   longjmp(env, 3);
272 }
273 
274 void catch(s)
275 int s;
276 {
277   longjmp(env, 4);
278 }
279 
280 void hard()
281 {
282   register char *p;
283 
284   signal(SIGHUP, catch);
285   for (p = buf; p <= &buf[511]; p++) *p = 025;
286   kill(getpid(), SIGHUP);
287 }
288