forked from ariadne/libucontext
commit
7599fe5ff2
10
Makefile
10
Makefile
|
@ -2,14 +2,8 @@ ARCH := $(shell uname -m)
|
|||
|
||||
CFLAGS = -ggdb3 -O2 -Wall -Iarch/${ARCH}
|
||||
|
||||
LIBUCONTEXT_C_SRC = \
|
||||
arch/${ARCH}/makecontext.c
|
||||
|
||||
LIBUCONTEXT_S_SRC = \
|
||||
arch/${ARCH}/getcontext.S \
|
||||
arch/${ARCH}/setcontext.S \
|
||||
arch/${ARCH}/swapcontext.S \
|
||||
arch/${ARCH}/startcontext.S
|
||||
LIBUCONTEXT_C_SRC = $(wildcard arch/${ARCH}/*.c)
|
||||
LIBUCONTEXT_S_SRC = $(wildcard arch/${ARCH}/*.S)
|
||||
|
||||
LIBUCONTEXT_OBJ = ${LIBUCONTEXT_C_SRC:.c=.o} ${LIBUCONTEXT_S_SRC:.S=.o}
|
||||
LIBUCONTEXT_SOVERSION = 0
|
||||
|
|
|
@ -19,7 +19,7 @@ Right now these archs are supported and should work on bare metal:
|
|||
* aarch64
|
||||
* s390x
|
||||
|
||||
These archs require kernel assistance and use a syscall (the only assembly is the trampoline):
|
||||
These archs require kernel assistance and use a syscall:
|
||||
|
||||
* ppc
|
||||
* ppc64 (ELFv2 ABI spec only, ELFv1 not supported)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
.global __getcontext
|
||||
.hidden __swapcontext
|
||||
__getcontext:
|
||||
li 4, 0
|
||||
b __swapcontext@local
|
||||
|
||||
.weak getcontext
|
||||
getcontext = __getcontext
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -11,10 +12,8 @@
|
|||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
@ -25,48 +24,34 @@ extern void __start_context(void);
|
|||
|
||||
|
||||
void
|
||||
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
|
||||
__makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
|
||||
{
|
||||
greg_t *sp, *argp;
|
||||
greg_t *sp;
|
||||
va_list va;
|
||||
int i;
|
||||
unsigned int uc_link, stack_args;
|
||||
unsigned int stack_args;
|
||||
|
||||
stack_args = argc > 8 ? argc - 8 : 0;
|
||||
uc_link = stack_args + 1;
|
||||
|
||||
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
|
||||
sp -= (uc_link + 1);
|
||||
sp = (greg_t *) (((uintptr_t) sp & -16L) - 8);
|
||||
sp -= stack_args + 2;
|
||||
sp = (greg_t *) ((uintptr_t) sp & -16L);
|
||||
|
||||
ucp->uc_mcontext.gregs[REG_NIP] = (uintptr_t) func;
|
||||
ucp->uc_mcontext.gregs[REG_LNK] = (uintptr_t) &__start_context;
|
||||
ucp->uc_mcontext.gregs[REG_R31] = (uintptr_t) ucp->uc_link;
|
||||
ucp->uc_mcontext.gregs[REG_SP] = (uintptr_t) sp;
|
||||
|
||||
sp[0] = (uintptr_t) &__start_context;
|
||||
sp[uc_link] = (uintptr_t) ucp->uc_link;
|
||||
argp = &sp[2];
|
||||
sp[0] = 0;
|
||||
|
||||
va_start(va, argc);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (i < 8)
|
||||
ucp->uc_mcontext.gregs[i + 3] = va_arg (va, greg_t);
|
||||
break;
|
||||
default:
|
||||
*argp++ = va_arg (va, greg_t);
|
||||
break;
|
||||
}
|
||||
else
|
||||
sp[i-8 + 2] = va_arg (va, greg_t);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -10,36 +11,15 @@
|
|||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
int
|
||||
__getcontext(ucontext_t *ucp)
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
int __retfromsyscall(long retval)
|
||||
{
|
||||
#ifdef SYS_swapcontext
|
||||
int r;
|
||||
|
||||
r = syscall(SYS_swapcontext, ucp, NULL, sizeof(ucontext_t));
|
||||
if (r < 0)
|
||||
{
|
||||
errno = -r;
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern __typeof(__getcontext) getcontext __attribute__((weak, __alias__("__getcontext")));
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
.global __setcontext
|
||||
.hidden __swapcontext
|
||||
__setcontext:
|
||||
mr 4, 3
|
||||
li 3, 0
|
||||
b __swapcontext@local
|
||||
|
||||
.weak setcontext
|
||||
setcontext = __setcontext
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
int
|
||||
__setcontext(const ucontext_t *ucp)
|
||||
{
|
||||
#ifdef SYS_swapcontext
|
||||
int r;
|
||||
|
||||
r = syscall(SYS_swapcontext, NULL, (void *) ucp, sizeof(ucontext_t));
|
||||
if (r < 0)
|
||||
{
|
||||
errno = -r;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern __typeof(__setcontext) setcontext __attribute__((weak, __alias__("__setcontext")));
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
.global __swapcontext
|
||||
__swapcontext:
|
||||
li 0, 249 # SYS_swapcontext
|
||||
li 5, 1184 # sizeof(ucontext_t)
|
||||
sc
|
||||
|
||||
.hidden __retfromsyscall
|
||||
b __retfromsyscall@local
|
||||
|
||||
.weak swapcontext
|
||||
swapcontext = __swapcontext
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
int
|
||||
__swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
|
||||
{
|
||||
#ifdef SYS_swapcontext
|
||||
int r;
|
||||
|
||||
r = syscall(SYS_swapcontext, oucp, ucp, sizeof(ucontext_t));
|
||||
if (r < 0)
|
||||
{
|
||||
errno = -r;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern __typeof(__swapcontext) swapcontext __attribute__((weak, __alias__("__swapcontext")));
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
.global __getcontext
|
||||
.hidden __swapcontext
|
||||
__getcontext:
|
||||
addis 2, 12, .TOC.-__getcontext@ha
|
||||
addi 2, 12, .TOC.-__getcontext@l
|
||||
|
||||
.localentry __getcontext,.-__getcontext
|
||||
|
||||
li 4, 0
|
||||
b __swapcontext
|
||||
|
||||
.weak getcontext
|
||||
getcontext = __getcontext
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -11,10 +12,8 @@
|
|||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
@ -25,19 +24,18 @@ extern void __start_context(void);
|
|||
|
||||
|
||||
void
|
||||
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
|
||||
__makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
|
||||
{
|
||||
greg_t *sp, *argp;
|
||||
greg_t *sp;
|
||||
va_list va;
|
||||
int i;
|
||||
unsigned int uc_link, stack_args;
|
||||
unsigned int stack_args;
|
||||
|
||||
stack_args = argc > 8 ? argc - 8 : 0;
|
||||
uc_link = stack_args + 1;
|
||||
stack_args = argc > 8 ? argc : 0;
|
||||
|
||||
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
|
||||
sp -= (uc_link + 1);
|
||||
sp = (greg_t *) (((uintptr_t) sp & -16L));
|
||||
sp -= stack_args + 4;
|
||||
sp = (greg_t *) ((uintptr_t) sp & -16L);
|
||||
|
||||
ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func;
|
||||
ucp->uc_mcontext.gp_regs[REG_LNK] = (uintptr_t) &__start_context;
|
||||
|
@ -45,29 +43,16 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
|
|||
ucp->uc_mcontext.gp_regs[REG_ENTRY] = (uintptr_t) func;
|
||||
ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link;
|
||||
|
||||
sp[0] = (uintptr_t) &__start_context;
|
||||
sp[uc_link] = (uintptr_t) ucp->uc_link;
|
||||
argp = &sp[2];
|
||||
sp[0] = 0;
|
||||
|
||||
va_start(va, argc);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (i < 8)
|
||||
ucp->uc_mcontext.gp_regs[i + 3] = va_arg (va, greg_t);
|
||||
break;
|
||||
default:
|
||||
*argp++ = va_arg (va, greg_t);
|
||||
break;
|
||||
}
|
||||
else
|
||||
sp[i + 4] = va_arg (va, greg_t);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -10,36 +11,15 @@
|
|||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
int
|
||||
__getcontext(ucontext_t *ucp)
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
int __retfromsyscall(long retval)
|
||||
{
|
||||
#ifdef SYS_swapcontext
|
||||
int r;
|
||||
|
||||
r = syscall(SYS_swapcontext, ucp, NULL, sizeof(ucontext_t));
|
||||
if (r < 0)
|
||||
{
|
||||
errno = -r;
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern __typeof(__getcontext) getcontext __attribute__((weak, __alias__("__getcontext")));
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
.global __setcontext
|
||||
.hidden __swapcontext
|
||||
__setcontext:
|
||||
addis 2, 12, .TOC.-__setcontext@ha
|
||||
addi 2, 12, .TOC.-__setcontext@l
|
||||
|
||||
.localentry __setcontext,.-__setcontext
|
||||
|
||||
mr 4, 3
|
||||
li 3, 0
|
||||
b __swapcontext
|
||||
|
||||
.weak setcontext
|
||||
setcontext = __setcontext
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
int
|
||||
__setcontext(const ucontext_t *ucp)
|
||||
{
|
||||
#ifdef SYS_swapcontext
|
||||
int r;
|
||||
|
||||
r = syscall(SYS_swapcontext, NULL, (void *) ucp, sizeof(ucontext_t));
|
||||
if (r < 0)
|
||||
{
|
||||
errno = -r;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern __typeof(__setcontext) setcontext __attribute__((weak, __alias__("__setcontext")));
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bobby Bingham <koorogi@koorogi.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
.global __swapcontext
|
||||
__swapcontext:
|
||||
addis 2, 12, .TOC.-__swapcontext@ha
|
||||
addi 2, 12, .TOC.-__swapcontext@l
|
||||
|
||||
.localentry __swapcontext,.-__swapcontext
|
||||
|
||||
li 0, 249 # SYS_swapcontext
|
||||
li 5, 1696 # sizeof(ucontext_t)
|
||||
sc
|
||||
|
||||
.hidden __retfromsyscall
|
||||
b __retfromsyscall
|
||||
|
||||
.weak swapcontext
|
||||
swapcontext = __swapcontext
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
int
|
||||
__swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
|
||||
{
|
||||
#ifdef SYS_swapcontext
|
||||
int r;
|
||||
|
||||
r = syscall(SYS_swapcontext, oucp, ucp, sizeof(ucontext_t));
|
||||
if (r < 0)
|
||||
{
|
||||
errno = -r;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern __typeof(__swapcontext) swapcontext __attribute__((weak, __alias__("__swapcontext")));
|
|
@ -6,13 +6,32 @@
|
|||
#include <stdio.h>
|
||||
#include <ucontext.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static ucontext_t ctx[3];
|
||||
|
||||
|
||||
static void f1 (void) {
|
||||
static void check_arg(int actual, int expected) {
|
||||
if (actual == expected) return;
|
||||
fprintf(stderr, "argument has wrong value. got %d, expected %d.\n", actual, expected);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static void f1 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
|
||||
check_arg(a, 1);
|
||||
check_arg(b, 2);
|
||||
check_arg(c, 3);
|
||||
check_arg(d, 4);
|
||||
check_arg(e, 5);
|
||||
check_arg(f, 6);
|
||||
check_arg(g, 7);
|
||||
check_arg(h, 8);
|
||||
check_arg(i, 9);
|
||||
check_arg(j, 10);
|
||||
|
||||
printf("start f1\n");
|
||||
swapcontext(&ctx[1], &ctx[2]);
|
||||
printf("finish f1\n");
|
||||
|
@ -29,6 +48,7 @@ static void f2 (void) {
|
|||
int main (int argc, const char *argv[]) {
|
||||
char st1[8192];
|
||||
char st2[8192];
|
||||
volatile int done = 0;
|
||||
|
||||
|
||||
/* poison each coroutine's stack memory for debugging purposes */
|
||||
|
@ -40,7 +60,7 @@ int main (int argc, const char *argv[]) {
|
|||
ctx[1].uc_stack.ss_sp = st1;
|
||||
ctx[1].uc_stack.ss_size = sizeof st1;
|
||||
ctx[1].uc_link = &ctx[0];
|
||||
makecontext(&ctx[1], f1, 0);
|
||||
makecontext(&ctx[1], f1, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
|
||||
|
||||
getcontext(&ctx[2]);
|
||||
|
@ -51,5 +71,16 @@ int main (int argc, const char *argv[]) {
|
|||
|
||||
|
||||
swapcontext(&ctx[0], &ctx[2]);
|
||||
|
||||
|
||||
/* test ability to use getcontext/setcontext without makecontext */
|
||||
getcontext(&ctx[1]);
|
||||
printf("done = %d\n", done);
|
||||
if (done++ == 0) setcontext(&ctx[1]);
|
||||
if (done != 2) {
|
||||
fprintf(stderr, "wrong value for done. got %d, expected 2\n", done);
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue