From: Ulrich Drepper Date: Sun, 15 Oct 2000 03:26:18 +0000 (+0000) Subject: Linux/HPPA specific clone implementation. X-Git-Tag: glibc-2.16-ports-before-merge~2194 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b35e240743eed04486e401463ef4abce5b93e5f9;p=thirdparty%2Fglibc.git Linux/HPPA specific clone implementation. --- diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S new file mode 100644 index 00000000000..510e0ff7990 --- /dev/null +++ b/sysdeps/unix/sysv/linux/hppa/clone.S @@ -0,0 +1,82 @@ +/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines , 2000. + Based on the Alpha version by Richard Henderson , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* clone() is even more special than fork() as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include +#include +#define _ERRNO_H 1 +#include + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */ + + .text +ENTRY(__clone) + /* FIXME: I have no idea how profiling works on hppa. */ + + /* Sanity check arguments. */ + comib,<> 0,%arg0,.Lerror /* no NULL function pointers */ + ldi EINVAL,%ret0 + comib,<> 0,%arg1,.Lerror /* no NULL stack pointers */ + nop + + /* Save the fn ptr and arg on the new stack. */ + stwm %arg3,64(%arg1) + stw %arg3,-60(%arg1) + + /* Do the system call */ + copy %arg2,%arg0 + ble 0x100(%sr7,%r0) + ldi __NR_clone,%r20 + + ldi -4096,%r1 + comclr,>>= %r1,%ret0,%r0 /* Note: unsigned compare. */ + b,n .Lerror + + comib,=,n 0,%ret0,thread_start + + /* Successful return from the parent */ + bv %r0(%rp) + nop + + /* Something bad happened -- no child created */ +.Lerror: + b __syscall_error + nop + +thread_start: + /* Load up the arguments. */ + ldw -60(%sp),%arg0 + ldwm -64(%sp),%r22 + + /* Call the user's function */ + bl $$dyncall,%r31 + copy %r31,%rp + + bl _exit,%rp + copy %ret0,%arg0 + + /* Die horribly. */ + iitlbp %r0,(%r0) + +PSEUDO_END(__clone) + +weak_alias(__clone, clone)