15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Copyright (c) 2005-2008, Google Inc. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions are 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * met: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * Redistributions of source code must retain the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * Redistributions in binary form must reproduce the above 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the documentation and/or other materials provided with the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribution. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * contributors may be used to endorse or promote products derived from 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this software without specific prior written permission. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * --- 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Markus Gutschke 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This file includes Linux-specific support functions common to the 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * coredumper and the thread lister; primarily, this is a collection 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of direct system calls, and a couple of symbols missing from 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * standard header files. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There are a few options that the including file can set to control 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the behavior of this file: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SYS_CPLUSPLUS: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The entire header file will normally be wrapped in 'extern "C" { }", 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * making it suitable for compilation as both C and C++ source. If you 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the wrapping. N.B. doing so will suppress inclusion of all prerequisite 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * system header files, too. It is the caller's responsibility to provide 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the necessary definitions. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SYS_ERRNO: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All system calls will update "errno" unless overriden by setting the 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * an l-value. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SYS_INLINE: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * New symbols will be defined "static inline", unless overridden by 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the SYS_INLINE macro. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SYS_LINUX_SYSCALL_SUPPORT_H 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This macro is used to avoid multiple inclusions of this header file. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If you need to include this file more than once, make sure to 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SYS_PREFIX: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * New system calls will have a prefix of "sys_" unless overridden by 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the SYS_PREFIX macro. Valid values for this macro are [0..9] which 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * results in prefixes "sys[0..9]_". It is also possible to set this 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * macro to -1, which avoids all prefixes. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file defines a few internal symbols that all start with "LSS_". 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do not access these symbols from outside this file. They are not part 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the supported API. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE: This is a stripped down version of the official opensource 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * version of linux_syscall_support.h, which lives at 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://code.google.com/p/linux-syscall-support/ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It includes only the syscalls that are used in perftools, plus a 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * few extra. Here's the breakdown: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1) Perftools uses these: grep -rho 'sys_[a-z0-9_A-Z]* *(' src | sort -u 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys__exit( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_clone( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_close( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_fcntl( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_fstat( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_futex( 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_futex1( 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_getcpu( 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_getdents( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_getppid( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_gettid( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_lseek( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_mmap( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_mremap( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_munmap( 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_open( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_pipe( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_prctl( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_ptrace( 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_ptrace_detach( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_read( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sched_yield( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigaction( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigaltstack( 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigdelset( 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigfillset( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigprocmask( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_socket( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_stat( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_waitpid( 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2) These are used as subroutines of the above: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_getpid -- gettid 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_kill -- ptrace_detach 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_restore -- sigaction 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_restore_rt -- sigaction 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_socketcall -- socket 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_wait4 -- waitpid 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3) I left these in even though they're not used. They either 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * complement the above (write vs read) or are variants (rt_sigaction): 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_fstat64 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_getdents64 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_llseek 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_mmap2 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_openat 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_rt_sigaction 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_rt_sigprocmask 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigaddset 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_sigemptyset 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_stat64 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sys_write 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SYS_LINUX_SYSCALL_SUPPORT_H 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYS_LINUX_SYSCALL_SUPPORT_H 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We currently only support x86-32, x86-64, ARM, MIPS, and PPC on Linux. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Porting to other related platforms should not be difficult. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(__mips__) || defined(__PPC__)) && defined(__linux) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SYS_CPLUSPLUS 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Some system header files in older versions of gcc neglect to properly 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * handle being included from C++. As it appears to be harmless to have 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * multiple nested 'extern "C"' blocks, just add another one here. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h> 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stddef.h> 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stdint.h> 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/ptrace.h> 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h> 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(__ANDROID__) 159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <sys/syscall.h> 160a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <sys/linux-syscalls.h> 161a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#else 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <syscall.h> 163a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <linux/unistd.h> 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <endian.h> 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Include definitions of the ABI currently in use. */ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sgidefs.h> 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* As glibc often provides subtly incompatible data structures (and implicit 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * wrapper functions that convert them), we provide our own kernel data 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * structures for use by the system calls. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These structures have been developed by using Linux 2.6.23 headers for 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reference. Note though, we do not care about exact API compatibility 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with the kernel, and in fact the kernel often does not have a single 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * API that works across architectures. Instead, we try to mimic the glibc 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * API where reasonable, and only guarantee ABI compatibility with the 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * kernel headers. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Most notably, here are a few changes that were made to the structures 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * defined by kernel headers: 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - we only define structures, but not symbolic names for kernel data 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * types. For the latter, we directly use the native C datatype 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (i.e. "unsigned" instead of "mode_t"). 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - in a few cases, it is possible to define identical structures for 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * standardizing on the 64bit version of the data types. In particular, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this means that we use "unsigned" where the 32bit headers say 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "unsigned long". 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - overall, we try to minimize the number of cases where we need to 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * conditionally define different structures. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - the "struct kernel_sigaction" class of structures have been 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modified to more closely mimic glibc's API by introducing an 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * anonymous union for the function pointer. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - a small number of field names had to have an underscore appended to 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * them, because glibc defines a global macro by the same name. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/dirent.h */ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_dirent64 { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long d_ino; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long d_off; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short d_reclen; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char d_type; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char d_name[256]; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/dirent.h */ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_dirent { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long d_ino; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long d_off; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short d_reclen; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char d_name[256]; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/time.h */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_timespec { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_sec; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_nsec; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/time.h */ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_timeval { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_sec; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_usec; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/resource.h */ 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_rusage { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_timeval ru_utime; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_timeval ru_stime; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_maxrss; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_ixrss; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_idrss; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_isrss; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_minflt; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_majflt; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nswap; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_inblock; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_oublock; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_msgsnd; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_msgrcv; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nsignals; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nvcsw; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nivcsw; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__i386__) || defined(__arm__) || defined(__PPC__) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,ppc}/signal.h */ 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_old_sigaction { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_handler_)(int); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void (*sa_sigaction_)(int, siginfo_t *, void *); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_mask; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_flags; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_restorer)(void); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} __attribute__((packed,aligned(4))); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define kernel_old_sigaction kernel_sigaction 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exactly match the size of the signal set, even though the API was 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * intended to be extensible. We define our own KERNEL_NSIG to deal with 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Please note that glibc provides signals [1.._NSIG-1], whereas the 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * kernel (and this header) provides the range [1..KERNEL_NSIG]. The 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * actual number of signals is obviously the same, but the constants 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * differ by one. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KERNEL_NSIG 128 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KERNEL_NSIG 64 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,x86_64}/signal.h */ 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_sigset_t { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (8*sizeof(unsigned long))]; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_sigaction { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_flags; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_handler_)(int); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void (*sa_sigaction_)(int, siginfo_t *, void *); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t sa_mask; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_handler_)(int); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void (*sa_sigaction_)(int, siginfo_t *, void *); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_flags; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_restorer)(void); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t sa_mask; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,ppc}/stat.h */ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if _MIPS_SIM == _MIPS_SIM_ABI64 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat64 { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_dev; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad0[3]; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_ino; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_rdev; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad1[3]; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_size; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_nsec_; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_nsec_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_nsec_; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blksize; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad2; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_blocks; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined __PPC__ 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat64 { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_dev; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_ino; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_rdev; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short int __pad2; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_size; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_blksize; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_blocks; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_atime_; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_nsec_; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_mtime_; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_nsec_; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_ctime_; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_nsec_; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused4; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused5; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat64 { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_dev; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char __pad0[4]; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __st_ino; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_rdev; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char __pad3[4]; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_size; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blksize; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_blocks; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_nsec_; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_nsec_; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_nsec_; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_ino; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__i386__) || defined(__arm__) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The kernel headers suggest that st_dev and st_rdev should be 32bit 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * quantities encoding 12bit major and 20bit minor numbers in an interleaved 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * format. In reality, we do not see useful data in the top bits. So, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we'll leave the padding in here, until we find a better solution. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_dev; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) short pad1; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ino; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_mode; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_nlink; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_uid; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_gid; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_rdev; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) short pad2; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_size; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blksize; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blocks; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_nsec_; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_nsec_; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_nsec_; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __unused4; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __unused5; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__x86_64__) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_dev; 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_ino; 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_nlink; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad0; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_rdev; 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64_t st_size; 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64_t st_blksize; 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64_t st_blocks; 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_atime_; 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_atime_nsec_; 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_mtime_; 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_mtime_nsec_; 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_ctime_; 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64_t st_ctime_nsec_; 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64_t __unused[3]; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__PPC__) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_dev; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ino; // ino_t 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mode; // mode_t 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_nlink; // nlink_t 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; // uid_t 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; // gid_t 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_rdev; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_size; // off_t 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_blksize; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_blocks; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_nsec_; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_nsec_; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_nsec_; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused4; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused5; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_dev; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad1[3]; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ino; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_rdev; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad2[2]; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_size; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad3; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_atime_; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_atime_nsec_; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_mtime_; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_mtime_nsec_; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_ctime_; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_ctime_nsec_; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_blksize; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_blocks; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad4[14]; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// ulong is not defined in Android while used to define __llseek. 480a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(__ANDROID__) 481a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)typedef unsigned long int ulong; 482a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif 483a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Definitions missing from the standard header files */ 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef O_DIRECTORY 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__arm__) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_DIRECTORY 0040000 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_DIRECTORY 0200000 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PR_GET_DUMPABLE 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PR_GET_DUMPABLE 3 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PR_SET_DUMPABLE 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PR_SET_DUMPABLE 4 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef AT_FDCWD 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AT_FDCWD (-100) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef AT_SYMLINK_NOFOLLOW 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AT_SYMLINK_NOFOLLOW 0x100 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef AT_REMOVEDIR 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AT_REMOVEDIR 0x200 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MREMAP_FIXED 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MREMAP_FIXED 2 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SA_RESTORER 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SA_RESTORER 0x04000000 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__i386__) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction 174 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask 175 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 195 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 197 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 220 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid 224 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex 240 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat 295 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu 318 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of i386 definitions */ 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__arm__) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __syscall 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__thumb__) || defined(__ARM_EABI__) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG(name) register long __sysreg __asm__("r6") = __NR_##name; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG_LIST(regs...) [sysreg] "r" (__sysreg) , ##regs 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall(name) "swi\t0" 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall_safe(name) \ 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "push {r7}\n" \ 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov r7,%[sysreg]\n" \ 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __syscall(name)"\n" \ 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop {r7}" 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG(name) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG_LIST(regs...) regs 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall(name) "swi\t" __sys1(__NR_##name) "" 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall_safe(name) __syscall(name) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 (__NR_SYSCALL_BASE + 195) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 (__NR_SYSCALL_BASE + 197) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 (__NR_SYSCALL_BASE + 217) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_SYSCALL_BASE + 224) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_SYSCALL_BASE + 240) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of ARM definitions */ 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__x86_64__) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid 186 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex 202 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 217 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat 257 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of x86-64 definitions */ 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__mips__) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if _MIPS_SIM == _MIPS_SIM_ABI32 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction (__NR_Linux + 194) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask (__NR_Linux + 195) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 (__NR_Linux + 213) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 (__NR_Linux + 215) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 (__NR_Linux + 219) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_Linux + 222) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_Linux + 238) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat (__NR_Linux + 288) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstatat 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstatat (__NR_Linux + 293) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu (__NR_Linux + 312) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS (old 32bit API) definitions */ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif _MIPS_SIM == _MIPS_SIM_ABI64 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_Linux + 178) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_Linux + 194) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat (__NR_Linux + 247) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstatat 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstatat (__NR_Linux + 252) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu (__NR_Linux + 271) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS (64bit API) definitions */ 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_Linux + 178) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_Linux + 194) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat (__NR_Linux + 251) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstatat 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstatat (__NR_Linux + 256) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu (__NR_Linux + 275) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS (new 32bit API) definitions */ 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS definitions */ 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__PPC__) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction 173 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask 174 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 195 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 197 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 202 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid 207 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex 221 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat 286 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu 302 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of powerpc defininitions */ 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* After forking, we must make sure to only call system calls. */ 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __BOUNDED_POINTERS__ 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #error "Need to port invocations of syscalls for bounded ptrs" 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The core dumper and the thread lister get executed after threads 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * have been suspended. As a consequence, we cannot call any functions 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that acquire locks. Unfortunately, libc wraps most system calls 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (e.g. in order to implement pthread_atfork, and to make calls 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cancellable), which means we cannot call these functions. Instead, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we have to call syscall() directly. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ERRNO 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef SYS_ERRNO 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allow the including file to override the location of errno. This can 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be useful when using clone() with the CLONE_VM option. 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ERRNO SYS_ERRNO 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ERRNO errno 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_INLINE 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef SYS_INLINE 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_INLINE SYS_INLINE 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_INLINE static inline 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allow the including file to override the prefix used for all new 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * system calls. By default, it will be set to "sys_". 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_NAME 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef SYS_PREFIX 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys_##name 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX < 0 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) name 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 0 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys0_##name 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 1 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys1_##name 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 2 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys2_##name 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 3 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys3_##name 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 4 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys4_##name 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 5 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys5_##name 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 6 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys6_##name 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 7 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys7_##name 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 8 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys8_##name 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 9 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys9_##name 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_RETURN 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__)) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Failing system calls return a negative result in the range of 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -1..-4095. These are "errno" values with the sign inverted. 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_RETURN(type, res) \ 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = -(res); \ 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = -1; \ 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (type) (res); \ 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__mips__) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On MIPS, failing system calls return -1, and set errno in a 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * separate CPU register. 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_RETURN(type, res, err) \ 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { \ 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = (res); \ 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = -1; \ 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (type) (res); \ 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__PPC__) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On PPC, failing system calls return -1, and set errno in a 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * separate CPU register. See linux/unistd.h. 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_RETURN(type, res, err) \ 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err & 0x10000000 ) { \ 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = (res); \ 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = -1; \ 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (type) (res); \ 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(NO_FRAME_POINTER) && (100 * __GNUC__ + __GNUC_MINOR__ >= 404) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This only works for GCC-4.4 and above -- the first version to use 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .cfi directives for dwarf unwind info. */ 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define CFI_ADJUST_CFA_OFFSET(adjust) \ 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".cfi_adjust_cfa_offset " #adjust "\n" 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define CFI_ADJUST_CFA_OFFSET(adjust) /**/ 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In PIC mode (e.g. when building shared libraries), gcc for i386 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reserves ebx. Unfortunately, most distribution ship with implementations 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of _syscallX() which clobber ebx. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Also, most definitions of _syscallX() neglect to mark "memory" as being 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * clobbered. This causes problems with compilers, that do a better job 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at optimizing across __asm__ calls. 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * So, we just have to redefine all of the _syscallX() macros. 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type,args...) \ 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("push %%ebx\n" \ 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFI_ADJUST_CFA_OFFSET(4) \ 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %2,%%ebx\n" \ 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" \ 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebx\n" \ 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFI_ADJUST_CFA_OFFSET(-4) \ 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args \ 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory"); \ 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type,name) \ 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(void) { \ 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ volatile("int $0x80" \ 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name) \ 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "memory"); \ 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res); \ 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type,name,type1,arg1) \ 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name), "ri" ((long)(arg1))); \ 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type,name,type1,arg1,type2,arg2) \ 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1,type2 arg2) { \ 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "d" ((long)(arg3))); \ 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "d" ((long)(arg3)),"S" ((long)(arg4))); \ 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("push %%ebx\n" \ 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %2,%%ebx\n" \ 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %1,%%eax\n" \ 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" \ 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebx" \ 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "ri" ((long)(arg1)), \ 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "c" ((long)(arg2)), "d" ((long)(arg3)), \ 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "S" ((long)(arg4)), "D" ((long)(arg5)) \ 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory"); \ 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res); \ 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("push %%ebp\n" \ 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "push %%ebx\n" \ 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl 4(%2),%%ebp\n" \ 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl 0(%2), %%ebx\n" \ 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %1,%%eax\n" \ 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" \ 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebx\n" \ 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebp" \ 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "0" ((long)(&__s)), \ 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "c" ((long)(arg2)), "d" ((long)(arg3)), \ 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "S" ((long)(arg4)), "D" ((long)(arg5)) \ 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory"); \ 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res); \ 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__(/* if (fn == NULL) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %3,%%ecx\n" 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jecxz 1f\n" 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (child_stack == NULL) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %4,%%ecx\n" 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jecxz 1f\n" 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set up alignment of the child stack: 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * child_stack = (child_stack & ~0xF) - 20; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "andl $-16,%%ecx\n" 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subl $20,%%ecx\n" 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %6,%%eax\n" 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,4(%%ecx)\n" 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %3,%%eax\n" 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,(%%ecx)\n" 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* %eax = syscall(%eax = __NR_clone, 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %ebx = flags, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %ecx = child_stack, 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %edx = parent_tidptr, 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %esi = newtls, 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %edi = child_tidptr) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Also, make sure that %ebx gets preserved as it is 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used in PIC mode. 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %8,%%esi\n" 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %7,%%edx\n" 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %5,%%eax\n" 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %9,%%edi\n" 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pushl %%ebx\n" 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,%%ebx\n" 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %2,%%eax\n" 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the parent: restore %ebx 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the child: move "fn" into %ebx 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "popl %%ebx\n" 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (%eax != 0) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return %eax; 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "test %%eax,%%eax\n" 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jnz 1f\n" 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child, now. Terminate frame pointer chain. 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl $0,%%ebp\n" 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call "fn". "arg" is already on the stack. 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "call *%%ebx\n" 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(%ebx). Unfortunately older versions 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of gcc restrict the number of arguments that can 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be passed to asm(). So, we need to hard-code the 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * system call number. 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,%%ebx\n" 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl $1,%%eax\n" 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return to parent. 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(-EINVAL), "i"(__NR_clone), 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory", "ecx", "edx", "esi", "edi"); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __res); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On i386, the kernel does not know how to return from a signal 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * handler. Instead, it relies on user space to provide a 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restorer function that calls the {rt_,}sigreturn() system call. 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unfortunately, we cannot just reference the glibc version of this 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * function, as glibc goes out of its way to make it inaccessible. 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*res)(void); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("call 2f\n" 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:.align 16\n" 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:movl %1,%%eax\n" 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "2:popl %0\n" 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addl $(1b-0b),%0\n" 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (res) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_rt_sigreturn)); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void (*LSS_NAME(restore)(void))(void) { 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On i386, the kernel does not know how to return from a signal 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * handler. Instead, it relies on user space to provide a 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restorer function that calls the {rt_,}sigreturn() system call. 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unfortunately, we cannot just reference the glibc version of this 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * function, as glibc goes out of its way to make it inaccessible. 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*res)(void); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("call 2f\n" 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:.align 16\n" 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:pop %%eax\n" 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %1,%%eax\n" 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "2:popl %0\n" 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addl $(1b-0b),%0\n" 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (res) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_sigreturn)); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__x86_64__) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* There are no known problems with any of the _syscallX() macros 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * currently shipping for x86_64, but we still need to be able to define 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * our own version so that we can override the location of the errno 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * location (e.g. when using the clone() system call with the CLONE_VM 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * option). 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_ENTRYPOINT 1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_ENTRYPOINT "syscall\n" 1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. 1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * We need to explicitly cast to an unsigned 64 bit type to avoid implicit 1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * sign extension. We can't cast pointers directly because those are 1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 32 bits, and gcc will dump ugly warnings about casting from a pointer 1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * to an integer of a different size. 1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_SYSCALL_ARG 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a)) 1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef _LSS_RETURN 1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define _LSS_RETURN(type, res, cast) \ 1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) do { \ 1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ 1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_ERRNO = -(res); \ 1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) res = -1; \ 1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } \ 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (type)(cast)(res); \ 1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } while (0) 1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_RETURN 1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t) 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef _LSS_BODY 1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define _LSS_BODY(nr, type, name, cast, ...) \ 1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) long long __res; \ 1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \ 1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : "=a" (__res) \ 1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \ 1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \ 1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _LSS_RETURN(type, __res, cast) 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY(nr, type, name, args...) \ 1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _LSS_BODY(nr, type, name, uintptr_t, ## args) 1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM0 1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM1 1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM2 1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM3 1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM4 1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM5 1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ASM6 1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM0 1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM1 LSS_BODY_ASM0 1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM2 LSS_BODY_ASM1 1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM3 LSS_BODY_ASM2 1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;" 1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;" 1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;" 1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER0 1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER1 1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER2 1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER3 1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER4 1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER5 1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_CLOBBER6 1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER0 1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0 1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1 1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2 1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10", 1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8", 1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9", 1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG0 1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG1 1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG2 1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG3 1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG4 1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG5 1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #undef LSS_BODY_ARG6 1100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG0() 1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG1(arg1) \ 1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY_ARG0(), "D" (arg1) 1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG2(arg1, arg2) \ 1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY_ARG1(arg1), "S" (arg2) 1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG3(arg1, arg2, arg3) \ 1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY_ARG2(arg1, arg2), "d" (arg3) 1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \ 1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4) 1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \ 1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5) 1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \ 1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6) 1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type,name) \ 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)() { \ 1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(0, type, name); \ 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type,name,type1,arg1) \ 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \ 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type,name,type1,arg1,type2,arg2) \ 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\ 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(arg3)); \ 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\ 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ 1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(arg5)); \ 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ 1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ 1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\ 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) long long __res; 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__(/* if (fn == NULL) 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "testq %4,%4\n" 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jz 1f\n" 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (child_stack == NULL) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "testq %5,%5\n" 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jz 1f\n" 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set up alignment of the child stack: 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * child_stack = (child_stack & ~0xF) - 16; 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "andq $-16,%5\n" 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subq $16,%5\n" 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %7,8(%5)\n" 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %4,0(%5)\n" 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* %rax = syscall(%rax = __NR_clone, 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %rdi = flags, 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %rsi = child_stack, 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %rdx = parent_tidptr, 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r8 = new_tls, 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r10 = child_tidptr) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %2,%%rax\n" 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %9,%%r8\n" 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %10,%%r10\n" 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (%rax != 0) 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "testq %%rax,%%rax\n" 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jnz 1f\n" 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child. Terminate frame pointer chain. 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xorq %%rbp,%%rbp\n" 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call "fn(arg)". 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "popq %%rax\n" 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "popq %%rdi\n" 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "call *%%rax\n" 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(%ebx). 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %%rax,%%rdi\n" 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %3,%%rax\n" 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return to parent. 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "r"(LSS_SYSCALL_ARG(fn)), 1228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "S"(LSS_SYSCALL_ARG(child_stack)), 1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "D"(LSS_SYSCALL_ARG(flags)), 1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "r"(LSS_SYSCALL_ARG(arg)), 1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "d"(LSS_SYSCALL_ARG(parent_tidptr)), 1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "r"(LSS_SYSCALL_ARG(newtls)), 1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "r"(LSS_SYSCALL_ARG(child_tidptr)) 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "rsp", "memory", "r8", "r10", "r11", "rcx"); 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __res); 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On x86-64, the kernel does not know how to return from 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a signal handler. Instead, it relies on user space to provide a 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restorer function that calls the rt_sigreturn() system call. 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unfortunately, we cannot just reference the glibc version of this 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * function, as glibc goes out of its way to make it inaccessible. 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) long long res; 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("call 2f\n" 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:.align 16\n" 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:movq %1,%%rax\n" 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "2:popq %0\n" 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addq $(1b-0b),%0\n" 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (res) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_rt_sigreturn)); 1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (void (*)(void))(uintptr_t)res; 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__arm__) 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Most definitions of _syscallX() neglect to mark "memory" as being 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * clobbered. This causes problems with compilers, that do a better job 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at optimizing across __asm__ calls. 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * So, we just have to redefine all fo the _syscallX() macros. 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_REG 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* r0..r3 are scratch registers and not preserved across function 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * calls. We need to first evaluate the first 4 syscall arguments 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and store them on stack. They must be loaded into r0..r3 after 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all function calls to avoid r0..r3 being clobbered. 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SAVE_ARG 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SAVE_ARG(r,a) long __tmp##r = (long)a 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOAD_ARG 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOAD_ARG(r) register long __r##r __asm__("r"#r) = __tmp##r 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type, name, args...) \ 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register long __res_r0 __asm__("r0"); \ 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __SYS_REG(name) \ 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ (__syscall_safe(name) \ 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=r"(__res_r0) \ 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : __SYS_REG_LIST(args) \ 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "lr", "memory"); \ 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __res = __res_r0; \ 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __res) 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type, name) \ 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)() { \ 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name); \ 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type, name, type1, arg1) \ 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* There is no need for using a volatile temp. */ \ 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(0, arg1); \ 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0)); \ 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type, name, type1, arg1, type2, arg2) \ 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4) \ 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(3, arg4); \ 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(3); \ 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5) \ 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(3, arg4); \ 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg5); \ 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(3); \ 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r4)); \ 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5, type6, arg6) \ 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(3, arg4); \ 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg5); \ 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(5, arg6); \ 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(3); \ 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r4), "r"(__r5)); \ 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register long __res __asm__("r5"); 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fn == NULL || child_stack == NULL) { 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __res = -EINVAL; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto clone_exit; 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* stash first 4 arguments on stack first because we can only load 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * them after all function calls. 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tmp_flags = flags; 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int * tmp_stack = (int*) child_stack; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * tmp_ptid = parent_tidptr; 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * tmp_tls = newtls; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int *__ctid __asm__("r4") = child_tidptr; 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--tmp_stack) = (int) arg; 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--tmp_stack) = (int) fn; 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We must load r0..r3 last after all possible function calls. */ 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int __flags __asm__("r0") = tmp_flags; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__stack __asm__("r1") = tmp_stack; 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__ptid __asm__("r2") = tmp_ptid; 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__tls __asm__("r3") = tmp_tls; 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* %r0 = syscall(%r0 = flags, 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r1 = child_stack, 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r2 = parent_tidptr, 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r3 = newtls, 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r4 = child_tidptr) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __SYS_REG(clone) 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__(/* %r0 = syscall(%r0 = flags, 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r1 = child_stack, 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r2 = parent_tidptr, 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r3 = newtls, 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r4 = child_tidptr) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "push {r7}\n" 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov r7,%1\n" 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __syscall(clone)"\n" 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (%r0 != 0) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return %r0; 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movs %0,r0\n" 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bne 1f\n" 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child, now. Call "fn(arg)". 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ldr r0,[sp, #4]\n" 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov lr,pc\n" 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ldr pc,[sp]\n" 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(%r0), which never returns. We only 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * need to set r7 for EABI syscall ABI but we do 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this always to simplify code sharing between 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * old and new syscall ABIs. 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov r7,%2\n" 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __syscall(exit)"\n" 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pop r7 from the stack only in the parent. 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1: pop {r7}\n" 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=r" (__res) 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "r"(__sysreg), 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "i"(__NR_exit), "r"(__stack), "r"(__flags), 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__ptid), "r"(__tls), "r"(__ctid) 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cc", "lr", "memory"); 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clone_exit: 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __res); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__mips__) 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_REG 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long)(a) 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://sources.redhat.com/ml/libc-alpha/2004-10/msg00050.html 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or http://www.linux-mips.org/archives/linux-mips/2004-10/msg00142.html 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12",\ 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$13", "$14", "$15", "$24", "$25", "memory" 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \ 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$14", "$15", "$24", "$25", "memory" 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type,name,r7,...) \ 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2") = __NR_##name; \ 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ ("syscall\n" \ 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), r7 (__r7) \ 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(__v0), ##__VA_ARGS__ \ 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MIPS_SYSCALL_CLOBBERS); \ 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __v0, __r7) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type, name) \ 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)() { \ 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "=r"); \ 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type, name, type1, arg1) \ 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type, name, type1, arg1, type2, arg2) \ 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); \ 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); \ 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The old 32bit MIPS system call API passes the fifth and sixth argument 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the stack, whereas the new APIs use registers "r8" and "r9". 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); \ 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2"); \ 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ (".set noreorder\n" \ 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $2, %6\n" \ 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu $29, 32\n" \ 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw $2, 16($29)\n" \ 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2, %2\n" \ 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" \ 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addiu $29, 32\n" \ 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".set reorder\n" \ 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), "+r" (__r7) \ 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "r"(__r4), "r"(__r5), \ 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r6), "m" ((unsigned long)arg5) \ 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MIPS_SYSCALL_CLOBBERS); \ 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __v0, __r7); \ 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); LSS_REG(8, arg5); \ 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r8)); \ 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The old 32bit MIPS system call API passes the fifth and sixth argument 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the stack, whereas the new APIs use registers "r8" and "r9". 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); \ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2"); \ 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ (".set noreorder\n" \ 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $2, %6\n" \ 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $8, %7\n" \ 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu $29, 32\n" \ 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw $2, 16($29)\n" \ 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw $8, 20($29)\n" \ 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2, %2\n" \ 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" \ 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addiu $29, 32\n" \ 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".set reorder\n" \ 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), "+r" (__r7) \ 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "r"(__r4), "r"(__r5), \ 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r6), "r" ((unsigned long)arg5), \ 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" ((unsigned long)arg6) \ 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MIPS_SYSCALL_CLOBBERS); \ 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __v0, __r7); \ 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5,type6 arg6) { \ 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r8), "r"(__r9)); \ 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2"); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int __flags __asm__("$4") = flags; 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__stack __asm__("$5") = child_stack; 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__ptid __asm__("$6") = parent_tidptr; 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int *__ctid __asm__("$8") = child_tidptr; 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__( 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu $29,24\n" 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sub $29,16\n" 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dsubu $29,16\n" 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (fn == NULL || child_stack == NULL) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li %0,%2\n" 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "beqz %5,1f\n" 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "beqz %6,1f\n" 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu %6,32\n" 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %5,0(%6)\n" 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %8,4(%6)\n" 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sub %6,32\n" 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %5,0(%6)\n" 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %8,8(%6)\n" 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dsubu %6,32\n" 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sd %5,0(%6)\n" 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sd %8,8(%6)\n" 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* $7 = syscall($4 = flags, 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $5 = child_stack, 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $6 = parent_tidptr, 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $7 = newtls, 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $8 = child_tidptr) 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2,%3\n" 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if ($7 != 0) 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return $2; 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bnez $7,1f\n" 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bnez $2,1f\n" 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child, now. Call "fn(arg)". 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $25,0($29)\n" 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $4,4($29)\n" 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $25,0($29)\n" 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $4,8($29)\n" 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ld $25,0($29)\n" 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ld $4,8($29)\n" 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jalr $25\n" 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit($2) 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "move $4,$2\n" 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2,%4\n" 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addu $29, 24\n" 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "add $29, 16\n" 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "daddu $29,16\n" 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r" (__v0), "=r" (__r7) 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__ptid), "r"(__r7), "r"(__ctid) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "$9", "$10", "$11", "$12", "$13", "$14", "$15", 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$24", "memory"); 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __v0, __r7); 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined (__PPC__) 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_0 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_0(name, dummy...) \ 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_0 = __NR_##name 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_1 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_1(name, arg1) \ 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_0(name); \ 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_3 = (unsigned long) (arg1) 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_2 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_2(name, arg1, arg2) \ 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_1(name, arg1); \ 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_4 = (unsigned long) (arg2) 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_3 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_2(name, arg1, arg2); \ 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_5 = (unsigned long) (arg3) 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_4 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_3(name, arg1, arg2, arg3); \ 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_6 = (unsigned long) (arg4) 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_5 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_7 = (unsigned long) (arg5) 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_6 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_8 = (unsigned long) (arg6) 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_0 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_0 "0" (__sc_0) 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_1 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_2 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_3 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_4 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_5 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_6 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(nr, type, name, args...) \ 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __sc_ret, __sc_err; \ 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { \ 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_0 __asm__ ("r0"); \ 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_3 __asm__ ("r3"); \ 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_4 __asm__ ("r4"); \ 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_5 __asm__ ("r5"); \ 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_6 __asm__ ("r6"); \ 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_7 __asm__ ("r7"); \ 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_8 __asm__ ("r8"); \ 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) \ 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_##nr(name, args); \ 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ \ 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ("sc\n\t" \ 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mfcr %0" \ 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r" (__sc_0), \ 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_3), "=&r" (__sc_4), \ 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_5), "=&r" (__sc_6), \ 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_7), "=&r" (__sc_8) \ 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : LSS_ASMINPUT_##nr \ 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cr0", "ctr", "memory", \ 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r9", "r10", "r11", "r12"); \ 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_ret = __sc_3; \ 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_err = __sc_0; \ 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __sc_ret, __sc_err) 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type, name) \ 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(void) { \ 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(0, type, name); \ 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type, name, type1, arg1) \ 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(1, type, name, arg1); \ 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type, name, type1, arg1, type2, arg2) \ 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(2, type, name, arg1, arg2); \ 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(3, type, name, arg1, arg2, arg3); \ 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4) \ 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5) \ 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5, type6, arg6) \ 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* clone function adapted from glibc 2.3.6 clone.S */ 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO(csilvers): consider wrapping some args up in a struct, like we 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do for i386's _syscall6, so we can compile successfully on gcc 2.95 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __ret, __err; 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int (*__fn)(void *) __asm__ ("r8") = fn; 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__cstack __asm__ ("r4") = child_stack; 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int __flags __asm__ ("r3") = flags; 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void * __arg __asm__ ("r9") = arg; 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int * __ptidptr __asm__ ("r5") = parent_tidptr; 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void * __newtls __asm__ ("r6") = newtls; 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int * __ctidptr __asm__ ("r7") = child_tidptr; 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__( 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* check for fn == NULL 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and child_stack == NULL 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cmpwi cr0, %6, 0\n\t" 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cmpwi cr1, %7, 0\n\t" 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "beq- cr0, 1f\n\t" 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* set up stack frame for child */ 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "clrrwi %7, %7, 4\n\t" 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li 0, 0\n\t" 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stwu 0, -16(%7)\n\t" 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* fn, arg, child_stack are saved across the syscall: r28-30 */ 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 28, %6\n\t" 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 29, %7\n\t" 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 27, %9\n\t" 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* syscall */ 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li 0, %4\n\t" 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* flags already in r3 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * child_stack already in r4 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ptidptr already in r5 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * newtls already in r6 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ctidptr already in r7 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sc\n\t" 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Test if syscall was successful */ 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cmpwi cr1, 3, 0\n\t" 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bne- cr1, 1f\n\t" 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do the function call */ 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mtctr 28\n\t" 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 3, 27\n\t" 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bctrl\n\t" 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(r3) */ 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li 0, %5\n\t" 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sc\n\t" 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return to parent */ 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mfcr %1\n\t" 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr %0, 3\n\t" 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=r" (__ret), "=r" (__err) 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (-1), "1" (EINVAL), 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "i" (__NR_clone), "i" (__NR_exit), 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" (__fn), "r" (__cstack), "r" (__flags), 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" (__arg), "r" (__ptidptr), "r" (__newtls), 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" (__ctidptr) 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cr0", "cr1", "memory", "ctr", 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r0", "r29", "r27", "r28"); 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __ret, __err); 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__exit __NR_exit 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__gettid __NR_gettid 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__mremap __NR_mremap 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(int, close, int, f) 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(int, _exit, int, e) 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, fcntl, int, f, 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, c, long, a) 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, fstat, int, f, 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat*, b) 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, futex, int*, a, 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, o, int, v, 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_timespec*, t) 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, getdents, int, f, 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_dirent*, d, int, c) 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __NR_getdents64 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, getdents64, int, f, 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_dirent64*, d, int, c) 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(pid_t, getpid) 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(pid_t, getppid) 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(pid_t, _gettid) 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, kill, pid_t, p, 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, s) 1884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #if defined(__x86_64__) 1885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Need to make sure off_t isn't truncated to 32-bits under x32. */ 1886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) { 1887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o), 1888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(w)); 1889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #else 1891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_INLINE _syscall3(off_t, lseek, int, f, 1892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) off_t, o, int, w) 1893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) #endif 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, munmap, void*, s, 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l) 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall5(void*, _mremap, void*, o, 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, os, size_t, ns, 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long, f, void *, a) 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, open, const char*, p, 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, m) 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, prctl, int, o, 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long, a) 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(long, ptrace, int, r, 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t, p, void *, a, void *, d) 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(ssize_t, read, int, f, 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *, b, size_t, c) 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, rt_sigaction, int, s, 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigaction*, a, 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction*, o, size_t, c) 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigset_t*, s, 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t*, o, size_t, c); 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(int, sched_yield) 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const stack_t*, o) 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, stat, const char*, f, 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat*, b) 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(ssize_t, write, int, f, 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *, b, size_t, c) 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__NR_getcpu) 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned *, node, void *, unused); 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__x86_64__) || \ 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, socket, int, d, 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, t, int, p) 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__x86_64__) 1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */ 1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, 1932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) __off64_t o) { 1933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l), 1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f), 1935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LSS_SYSCALL_ARG(d), (uint64_t)(o)); 1936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigaction)(int signum, 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigaction *act, 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction *oldact) { 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On x86_64, the kernel requires us to always set our own 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SA_RESTORER in order to be able to return from a signal handler. 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function must have a "magic" signature that the "gdb" 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (and maybe the kernel?) can recognize. 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (act != NULL && !(act->sa_flags & SA_RESTORER)) { 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction a = *act; 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_flags |= SA_RESTORER; 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_restorer = LSS_NAME(restore_rt)(); 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(rt_sigaction)(signum, &a, oldact, 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (KERNEL_NSIG+7)/8); 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(rt_sigaction)(signum, act, oldact, 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (KERNEL_NSIG+7)/8); 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigprocmask)(int how, 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigset_t *set, 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t *oldset) { 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__x86_64__) || \ 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(__arm__) || \ 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int*, s, int, o, 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_rusage*, r) 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){ 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(wait4)(pid, status, options, 0); 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 1974a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__)) && \ 1975a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) !defined(__ANDROID__) 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&set->sig, 0, sizeof(set->sig)); 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&set->sig, -1, sizeof(set->sig)); 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int signum) { 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = EINVAL; 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0]))); 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int signum) { 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = EINVAL; 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0])))); 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || \ 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(__arm__) || \ 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__) 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__sigaction __NR_sigaction 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__sigprocmask __NR_sigprocmask 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, fstat64, int, f, 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat64 *, b) 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loff_t *, res, uint, wh) 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __PPC64__ 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall6(void*, mmap, void*, s, 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l, int, p, 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, d, 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t, o) 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef __ARM_EABI__ 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Not available on ARM EABI Linux. */ 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(void*, mmap, void*, a) 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall6(void*, mmap2, void*, s, 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l, int, p, 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, d, 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t, o) 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, _sigaction, int, s, 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_old_sigaction*, a, 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_old_sigaction*, o) 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, _sigprocmask, int, h, 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned long*, s, 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long*, o) 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, stat64, const char *, p, 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat64 *, b) 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigaction)(int signum, 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigaction *act, 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction *oldact) { 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_errno = LSS_ERRNO; 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction a; 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (act != NULL) { 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a = *act; 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef __i386__ 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On i386, the kernel requires us to always set our own 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SA_RESTORER when using realtime signals. Otherwise, it does not 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * know how to return from a signal handler. This function must have 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a "magic" signature that the "gdb" (and maybe the kernel?) can 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * recognize. 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Apparently, a SA_RESTORER is implicitly set by the kernel, when 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * using non-realtime signals. 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Test whether ARM needs a restorer 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(a.sa_flags & SA_RESTORER)) { 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_flags |= SA_RESTORER; 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_restorer = (a.sa_flags & SA_SIGINFO) 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (KERNEL_NSIG+7)/8); 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc < 0 && LSS_ERRNO == ENOSYS) { 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!act) { 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_a = NULL; 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oa.sa_handler_ = act->sa_handler_; 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef __mips__ 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oa.sa_restorer = act->sa_restorer; 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oa.sa_flags = act->sa_flags; 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!oldact) { 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_oa = NULL; 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = old_errno; 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc == 0 && oldact) { 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (act) { 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(oldact, act, sizeof(*act)); 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(oldact, 0, sizeof(*oldact)); 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldact->sa_handler_ = ptr_oa->sa_handler_; 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldact->sa_flags = ptr_oa->sa_flags; 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef __mips__ 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldact->sa_restorer = ptr_oa->sa_restorer; 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigprocmask)(int how, 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigset_t *set, 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t *oldset) { 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int olderrno = LSS_ERRNO; 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc < 0 && LSS_ERRNO == ENOSYS) { 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = olderrno; 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (oldset) { 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_NAME(sigemptyset)(oldset); 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(_sigprocmask)(how, 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ? &set->sig[0] : NULL, 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldset ? &oldset->sig[0] : NULL); 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__PPC__) 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_0 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_0(dummy...) 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_1 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_1(arg1) \ 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_4 = (unsigned long) (arg1) 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_2 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_2(arg1, arg2) \ 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_1(arg1); \ 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_5 = (unsigned long) (arg2) 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_3 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_2(arg1, arg2); \ 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_6 = (unsigned long) (arg3) 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_4 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_7 = (unsigned long) (arg4) 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_5 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_8 = (unsigned long) (arg5) 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_BODY 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_BODY(nr, type, opt, args...) \ 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __sc_ret, __sc_err; \ 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { \ 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_3 __asm__ ("r3") = opt; \ 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_4 __asm__ ("r4"); \ 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_5 __asm__ ("r5"); \ 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_6 __asm__ ("r6"); \ 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_7 __asm__ ("r7"); \ 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_8 __asm__ ("r8"); \ 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_##nr(args); \ 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ \ 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ("stwu 1, -48(1)\n\t" \ 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 4, 20(1)\n\t" \ 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 5, 24(1)\n\t" \ 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 6, 28(1)\n\t" \ 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 7, 32(1)\n\t" \ 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 8, 36(1)\n\t" \ 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addi 4, 1, 20\n\t" \ 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sc\n\t" \ 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mfcr %0" \ 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r" (__sc_0), \ 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_3), "=&r" (__sc_4), \ 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_5), "=&r" (__sc_6), \ 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_7), "=&r" (__sc_8) \ 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : LSS_ASMINPUT_##nr \ 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cr0", "ctr", "memory"); \ 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_ret = __sc_3; \ 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_err = __sc_0; \ 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __sc_ret, __sc_err) 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_BODY(3, int, 1, domain, type, protocol); 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || \ 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__arm__) && !defined(__ARM_EABI__)) || \ 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See sys_socketcall in net/socket.c in kernel source. 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It de-multiplexes on its first arg and unpacks the arglist 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array in its second arg. 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(long, socketcall, int, c, unsigned long*, a) 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long args[3] = { 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long) domain, 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long) type, 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long) protocol 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(socketcall)(1, args); 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__ARM_EABI__) 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, socket, int, d, 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, t, int, p) 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || defined(__PPC__) || \ 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int*, s, int, o) 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__mips__) 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* sys_pipe() on MIPS has non-standard calling conventions, as it returns 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both file handles through CPU registers. 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(pipe)(int *p) { 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2") = __NR_pipe; 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v1 __asm__("$3"); 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ ("syscall\n" 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), "=&r"(__v1), "+r" (__r7) 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(__v0) 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "$8", "$9", "$10", "$11", "$12", 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$13", "$14", "$15", "$24", "memory"); 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (__r7) { 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = __v0; 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[0] = __v0; 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[1] = __v1; 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(int, pipe, int *, p) 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE pid_t LSS_NAME(gettid)() { 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t tid = LSS_NAME(_gettid)(); 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tid != -1) { 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tid; 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(getpid)(); 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t new_size, int flags, ...) { 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *new_address, *rc; 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start(ap, flags); 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_address = va_arg(ap, void *); 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(_mremap)(old_address, old_size, new_size, 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags, new_address); 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end(ap); 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) { 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* PTRACE_DETACH can sometimes forget to wake up the tracee and it 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then sends job control signals to the real parent, rather than to 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the tracer. We reduce the risk of this happening by starting a 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * whole new time slice, and then quickly sending a SIGCONT signal 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * right after detaching from the tracee. 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc, err; 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_NAME(sched_yield)(); 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = LSS_ERRNO; 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_NAME(kill)(pid, SIGCONT); 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = err; 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2279