setcontext() used to be incompatible with -lpthread since it affected
the TLS pointer, therefore wrecking the pthread environement. Some ports had _UC_TLSBASE flag or equivalent (_UC_UNIQUE on alpha) that controlled whether setcontext() would change the TLS pointer. This change let libpthread override setcontext() with its own version that unsets _UC_TLSBASE, enabling safe usage of setcontext() with -lpthread. We also have the following required changes here: - rename alpha's _UC_UNIQUE into _UC_TLSBASE - add _UC_TLSBASE definition in header file for all ports (powerpc, sh3, sparc and sparc64 lack the implementation for now) - introduce a libc stub that can be overriden for setcontext() - modify MD libcs swapcontext() implementations so that they use the setcontext() libc stub instead of doing a plain system call. While we are there: - document various MD _UC_* flags in header file - add libc and libpthread tests for swapcontext() behavior (hopefully helpful to spot MD problems introduced with this change) Future work: - Deciding whether kernel support or _UC_TLSBASE should be added for powerpc, sh3, sparc and sparc64 is left to portmasters sparc64 Approved by core@
This commit is contained in:
parent
9a4c8f31d9
commit
bba80928a8
@ -1,4 +1,4 @@
|
||||
# $NetBSD: mi,v 1.490 2012/08/26 23:03:21 jmmv Exp $
|
||||
# $NetBSD: mi,v 1.491 2012/09/12 02:00:51 manu Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
@ -573,6 +573,7 @@
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_sigqueue.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_socketpair.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_stat.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_swapcontext.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_timer_create.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_truncate.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/sys/t_ucontext.debug tests-lib-debug debug,atf
|
||||
@ -674,6 +675,7 @@
|
||||
./usr/libdata/debug/usr/tests/lib/libpthread/t_siglongjmp.debug tests-lib-tests debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libpthread/t_sleep.debug tests-lib-tests debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libpthread/t_status.debug tests-obsolete obsolete
|
||||
./usr/libdata/debug/usr/tests/lib/libpthread/t_swapcontext.debug tests-lib-tests debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/librt tests-lib-debug
|
||||
./usr/libdata/debug/usr/tests/lib/librt/t_sched.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/librt/t_sem.debug tests-lib-debug debug,atf
|
||||
@ -2486,6 +2488,7 @@
|
||||
./usr/tests/lib/libc/sys/t_sigqueue tests-lib-tests atf
|
||||
./usr/tests/lib/libc/sys/t_socketpair tests-lib-tests atf
|
||||
./usr/tests/lib/libc/sys/t_stat tests-lib-tests atf
|
||||
./usr/tests/lib/libc/sys/t_swapcontext tests-lib-tests atf
|
||||
./usr/tests/lib/libc/sys/t_timer_create tests-lib-tests atf
|
||||
./usr/tests/lib/libc/sys/t_truncate tests-lib-tests atf
|
||||
./usr/tests/lib/libc/sys/t_ucontext tests-lib-tests atf
|
||||
@ -2714,6 +2717,7 @@
|
||||
./usr/tests/lib/libpthread/t_siglongjmp tests-lib-tests atf
|
||||
./usr/tests/lib/libpthread/t_sleep tests-lib-tests atf
|
||||
./usr/tests/lib/libpthread/t_status tests-obsolete obsolete
|
||||
./usr/tests/lib/libpthread/t_swapcontext tests-lib-tests atf
|
||||
./usr/tests/lib/librt tests-lib-tests atf
|
||||
./usr/tests/lib/librt/Atffile tests-lib-tests atf
|
||||
./usr/tests/lib/librt/t_sched tests-lib-tests atf
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: swapcontext.S,v 1.4 2008/04/28 20:22:56 martin Exp $ */
|
||||
/* $NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -33,7 +33,7 @@
|
||||
#include <machine/mcontext.h>
|
||||
|
||||
#if defined(SYSLIBC_SCCS) && !defined(lint)
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.4 2008/04/28 20:22:56 martin Exp $")
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $")
|
||||
#endif /* SYSLIBC_SCCS && !lint */
|
||||
|
||||
LEAF_ENTRY(swapcontext)
|
||||
@ -44,10 +44,15 @@ LEAF_ENTRY(swapcontext)
|
||||
|
||||
ldw HPPA_FRAME_ARG(0)(%sp), %arg1
|
||||
ldw HPPA_FRAME_ARG(1)(%sp), %arg0
|
||||
stw %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
|
||||
|
||||
ldw HPPA_FRAME_CRP(%sp), %rp
|
||||
ldo 4(%rp), %r1
|
||||
stw %r1, (_OFFSETOF_UC_GREGS + _REG_PCOQT * SZREG)(%arg1)
|
||||
stw %rp, (_OFFSETOF_UC_GREGS + _REG_PCOQH * SZREG)(%arg1)
|
||||
SYSCALL(setcontext)
|
||||
bl setcontext, %rp
|
||||
stw %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
|
||||
|
||||
ldw HPPA_FRAME_CRP(%sp), %rp
|
||||
bv,n %r0(%rp)
|
||||
EXIT(swapcontext)
|
||||
.end
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: _resumecontext.S,v 1.6 2009/12/14 01:07:42 matt Exp $ */
|
||||
/* $NetBSD: _resumecontext.S,v 1.7 2012/09/12 02:00:52 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -35,7 +35,7 @@
|
||||
#include "assym.h"
|
||||
|
||||
#if defined(SYSLIBC_SCCS) && !defined(lint)
|
||||
RCSID("$NetBSD: _resumecontext.S,v 1.6 2009/12/14 01:07:42 matt Exp $")
|
||||
RCSID("$NetBSD: _resumecontext.S,v 1.7 2012/09/12 02:00:52 manu Exp $")
|
||||
#endif /* SYSLIBC_SCCS && !lint */
|
||||
|
||||
.set reorder
|
||||
@ -53,7 +53,7 @@ LEAF_NOPROFILE(__resumecontext)
|
||||
PTR_L a0, _OFFSETOF_UC_LINK(a0) # linked context?
|
||||
beq a0, zero, 1f # nope, exit process
|
||||
nop
|
||||
SYSTRAP(setcontext) # yes, become it.
|
||||
PIC_TAILCALL(setcontext) # yes, become it.
|
||||
/* NOTREACHED (in theory) */
|
||||
li a0, -1 # failure,
|
||||
1:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: swapcontext.S,v 1.4 2009/12/14 01:07:42 matt Exp $ */
|
||||
/* $NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -33,7 +33,7 @@
|
||||
#include "assym.h"
|
||||
|
||||
#if defined(SYSLIBC_SCCS) && !defined(lint)
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.4 2009/12/14 01:07:42 matt Exp $")
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $")
|
||||
#endif /* SYSLIBC_SCCS && !lint */
|
||||
|
||||
.set reorder
|
||||
@ -57,7 +57,7 @@ NESTED(swapcontext, CALLFRAME_SIZ, ra)
|
||||
REG_S v0, _OFFSETOF_UC_GREGS_SP(v1)
|
||||
REG_EPILOGUE
|
||||
|
||||
SYSTRAP(setcontext)
|
||||
PIC_TAILCALL(setcontext)
|
||||
/* NOTREACHED */
|
||||
1:
|
||||
PTR_ADDU sp, sp, CALLFRAME_SIZ
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $ */
|
||||
/* $NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:52 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
.text
|
||||
.asciz "$NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $"
|
||||
.asciz "$NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:52 manu Exp $"
|
||||
#endif /* LIBC_SCCS && !lint */
|
||||
|
||||
ENTRY(swapcontext)
|
||||
@ -52,8 +52,8 @@ ENTRY(swapcontext)
|
||||
std %r0,mc_off+34*8(%r11) # pc <- lr
|
||||
la %r0,16(%r1)
|
||||
std %r0,mc_off+1*8(%r11) # adjust sp
|
||||
ld %r3,SF_PARAM+8(%r1) # load ucp
|
||||
bl .setcontext # setcontext(ucp)
|
||||
ld %r3,SF_PARAM+8(%r1) # load ucp
|
||||
bl PIC_PLT(_C_LABEL(setcontext)) # setcontext(ucp)
|
||||
nop
|
||||
1:
|
||||
ld %r0,SF_SZ+SF_LR(%r1)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $ */
|
||||
/* $NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:53 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -32,7 +32,7 @@
|
||||
#include "SYS.h"
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $")
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:53 manu Exp $")
|
||||
#endif /* LIBC_SCCS && !lint */
|
||||
|
||||
ENTRY(swapcontext)
|
||||
@ -49,8 +49,13 @@ ENTRY(swapcontext)
|
||||
add %o7, 8, %o1
|
||||
st %o1, [%o2 + 40 + 1 * 4] ! gr[_REG_PC] = retaddr
|
||||
|
||||
mov %o3, %o0
|
||||
mov %o1, %g2 ! optimize `return'
|
||||
mov SYS_setcontext|SYSCALL_G2RFLAG, %g1
|
||||
t ST_SYSCALL
|
||||
ERROR()
|
||||
#ifdef PIC
|
||||
PIC_PROLOGUE(%g1, %g2) ! %g1 = _GLOBAL_OFFSET_TABLE
|
||||
set _C_LABEL(setcontext), %g2
|
||||
ld [%g1 + %g2], %g1
|
||||
jmp %g1
|
||||
mov %o3, %o0
|
||||
#else
|
||||
jmp _C_LABEL(setcontext)
|
||||
mov %o3, %o0
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: swapcontext.S,v 1.5 2011/03/28 11:19:13 martin Exp $ */
|
||||
/* $NetBSD: swapcontext.S,v 1.6 2012/09/12 02:00:53 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -32,7 +32,7 @@
|
||||
#include "SYS.h"
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.5 2011/03/28 11:19:13 martin Exp $")
|
||||
RCSID("$NetBSD: swapcontext.S,v 1.6 2012/09/12 02:00:53 manu Exp $")
|
||||
#endif /* LIBC_SCCS && !lint */
|
||||
|
||||
|
||||
@ -50,8 +50,17 @@ ENTRY(swapcontext)
|
||||
add %o7, 8, %o1
|
||||
stx %o1, [%o2 + 64 + 1 * 8] /* gr[_REG_PC] = retaddr */
|
||||
|
||||
mov %o3, %o0
|
||||
mov %o1, %g5 /* optimize `return' */
|
||||
mov SYS_setcontext|SYSCALL_G5RFLAG, %g1
|
||||
t ST_SYSCALL
|
||||
ERROR()
|
||||
#ifdef PIC
|
||||
PIC_PROLOGUE(%g5,%o4) /* %g5 = _GLOBAL_OFFSET_TABLE */
|
||||
#ifdef BIGPIC
|
||||
set _C_LABEL(setcontext), %o6
|
||||
ldx [%g5+%o6], %o5
|
||||
#else
|
||||
ldx [%g5+_C_LABEL(setcontext)], %o5
|
||||
#endif
|
||||
jmp %o5
|
||||
mov %o3, %o0
|
||||
#else
|
||||
ba,a _C_LABEL(setcontext)
|
||||
mov %o3, %o0
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.19 2011/09/19 21:24:58 joerg Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.20 2012/09/12 02:00:53 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
|
||||
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern char *__minbrk;
|
||||
@ -67,4 +68,6 @@ int vsnprintf_ss(char * __restrict, size_t, const char * __restrict,
|
||||
void _malloc_prefork(void);
|
||||
void _malloc_postfork(void);
|
||||
|
||||
int _sys_setcontext(const ucontext_t *);
|
||||
|
||||
__END_DECLS
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile.inc,v 1.215 2012/06/22 18:28:38 christos Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.216 2012/09/12 02:00:53 manu Exp $
|
||||
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
|
||||
|
||||
# sys sources
|
||||
@ -120,7 +120,7 @@ ASM= access.S acct.S \
|
||||
rasctl.S readlinkat.S reboot.S recvfrom.S recvmmsg.S recvmsg.S rename.S \
|
||||
renameat.S revoke.S rmdir.S \
|
||||
semconfig.S semget.S semop.S \
|
||||
sendmmsg.S sendmsg.S sendto.S setegid.S setcontext.S seteuid.S \
|
||||
sendmmsg.S sendmsg.S sendto.S setegid.S seteuid.S \
|
||||
setgid.S setgroups.S __setitimer50.S __setlogin.S setpgid.S \
|
||||
setpriority.S \
|
||||
setregid.S setreuid.S setrlimit.S setsid.S setsockopt.S \
|
||||
@ -156,7 +156,7 @@ WEAKASM= accept.S __aio_suspend50.S close.S connect.S execve.S \
|
||||
__pollts50.S __pselect50.S read.S readlink.S \
|
||||
readv.S _sched_setparam.S _sched_getparam.S _sched_setaffinity.S \
|
||||
_sched_getaffinity.S sched_yield.S \
|
||||
__select50.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
|
||||
__select50.S setcontext.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
|
||||
__wait450.S write.S writev.S
|
||||
|
||||
NOERR= getegid.S geteuid.S getgid.S getpid.S getppid.S getuid.S \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pthread_specific.c,v 1.21 2008/06/23 10:38:39 ad Exp $ */
|
||||
/* $NetBSD: pthread_specific.c,v 1.22 2012/09/12 02:00:53 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
|
||||
@ -30,19 +30,26 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: pthread_specific.c,v 1.21 2008/06/23 10:38:39 ad Exp $");
|
||||
__RCSID("$NetBSD: pthread_specific.c,v 1.22 2012/09/12 02:00:53 manu Exp $");
|
||||
|
||||
/* Functions and structures dealing with thread-specific data */
|
||||
|
||||
#include "pthread.h"
|
||||
#include "pthread_int.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/lwpctl.h>
|
||||
|
||||
#include "../libc/include/extern.h" /* for _sys_setcontext() */
|
||||
|
||||
int pthread_setcontext(const ucontext_t *);
|
||||
|
||||
__strong_alias(__libc_thr_setspecific,pthread_setspecific)
|
||||
__strong_alias(__libc_thr_getspecific,pthread_getspecific)
|
||||
__strong_alias(__libc_thr_curcpu,pthread_curcpu_np)
|
||||
|
||||
__strong_alias(setcontext,pthread_setcontext)
|
||||
|
||||
int
|
||||
pthread_setspecific(pthread_key_t key, const void *value)
|
||||
{
|
||||
@ -75,3 +82,16 @@ pthread_curcpu_np(void)
|
||||
|
||||
return pthread__self()->pt_lwpctl->lc_curcpu;
|
||||
}
|
||||
|
||||
/*
|
||||
* Override setcontext so that pthread private pointer is preserved
|
||||
*/
|
||||
int
|
||||
pthread_setcontext(const ucontext_t *ucp)
|
||||
{
|
||||
ucontext_t uc;
|
||||
|
||||
(void)memcpy(&uc, ucp, sizeof(uc));
|
||||
uc.uc_flags &= ~_UC_TLSBASE;
|
||||
return _sys_setcontext(&uc);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.341 2012/07/28 00:57:04 matt Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.342 2012/09/12 02:00:53 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -68,7 +68,7 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.341 2012/07/28 00:57:04 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.342 2012/09/12 02:00:53 manu Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -1793,7 +1793,7 @@ cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
|
||||
(void *) gr[_REG_PC])) != -1)
|
||||
gr[_REG_PC] = ras_pc;
|
||||
|
||||
*flags |= _UC_CPU | _UC_UNIQUE;
|
||||
*flags |= _UC_CPU | _UC_TLSBASE;
|
||||
|
||||
/* Save floating point register context, if any, and copy it. */
|
||||
if (fpu_used_p(l)) {
|
||||
@ -1840,7 +1840,7 @@ cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
|
||||
frame->tf_regs[FRAME_PC] = gr[_REG_PC];
|
||||
frame->tf_regs[FRAME_PS] = gr[_REG_PS];
|
||||
}
|
||||
if (flags & _UC_UNIQUE)
|
||||
if (flags & _UC_TLSBASE)
|
||||
lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_UNIQUE]);
|
||||
/* Restore floating point register context, if any. */
|
||||
if (flags & _UC_FPU) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcontext.h,v 1.7 2011/02/25 14:07:12 joerg Exp $ */
|
||||
/* $NetBSD: mcontext.h,v 1.8 2012/09/12 02:00:54 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -93,7 +93,7 @@ typedef struct {
|
||||
} mcontext_t;
|
||||
|
||||
/* Machine-dependent uc_flags */
|
||||
#define _UC_UNIQUE 0x20 /* valid process-unique value in _REG_UNIQUE */
|
||||
#define _UC_TLSBASE 0x20 /* valid process-unique value in _REG_UNIQUE */
|
||||
|
||||
#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_SP])
|
||||
#define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_PC])
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcontext.h,v 1.9 2011/02/25 14:07:13 joerg Exp $ */
|
||||
/* $NetBSD: mcontext.h,v 1.10 2012/09/12 02:00:54 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -92,6 +92,7 @@ typedef struct {
|
||||
*/
|
||||
#define _UC_SETSTACK 0x10000
|
||||
#define _UC_CLRSTACK 0x20000
|
||||
#define _UC_TLSBASE 0x80000
|
||||
|
||||
static __inline void *
|
||||
__lwp_getprivate_fast(void)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcontext.h,v 1.12 2011/02/25 14:07:13 joerg Exp $ */
|
||||
/* $NetBSD: mcontext.h,v 1.13 2012/09/12 02:00:54 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
#define _UC_SETSTACK 0x00010000
|
||||
#define _UC_CLRSTACK 0x00020000
|
||||
#define _UC_TLSBASE 0x00080000
|
||||
|
||||
/*
|
||||
* Layout of mcontext_t according the System V Application Binary Interface,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mcontext.h,v 1.8 2006/03/16 16:05:53 cube Exp $ */
|
||||
/* $NetBSD: mcontext.h,v 1.9 2012/09/12 02:00:54 manu Exp $ */
|
||||
|
||||
#ifndef _SPARC64_MCONTEXT_H_
|
||||
#define _SPARC64_MCONTEXT_H_
|
||||
@ -74,5 +74,6 @@ typedef struct {
|
||||
|
||||
#define _UC_SETSTACK 0x00010000
|
||||
#define _UC_CLRSTACK 0x00020000
|
||||
#define _UC_TLSBASE 0x00080000
|
||||
|
||||
#endif /* _SPARC64_MCONTEXT_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ucontext.h,v 1.16 2012/05/21 14:15:19 martin Exp $ */
|
||||
/* $NetBSD: ucontext.h,v 1.17 2012/09/12 02:00:54 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2003 The NetBSD Foundation, Inc.
|
||||
@ -57,21 +57,48 @@ struct __ucontext {
|
||||
#define _UC_STACK 0x02 /* valid uc_stack */
|
||||
#define _UC_CPU 0x04 /* valid GPR context in uc_mcontext */
|
||||
#define _UC_FPU 0x08 /* valid FPU context in uc_mcontext */
|
||||
#define _UC_MD 0x40070020 /* MD bits. see below */
|
||||
#define _UC_MD 0x400f0020 /* MD bits. see below */
|
||||
|
||||
/*
|
||||
* _UC_MD includes:
|
||||
* _UC_SETSTACK 0x00010000 (many ports) and 0x00020000 (arm)
|
||||
* _UC_CLRSTACK 0x00020000 (many ports) and 0x00040000 (arm)
|
||||
* _UC_POWERPC_VEC 0x00010000 (powerpc)
|
||||
* _UC_M68K_UC_USER 0x40000000 (m68k)
|
||||
* _UC_UNIQUE 0x00000020 (alpha)
|
||||
* _UC_ARM_VFP 0x00010000 (arm)
|
||||
* _UC_VM 0x00040000 (i386)
|
||||
* _UC_FXSAVE 0x00000020 (i386)
|
||||
*
|
||||
* if your port needs more MD bits, please try to choose bits from _UC_MD
|
||||
* first, rather than picking random unused bits.
|
||||
*
|
||||
* _UC_MD details
|
||||
*
|
||||
* _UC_TLSBASE Context contains valid pthread private pointer
|
||||
* All ports must define this MD flag
|
||||
* 0x00040000 hppa, mips
|
||||
* 0x00000020 alpha
|
||||
* 0x00080000 all other ports
|
||||
*
|
||||
* _UC_SETSTACK Context uses signal stack
|
||||
* 0x00020000 arm
|
||||
* [undefined] alpha, powerpc and vax
|
||||
* 0x00010000 other ports
|
||||
*
|
||||
* _UC_CLRSTACK Context does not use signal stack
|
||||
* 0x00040000 arm
|
||||
* [undefined] alpha, powerpc and vax
|
||||
* 0x00020000 other ports
|
||||
*
|
||||
* _UC_POWERPC_VEC Context does not use signal stack
|
||||
* 0x00010000 powerpc only
|
||||
*
|
||||
* _UC_POWERPC_SPE Context contains valid SPE context
|
||||
* 0x00020000 powerpc only
|
||||
*
|
||||
* _UC_M68K_UC_USER Used by m68k machdep code, but undocumented
|
||||
* 0x40000000 m68k only
|
||||
*
|
||||
* _UC_ARM_VFP Unused
|
||||
* 0x00010000 arm only
|
||||
*
|
||||
* _UC_VM Context contains valid virtual 8086 context
|
||||
* 0x00040000 i386, amd64 only
|
||||
*
|
||||
* _UC_FXSAVE Context contains FPU context in that
|
||||
* is in FXSAVE format in XMM space
|
||||
* 0x00000020 i386, amd64 only
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.27 2012/08/08 13:57:06 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.28 2012/09/12 02:00:55 manu Exp $
|
||||
|
||||
MKMAN= no
|
||||
|
||||
@ -54,6 +54,7 @@ TESTS_C+= t_setuid
|
||||
TESTS_C+= t_sigaction
|
||||
TESTS_C+= t_sigqueue
|
||||
TESTS_C+= t_socketpair
|
||||
TESTS_C+= t_swapcontext
|
||||
TESTS_C+= t_stat
|
||||
TESTS_C+= t_timer_create
|
||||
TESTS_C+= t_truncate
|
||||
|
133
tests/lib/libc/sys/t_swapcontext.c
Normal file
133
tests/lib/libc/sys/t_swapcontext.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* $NetBSD: t_swapcontext.c,v 1.1 2012/09/12 02:00:55 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD");
|
||||
|
||||
#include <ucontext.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <lwp.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#define STACKSIZE 65536
|
||||
|
||||
char stack[STACKSIZE];
|
||||
ucontext_t nctx;
|
||||
ucontext_t octx;
|
||||
void *otls;
|
||||
void *ntls;
|
||||
int val1, val2;
|
||||
int alter_tlsbase;
|
||||
|
||||
/* ARGSUSED0 */
|
||||
static void
|
||||
swapfunc(void *arg)
|
||||
{
|
||||
ntls = _lwp_getprivate();
|
||||
printf("after swapcontext TLS pointer = %p\n", ntls);
|
||||
|
||||
if (alter_tlsbase) {
|
||||
ATF_REQUIRE_EQ(ntls, &val1);
|
||||
printf("TLS pointer modified by swapcontext()\n");
|
||||
} else {
|
||||
ATF_REQUIRE_EQ(ntls, &val2);
|
||||
printf("TLS pointer left untouched by swapcontext()\n");
|
||||
}
|
||||
|
||||
/* Go back in main */
|
||||
ATF_REQUIRE(swapcontext(&nctx, &octx));
|
||||
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
mainfunc(void)
|
||||
{
|
||||
printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE "
|
||||
"is %s\n", (alter_tlsbase) ? "left set" : "cleared");
|
||||
|
||||
_lwp_setprivate(&val1);
|
||||
printf("before swapcontext TLS pointer = %p\n", &val1);
|
||||
|
||||
ATF_REQUIRE(getcontext(&nctx) == 0);
|
||||
|
||||
nctx.uc_stack.ss_sp = stack;
|
||||
nctx.uc_stack.ss_size = sizeof(stack);
|
||||
|
||||
#ifndef _UC_TLSBASE
|
||||
ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined");
|
||||
#else /* _UC_TLSBASE */
|
||||
ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE);
|
||||
if (!alter_tlsbase)
|
||||
nctx.uc_flags &= ~_UC_TLSBASE;
|
||||
#endif /* _UC_TLSBASE */
|
||||
|
||||
makecontext(&nctx, (void *)*swapfunc, 0);
|
||||
|
||||
_lwp_setprivate(&val2);
|
||||
otls = _lwp_getprivate();
|
||||
printf("before swapcontext TLS pointer = %p\n", otls);
|
||||
ATF_REQUIRE(swapcontext(&octx, &nctx) == 0);
|
||||
|
||||
printf("Test completed\n");
|
||||
}
|
||||
|
||||
|
||||
ATF_TC(swapcontext1);
|
||||
ATF_TC_HEAD(swapcontext1, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let "
|
||||
"TLS pointer untouched");
|
||||
}
|
||||
ATF_TC_BODY(swapcontext1, tc)
|
||||
{
|
||||
alter_tlsbase = 0;
|
||||
mainfunc();
|
||||
}
|
||||
|
||||
ATF_TC(swapcontext2);
|
||||
ATF_TC_HEAD(swapcontext2, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can "
|
||||
"modify TLS pointer");
|
||||
}
|
||||
ATF_TC_BODY(swapcontext2, tc)
|
||||
{
|
||||
alter_tlsbase = 1;
|
||||
mainfunc();
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, swapcontext1);
|
||||
ATF_TP_ADD_TC(tp, swapcontext2);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.7 2011/04/06 16:04:16 jruoho Exp $
|
||||
# $NetBSD: Makefile,v 1.8 2012/09/12 02:00:55 manu Exp $
|
||||
|
||||
NOMAN= # defined
|
||||
|
||||
@ -35,6 +35,7 @@ TESTS_C+= t_sigmask
|
||||
TESTS_C+= t_sigsuspend
|
||||
TESTS_C+= t_siglongjmp
|
||||
TESTS_C+= t_sleep
|
||||
TESTS_C+= t_swapcontext
|
||||
|
||||
LDADD.t_sem+= -lrt
|
||||
|
||||
|
111
tests/lib/libpthread/t_swapcontext.c
Normal file
111
tests/lib/libpthread/t_swapcontext.c
Normal file
@ -0,0 +1,111 @@
|
||||
/* $NetBSD: t_swapcontext.c,v 1.1 2012/09/12 02:00:55 manu Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD");
|
||||
|
||||
#include <pthread.h>
|
||||
#include <ucontext.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#include "h_common.h"
|
||||
|
||||
#define STACKSIZE 65536
|
||||
|
||||
char stack[STACKSIZE];
|
||||
ucontext_t nctx;
|
||||
ucontext_t octx;
|
||||
void *oself;
|
||||
void *nself;
|
||||
int val1, val2;
|
||||
|
||||
/* ARGSUSED0 */
|
||||
static void
|
||||
swapfunc(void *arg)
|
||||
{
|
||||
/*
|
||||
* If the test fails, we are very likely to crash
|
||||
* without the opportunity to report
|
||||
*/
|
||||
nself = (void *)pthread_self();
|
||||
printf("after swapcontext self = %p\n", nself);
|
||||
|
||||
ATF_REQUIRE_EQ(oself, nself);
|
||||
printf("Test succeeded\n");
|
||||
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
|
||||
/* ARGSUSED0 */
|
||||
static void *
|
||||
threadfunc(void *arg)
|
||||
{
|
||||
nctx.uc_stack.ss_sp = stack;
|
||||
nctx.uc_stack.ss_size = sizeof(stack);
|
||||
|
||||
makecontext(&nctx, (void *)*swapfunc, 0);
|
||||
|
||||
oself = (void *)pthread_self();
|
||||
printf("before swapcontext self = %p\n", oself);
|
||||
PTHREAD_REQUIRE(swapcontext(&octx, &nctx));
|
||||
|
||||
/* NOTREACHED */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ATF_TC(swapcontext1);
|
||||
ATF_TC_HEAD(swapcontext1, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() "
|
||||
"alters pthread_self()");
|
||||
}
|
||||
ATF_TC_BODY(swapcontext1, tc)
|
||||
{
|
||||
pthread_t thread;
|
||||
|
||||
oself = (void *)&val1;
|
||||
nself = (void *)&val2;
|
||||
|
||||
printf("Testing if swapcontext() alters pthread_self()\n");
|
||||
|
||||
PTHREAD_REQUIRE(getcontext(&nctx));
|
||||
PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, swapcontext1);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user