--- libcoro/coro.c 2001/07/23 22:16:38 1.3 +++ libcoro/coro.c 2001/11/06 20:34:11 1.9 @@ -32,7 +32,21 @@ #include "coro.h" -#if CORO_LOOSE || CORO_SJLJ +#if !defined(STACK_ADJUST_PTR) +/* IRIX is decidedly NON-unix */ +# if __sgi +# define STACK_ADJUST_PTR(sp,ss) ((char *)(sp) + (ss) - 8) +# define STACK_ADJUST_SIZE(sp,ss) ((ss) - 8) +# elif __i386__ && CORO_LINUX +# define STACK_ADJUST_PTR(sp,ss) ((char *)(sp) + (ss)) +# define STACK_ADJUST_SIZE(sp,ss) (ss) +# else +# define STACK_ADJUST_PTR(sp,ss) (sp) +# define STACK_ADJUST_SIZE(sp,ss) (ss) +# endif +#endif + +#if CORO_SJLJ || CORO_LOOSE || CORO_LINUX || CORO_IRIX #include @@ -55,7 +69,6 @@ } # if CORO_SJLJ -# define coro_save(ctx) (void)setjmp((ctx)->env) static volatile int trampoline_count; @@ -71,8 +84,6 @@ # endif -#elif CORO_UCONTEXT -# define coro_save(ctx) getcontext(&((ctx)->uc)) #endif /* initialize a machine state */ @@ -84,14 +95,14 @@ getcontext (&(ctx->uc)); - ctx->uc.uc_link = 0; - ctx->uc.uc_stack.ss_sp = sptr; - ctx->uc.uc_stack.ss_size = (size_t) ssize; + ctx->uc.uc_link = 0; + ctx->uc.uc_stack.ss_sp = STACK_ADJUST_PTR (sptr,ssize); + ctx->uc.uc_stack.ss_size = (size_t) STACK_ADJUST_SIZE (sptr,ssize); ctx->uc.uc_stack.ss_flags = 0; makecontext (&(ctx->uc), (void (*)()) coro, 1, arg); -#elif CORO_SJLJ || CORO_LOOSE +#elif CORO_SJLJ || CORO_LOOSE || CORO_LINUX || CORO_IRIX # if CORO_SJLJ stack_t ostk, nstk; @@ -121,8 +132,8 @@ perror ("sigaction"); /* set the new stack */ - nstk.ss_sp = sptr; - nstk.ss_size = ssize; + nstk.ss_sp = STACK_ADJUST_PTR (sptr,ssize); /* yes, some platforms (IRIX) get this wrong. */ + nstk.ss_size = STACK_ADJUST_SIZE (sptr,ssize); nstk.ss_flags = 0; if (sigaltstack (&nstk, &ostk) < 0) @@ -151,11 +162,35 @@ sigprocmask (SIG_SETMASK, &osig, 0); -# elif MS_LOOSE +# elif CORO_LOOSE - coro_save (ctx); + setjmp (ctx->env); ctx->env[7] = (int)((char *)sptr + ssize); - ctx->env[8] = (int)coro; + ctx->env[8] = (int)coro_init; + +# elif CORO_LINUX + + setjmp (ctx->env); +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined(JB_PC) && defined(JB_SP) + ctx->env[0].__jmpbuf[JB_PC] = (int)coro_init; + ctx->env[0].__jmpbuf[JB_SP] = (int)STACK_ADJUST_PTR (sptr,ssize); +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined(__mc68000__) + ctx->env[0].__jmpbuf[0].__aregs[0] = (long int)coro_init; + ctx->env[0].__jmpbuf[0].__sp = (int *)((char *)sptr + ssize); +#elif defined(__GNU_LIBRARY__) && defined(__i386__) + ctx->env[0].__jmpbuf[0].__pc = (char *)coro_init; + ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize); +#else +#error "linux libc or architecture not supported" +#endif + +# elif CORO_IRIX + + setjmp (ctx->env); + ctx->env[JB_PC] = (__uint64_t)coro_init; + ctx->env[JB_SP] = (__uint64_t)STACK_ADJUST_PTR (sptr,ssize); # endif