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