src/thread/linux/clone.S

/* [<][>][^][v][top]
[bottom][index][help] */

FUNCTIONS

This source file includes following functions.

   1 
   2 /* Taken with thanks from LinuxThreads 0.6 */
   3 
   4 /* This is no longer necessary with glibc-2.1, which has it's own clone() */
   5 #ifdef linux
   6 /* Look to see if glibc is available, and if so, what version */
   7 #include <features.h>
   8 
   9 #if (__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
  10 #define HAVE_CLONE
  11 #endif /* glibc 2.1 or newer */
  12 #endif /* linux */
  13 
  14 #if defined(linux) && !defined(SDL_USE_PTHREADS) && !defined(HAVE_CLONE)
  15 
  16 #if defined(__i386__)
  17 /************************************************************************/
  18 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
  19    Contributed by Richard Henderson (rth@tamu.edu)
  20 
  21 The GNU C Library is free software; you can redistribute it and/or
  22 modify it under the terms of the GNU Library General Public License as
  23 published by the Free Software Foundation; either version 2 of the
  24 License, or (at your option) any later version.
  25 
  26 The GNU C Library is distributed in the hope that it will be useful,
  27 but WITHOUT ANY WARRANTY; without even the implied warranty of
  28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  29 Library General Public License for more details.
  30 
  31 You should have received a copy of the GNU Library General Public
  32 License along with the GNU C Library; see the file COPYING.LIB.  If
  33 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  34 
  35 #ifdef SAVE_RCSID
  36 static char rcsid =
  37  "@(#) $Id: clone.S,v 1.1.1.1.2.1 2000/04/20 21:03:15 hercules Exp $";
  38 #endif
  39 Cambridge, MA 02139, USA.  */
  40 
  41 /* clone() is even more special than fork() as it mucks with stacks
  42    and invokes a function in the right context after its all over.  */
  43 
  44 #include <asm/errno.h>
  45 #include <asm/unistd.h>
  46 
  47 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
  48 
  49         .text
  50         .align  4
  51         .globl  __clone
  52         .type   __clone,@function
  53         .weak   clone
  54         clone   = __clone
  55 __clone:
  56         /* Sanity check arguments.  */
  57         movl    $-EINVAL,%eax
  58         movl    4(%esp),%ecx            /* no NULL function pointers */
  59         testl   %ecx,%ecx
  60         jz      syscall_error
  61         movl    8(%esp),%ecx            /* no NULL stack pointers */
  62         testl   %ecx,%ecx
  63         jz      syscall_error
  64 
  65         /* Insert the argument onto the new stack.  */
  66         subl    $8,%ecx
  67         movl    16(%esp),%eax
  68         movl    %eax,4(%ecx)
  69 
  70         /* Save the function pointer as the zeroth argument. */
  71         /* It will be popped off in the child in the ebx frobbing below.  */
  72         movl    4(%esp),%eax
  73         movl    %eax,0(%ecx)
  74 
  75         /* Do the system call */
  76         pushl   %ebx
  77         movl    16(%esp),%ebx
  78         movl    $__NR_clone,%eax
  79         int     $0x80
  80         popl    %ebx
  81 
  82         test    %eax,%eax
  83         jl      syscall_error
  84         jz      thread_start
  85 
  86         ret
  87 
  88 syscall_error:
  89         negl    %eax
  90         pushl   %eax
  91 #ifdef __PIC__
  92         call    __errno_location@PLT
  93 #else
  94         call    __errno_location
  95 #endif
  96         popl    0(%eax)
  97         movl    $-1, %eax
  98         ret
  99 
 100 thread_start:
 101         subl    %ebp,%ebp       /* terminate the stack frame */
 102         call    *%ebx
 103         pushl   %eax
 104 #ifdef __PIC__
 105         call    _exit@PLT
 106 #else
 107         call    _exit
 108 #endif
 109 /************************************************************************/
 110 #elif defined(sparc)
 111 /************************************************************************/
 112 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
 113    Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx)
 114    Based on code written for the Intel by Richard 
 115    Henderson (rth@tamu.edu)
 116         
 117 The GNU C Library is free software; you can redistribute it and/or
 118 modify it under the terms of the GNU Library General Public License as
 119 published by the Free Software Foundation; either version 2 of the
 120 License, or (at your option) any later version.
 121 
 122 The GNU C Library is distributed in the hope that it will be useful,
 123 but WITHOUT ANY WARRANTY; without even the implied warranty of
 124 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 125 Library General Public License for more details.
 126 
 127 You should have received a copy of the GNU Library General Public
 128 License along with the GNU C Library; see the file COPYING.LIB.  If
 129 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 130 Cambridge, MA 02139, USA.  */
 131 
 132 /* clone() is even more special than fork() as it mucks with stacks
 133    and invokes a function in the right context after its all over.  */
 134         
 135 #include <asm/errno.h>
 136 #include <asm/unistd.h>
 137 
 138 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
 139 
 140         .text
 141         .align  4
 142         .globl  __clone
 143         .type   __clone,@function
 144         .weak   clone
 145         clone   = __clone
 146 __clone:        
 147         save    %sp,-96,%sp
 148         /* sanity check arguments */
 149         tst     %i0
 150         be      __clone_syscall_error
 151         tst     %i1
 152         be      __clone_syscall_error
 153         nop
 154 
 155         /* Do the system call */
 156         mov     %i1,%o1
 157         mov     %i2,%o0
 158         set     __NR_clone,%g1
 159         ta      0x10
 160         bcs     __clone_syscall_error
 161         tst     %o1
 162         bne     __thread_start
 163         nop
 164         mov     %o0,%i0
 165         ret
 166         restore
 167         
 168 __clone_syscall_error:
 169         call    __errno_location
 170         set     EINVAL,%i0
 171         st      %i0,[%o0]
 172         mov     -1,%i0
 173         ret
 174         restore
 175 
 176 __thread_start:
 177         call    %i0
 178         mov     %i3,%o0
 179         call    _exit,0
 180         nop
 181 /************************************************************************/
 182 #else 
 183 #error "Unknown Linux architecture"
 184 #endif
 185 
 186 #endif /* Linux && ! SDL_USE_PTHREADS */

/* [<][>][^][v][top][bottom][index][help] */