2004-12-04  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/i386/clone.S: Add support for NPTL where
	the PID is stored at userlevel and needs to be reset when CLONE_THREAD
	is not used.
	* sysdeps/unix/sysv/linux/86_64/clone.S: Likewise.

	* sysdeps/unix/sysv/linux/arm/clone.S: Update uses of RETINSTR.
	* sysdeps/unix/sysv/linux/arm/mmap.S: Likewise.
	* sysdeps/unix/sysv/linux/arm/mmap64.S: Likewise.
	* sysdeps/unix/sysv/linux/arm/socket.S: Likewise.
	* sysdeps/unix/sysv/linux/arm/sysdep.h: Likewise.
	* sysdeps/unix/sysv/linux/arm/vfork.S: Likewise.
This commit is contained in:
Ulrich Drepper 2004-12-05 07:50:01 +00:00
parent 110b21a2ba
commit 1ff241b87c
7 changed files with 175 additions and 11 deletions

View File

@ -1,3 +1,10 @@
2004-12-04 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/clone.S: Add support for NPTL where
the PID is stored at userlevel and needs to be reset when CLONE_THREAD
is not used.
* sysdeps/unix/sysv/linux/86_64/clone.S: Likewise.
2004-11-18 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/arm/sysdep.h: Define __USE_BX__ if bx is available.
@ -9,12 +16,12 @@
* sysdeps/arm/strlen.S: Use DO_RET.
* sysdeps/unix/arm/brk.S, sysdeps/unix/arm/fork.S,
sysdeps/unix/arm/sysdep.S, sysdeps/unix/arm/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/arm/clone.S,
sysdeps/unix/sysv/linux/arm/mmap.S,
sysdeps/unix/sysv/linux/arm/mmap64.S,
sysdeps/unix/sysv/linux/arm/socket.S,
sysdeps/unix/sysv/linux/arm/sysdep.h,
sysdeps/unix/sysv/linux/arm/vfork.S: Update uses of RETINSTR.
* sysdeps/unix/sysv/linux/arm/clone.S: Update uses of RETINSTR.
* sysdeps/unix/sysv/linux/arm/mmap.S: Likewise.
* sysdeps/unix/sysv/linux/arm/mmap64.S: Likewise.
* sysdeps/unix/sysv/linux/arm/socket.S: Likewise.
* sysdeps/unix/sysv/linux/arm/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/arm/vfork.S: Likewise.
2004-12-02 Roland McGrath <roland@redhat.com>

View File

@ -1,3 +1,10 @@
2004-12-04 Ulrich Drepper <drepper@redhat.com>
* Makefile (tests): Add tst-getpid1.
* tst-getpid1.c: New file.
* sysdeps/unix/sysv/linux/i386/clone.S: New file.
* sysdeps/unix/sysv/linux/x86_64/clone.S: New file.
2004-12-02 Roland McGrath <roland@redhat.com>
* Makefile (libpthread-nonshared): Variable removed.

View File

@ -240,7 +240,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
tst-sched1 \
tst-backtrace1 \
tst-oddstacklimit \
tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x
tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
tst-getpid1
xtests = tst-setuid1 tst-setuid1-static
# Files which must not be linked with libpthread.

View File

@ -0,0 +1,2 @@
#define RESET_PID
#include <sysdeps/unix/sysv/linux/x86_64/clone.S>

99
nptl/tst-getpid1.c Normal file
View File

@ -0,0 +1,99 @@
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
static int sig;
static int
f (void *a)
{
puts ("in f");
union sigval sival;
sival.sival_int = getpid ();
printf ("pid = %d\n", sival.sival_int);
if (sigqueue (getppid (), sig, sival) != 0)
return 1;
return 0;
}
static int
do_test (void)
{
int mypid = getpid ();
sig = SIGRTMIN;
sigset_t ss;
sigemptyset (&ss);
sigaddset (&ss, sig);
if (sigprocmask (SIG_BLOCK, &ss, NULL) != 0)
{
printf ("sigprocmask failed: %m\n");
return 1;
}
char st[128 * 1024];
pid_t p = clone (f, st + sizeof (st), 0, 0);
if (p == -1)
{
printf("clone failed: %m\n");
return 1;
}
printf ("new thread: %d\n", (int) p);
siginfo_t si;
do
if (sigwaitinfo (&ss, &si) < 0)
{
printf("sigwaitinfo failed: %m\n");
kill (p, SIGKILL);
return 1;
}
while (si.si_signo != sig || si.si_code != SI_QUEUE);
if (si.si_int != (int) p)
{
printf ("expected PID %d, got si_int %d\n", (int) p, si.si_int);
kill (p, SIGKILL);
return 1;
}
if (si.si_pid != p)
{
printf ("expected PID %d, got si_pid %d\n", (int) p, (int) si.si_pid);
kill (p, SIGKILL);
return 1;
}
int e;
if (waitpid (p, &e, __WCLONE) != p)
{
puts ("waitpid failed");
kill (p, SIGKILL);
return 1;
}
if (!WIFEXITED (e))
{
puts ("did not terminate correctly");
return 1;
}
if (WEXITSTATUS (e) != 0)
{
printf ("exit code %d\n", WEXITSTATUS (e));
return 1;
}
if (getpid () != mypid)
{
puts ("my PID changed");
return 1;
}
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996,1997,98,99,2000,02,03 Free Software Foundation, Inc.
/* Copyright (C) 1996,1997,98,99,2000,02,03,04 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson (rth@tamu.edu)
@ -42,6 +42,9 @@
#define __NR_clone 120
#define SYS_clone 120
#define CLONE_VM 0x00000100
#define CLONE_THREAD 0x00010000
.text
ENTRY (BP_SYM (__clone))
/* Sanity check arguments. */
@ -74,7 +77,9 @@ ENTRY (BP_SYM (__clone))
movl %eax,8(%ecx)
/* Don't leak any information. */
movl $0,4(%ecx)
#ifndef RESET_PID
movl $0,(%ecx)
#endif
/* Do the system call */
pushl %ebx
@ -85,6 +90,12 @@ ENTRY (BP_SYM (__clone))
movl FLAGS+12(%esp),%ebx
movl CTID+12(%esp),%edi
movl $SYS_ify(clone),%eax
#ifdef RESET_PID
/* Remember the flag value. */
movl %ebx, (%ecx)
#endif
int $0x80
popl %edi
popl %esi
@ -98,7 +109,13 @@ L(pseudo_end):
ret
L(thread_start):
subl %ebp,%ebp /* terminate the stack frame */
/* Note: %esi is zero. */
movl %esi,%ebp /* terminate the stack frame */
#ifdef RESET_PID
testl $CLONE_THREAD, %edi
je L(newpid)
L(haspid):
#endif
call *%ebx
#ifdef PIC
call L(here)
@ -110,6 +127,21 @@ L(here):
movl $SYS_ify(exit), %eax
int $0x80
#ifdef RESET_PID
.subsection 2
L(newpid):
testl $CLONE_VM, %edi
movl $-1, %eax
jne L(nomoregetpid)
movl $SYS_ify(getpid), %eax
ENTER_KERNEL
L(nomoregetpid):
movl %eax, %gs:PID
movl %eax, %gs:TID
jmp L(haspid)
.previous
#endif
PSEUDO_END (BP_SYM (__clone))
weak_alias (BP_SYM (__clone), BP_SYM (clone))

View File

@ -26,6 +26,9 @@
#include <bp-sym.h>
#include <bp-asm.h>
#define CLONE_VM 0x00000100
#define CLONE_THREAD 0x00010000
/* The userland implementation is:
int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
the kernel entry is:
@ -80,16 +83,29 @@ ENTRY (BP_SYM (__clone))
testq %rax,%rax
jl SYSCALL_ERROR_LABEL
jz thread_start
jz L(thread_start)
L(pseudo_end):
ret
thread_start:
L(thread_start):
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorq %rbp, %rbp
#ifdef RESET_PID
testq $CLONE_THREAD, %rdi
jne 1f
testq $CLONE_VM, %rdi
movl $-1, %eax
jne 2f
movq $SYS_ify(getpid), %rax
syscall
2: movl %eax, %fs:PID
movl %eax, %fs:TID
1:
#endif
/* Set up arguments for the function call. */
popq %rax /* Function to call. */
popq %rdi /* Argument. */