diff options
29 files changed, 212 insertions, 195 deletions
diff --git a/include/unistd.h b/include/unistd.h index 61b10f06ff3..c4a2fa92775 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.72 2012/05/30 19:34:30 matthew Exp $ */ +/* $OpenBSD: unistd.h,v 1.73 2012/06/21 00:56:59 guenther Exp $ */ /* $NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $ */ /*- @@ -501,6 +501,8 @@ void setusershell(void); int strtofflags(char **, u_int32_t *, u_int32_t *); int swapctl(int cmd, const void *arg, int misc); int syscall(int, ...); +pid_t __tfork_thread(const struct __tfork *, size_t, void (*)(void *), + void *); #endif /* __BSD_VISIBLE */ __END_DECLS diff --git a/lib/libc/arch/alpha/sys/tfork_thread.S b/lib/libc/arch/alpha/sys/tfork_thread.S index 10fac103287..9b84cd0158a 100644 --- a/lib/libc/arch/alpha/sys/tfork_thread.S +++ b/lib/libc/arch/alpha/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,10 +28,10 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ LEAF(__tfork_thread,0) - /* a0 = flags, a1 = stack, a2 = func, a3 = arg */ + /* a0 = flags, a1 = psize, a2 = func, a3 = arg */ mov a3, a5 CALLSYS_ERROR(__tfork) @@ -44,9 +44,8 @@ LEAF(__tfork_thread,0) 1: /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - mov a1, sp /* stack */ mov a5, a0 /* arg */ mov a2, pv /* func */ jsr ra, (pv) diff --git a/lib/libc/arch/amd64/sys/tfork_thread.S b/lib/libc/arch/amd64/sys/tfork_thread.S index 41a42d79972..9eb4f0631fe 100644 --- a/lib/libc/arch/amd64/sys/tfork_thread.S +++ b/lib/libc/arch/amd64/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /*- * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> @@ -38,11 +38,11 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/amd64/gen/rfork_thread.S,v 1.1 #include "SYS.h" /* - * %rdi %rsi %rdx %rcx - * __tfork_thread(param, stack_addr, start_fnc, start_arg); + * %rdi %rsi %rdx %rcx + * __tfork_thread(param, psize, start_fnc, start_arg); * * param: Argument to pass to the actual kernel call. - * stack_addr: Top of stack for thread. + * psize: Other argument to pass to the actual kernel call. * start_fnc: Address of thread function to call in child. * start_arg: Argument to pass to the thread function in child. */ @@ -71,7 +71,6 @@ ENTRY(__tfork_thread) * returns, then call __threxit. */ 1: - movq %rsi, %rsp movq %r9, %rdi call *%r8 diff --git a/lib/libc/arch/arm/sys/tfork_thread.S b/lib/libc/arch/arm/sys/tfork_thread.S index 0ece8d15d2a..4115477f28d 100644 --- a/lib/libc/arch/arm/sys/tfork_thread.S +++ b/lib/libc/arch/arm/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> * @@ -19,30 +19,23 @@ #include "SYS.h" /* - * r0 r1 r2 r3 - * __tfork_thread(param, stack_addr, start_fnc, start_arg); + * r0 r1 r2 r3 + * __tfork_thread(param, psize, start_fnc, start_arg); */ ENTRY(__tfork_thread) - stmdb sp!, {r4} - mov r4, r1 - - SYSTRAP(__tfork) - bcs 1f + bcs 1f /* XXX can this be PIC_SYM(CERROR, PLT) ? */ /* check if we are parent or child */ cmp r0, #0 - ldmneia sp!, {r4} movne pc, lr /* child */ - mov sp, r4 mov r0, r3 mov lr, pc mov pc, r2 nop SYSTRAP(__threxit) 1: - ldmia sp!, {r4} - b PIC_SYM(CERROR, PLT) + b PIC_SYM(CERROR, PLT) diff --git a/lib/libc/arch/hppa/sys/tfork_thread.S b/lib/libc/arch/hppa/sys/tfork_thread.S index 5a77bd3bbea..65a8af3c514 100644 --- a/lib/libc/arch/hppa/sys/tfork_thread.S +++ b/lib/libc/arch/hppa/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,7 +28,7 @@ #include "SYS.h" /* - * int __tfork_thread(param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(param, size_t psize, void (*func)(void *), void *arg); */ ENTRY(__tfork_thread, 0) SYSCALL(__tfork) @@ -36,20 +36,8 @@ ENTRY(__tfork_thread, 0) nop /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - - /* - * PIC code expects 32 bytes of room available below sp. - * Then the regular procedure invocation requires us to allocate - * 64 bytes as well. - */ - copy arg1, sp - ldo 0(sp), r3 - stw,ma r0, HPPA_FRAME_SIZE(sp) - stw r0, HPPA_FRAME_CRP(sp) - stw r0, HPPA_FRAME_PSP(sp) - copy arg3, arg0 /* arg */ copy arg2, t1 bl $$dyncall, r31 diff --git a/lib/libc/arch/hppa64/sys/tfork_thread.S b/lib/libc/arch/hppa64/sys/tfork_thread.S index 96a8e4a72f6..4fd2cb67700 100644 --- a/lib/libc/arch/hppa64/sys/tfork_thread.S +++ b/lib/libc/arch/hppa64/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/04/11 12:27:08 jsing Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat * @@ -27,7 +27,7 @@ #include "SYS.h" /* - * int __tfork_thread(param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(param, size_t psize, void (*func)(void *), void *arg); */ ENTRY(__tfork_thread, 0) SYSCALL(__tfork) @@ -35,13 +35,8 @@ ENTRY(__tfork_thread, 0) nop /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - copy %arg1, %sp - ldo 0(%sp), %r3 - std,ma %r0, HPPA_FRAME_SIZE(%sp) - std %r0, HPPA_FRAME_PSP(%sp) - copy %arg3, %arg0 /* arg */ copy %arg2, %t1 b,l $$dyncall, %r31 diff --git a/lib/libc/arch/i386/sys/tfork_thread.S b/lib/libc/arch/i386/sys/tfork_thread.S index 4b7de1b030c..57a7339eed3 100644 --- a/lib/libc/arch/i386/sys/tfork_thread.S +++ b/lib/libc/arch/i386/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.2 2012/04/11 18:36:57 kettenis Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.3 2012/06/21 00:56:59 guenther Exp $ */ /*- * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> * All rights reserved. @@ -37,11 +37,11 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/i386/gen/rfork_thread.S,v 1.5 2 #include "SYS.h" /* - * 8 12 16 20 - * __tfork_thread(param, stack_addr, start_fnc, start_arg); + * 8 12 16 20 + * __tfork_thread(param, psize, start_fnc, start_arg); * * param: Arguments to actual system call. - * stack_addr: Top of stack for thread. + * psize: Other argument to pass to the actual kernel call. * start_fnc: Address of thread function to call in child. * start_arg: Argument to pass to the thread function in child. */ @@ -50,25 +50,20 @@ ENTRY(__tfork_thread) pushl %ebp movl %esp, %ebp pushl %esi + pushl %edi /* - * Push thread info onto the new thread's stack + * Save the thread info in esi and ebx */ - movl 12(%ebp), %esi # get stack addr - - subl $4, %esi - movl 20(%ebp), %eax # get start argument - movl %eax, (%esi) - - subl $4, %esi - movl 16(%ebp), %eax # get start thread address - movl %eax, (%esi) + movl 16(%ebp), %esi # get start thread address + movl 20(%ebp), %edi # get start argument /* * Prepare and execute the thread creation syscall */ - pushl 8(%ebp) - pushl $0 + pushl 12(%ebp) # push psize + pushl 8(%ebp) # push param + pushl $0 # slot for return address, ignored by kernel movl $SYS___tfork, %eax int $0x80 jb 2f @@ -78,7 +73,8 @@ ENTRY(__tfork_thread) */ cmpl $0, %edx jnz 1f - addl $8, %esp + addl $12, %esp + popl %edi popl %esi movl %ebp, %esp popl %ebp @@ -88,20 +84,19 @@ ENTRY(__tfork_thread) /* * If we are in the child (new thread), then * set-up the call to the internal subroutine. If it - * returns, then call __exit. + * returns, then call __threxit. */ 1: xorl %ebp, %ebp # mark outermost frame - movl %esi, %esp - popl %eax - call *%eax + pushl %edi # push start argument + call *%esi addl $4, %esp /* * Exit system call */ - pushl %eax - pushl $0 + pushl $0 # NULL pointer argument to __threxit + pushl $0 # slot for return address, ignored by kernel movl $SYS___threxit, %eax int $0x80 @@ -109,7 +104,8 @@ ENTRY(__tfork_thread) * Branch here if the thread creation fails: */ 2: - addl $8, %esp + addl $12, %esp + popl %edi popl %esi movl %ebp, %esp popl %ebp diff --git a/lib/libc/arch/m68k/sys/tfork_thread.S b/lib/libc/arch/m68k/sys/tfork_thread.S index 2d6d791ae42..b44442f2bcb 100644 --- a/lib/libc/arch/m68k/sys/tfork_thread.S +++ b/lib/libc/arch/m68k/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,14 +28,13 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ ENTRY(__tfork_thread) /* - * Set up the new thread's stack. + * Move info for the new thread into registers. */ - movl sp@(8), a0 /* stack */ - movl sp@(16), a0@- /* arg */ + movl sp@(16), a0 /* arg */ movl sp@(12), a1 /* func */ /* @@ -55,9 +54,9 @@ ENTRY(__tfork_thread) 1: /* - * child process: switch stacks, invoke function, then exit. + * child process: invoke function, then exit. */ - movl a0, sp /* stack with arg pushed on it */ + movl a0, sp@- /* stack with arg pushed on it */ jsr a1@ /* func */ addq #4, sp diff --git a/lib/libc/arch/m88k/sys/tfork_thread.S b/lib/libc/arch/m88k/sys/tfork_thread.S index 351d93151da..df901bba981 100644 --- a/lib/libc/arch/m88k/sys/tfork_thread.S +++ b/lib/libc/arch/m88k/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,10 +28,9 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ ENTRY(__tfork_thread) - or r6, r3, r0 /* save stack */ or r13, r0, __SYSCALLNAME(SYS_,__tfork) tb0 0, r0, 128 /* corrupts r2 and r3 in the child */ br __cerror @@ -45,9 +44,8 @@ ENTRY(__tfork_thread) 1: /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - or r31, r6, r0 /* stack */ jsr.n r4 /* func */ or r2, r5, r0 /* arg */ diff --git a/lib/libc/arch/mips64/sys/tfork_thread.S b/lib/libc/arch/mips64/sys/tfork_thread.S index aaedba7df17..b0cf318553a 100644 --- a/lib/libc/arch/mips64/sys/tfork_thread.S +++ b/lib/libc/arch/mips64/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:55 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,27 +28,26 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ FRAMESZ=4*REGSZ GPOFF=FRAMESZ-2*REGSZ LEAF(__tfork_thread, FRAMESZ) - /* a0 = param, a1 = stack, a2 = func, a3 = arg */ + /* a0 = param, a1 = psize, a2 = func, a3 = arg */ PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, _C_LABEL(__tfork_thread)) .set reorder - move t0, a1 /* stack */ move t1, a3 /* arg */ __DO_SYSCALL(__tfork) bnez a3, 9f + beqz v0, 1f + RESTORE_GP64 PTR_ADDU sp, FRAMESZ - beqz v0, 1f - /* * In parent process: just return. */ @@ -56,10 +55,9 @@ LEAF(__tfork_thread, FRAMESZ) 1: /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - move sp, t0 /* stack */ move t9, a2 /* func */ move a0, t1 /* arg */ move v0, zero diff --git a/lib/libc/arch/powerpc/sys/tfork_thread.S b/lib/libc/arch/powerpc/sys/tfork_thread.S index 2e9a46a7664..aa5f59c966d 100644 --- a/lib/libc/arch/powerpc/sys/tfork_thread.S +++ b/lib/libc/arch/powerpc/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:56 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005 Tim Wiess <tim@nop.cx> @@ -21,13 +21,9 @@ ENTRY(__tfork_thread) /* sanity check */ - cmpwi %r4, 0 - beq 1f cmpwi %r5, 0 beq 1f - mr %r7,%r4 - /* call __tfork */ li %r0, SYS___tfork sc @@ -41,7 +37,7 @@ ENTRY(__tfork_thread) /* child */ mtlr %r5 /* fp */ mr %r3, %r6 /* arg */ - subi %r1, %r7, 16 /* fixup sp to get headroom */ + subi %r1, %r1, 16 /* fixup sp to get headroom */ blrl /* child returned, call _exit */ diff --git a/lib/libc/arch/sh/sys/tfork_thread.S b/lib/libc/arch/sh/sys/tfork_thread.S index bfca155e1d0..49235c0b829 100644 --- a/lib/libc/arch/sh/sys/tfork_thread.S +++ b/lib/libc/arch/sh/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:56 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. @@ -20,7 +20,7 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); * r4 r5 r6 r7 */ ENTRY(__tfork_thread) @@ -39,9 +39,8 @@ ENTRY(__tfork_thread) 1: /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - mov r5, sp jsr @r6 mov r7, r4 diff --git a/lib/libc/arch/sparc/sys/tfork_thread.S b/lib/libc/arch/sparc/sys/tfork_thread.S index 882a07f7234..09bf0083810 100644 --- a/lib/libc/arch/sparc/sys/tfork_thread.S +++ b/lib/libc/arch/sparc/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:56 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,11 +28,9 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ ENTRY(__tfork_thread) - mov %o1, %o4 /* save stack */ - /* * We can not invoke __tfork as a G2-style system call since we want * different return paths. @@ -54,12 +52,8 @@ ENTRY(__tfork_thread) 1: /* - * In child process: switch stack, invoke function, then exit. - * Don't forget to allocate room for a window save on the new - * stack! + * In child process: invoke function, then exit. */ - sub %g0, %g0, %fp - sub %o4, 96, %sp /* stack */ call %o2 /* func */ mov %o3, %o0 /* arg */ diff --git a/lib/libc/arch/sparc64/sys/tfork_thread.S b/lib/libc/arch/sparc64/sys/tfork_thread.S index d22aba43a55..cf70b25d401 100644 --- a/lib/libc/arch/sparc64/sys/tfork_thread.S +++ b/lib/libc/arch/sparc64/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:56 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,11 +28,9 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ ENTRY(__tfork_thread) - mov %o1, %o4 /* save stack */ - /* * We can not invoke __tfork as a G2-style system call since we want * different return paths. @@ -54,11 +52,8 @@ ENTRY(__tfork_thread) 1: /* - * In child process: switch stack, invoke function, then exit. + * In child process: invoke function, then exit. */ - - mov %g0, %fp /* clear frame pointer */ - sub %o4, (BIAS + CC64FSZ), %sp /* stack */ call %o2 /* func */ mov %o3, %o0 /* arg */ diff --git a/lib/libc/arch/vax/sys/tfork_thread.S b/lib/libc/arch/vax/sys/tfork_thread.S index 1d22f1e924b..123c4a83641 100644 --- a/lib/libc/arch/vax/sys/tfork_thread.S +++ b/lib/libc/arch/vax/sys/tfork_thread.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tfork_thread.S,v 1.1 2012/03/22 00:44:56 guenther Exp $ */ +/* $OpenBSD: tfork_thread.S,v 1.2 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -28,15 +28,14 @@ #include "SYS.h" /* - * int __tfork_thread(const struct __tfork *param, void *stack, void (*func)(void *), void *arg); + * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); */ -ENTRY(__tfork_thread, R2|R3|R4) +ENTRY(__tfork_thread, R2|R3) /* * Save thread creation arguments into registers. */ - movl 8(ap), r2 /* stack */ - movl 12(ap), r3 /* func */ - movl 16(ap), r4 /* arg */ + movl 12(ap), r2 /* func */ + movl 16(ap), r3 /* arg */ __DO_SYSCALL(__tfork) jcs 9f @@ -55,9 +54,8 @@ ENTRY(__tfork_thread, R2|R3|R4) * Note that since we can not pass a register to calls, we need * to waste 4 bytes of stack in every thread. */ - movl r2, sp /* stack */ - pushl r3 /* func */ - pushl r4 /* arg */ + pushl r2 /* func */ + pushl r3 /* arg */ calls $1, *4(sp) /* func */ __DO_SYSCALL(__threxit) diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 56a8145c9df..bb49a127eb9 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ -major=64 -minor=2 +major=65 +minor=0 # note: If changes were made to include/thread_private.h or if system # calls were added/changed then libpthread must also be updated. diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index f8f6605e726..27a9b6dbf72 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.61 2012/04/10 21:10:45 guenther Exp $ */ +/* $OpenBSD: rthread.c,v 1.62 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -48,8 +48,6 @@ static _spinlock_lock_t _thread_gc_lock = _SPINLOCK_UNLOCKED; struct pthread _initial_thread; struct thread_control_block _initial_thread_tcb; -int __tfork_thread(const struct __tfork *, void *, void (*)(void *), void *); - struct pthread_attr _rthread_attr_default = { #ifndef lint .stack_addr = NULL, @@ -86,7 +84,7 @@ _spinunlock(_spinlock_lock_t *lock) /* * This sets up the thread base for the initial thread so that it * references the errno location provided by libc. For other threads - * this is handled by the block in _rthread_start(). + * this is handled by __tfork_thread() */ void _rthread_initlib(void) __attribute__((constructor)); void _rthread_initlib(void) @@ -415,7 +413,7 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, param.tf_tcb = tcb; param.tf_tid = &thread->tid; - param.tf_flags = 0; + param.tf_stack = thread->stack->sp; _spinlock(&_thread_lock); LIST_INSERT_HEAD(&_thread_list, thread, threads); @@ -423,7 +421,7 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, /* we're going to be multi-threaded real soon now */ __isthreaded = 1; - rc = __tfork_thread(¶m, thread->stack->sp, _rthread_start, thread); + rc = __tfork_thread(¶m, sizeof(param), _rthread_start, thread); if (rc != -1) { /* success */ *threadp = thread; diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version index 998729533f3..84e2c2920d7 100644 --- a/lib/librthread/shlib_version +++ b/lib/librthread/shlib_version @@ -1,2 +1,2 @@ -major=15 -minor=2 +major=16 +minor=0 diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index f38055b2363..2cc1d6ee24d 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.205 2011/09/20 09:49:38 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.206 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 1999-2003 Michael Shalayeff @@ -1133,6 +1133,25 @@ copyout(const void *src, void *dst, size_t size) } /* + * Set up tf_sp and tf_r3 (the frame pointer) and copy out the + * frame marker and the old r3 + */ +int +setstack(struct trapframe *tf, u_long stack, register_t old_r3) +{ + static const register_t zero = 0; + int err; + + tf->tf_r3 = stack; + err = copyout(&old_r3, (caddr_t)stack, sizeof(register_t)); + + tf->tf_sp = stack += HPPA_FRAME_SIZE; + return (copyout(&zero, (caddr_t)(stack + HPPA_FRAME_CRP), + sizeof(register_t)) || err); +} + + +/* * Set registers on exec. */ void @@ -1141,7 +1160,6 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack, { struct trapframe *tf = p->p_md.md_regs; struct pcb *pcb = &p->p_addr->u_pcb; - register_t zero; tf->tf_flags = TFF_SYS|TFF_LAST; tf->tf_iioq_tail = 4 + @@ -1151,12 +1169,7 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack, tf->tf_arg1 = tf->tf_arg2 = 0; /* XXX dynload stuff */ /* setup terminal stack frame */ - stack = (stack + 0x1f) & ~0x1f; - tf->tf_r3 = stack; - tf->tf_sp = stack += HPPA_FRAME_SIZE; - zero = 0; - copyout(&zero, (caddr_t)(stack - HPPA_FRAME_SIZE), sizeof(register_t)); - copyout(&zero, (caddr_t)(stack + HPPA_FRAME_CRP), sizeof(register_t)); + setstack(tf, (stack + 0x1f) & ~0x1f, 0); /* reset any of the pending FPU exceptions */ fpu_proc_flush(p); @@ -1261,12 +1274,13 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, bcopy(&p->p_addr->u_pcb.pcb_fpstate->hfp_regs, ksc.sc_fpregs, sizeof(ksc.sc_fpregs)); - sss += HPPA_FRAME_SIZE; + if (setstack(tf, scp + sss, tf->tf_r3)) + sigexit(p, SIGILL); + tf->tf_arg0 = sig; tf->tf_arg1 = sip; tf->tf_arg2 = tf->tf_r4 = scp; tf->tf_arg3 = (register_t)catcher; - tf->tf_sp = scp + sss; tf->tf_ipsw &= ~(PSL_N|PSL_B|PSL_T); tf->tf_iioq_head = HPPA_PC_PRIV_USER | p->p_sigcode; tf->tf_iioq_tail = tf->tf_iioq_head + 4; @@ -1276,7 +1290,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n", - p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss); + p->p_pid, sig, scp, ksc.sc_fp, tf->tf_sp); #endif if (copyout(&ksc, (void *)scp, sizeof(ksc))) @@ -1288,11 +1302,6 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, sigexit(p, SIGILL); } - if (copyout(&tf->tf_r3, (caddr_t)(tf->tf_sp - HPPA_FRAME_SIZE), - sizeof(register_t))) - sigexit(p, SIGILL); - tf->tf_r3 = tf->tf_sp - HPPA_FRAME_SIZE; - #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sendsig(%d): pc 0x%x catcher 0x%x\n", p->p_pid, diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c index 3d6154beebf..9642cf0da5b 100644 --- a/sys/arch/hppa/hppa/vm_machdep.c +++ b/sys/arch/hppa/hppa/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.75 2011/09/20 21:46:08 miod Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.76 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 1999-2004 Michael Shalayeff @@ -147,7 +147,7 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, * If specified, give the child a different stack. */ if (stack != NULL) - tf->tf_sp = (register_t)stack; + setstack(tf, (u_long)stack, 0); /* XXX ignore error? */ /* * Build stack frames for the cpu_switchto & co. diff --git a/sys/arch/hppa/include/frame.h b/sys/arch/hppa/include/frame.h index 09b289e476f..28810732471 100644 --- a/sys/arch/hppa/include/frame.h +++ b/sys/arch/hppa/include/frame.h @@ -1,4 +1,4 @@ -/* $OpenBSD: frame.h,v 1.18 2011/11/14 14:29:53 deraadt Exp $ */ +/* $OpenBSD: frame.h,v 1.19 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 1999-2004 Michael Shalayeff @@ -135,6 +135,11 @@ struct trapframe { unsigned long tf_pad[3]; /* pad to 256 bytes */ }; + +#ifdef _KERNEL +int setstack(struct trapframe *, u_long, register_t); +#endif /* _KERNEL */ + #endif /* !_LOCORE */ #endif /* !_MACHINE_FRAME_H_ */ diff --git a/sys/arch/hppa64/hppa64/machdep.c b/sys/arch/hppa64/hppa64/machdep.c index 8634c3e40a0..f701dddc6a7 100644 --- a/sys/arch/hppa64/hppa64/machdep.c +++ b/sys/arch/hppa64/hppa64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.45 2011/09/22 21:48:34 jsing Exp $ */ +/* $OpenBSD: machdep.c,v 1.46 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff @@ -777,6 +777,26 @@ copyout(const void *src, void *dst, size_t size) } /* + * Set up tf_sp and tf_r3 (the frame pointer) and copy out the + * frame marker and the old r3. + * XXX old_r3 is always zero on hppa64? It's non-zero on hppa in sendsig() + * XXX Set up tf_ret1 (aka "ap") too? + */ +int +setstack(struct trapframe *tf, u_long stack, register_t old_r3) +{ + static const register_t zero = 0; + int err; + + tf->tf_r3 = stack; + err = copyout(&old_r3, (caddr_t)stack, sizeof(register_t)); + + tf->tf_sp = stack += HPPA_FRAME_SIZE; + return (copyout(&zero, (caddr_t)(stack + HPPA_FRAME_CRP), + sizeof(register_t)) || err); +} + +/* * Set registers on exec. */ void @@ -785,7 +805,6 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack, { struct trapframe *tf = p->p_md.md_regs; struct pcb *pcb = &p->p_addr->u_pcb; - register_t zero; tf->tf_flags = TFF_SYS|TFF_LAST; tf->tf_iioq[1] = 4 + @@ -795,13 +814,8 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack, tf->tf_args[1] = tf->tf_args[2] = 0; /* XXX dynload stuff */ /* setup terminal stack frame */ - stack = (stack + 0x1f) & ~0x1f; - tf->tf_r3 = stack; - tf->tf_sp = stack += HPPA_FRAME_SIZE; - tf->tf_ret1 = stack - 16; /* ap */ - zero = 0; - copyout(&zero, (caddr_t)(stack - HPPA_FRAME_SIZE), sizeof(register_t)); - copyout(&zero, (caddr_t)(stack + HPPA_FRAME_RP), sizeof(register_t)); + setstack(tf, (stack + 0x1f) & ~0x1f, 0); + tf->tf_ret1 = tf->tf_sp - 16; /* ap */ /* reset any of the pending FPU exceptions */ fpu_proc_flush(p); @@ -827,7 +841,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, struct sigacts *psp = p->p_sigacts; struct sigcontext ksc; siginfo_t ksi; - register_t scp, sip, zero; + register_t scp, sip; int sss; #ifdef DEBUG @@ -874,12 +888,13 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, bcopy(&p->p_addr->u_pcb.pcb_fpstate->hfp_regs, ksc.sc_fpregs, sizeof(ksc.sc_fpregs)); - sss += HPPA_FRAME_SIZE; + if (setstack(tf, scp + sss, 0)) + sigexit(p, SIGILL); + tf->tf_args[0] = sig; tf->tf_args[1] = sip; tf->tf_args[2] = tf->tf_r4 = scp; tf->tf_args[3] = (register_t)catcher; - tf->tf_sp = scp + sss; tf->tf_ipsw &= ~(PSL_N|PSL_B|PSL_T); tf->tf_iioq[0] = HPPA_PC_PRIV_USER | p->p_sigcode; tf->tf_iioq[1] = tf->tf_iioq[0] + 4; @@ -889,7 +904,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n", - p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss); + p->p_pid, sig, scp, ksc.sc_fp, tf->tf_sp); #endif if (copyout(&ksc, (void *)scp, sizeof(ksc))) @@ -901,11 +916,6 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, sigexit(p, SIGILL); } - zero = 0; - if (copyout(&zero, (caddr_t)scp + sss - HPPA_FRAME_SIZE, - sizeof(register_t))) - sigexit(p, SIGILL); - #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid, diff --git a/sys/arch/hppa64/hppa64/vm_machdep.c b/sys/arch/hppa64/hppa64/vm_machdep.c index e0ab2e49822..2facb90e8c3 100644 --- a/sys/arch/hppa64/hppa64/vm_machdep.c +++ b/sys/arch/hppa64/hppa64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.17 2011/09/22 13:50:30 deraadt Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.18 2012/06/21 00:56:59 guenther Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff @@ -136,7 +136,7 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, * If specified, give the child a different stack. */ if (stack != NULL) - tf->tf_sp = (register_t)stack; + setstack(tf, (u_long)stack, 0); /* XXX ignore error? */ /* * Build stack frames for the cpu_switchto & co. diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c index 80b24f37955..8f28e16bd3f 100644 --- a/sys/arch/sparc/sparc/vm_machdep.c +++ b/sys/arch/sparc/sparc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.54 2011/04/07 15:30:16 miod Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.55 2012/06/21 00:56:59 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.30 1997/03/10 23:55:40 pk Exp $ */ /* @@ -407,12 +407,6 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) /* Copy parent's trapframe */ *tf2 = *(struct trapframe *)((int)opcb + USPACE - sizeof(*tf2)); - /* - * If specified, give the child a different stack. - */ - if (stack != NULL) - tf2->tf_out[6] = (u_int)stack + stacksize; - /* Duplicate efforts of syscall(), but slightly differently */ if (tf2->tf_global[1] & SYSCALL_G2RFLAG) { /* jmp %g2 (or %g7, deprecated) on success */ @@ -439,6 +433,16 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) rp->rw_local[0] = (int)func; /* Function to call */ rp->rw_local[1] = (int)arg; /* and its argument */ + /* + * If specified, give the child a different stack, with space + * reserved for the frame, and zero the frame pointer. + */ + if (stack != NULL) { + tf2->tf_out[6] = (u_int)stack + stacksize + - sizeof(struct frame); + rp->rw_in[6] = 0; + } + npcb->pcb_pc = (int)proc_trampoline - 8; npcb->pcb_sp = (int)rp; npcb->pcb_psr &= ~PSR_CWP; /* Run in window #0 */ diff --git a/sys/arch/sparc64/sparc64/vm_machdep.c b/sys/arch/sparc64/sparc64/vm_machdep.c index 0e7b07d4c20..c3a454f3d30 100644 --- a/sys/arch/sparc64/sparc64/vm_machdep.c +++ b/sys/arch/sparc64/sparc64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.27 2011/01/13 21:19:42 kettenis Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.28 2012/06/21 00:56:59 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.38 2001/06/30 00:02:20 eeh Exp $ */ /* @@ -241,10 +241,14 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) *tf2 = *(struct trapframe *)((long)opcb + USPACE - sizeof(*tf2)); /* - * If specified, give the child a different stack. + * If specified, give the child a different stack, offset and + * with space reserved for the frame, and zero the frame pointer. */ - if (stack != NULL) - tf2->tf_out[6] = (u_int64_t)(u_long)stack + stacksize; + if (stack != NULL) { + tf2->tf_out[6] = (u_int64_t)(u_long)stack + stacksize + - (BIAS + CC64FSZ); + tf2->tf_in[6] = 0; + } /* Duplicate efforts of syscall(), but slightly differently */ if (tf2->tf_global[1] & SYSCALL_G2RFLAG) { diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 695cac4b619..7546a5f682d 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.140 2012/05/10 05:01:23 guenther Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.141 2012/06/21 00:56:59 guenther Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -117,9 +117,38 @@ int sys___tfork(struct proc *p, void *v, register_t *retval) { struct sys___tfork_args /* { - syscallarg(struct __tfork) *param; + syscallarg(const struct __tfork) *param; + syscallarg(size_t) psize; } */ *uap = v; - struct __tfork param; + size_t psize = SCARG(uap, psize); + struct __tfork param = { 0 }; + int flags; + int error; + + if (psize == 0 || psize > sizeof(param)) + return (EINVAL); + if ((error = copyin(SCARG(uap, param), ¶m, psize))) + return (error); +#ifdef KTRACE + if (KTRPOINT(p, KTR_STRUCT)) + ktrstruct(p, "tfork", ¶m, sizeof(param)); +#endif + + flags = FORK_TFORK | FORK_THREAD | FORK_SIGHAND | FORK_SHAREVM + | FORK_NOZOMBIE | FORK_SHAREFILES; + + return (fork1(p, 0, flags, param.tf_stack, param.tf_tid, + tfork_child_return, param.tf_tcb, retval, NULL)); +} + +#ifdef COMPAT_O51 +int +compat_o51_sys___tfork(struct proc *p, void *v, register_t *retval) +{ + struct compat_o51_sys___tfork_args /* { + syscallarg(struct __tfork51) *param; + } */ *uap = v; + struct __tfork51 param; int flags; int error; @@ -135,6 +164,7 @@ sys___tfork(struct proc *p, void *v, register_t *retval) return (fork1(p, 0, flags, NULL, param.tf_tid, tfork_child_return, param.tf_tcb, retval, NULL)); } +#endif void tfork_child_return(void *arg) diff --git a/sys/kern/syscalls.conf b/sys/kern/syscalls.conf index a00a694b5ce..068f33e3df9 100644 --- a/sys/kern/syscalls.conf +++ b/sys/kern/syscalls.conf @@ -1,11 +1,11 @@ -# $OpenBSD: syscalls.conf,v 1.14 2011/07/09 05:46:26 matthew Exp $ +# $OpenBSD: syscalls.conf,v 1.15 2012/06/21 00:56:59 guenther Exp $ # $NetBSD: syscalls.conf,v 1.2 1994/10/26 06:45:57 cgd Exp $ sysnames="syscalls.c" sysnumhdr="../sys/syscall.h" syssw="init_sysent.c" sysarghdr="../sys/syscallargs.h" -compatopts="compat_o48" +compatopts="compat_o48 compat_o51" libcompatopts="" switchname="sysent" diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 5a48907c854..33b04db32ed 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.123 2012/04/12 12:33:03 deraadt Exp $ +; $OpenBSD: syscalls.master,v 1.124 2012/06/21 00:56:59 guenther Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -60,7 +60,8 @@ 6 STD { int sys_close(int fd); } 7 STD { pid_t sys_wait4(pid_t pid, int *status, int options, \ struct rusage *rusage); } -8 OBSOL ocreat +8 STD { int sys___tfork(const struct __tfork *param, \ + size_t psize); } 9 STD { int sys_link(const char *path, const char *link); } 10 STD { int sys_unlink(const char *path); } 11 OBSOL execv @@ -567,6 +568,6 @@ const struct timespec *times, int flag); } 327 STD { int sys_futimens(int fd, \ const struct timespec *times); } -328 STD { int sys___tfork(struct __tfork *param); } +328 COMPAT_O51 { int sys___tfork(struct __tfork51 *param); } 329 STD NOLOCK { void sys___set_tcb(void *tcb); } 330 STD NOLOCK { void *sys___get_tcb(void); } diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h index 3f8284f2252..a7bdfaec207 100644 --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.23 2012/06/19 00:09:55 matthew Exp $ */ +/* $OpenBSD: unistd.h,v 1.24 2012/06/21 00:56:59 guenther Exp $ */ /* $NetBSD: unistd.h,v 1.10 1994/06/29 06:46:06 cgd Exp $ */ /* @@ -63,6 +63,13 @@ struct __tfork { void *tf_tcb; pid_t *tf_tid; + void *tf_stack; +}; + +/* COMPAT_O51 */ +struct __tfork51 { + void *tf_tcb; + pid_t *tf_tid; int tf_flags; }; #endif |