 5977114c42
			
		
	
	
		5977114c42
		
	
	
	
	
		
			
			. make common.o link with the tests instead of being #included as common.c . fix warnings about missing prototypes by declaring functions static . reduces some duplicated code Change-Id: Ic2a765d7f5886add5863190efec3fdd2d2ea2137
		
			
				
	
	
		
			288 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Test 9 setjmp with register variables.	Author: Ceriel Jacobs */
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <setjmp.h>
 | |
| #include <signal.h>
 | |
| 
 | |
| int max_error = 4;
 | |
| #include "common.h"
 | |
| 
 | |
| 
 | |
| 
 | |
| char *tmpa;
 | |
| 
 | |
| int main(int argc, char *argv []);
 | |
| void test9a(void);
 | |
| void test9b(void);
 | |
| void test9c(void);
 | |
| void test9d(void);
 | |
| void test9e(void);
 | |
| void test9f(void);
 | |
| char *addr(void);
 | |
| void garbage(void);
 | |
| void level1(void);
 | |
| void level2(void);
 | |
| void dolev(void);
 | |
| void catch(int s);
 | |
| void hard(void);
 | |
| 
 | |
| int main(argc, argv)
 | |
| int argc;
 | |
| char *argv[];
 | |
| {
 | |
|   jmp_buf envm;
 | |
|   int i, j, m = 0xFFFF;
 | |
| 
 | |
|   start(9);
 | |
|   if (argc == 2) m = atoi(argv[1]);
 | |
|   for (j = 0; j < 100; j++) {
 | |
| 	if (m & 00001) test9a();
 | |
| 	if (m & 00002) test9b();
 | |
| 	if (m & 00004) test9c();
 | |
| 	if (m & 00010) test9d();
 | |
| 	if (m & 00020) test9e();
 | |
| 	if (m & 00040) test9f();
 | |
|   }
 | |
|   if (errct) quit();
 | |
|   i = 1;
 | |
|   if (setjmp(envm) == 0) {
 | |
| 	i = 2;
 | |
| 	longjmp(envm, 1);
 | |
|   } else {
 | |
| 	if (i == 2) {
 | |
| 		/* Correct */
 | |
| 	} else if (i == 1) {
 | |
| 		printf("WARNING: The setjmp/longjmp of this machine restore register variables\n\
 | |
| to the value they had at the time of the Setjmp\n");
 | |
| 	} else {
 | |
| 		printf("Aha, I just found one last error\n");
 | |
| 		return 1;
 | |
| 	}
 | |
|   }
 | |
|   quit();
 | |
|   return(-1);			/* impossible */
 | |
| }
 | |
| 
 | |
| void test9a()
 | |
| {
 | |
|   register int p;
 | |
| 
 | |
|   subtest = 1;
 | |
|   p = 200;
 | |
|   garbage();
 | |
|   if (p != 200) e(1);
 | |
| }
 | |
| 
 | |
| void test9b()
 | |
| {
 | |
|   register int p, q;
 | |
| 
 | |
|   subtest = 2;
 | |
|   p = 200;
 | |
|   q = 300;
 | |
|   garbage();
 | |
|   if (p != 200) e(1);
 | |
|   if (q != 300) e(2);
 | |
| }
 | |
| 
 | |
| void test9c()
 | |
| {
 | |
|   register int p, q, r;
 | |
| 
 | |
|   subtest = 3;
 | |
|   p = 200;
 | |
|   q = 300;
 | |
|   r = 400;
 | |
|   garbage();
 | |
|   if (p != 200) e(1);
 | |
|   if (q != 300) e(2);
 | |
|   if (r != 400) e(3);
 | |
| }
 | |
| 
 | |
| char buf[512];
 | |
| 
 | |
| void test9d()
 | |
| {
 | |
|   register char *p;
 | |
| 
 | |
|   subtest = 4;
 | |
|   p = &buf[100];
 | |
|   garbage();
 | |
|   if (p != &buf[100]) e(1);
 | |
| }
 | |
| 
 | |
| void test9e()
 | |
| {
 | |
|   register char *p, *q;
 | |
| 
 | |
|   subtest = 5;
 | |
|   p = &buf[100];
 | |
|   q = &buf[200];
 | |
|   garbage();
 | |
|   if (p != &buf[100]) e(1);
 | |
|   if (q != &buf[200]) e(2);
 | |
| }
 | |
| 
 | |
| void test9f()
 | |
| {
 | |
|   register char *p, *q, *r;
 | |
| 
 | |
|   subtest = 6;
 | |
|   p = &buf[100];
 | |
|   q = &buf[200];
 | |
|   r = &buf[300];
 | |
|   garbage();
 | |
|   if (p != &buf[100]) e(1);
 | |
|   if (q != &buf[200]) e(2);
 | |
|   if (r != &buf[300]) e(3);
 | |
| }
 | |
| 
 | |
| jmp_buf env;
 | |
| 
 | |
| /*	return address of local variable.
 | |
|   This way we can check that the stack is not polluted.
 | |
| */
 | |
| char *
 | |
|  addr()
 | |
| {
 | |
|   char a, *ret;
 | |
| 
 | |
|   ret = &a;
 | |
|   return(ret);
 | |
| }
 | |
| 
 | |
| void garbage()
 | |
| {
 | |
|   register int i, j, k;
 | |
|   register char *p, *q, *r;
 | |
|   char *a = NULL;
 | |
| 
 | |
|   p = &buf[300];
 | |
|   q = &buf[400];
 | |
|   r = &buf[500];
 | |
|   i = 10;
 | |
|   j = 20;
 | |
|   k = 30;
 | |
|   switch (setjmp(env)) {
 | |
|       case 0:
 | |
| 	a = addr();
 | |
| #ifdef __GNUC__
 | |
| 	/*
 | |
| 	 * to defeat the smartness of the GNU C optimizer we pretend we
 | |
| 	 * use 'a'. Otherwise the optimizer will not detect the looping
 | |
| 	 * effectuated by setjmp/longjmp, so that it thinks it can get
 | |
| 	 * rid of the assignment to 'a'.
 | |
| 	 */
 | |
| 	srand((unsigned)&a);
 | |
| #endif
 | |
| 	longjmp(env, 1);
 | |
| 	break;
 | |
|       case 1:
 | |
| 	if (i != 10) e(11);
 | |
| 	if (j != 20) e(12);
 | |
| 	if (k != 30) e(13);
 | |
| 	if (p != &buf[300]) e(14);
 | |
| 	if (q != &buf[400]) e(15);
 | |
| 	if (r != &buf[500]) e(16);
 | |
| 	tmpa = addr();
 | |
| 	if (a != tmpa) e(17);
 | |
| 	level1();
 | |
| 	break;
 | |
|       case 2:
 | |
| 	if (i != 10) e(21);
 | |
| 	if (j != 20) e(22);
 | |
| 	if (k != 30) e(23);
 | |
| 	if (p != &buf[300]) e(24);
 | |
| 	if (q != &buf[400]) e(25);
 | |
| 	if (r != &buf[500]) e(26);
 | |
| 	tmpa = addr();
 | |
| 	if (a != tmpa) e(27);
 | |
| 	level2();
 | |
| 	break;
 | |
|       case 3:
 | |
| 	if (i != 10) e(31);
 | |
| 	if (j != 20) e(32);
 | |
| 	if (k != 30) e(33);
 | |
| 	if (p != &buf[300]) e(34);
 | |
| 	if (q != &buf[400]) e(35);
 | |
| 	if (r != &buf[500]) e(36);
 | |
| 	tmpa = addr();
 | |
| 	if (a != tmpa) e(37);
 | |
| 	hard();
 | |
|       case 4:
 | |
| 	if (i != 10) e(41);
 | |
| 	if (j != 20) e(42);
 | |
| 	if (k != 30) e(43);
 | |
| 	if (p != &buf[300]) e(44);
 | |
| 	if (q != &buf[400]) e(45);
 | |
| 	if (r != &buf[500]) e(46);
 | |
| 	tmpa = addr();
 | |
| 	if (a != tmpa) e(47);
 | |
| 	return;
 | |
| 	break;
 | |
|       default:	e(100);
 | |
|   }
 | |
|   e(200);
 | |
| }
 | |
| 
 | |
| void level1()
 | |
| {
 | |
|   register char *p;
 | |
|   register int i;
 | |
| 
 | |
|   i = 1000;
 | |
|   p = &buf[10];
 | |
|   i = 200;
 | |
|   p = &buf[20];
 | |
|  
 | |
| #ifdef __GNUC__
 | |
| 	/*
 | |
| 	 * to defeat the smartness of the GNU C optimizer we pretend we
 | |
| 	 * use 'a'. Otherwise the optimizer will not detect the looping
 | |
| 	 * effectuated by setjmp/longjmp, so that it thinks it can get
 | |
| 	 * rid of the assignment to 'a'.
 | |
| 	 */
 | |
|   srand(i);
 | |
|   srand((int)*p);
 | |
| #endif
 | |
| 
 | |
|   longjmp(env, 2);
 | |
| }
 | |
| 
 | |
| void level2()
 | |
| {
 | |
|   register char *p;
 | |
|   register int i;
 | |
| 
 | |
|   i = 0200;
 | |
|   p = &buf[2];
 | |
|   *p = i;
 | |
|   dolev();
 | |
| }
 | |
| 
 | |
| void dolev()
 | |
| {
 | |
|   register char *p;
 | |
|   register int i;
 | |
| 
 | |
|   i = 010;
 | |
|   p = &buf[3];
 | |
|   *p = i;
 | |
|   longjmp(env, 3);
 | |
| }
 | |
| 
 | |
| void catch(s)
 | |
| int s;
 | |
| {
 | |
|   longjmp(env, 4);
 | |
| }
 | |
| 
 | |
| void hard()
 | |
| {
 | |
|   register char *p;
 | |
| 
 | |
|   signal(SIGHUP, catch);
 | |
|   for (p = buf; p <= &buf[511]; p++) *p = 025;
 | |
|   kill(getpid(), SIGHUP);
 | |
| }
 |