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