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