Sophie

Sophie

distrib > Mandriva > 2007.0 > i586 > media > contrib-release > by-pkgid > 4c9f17ec5da473f7fb52041bb9197c5a > files > 145

kaffe-devel-1.1.8-0.20060723.1mdv2007.0.i586.rpm

/*
 * a program to guess the correct value of SP_OFFSET for your architecture.
 *
 * Compile with cc sp_offset.c and run with ./a.out
 * This program may leave core dumps in your current dir.
 *
 * Written by Godmar Back <gback@cs.utah.edu>
 */
#include <setjmp.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>

#define STACK_SIZE	65536
#define STACK_COPY	128
#define GET_SP(E)       (((void**)(E))[SP_OFFSET])
#define SET_SP(E, V)    ((void**)(E))[SP_OFFSET] = (V)

int fork();

int  SP_OFFSET;
char new_stack[STACK_SIZE];
jmp_buf buf, buf2;

void alarm()
{
    longjmp(buf2, 1);
}

static void
check()
{
    char x;
    if (&x > new_stack && &new_stack[sizeof new_stack] > &x)
	printf("#define\tSP_OFFSET\t%d\n", SP_OFFSET);
    exit(0);
}

int
main(int ac, char *av[])
{
    int  stat;
    pid_t child;
    void *oldsp, *newsp;

    for (; SP_OFFSET < sizeof (buf) / sizeof (int); SP_OFFSET++) {

	if ((child = fork()) == 0) {	/* child */

	    if (setjmp(buf)) 
		check();

	    oldsp = GET_SP(buf);
	    newsp = &new_stack[(sizeof new_stack)/2];
	    SET_SP(buf, newsp);
	    memcpy(newsp, oldsp, STACK_COPY);
	    longjmp(buf, 1);
	    exit(-1);

	} else {	/* parent */

	    if (!setjmp(buf2)) {
		signal(SIGALRM, alarm);
		alarm(3);
		assert(child == wait(&stat));
		alarm(0);
	    }
	    /* else timed out, continue */
	}
    }
    return 0;
}