1*1b191cb5SApple OSS Distributions/* 2*1b191cb5SApple OSS Distributions * Copyright (c) 1999-2007 Apple Inc. All rights reserved. 3*1b191cb5SApple OSS Distributions * 4*1b191cb5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*1b191cb5SApple OSS Distributions * 6*1b191cb5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*1b191cb5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*1b191cb5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*1b191cb5SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*1b191cb5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*1b191cb5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*1b191cb5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*1b191cb5SApple OSS Distributions * terms of an Apple operating system software license agreement. 14*1b191cb5SApple OSS Distributions * 15*1b191cb5SApple OSS Distributions * Please obtain a copy of the License at 16*1b191cb5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*1b191cb5SApple OSS Distributions * 18*1b191cb5SApple OSS Distributions * The Original Code and all software distributed under the License are 19*1b191cb5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*1b191cb5SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*1b191cb5SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*1b191cb5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*1b191cb5SApple OSS Distributions * Please see the License for the specific language governing rights and 24*1b191cb5SApple OSS Distributions * limitations under the License. 25*1b191cb5SApple OSS Distributions * 26*1b191cb5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*1b191cb5SApple OSS Distributions */ 28*1b191cb5SApple OSS Distributions 29*1b191cb5SApple OSS Distributions#include "SYS.h" 30*1b191cb5SApple OSS Distributions 31*1b191cb5SApple OSS Distributions#if defined(__i386__) 32*1b191cb5SApple OSS Distributions 33*1b191cb5SApple OSS Distributions .data 34*1b191cb5SApple OSS Distributions .private_extern __current_pid 35*1b191cb5SApple OSS DistributionsL__current_pid_addr: 36*1b191cb5SApple OSS Distributions __current_pid: 37*1b191cb5SApple OSS Distributions .long 0 38*1b191cb5SApple OSS Distributions 39*1b191cb5SApple OSS Distributions#if defined(__DYNAMIC__) 40*1b191cb5SApple OSS Distributions#define GET_CURRENT_PID \ 41*1b191cb5SApple OSS Distributions call 0f ; \ 42*1b191cb5SApple OSS Distributions0: ; \ 43*1b191cb5SApple OSS Distributions popl %ecx ; \ 44*1b191cb5SApple OSS Distributions leal L__current_pid_addr-0b(%ecx), %ecx 45*1b191cb5SApple OSS Distributions 46*1b191cb5SApple OSS Distributions#define __current_pid (%ecx) 47*1b191cb5SApple OSS Distributions 48*1b191cb5SApple OSS Distributions#else 49*1b191cb5SApple OSS Distributions#define GET_CURRENT_PID 50*1b191cb5SApple OSS Distributions#endif 51*1b191cb5SApple OSS Distributions 52*1b191cb5SApple OSS Distributions/* 53*1b191cb5SApple OSS Distributions * If __current_pid is > 0, return it, else make syscall. 54*1b191cb5SApple OSS Distributions * If __current_pid is 0, cache result of syscall. 55*1b191cb5SApple OSS Distributions */ 56*1b191cb5SApple OSS DistributionsTEXT 57*1b191cb5SApple OSS DistributionsLEAF(___getpid, 0) 58*1b191cb5SApple OSS Distributions GET_CURRENT_PID 59*1b191cb5SApple OSS Distributions movl __current_pid, %eax 60*1b191cb5SApple OSS Distributions testl %eax, %eax 61*1b191cb5SApple OSS Distributions jle 1f 62*1b191cb5SApple OSS Distributions ret 63*1b191cb5SApple OSS Distributions1: 64*1b191cb5SApple OSS Distributions UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) 65*1b191cb5SApple OSS Distributions movl %eax, %edx 66*1b191cb5SApple OSS Distributions xorl %eax, %eax 67*1b191cb5SApple OSS Distributions GET_CURRENT_PID 68*1b191cb5SApple OSS Distributions lock 69*1b191cb5SApple OSS Distributions cmpxchgl %edx, __current_pid 70*1b191cb5SApple OSS Distributions movl %edx, %eax 71*1b191cb5SApple OSS Distributions ret 72*1b191cb5SApple OSS Distributions 73*1b191cb5SApple OSS Distributions#elif defined(__x86_64__) 74*1b191cb5SApple OSS Distributions 75*1b191cb5SApple OSS Distributions .data 76*1b191cb5SApple OSS Distributions .private_extern __current_pid 77*1b191cb5SApple OSS Distributions__current_pid: 78*1b191cb5SApple OSS Distributions .long 0 79*1b191cb5SApple OSS Distributions 80*1b191cb5SApple OSS Distributions/* 81*1b191cb5SApple OSS Distributions * If __current_pid is > 0, return it, else make syscall. 82*1b191cb5SApple OSS Distributions * If __current_pid is 0, cache result of syscall. 83*1b191cb5SApple OSS Distributions */ 84*1b191cb5SApple OSS DistributionsTEXT 85*1b191cb5SApple OSS DistributionsLEAF(___getpid, 0) 86*1b191cb5SApple OSS Distributions movl __current_pid(%rip), %eax 87*1b191cb5SApple OSS Distributions testl %eax, %eax 88*1b191cb5SApple OSS Distributions jle 1f 89*1b191cb5SApple OSS Distributions ret 90*1b191cb5SApple OSS Distributions1: 91*1b191cb5SApple OSS Distributions UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) 92*1b191cb5SApple OSS Distributions movl %eax, %edx 93*1b191cb5SApple OSS Distributions xorl %eax, %eax 94*1b191cb5SApple OSS Distributions leaq __current_pid(%rip), %rcx 95*1b191cb5SApple OSS Distributions lock 96*1b191cb5SApple OSS Distributions cmpxchgl %edx, (%rcx) 97*1b191cb5SApple OSS Distributions movl %edx, %eax 98*1b191cb5SApple OSS Distributions ret 99*1b191cb5SApple OSS Distributions UNWIND_EPILOGUE 100*1b191cb5SApple OSS Distributions 101*1b191cb5SApple OSS Distributions#elif defined(__arm__) 102*1b191cb5SApple OSS Distributions 103*1b191cb5SApple OSS Distributions#include <arm/arch.h> 104*1b191cb5SApple OSS Distributions 105*1b191cb5SApple OSS Distributions .data 106*1b191cb5SApple OSS Distributions .globl __current_pid 107*1b191cb5SApple OSS Distributions .align 2 108*1b191cb5SApple OSS Distributions__current_pid: 109*1b191cb5SApple OSS Distributions /* Cached pid. Possible values: 110*1b191cb5SApple OSS Distributions * 0: no value cached 111*1b191cb5SApple OSS Distributions * > 0: cached PID of current process 112*1b191cb5SApple OSS Distributions * < 0: negative number of vforks in progress 113*1b191cb5SApple OSS Distributions * INT_MIN: for pre-ARMv6, "looking" value (0x80000000) 114*1b191cb5SApple OSS Distributions */ 115*1b191cb5SApple OSS Distributions .long 0 116*1b191cb5SApple OSS Distributions 117*1b191cb5SApple OSS DistributionsMI_ENTRY_POINT(___getpid) 118*1b191cb5SApple OSS Distributions ldr r3, L__current_pid 119*1b191cb5SApple OSS DistributionsL1: add r3, pc, r3 // r3 = &__current_pid 120*1b191cb5SApple OSS Distributions ldr r0, [r3] // get the cached pid 121*1b191cb5SApple OSS Distributions cmp r0, #0 122*1b191cb5SApple OSS Distributions bxgt lr // if positive, return it 123*1b191cb5SApple OSS Distributions 124*1b191cb5SApple OSS Distributions SYSCALL_NONAME(getpid, 0, cerror_nocancel) 125*1b191cb5SApple OSS Distributions 126*1b191cb5SApple OSS Distributions#ifdef _ARM_ARCH_6 127*1b191cb5SApple OSS Distributions ldrex r2, [r3] // see if we can cache it 128*1b191cb5SApple OSS Distributions cmp r2, #0 // we can't if there are any... 129*1b191cb5SApple OSS Distributions bxlt lr // ...vforks in progress 130*1b191cb5SApple OSS Distributions strex r2, r0, [r3] // ignore conflicts 131*1b191cb5SApple OSS Distributions#else 132*1b191cb5SApple OSS Distributions mov r1, #0x80000000 // load "looking" value 133*1b191cb5SApple OSS Distributions swp r2, r1, [r3] // look at the value, lock others out 134*1b191cb5SApple OSS Distributions cmp r2, r1 // anyone else trying to look? 135*1b191cb5SApple OSS Distributions bxeq lr // yes, so return immediately/ 136*1b191cb5SApple OSS Distributions cmp r2, #0 // see if we can cache it 137*1b191cb5SApple OSS Distributions streq r0, [r3] // if zero, we can 138*1b191cb5SApple OSS Distributions strne r2, [r3] // otherwise restore previous value 139*1b191cb5SApple OSS Distributions#endif 140*1b191cb5SApple OSS Distributions 141*1b191cb5SApple OSS Distributions bx lr 142*1b191cb5SApple OSS Distributions 143*1b191cb5SApple OSS DistributionsL__current_pid: 144*1b191cb5SApple OSS Distributions .long __current_pid - (L1+8) 145*1b191cb5SApple OSS Distributions 146*1b191cb5SApple OSS Distributions#elif defined(__arm64__) 147*1b191cb5SApple OSS Distributions .data 148*1b191cb5SApple OSS Distributions .globl __current_pid 149*1b191cb5SApple OSS Distributions .align 2 150*1b191cb5SApple OSS Distributions__current_pid: 151*1b191cb5SApple OSS Distributions /* cached pid. possible values: 152*1b191cb5SApple OSS Distributions * 0: no value cached 153*1b191cb5SApple OSS Distributions * > 0: cached pid of current process 154*1b191cb5SApple OSS Distributions * < 0: negative number of vforks in progress 155*1b191cb5SApple OSS Distributions * int_min: for pre-armv6, "looking" value (0x80000000) 156*1b191cb5SApple OSS Distributions */ 157*1b191cb5SApple OSS Distributions .long 0 158*1b191cb5SApple OSS Distributions 159*1b191cb5SApple OSS DistributionsMI_ENTRY_POINT(___getpid) 160*1b191cb5SApple OSS Distributions MI_GET_ADDRESS(x9, __current_pid) // Get address of cached value 161*1b191cb5SApple OSS Distributions ldr w0, [x9] // Load it 162*1b191cb5SApple OSS Distributions cmp w0, #0 // See if there's a cached value 163*1b191cb5SApple OSS Distributions b.le L_notcached // If not, make syscall 164*1b191cb5SApple OSS Distributions ret // Else, we're done 165*1b191cb5SApple OSS DistributionsL_notcached: 166*1b191cb5SApple OSS Distributions SYSCALL_NONAME(getpid, 0, cerror_nocancel) 167*1b191cb5SApple OSS Distributions ldxr w10, [x9] // Exclusive load 168*1b191cb5SApple OSS Distributions cbnz w10, L_done // Unless unset, don't even try 169*1b191cb5SApple OSS Distributions stxr wzr, w0, [x9] // Try to store, but don't care if we fail (someone will win, or not) 170*1b191cb5SApple OSS DistributionsL_done: 171*1b191cb5SApple OSS Distributions ret // Done 172*1b191cb5SApple OSS Distributions#else 173*1b191cb5SApple OSS Distributions#error Unsupported architecture 174*1b191cb5SApple OSS Distributions#endif 175