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> 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/ptrace.h> 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h> 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <syscall.h> 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <linux/unistd.h> 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <endian.h> 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Include definitions of the ABI currently in use. */ 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sgidefs.h> 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* As glibc often provides subtly incompatible data structures (and implicit 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * wrapper functions that convert them), we provide our own kernel data 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * structures for use by the system calls. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These structures have been developed by using Linux 2.6.23 headers for 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reference. Note though, we do not care about exact API compatibility 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with the kernel, and in fact the kernel often does not have a single 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * API that works across architectures. Instead, we try to mimic the glibc 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * API where reasonable, and only guarantee ABI compatibility with the 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * kernel headers. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Most notably, here are a few changes that were made to the structures 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * defined by kernel headers: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - we only define structures, but not symbolic names for kernel data 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * types. For the latter, we directly use the native C datatype 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (i.e. "unsigned" instead of "mode_t"). 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - in a few cases, it is possible to define identical structures for 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * standardizing on the 64bit version of the data types. In particular, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this means that we use "unsigned" where the 32bit headers say 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "unsigned long". 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - overall, we try to minimize the number of cases where we need to 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * conditionally define different structures. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - the "struct kernel_sigaction" class of structures have been 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modified to more closely mimic glibc's API by introducing an 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * anonymous union for the function pointer. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - a small number of field names had to have an underscore appended to 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * them, because glibc defines a global macro by the same name. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/dirent.h */ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_dirent64 { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long d_ino; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long d_off; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short d_reclen; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char d_type; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char d_name[256]; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/dirent.h */ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_dirent { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long d_ino; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long d_off; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short d_reclen; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char d_name[256]; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/time.h */ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_timespec { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_sec; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_nsec; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/time.h */ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_timeval { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_sec; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long tv_usec; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/linux/resource.h */ 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_rusage { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_timeval ru_utime; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_timeval ru_stime; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_maxrss; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_ixrss; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_idrss; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_isrss; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_minflt; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_majflt; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nswap; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_inblock; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_oublock; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_msgsnd; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_msgrcv; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nsignals; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nvcsw; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long ru_nivcsw; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__i386__) || defined(__arm__) || defined(__PPC__) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,ppc}/signal.h */ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_old_sigaction { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_handler_)(int); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void (*sa_sigaction_)(int, siginfo_t *, void *); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_mask; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_flags; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_restorer)(void); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} __attribute__((packed,aligned(4))); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define kernel_old_sigaction kernel_sigaction 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exactly match the size of the signal set, even though the API was 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * intended to be extensible. We define our own KERNEL_NSIG to deal with 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Please note that glibc provides signals [1.._NSIG-1], whereas the 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * kernel (and this header) provides the range [1..KERNEL_NSIG]. The 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * actual number of signals is obviously the same, but the constants 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * differ by one. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KERNEL_NSIG 128 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KERNEL_NSIG 64 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,x86_64}/signal.h */ 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_sigset_t { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (8*sizeof(unsigned long))]; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_sigaction { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_flags; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_handler_)(int); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void (*sa_sigaction_)(int, siginfo_t *, void *); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t sa_mask; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_handler_)(int); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void (*sa_sigaction_)(int, siginfo_t *, void *); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long sa_flags; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*sa_restorer)(void); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t sa_mask; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,ppc}/stat.h */ 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __mips__ 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if _MIPS_SIM == _MIPS_SIM_ABI64 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat64 { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_dev; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad0[3]; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_ino; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_rdev; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad1[3]; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_size; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_nsec_; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_nsec_; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_nsec_; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blksize; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad2; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_blocks; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined __PPC__ 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat64 { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_dev; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_ino; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_rdev; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short int __pad2; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_size; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_blksize; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_blocks; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_atime_; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_nsec_; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_mtime_; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_nsec_; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_ctime_; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_nsec_; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused4; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused5; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat64 { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_dev; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char __pad0[4]; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __st_ino; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_rdev; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char __pad3[4]; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long st_size; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blksize; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_blocks; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_nsec_; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_nsec_; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_nsec_; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long st_ino; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */ 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__i386__) || defined(__arm__) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The kernel headers suggest that st_dev and st_rdev should be 32bit 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * quantities encoding 12bit major and 20bit minor numbers in an interleaved 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * format. In reality, we do not see useful data in the top bits. So, 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we'll leave the padding in here, until we find a better solution. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_dev; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) short pad1; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ino; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_mode; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_nlink; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_uid; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_gid; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_rdev; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) short pad2; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_size; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blksize; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_blocks; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_atime_nsec_; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mtime_nsec_; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ctime_nsec_; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __unused4; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __unused5; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__x86_64__) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_dev; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ino; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_nlink; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned __pad0; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_rdev; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_size; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_blksize; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_blocks; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_nsec_; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_nsec_; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_nsec_; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __unused[3]; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__PPC__) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_dev; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ino; // ino_t 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mode; // mode_t 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned short st_nlink; // nlink_t 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; // uid_t 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; // gid_t 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_rdev; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_size; // off_t 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_blksize; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_blocks; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_atime_nsec_; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_mtime_nsec_; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long st_ctime_nsec_; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused4; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long __unused5; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct kernel_stat { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_dev; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad1[3]; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_ino; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_mode; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_nlink; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_uid; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_gid; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned st_rdev; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad2[2]; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_size; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad3; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_atime_; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_atime_nsec_; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_mtime_; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_mtime_nsec_; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_ctime_; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long st_ctime_nsec_; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_blksize; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_blocks; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int st_pad4[14]; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Definitions missing from the standard header files */ 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef O_DIRECTORY 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__arm__) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_DIRECTORY 0040000 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_DIRECTORY 0200000 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PR_GET_DUMPABLE 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PR_GET_DUMPABLE 3 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PR_SET_DUMPABLE 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PR_SET_DUMPABLE 4 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef AT_FDCWD 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AT_FDCWD (-100) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef AT_SYMLINK_NOFOLLOW 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AT_SYMLINK_NOFOLLOW 0x100 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef AT_REMOVEDIR 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AT_REMOVEDIR 0x200 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MREMAP_FIXED 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MREMAP_FIXED 2 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SA_RESTORER 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SA_RESTORER 0x04000000 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__i386__) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction 174 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask 175 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 195 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 197 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 220 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid 224 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex 240 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat 295 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu 318 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of i386 definitions */ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__arm__) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __syscall 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__thumb__) || defined(__ARM_EABI__) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG(name) register long __sysreg __asm__("r6") = __NR_##name; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG_LIST(regs...) [sysreg] "r" (__sysreg) , ##regs 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall(name) "swi\t0" 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall_safe(name) \ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "push {r7}\n" \ 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov r7,%[sysreg]\n" \ 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __syscall(name)"\n" \ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop {r7}" 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG(name) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __SYS_REG_LIST(regs...) regs 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall(name) "swi\t" __sys1(__NR_##name) "" 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __syscall_safe(name) __syscall(name) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 (__NR_SYSCALL_BASE + 195) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 (__NR_SYSCALL_BASE + 197) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 (__NR_SYSCALL_BASE + 217) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_SYSCALL_BASE + 224) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_SYSCALL_BASE + 240) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of ARM definitions */ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__x86_64__) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid 186 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex 202 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 217 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat 257 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of x86-64 definitions */ 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__mips__) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if _MIPS_SIM == _MIPS_SIM_ABI32 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction (__NR_Linux + 194) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask (__NR_Linux + 195) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 (__NR_Linux + 213) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 (__NR_Linux + 215) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 (__NR_Linux + 219) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_Linux + 222) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_Linux + 238) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat (__NR_Linux + 288) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstatat 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstatat (__NR_Linux + 293) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu (__NR_Linux + 312) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS (old 32bit API) definitions */ 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif _MIPS_SIM == _MIPS_SIM_ABI64 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_Linux + 178) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_Linux + 194) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat (__NR_Linux + 247) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstatat 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstatat (__NR_Linux + 252) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu (__NR_Linux + 271) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS (64bit API) definitions */ 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid (__NR_Linux + 178) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex (__NR_Linux + 194) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat (__NR_Linux + 251) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstatat 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstatat (__NR_Linux + 256) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu (__NR_Linux + 275) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS (new 32bit API) definitions */ 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of MIPS definitions */ 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__PPC__) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_rt_sigaction 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigaction 173 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_rt_sigprocmask 174 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_stat64 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_stat64 195 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_fstat64 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_fstat64 197 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getdents64 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getdents64 202 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_gettid 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_gettid 207 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_futex 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_futex 221 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_openat 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_openat 286 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __NR_getcpu 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __NR_getcpu 302 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* End of powerpc defininitions */ 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* After forking, we must make sure to only call system calls. */ 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __BOUNDED_POINTERS__ 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #error "Need to port invocations of syscalls for bounded ptrs" 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The core dumper and the thread lister get executed after threads 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * have been suspended. As a consequence, we cannot call any functions 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that acquire locks. Unfortunately, libc wraps most system calls 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (e.g. in order to implement pthread_atfork, and to make calls 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cancellable), which means we cannot call these functions. Instead, 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we have to call syscall() directly. 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ERRNO 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef SYS_ERRNO 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allow the including file to override the location of errno. This can 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be useful when using clone() with the CLONE_VM option. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ERRNO SYS_ERRNO 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ERRNO errno 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_INLINE 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef SYS_INLINE 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_INLINE SYS_INLINE 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_INLINE static inline 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allow the including file to override the prefix used for all new 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * system calls. By default, it will be set to "sys_". 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_NAME 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef SYS_PREFIX 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys_##name 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX < 0 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) name 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 0 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys0_##name 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 1 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys1_##name 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 2 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys2_##name 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 3 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys3_##name 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 4 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys4_##name 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 5 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys5_##name 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 6 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys6_##name 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 7 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys7_##name 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 8 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys8_##name 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif SYS_PREFIX == 9 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_NAME(name) sys9_##name 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_RETURN 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__)) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Failing system calls return a negative result in the range of 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -1..-4095. These are "errno" values with the sign inverted. 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_RETURN(type, res) \ 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = -(res); \ 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = -1; \ 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (type) (res); \ 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__mips__) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On MIPS, failing system calls return -1, and set errno in a 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * separate CPU register. 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_RETURN(type, res, err) \ 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { \ 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(__PPC__) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On PPC, failing system calls return -1, and set errno in a 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * separate CPU register. See linux/unistd.h. 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_RETURN(type, res, err) \ 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err & 0x10000000 ) { \ 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) #endif 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(NO_FRAME_POINTER) && (100 * __GNUC__ + __GNUC_MINOR__ >= 404) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This only works for GCC-4.4 and above -- the first version to use 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .cfi directives for dwarf unwind info. */ 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define CFI_ADJUST_CFA_OFFSET(adjust) \ 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".cfi_adjust_cfa_offset " #adjust "\n" 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define CFI_ADJUST_CFA_OFFSET(adjust) /**/ 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In PIC mode (e.g. when building shared libraries), gcc for i386 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reserves ebx. Unfortunately, most distribution ship with implementations 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of _syscallX() which clobber ebx. 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Also, most definitions of _syscallX() neglect to mark "memory" as being 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * clobbered. This causes problems with compilers, that do a better job 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at optimizing across __asm__ calls. 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * So, we just have to redefine all of the _syscallX() macros. 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type,args...) \ 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("push %%ebx\n" \ 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFI_ADJUST_CFA_OFFSET(4) \ 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %2,%%ebx\n" \ 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" \ 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebx\n" \ 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFI_ADJUST_CFA_OFFSET(-4) \ 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args \ 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory"); \ 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type,name) \ 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(void) { \ 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ volatile("int $0x80" \ 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name) \ 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "memory"); \ 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res); \ 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type,name,type1,arg1) \ 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name), "ri" ((long)(arg1))); \ 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type,name,type1,arg1,type2,arg2) \ 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1,type2 arg2) { \ 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "d" ((long)(arg3))); \ 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, \ 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "d" ((long)(arg3)),"S" ((long)(arg4))); \ 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("push %%ebx\n" \ 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %2,%%ebx\n" \ 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %1,%%eax\n" \ 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" \ 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebx" \ 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "ri" ((long)(arg1)), \ 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "c" ((long)(arg2)), "d" ((long)(arg3)), \ 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "S" ((long)(arg4)), "D" ((long)(arg5)) \ 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory"); \ 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res); \ 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("push %%ebp\n" \ 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "push %%ebx\n" \ 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl 4(%2),%%ebp\n" \ 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl 0(%2), %%ebx\n" \ 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %1,%%eax\n" \ 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" \ 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebx\n" \ 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pop %%ebp" \ 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) \ 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "0" ((long)(&__s)), \ 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "c" ((long)(arg2)), "d" ((long)(arg3)), \ 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "S" ((long)(arg4)), "D" ((long)(arg5)) \ 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory"); \ 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type,__res); \ 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__(/* if (fn == NULL) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %3,%%ecx\n" 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jecxz 1f\n" 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (child_stack == NULL) 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %4,%%ecx\n" 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jecxz 1f\n" 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set up alignment of the child stack: 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * child_stack = (child_stack & ~0xF) - 20; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "andl $-16,%%ecx\n" 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subl $20,%%ecx\n" 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %6,%%eax\n" 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,4(%%ecx)\n" 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %3,%%eax\n" 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,(%%ecx)\n" 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* %eax = syscall(%eax = __NR_clone, 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %ebx = flags, 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %ecx = child_stack, 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %edx = parent_tidptr, 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %esi = newtls, 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %edi = child_tidptr) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Also, make sure that %ebx gets preserved as it is 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used in PIC mode. 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %8,%%esi\n" 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %7,%%edx\n" 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %5,%%eax\n" 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %9,%%edi\n" 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pushl %%ebx\n" 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,%%ebx\n" 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %2,%%eax\n" 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the parent: restore %ebx 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the child: move "fn" into %ebx 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "popl %%ebx\n" 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (%eax != 0) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return %eax; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "test %%eax,%%eax\n" 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jnz 1f\n" 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child, now. Terminate frame pointer chain. 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl $0,%%ebp\n" 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call "fn". "arg" is already on the stack. 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "call *%%ebx\n" 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(%ebx). Unfortunately older versions 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of gcc restrict the number of arguments that can 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * be passed to asm(). So, we need to hard-code the 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * system call number. 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %%eax,%%ebx\n" 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl $1,%%eax\n" 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return to parent. 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(-EINVAL), "i"(__NR_clone), 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "esp", "memory", "ecx", "edx", "esi", "edi"); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __res); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On i386, the kernel does not know how to return from a signal 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * handler. Instead, it relies on user space to provide a 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restorer function that calls the {rt_,}sigreturn() system call. 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unfortunately, we cannot just reference the glibc version of this 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * function, as glibc goes out of its way to make it inaccessible. 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*res)(void); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("call 2f\n" 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:.align 16\n" 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:movl %1,%%eax\n" 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "2:popl %0\n" 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addl $(1b-0b),%0\n" 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (res) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_rt_sigreturn)); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void (*LSS_NAME(restore)(void))(void) { 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On i386, the kernel does not know how to return from a signal 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * handler. Instead, it relies on user space to provide a 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restorer function that calls the {rt_,}sigreturn() system call. 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unfortunately, we cannot just reference the glibc version of this 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * function, as glibc goes out of its way to make it inaccessible. 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*res)(void); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("call 2f\n" 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:.align 16\n" 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:pop %%eax\n" 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movl %1,%%eax\n" 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $0x80\n" 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "2:popl %0\n" 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addl $(1b-0b),%0\n" 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (res) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_sigreturn)); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__x86_64__) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* There are no known problems with any of the _syscallX() macros 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * currently shipping for x86_64, but we still need to be able to define 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * our own version so that we can override the location of the errno 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * location (e.g. when using the clone() system call with the CLONE_VM 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * option). 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type,name, ...) \ 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("syscall" : "=a" (__res) : "0" (__NR_##name), \ 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ##__VA_ARGS__ : "r11", "rcx", "memory"); \ 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __res) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type,name) \ 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)() { \ 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name); \ 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type,name,type1,arg1) \ 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "D" ((long)(arg1))); \ 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type,name,type1,arg1,type2,arg2) \ 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "d" ((long)(arg3))); \ 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("movq %5,%%r10; syscall" : \ 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=a" (__res) : "0" (__NR_##name), \ 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \ 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __res); \ 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; syscall" : \ 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=a" (__res) : "0" (__NR_##name), \ 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" ((long)(arg4)), "r" ((long)(arg5)) : \ 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r8", "r10", "r11", "rcx", "memory"); \ 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __res); \ 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall" : \ 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=a" (__res) : "0" (__NR_##name), \ 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" ((long)(arg4)), "r" ((long)(arg5)), "r" ((long)(arg6)) : \ 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r8", "r9", "r10", "r11", "rcx", "memory"); \ 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __res); \ 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__(/* if (fn == NULL) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "testq %4,%4\n" 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jz 1f\n" 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (child_stack == NULL) 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "testq %5,%5\n" 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jz 1f\n" 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set up alignment of the child stack: 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * child_stack = (child_stack & ~0xF) - 16; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "andq $-16,%5\n" 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subq $16,%5\n" 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %7,8(%5)\n" 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %4,0(%5)\n" 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* %rax = syscall(%rax = __NR_clone, 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %rdi = flags, 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %rsi = child_stack, 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %rdx = parent_tidptr, 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r8 = new_tls, 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r10 = child_tidptr) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %2,%%rax\n" 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %9,%%r8\n" 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %10,%%r10\n" 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (%rax != 0) 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return; 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "testq %%rax,%%rax\n" 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jnz 1f\n" 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child. Terminate frame pointer chain. 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xorq %%rbp,%%rbp\n" 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call "fn(arg)". 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "popq %%rax\n" 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "popq %%rdi\n" 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "call *%%rax\n" 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(%ebx). 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %%rax,%%rdi\n" 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movq %3,%%rax\n" 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return to parent. 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (__res) 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "d"(parent_tidptr), "g"(newtls), "g"(child_tidptr) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "rsp", "memory", "r8", "r10", "r11", "rcx"); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __res); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On x86-64, the kernel does not know how to return from 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a signal handler. Instead, it relies on user space to provide a 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * restorer function that calls the rt_sigreturn() system call. 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unfortunately, we cannot just reference the glibc version of this 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * function, as glibc goes out of its way to make it inaccessible. 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*res)(void); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__("call 2f\n" 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:.align 16\n" 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:movq %1,%%rax\n" 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "2:popq %0\n" 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addq $(1b-0b),%0\n" 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=a" (res) 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_rt_sigreturn)); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return res; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__arm__) 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Most definitions of _syscallX() neglect to mark "memory" as being 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * clobbered. This causes problems with compilers, that do a better job 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at optimizing across __asm__ calls. 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * So, we just have to redefine all fo the _syscallX() macros. 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_REG 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* r0..r3 are scratch registers and not preserved across function 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * calls. We need to first evaluate the first 4 syscall arguments 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and store them on stack. They must be loaded into r0..r3 after 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all function calls to avoid r0..r3 being clobbered. 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SAVE_ARG 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SAVE_ARG(r,a) long __tmp##r = (long)a 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOAD_ARG 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOAD_ARG(r) register long __r##r __asm__("r"#r) = __tmp##r 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type, name, args...) \ 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register long __res_r0 __asm__("r0"); \ 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __res; \ 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __SYS_REG(name) \ 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ (__syscall_safe(name) \ 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=r"(__res_r0) \ 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : __SYS_REG_LIST(args) \ 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "lr", "memory"); \ 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __res = __res_r0; \ 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __res) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type, name) \ 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)() { \ 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name); \ 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type, name, type1, arg1) \ 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* There is no need for using a volatile temp. */ \ 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(0, arg1); \ 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0)); \ 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type, name, type1, arg1, type2, arg2) \ 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4) \ 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(3, arg4); \ 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(3); \ 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5) \ 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(3, arg4); \ 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg5); \ 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(3); \ 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r4)); \ 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5, type6, arg6) \ 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(0, arg1); \ 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(1, arg2); \ 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(2, arg3); \ 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SAVE_ARG(3, arg4); \ 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg5); \ 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(5, arg6); \ 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(0); \ 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(1); \ 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(2); \ 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOAD_ARG(3); \ 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r4), "r"(__r5)); \ 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register long __res __asm__("r5"); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fn == NULL || child_stack == NULL) { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __res = -EINVAL; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto clone_exit; 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* stash first 4 arguments on stack first because we can only load 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * them after all function calls. 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tmp_flags = flags; 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int * tmp_stack = (int*) child_stack; 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * tmp_ptid = parent_tidptr; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void * tmp_tls = newtls; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int *__ctid __asm__("r4") = child_tidptr; 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--tmp_stack) = (int) arg; 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(--tmp_stack) = (int) fn; 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We must load r0..r3 last after all possible function calls. */ 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int __flags __asm__("r0") = tmp_flags; 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__stack __asm__("r1") = tmp_stack; 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__ptid __asm__("r2") = tmp_ptid; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__tls __asm__("r3") = tmp_tls; 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* %r0 = syscall(%r0 = flags, 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r1 = child_stack, 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r2 = parent_tidptr, 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r3 = newtls, 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r4 = child_tidptr) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __SYS_REG(clone) 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__(/* %r0 = syscall(%r0 = flags, 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r1 = child_stack, 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r2 = parent_tidptr, 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r3 = newtls, 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %r4 = child_tidptr) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "push {r7}\n" 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov r7,%1\n" 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __syscall(clone)"\n" 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (%r0 != 0) 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return %r0; 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "movs %0,r0\n" 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bne 1f\n" 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child, now. Call "fn(arg)". 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ldr r0,[sp, #4]\n" 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov lr,pc\n" 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ldr pc,[sp]\n" 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(%r0), which never returns. We only 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * need to set r7 for EABI syscall ABI but we do 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this always to simplify code sharing between 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * old and new syscall ABIs. 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mov r7,%2\n" 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __syscall(exit)"\n" 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pop r7 from the stack only in the parent. 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1: pop {r7}\n" 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=r" (__res) 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "r"(__sysreg), 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "i"(__NR_exit), "r"(__stack), "r"(__flags), 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__ptid), "r"(__tls), "r"(__ctid) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cc", "lr", "memory"); 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clone_exit: 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __res); 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__mips__) 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_REG 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long)(a) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://sources.redhat.com/ml/libc-alpha/2004-10/msg00050.html 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or http://www.linux-mips.org/archives/linux-mips/2004-10/msg00142.html 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12",\ 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$13", "$14", "$15", "$24", "$25", "memory" 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \ 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$14", "$15", "$24", "$25", "memory" 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(type,name,r7,...) \ 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2") = __NR_##name; \ 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ ("syscall\n" \ 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), r7 (__r7) \ 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(__v0), ##__VA_ARGS__ \ 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MIPS_SYSCALL_CLOBBERS); \ 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __v0, __r7) 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type, name) \ 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)() { \ 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "=r"); \ 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type, name, type1, arg1) \ 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type, name, type1, arg1, type2, arg2) \ 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); \ 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); \ 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); \ 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The old 32bit MIPS system call API passes the fifth and sixth argument 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the stack, whereas the new APIs use registers "r8" and "r9". 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); \ 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2"); \ 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ (".set noreorder\n" \ 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $2, %6\n" \ 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu $29, 32\n" \ 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw $2, 16($29)\n" \ 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2, %2\n" \ 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" \ 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addiu $29, 32\n" \ 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".set reorder\n" \ 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), "+r" (__r7) \ 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "r"(__r4), "r"(__r5), \ 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r6), "m" ((unsigned long)arg5) \ 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MIPS_SYSCALL_CLOBBERS); \ 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __v0, __r7); \ 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5) \ 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); LSS_REG(8, arg5); \ 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r8)); \ 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The old 32bit MIPS system call API passes the fifth and sixth argument 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the stack, whereas the new APIs use registers "r8" and "r9". 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); \ 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2"); \ 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ (".set noreorder\n" \ 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $2, %6\n" \ 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $8, %7\n" \ 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu $29, 32\n" \ 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw $2, 16($29)\n" \ 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw $8, 20($29)\n" \ 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2, %2\n" \ 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" \ 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addiu $29, 32\n" \ 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".set reorder\n" \ 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), "+r" (__r7) \ 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i" (__NR_##name), "r"(__r4), "r"(__r5), \ 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r6), "r" ((unsigned long)arg5), \ 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" ((unsigned long)arg6) \ 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MIPS_SYSCALL_CLOBBERS); \ 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __v0, __r7); \ 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5,arg5,type6,arg6) \ 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5,type6 arg6) { \ 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__r8), "r"(__r9)); \ 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2"); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int __flags __asm__("$4") = flags; 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__stack __asm__("$5") = child_stack; 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__ptid __asm__("$6") = parent_tidptr; 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int *__ctid __asm__("$8") = child_tidptr; 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__( 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu $29,24\n" 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sub $29,16\n" 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dsubu $29,16\n" 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if (fn == NULL || child_stack == NULL) 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return -EINVAL; 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li %0,%2\n" 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "beqz %5,1f\n" 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "beqz %6,1f\n" 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Push "arg" and "fn" onto the stack that will be 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used by the child. 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "subu %6,32\n" 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %5,0(%6)\n" 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %8,4(%6)\n" 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sub %6,32\n" 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %5,0(%6)\n" 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sw %8,8(%6)\n" 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dsubu %6,32\n" 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sd %5,0(%6)\n" 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sd %8,8(%6)\n" 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* $7 = syscall($4 = flags, 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $5 = child_stack, 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $6 = parent_tidptr, 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $7 = newtls, 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * $8 = child_tidptr) 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2,%3\n" 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if ($7 != 0) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * return $2; 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bnez $7,1f\n" 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bnez $2,1f\n" 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In the child, now. Call "fn(arg)". 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $25,0($29)\n" 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $4,4($29)\n" 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $25,0($29)\n" 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lw $4,8($29)\n" 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ld $25,0($29)\n" 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ld $4,8($29)\n" 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "jalr $25\n" 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit($2) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "move $4,$2\n" 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li $2,%4\n" 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syscall\n" 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addu $29, 24\n" 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif _MIPS_SIM == _MIPS_SIM_NABI32 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "add $29, 16\n" 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "daddu $29,16\n" 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r" (__v0), "=r" (__r7) 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r"(__ptid), "r"(__r7), "r"(__ctid) 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "$9", "$10", "$11", "$12", "$13", "$14", "$15", 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$24", "memory"); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __v0, __r7); 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined (__PPC__) 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_0 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_0(name, dummy...) \ 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_0 = __NR_##name 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_1 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_1(name, arg1) \ 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_0(name); \ 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_3 = (unsigned long) (arg1) 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_2 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_2(name, arg1, arg2) \ 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_1(name, arg1); \ 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_4 = (unsigned long) (arg2) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_3 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_2(name, arg1, arg2); \ 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_5 = (unsigned long) (arg3) 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_4 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_3(name, arg1, arg2, arg3); \ 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_6 = (unsigned long) (arg4) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_5 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_7 = (unsigned long) (arg5) 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_LOADARGS_6 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_8 = (unsigned long) (arg6) 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_0 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_0 "0" (__sc_0) 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_1 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_2 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_3 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_4 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_5 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_ASMINPUT_6 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_BODY 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_BODY(nr, type, name, args...) \ 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __sc_ret, __sc_err; \ 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { \ 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_0 __asm__ ("r0"); \ 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_3 __asm__ ("r3"); \ 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_4 __asm__ ("r4"); \ 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_5 __asm__ ("r5"); \ 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_6 __asm__ ("r6"); \ 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_7 __asm__ ("r7"); \ 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_8 __asm__ ("r8"); \ 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) \ 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_LOADARGS_##nr(name, args); \ 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ \ 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ("sc\n\t" \ 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mfcr %0" \ 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r" (__sc_0), \ 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_3), "=&r" (__sc_4), \ 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_5), "=&r" (__sc_6), \ 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_7), "=&r" (__sc_8) \ 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : LSS_ASMINPUT_##nr \ 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cr0", "ctr", "memory", \ 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r9", "r10", "r11", "r12"); \ 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_ret = __sc_3; \ 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_err = __sc_0; \ 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __sc_ret, __sc_err) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall0 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall0(type, name) \ 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(void) { \ 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(0, type, name); \ 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall1 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall1(type, name, type1, arg1) \ 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1) { \ 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(1, type, name, arg1); \ 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall2 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall2(type, name, type1, arg1, type2, arg2) \ 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2) { \ 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(2, type, name, arg1, arg2); \ 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall3 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(3, type, name, arg1, arg2, arg3); \ 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall4 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4) \ 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall5 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5) \ 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5) { \ 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef _syscall6 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type4, arg4, type5, arg5, type6, arg6) \ 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type5 arg5, type6 arg6) { \ 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* clone function adapted from glibc 2.3.6 clone.S */ 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO(csilvers): consider wrapping some args up in a struct, like we 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do for i386's _syscall6, so we can compile successfully on gcc 2.95 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, void *arg, int *parent_tidptr, 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *newtls, int *child_tidptr) { 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __ret, __err; 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int (*__fn)(void *) __asm__ ("r8") = fn; 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void *__cstack __asm__ ("r4") = child_stack; 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int __flags __asm__ ("r3") = flags; 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void * __arg __asm__ ("r9") = arg; 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int * __ptidptr __asm__ ("r5") = parent_tidptr; 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register void * __newtls __asm__ ("r6") = newtls; 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int * __ctidptr __asm__ ("r7") = child_tidptr; 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__( 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* check for fn == NULL 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and child_stack == NULL 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cmpwi cr0, %6, 0\n\t" 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cmpwi cr1, %7, 0\n\t" 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "beq- cr0, 1f\n\t" 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* set up stack frame for child */ 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "clrrwi %7, %7, 4\n\t" 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li 0, 0\n\t" 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stwu 0, -16(%7)\n\t" 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* fn, arg, child_stack are saved across the syscall: r28-30 */ 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 28, %6\n\t" 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 29, %7\n\t" 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 27, %9\n\t" 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* syscall */ 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li 0, %4\n\t" 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* flags already in r3 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * child_stack already in r4 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ptidptr already in r5 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * newtls already in r6 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ctidptr already in r7 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sc\n\t" 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Test if syscall was successful */ 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cmpwi cr1, 3, 0\n\t" 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bne- cr1, 1f\n\t" 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do the function call */ 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mtctr 28\n\t" 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr 3, 27\n\t" 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bctrl\n\t" 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Call _exit(r3) */ 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "li 0, %5\n\t" 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sc\n\t" 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Return to parent */ 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1:\n" 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mfcr %1\n\t" 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mr %0, 3\n\t" 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=r" (__ret), "=r" (__err) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0" (-1), "1" (EINVAL), 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "i" (__NR_clone), "i" (__NR_exit), 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" (__fn), "r" (__cstack), "r" (__flags), 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" (__arg), "r" (__ptidptr), "r" (__newtls), 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r" (__ctidptr) 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cr0", "cr1", "memory", "ctr", 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "r0", "r29", "r27", "r28"); 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(int, __ret, __err); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__exit __NR_exit 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__gettid __NR_gettid 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__mremap __NR_mremap 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(int, close, int, f) 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(int, _exit, int, e) 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, fcntl, int, f, 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, c, long, a) 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, fstat, int, f, 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat*, b) 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, futex, int*, a, 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, o, int, v, 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_timespec*, t) 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, getdents, int, f, 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_dirent*, d, int, c) 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __NR_getdents64 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, getdents64, int, f, 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_dirent64*, d, int, c) 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(pid_t, getpid) 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(pid_t, getppid) 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(pid_t, _gettid) 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, kill, pid_t, p, 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, s) 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(off_t, lseek, int, f, 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t, o, int, w) 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, munmap, void*, s, 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l) 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall5(void*, _mremap, void*, o, 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, os, size_t, ns, 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long, f, void *, a) 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, open, const char*, p, 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, m) 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, prctl, int, o, 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long, a) 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(long, ptrace, int, r, 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t, p, void *, a, void *, d) 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(ssize_t, read, int, f, 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *, b, size_t, c) 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, rt_sigaction, int, s, 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigaction*, a, 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction*, o, size_t, c) 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigset_t*, s, 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t*, o, size_t, c); 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall0(int, sched_yield) 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const stack_t*, o) 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, stat, const char*, f, 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat*, b) 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(ssize_t, write, int, f, 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *, b, size_t, c) 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__NR_getcpu) 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned *, node, void *, unused); 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__x86_64__) || \ 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, socket, int, d, 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, t, int, p) 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__x86_64__) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall6(void*, mmap, void*, s, 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l, int, p, 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, d, 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __off64_t, o) 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigaction)(int signum, 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigaction *act, 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction *oldact) { 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On x86_64, the kernel requires us to always set our own 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SA_RESTORER in order to be able to return from a signal handler. 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function must have a "magic" signature that the "gdb" 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (and maybe the kernel?) can recognize. 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (act != NULL && !(act->sa_flags & SA_RESTORER)) { 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction a = *act; 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_flags |= SA_RESTORER; 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_restorer = LSS_NAME(restore_rt)(); 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(rt_sigaction)(signum, &a, oldact, 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (KERNEL_NSIG+7)/8); 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(rt_sigaction)(signum, act, oldact, 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (KERNEL_NSIG+7)/8); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigprocmask)(int how, 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigset_t *set, 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t *oldset) { 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__x86_64__) || \ 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(__arm__) || \ 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int*, s, int, o, 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_rusage*, r) 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){ 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(wait4)(pid, status, options, 0); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&set->sig, 0, sizeof(set->sig)); 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&set->sig, -1, sizeof(set->sig)); 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int signum) { 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = EINVAL; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0]))); 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int signum) { 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (signum < 1 || signum > (int)(8*sizeof(set->sig))) { 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = EINVAL; 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0])))); 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || \ 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(__arm__) || \ 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__) 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__sigaction __NR_sigaction 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define __NR__sigprocmask __NR_sigprocmask 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, fstat64, int, f, 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat64 *, b) 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loff_t *, res, uint, wh) 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __PPC64__ 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall6(void*, mmap, void*, s, 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l, int, p, 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, d, 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t, o) 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef __ARM_EABI__ 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Not available on ARM EABI Linux. */ 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(void*, mmap, void*, a) 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall6(void*, mmap2, void*, s, 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t, l, int, p, 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, f, int, d, 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t, o) 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, _sigaction, int, s, 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_old_sigaction*, a, 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_old_sigaction*, o) 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, _sigprocmask, int, h, 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned long*, s, 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long*, o) 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(int, stat64, const char *, p, 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_stat64 *, b) 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigaction)(int signum, 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigaction *act, 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction *oldact) { 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_errno = LSS_ERRNO; 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigaction a; 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (act != NULL) { 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a = *act; 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifdef __i386__ 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* On i386, the kernel requires us to always set our own 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SA_RESTORER when using realtime signals. Otherwise, it does not 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * know how to return from a signal handler. This function must have 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a "magic" signature that the "gdb" (and maybe the kernel?) can 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * recognize. 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Apparently, a SA_RESTORER is implicitly set by the kernel, when 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * using non-realtime signals. 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Test whether ARM needs a restorer 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(a.sa_flags & SA_RESTORER)) { 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_flags |= SA_RESTORER; 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.sa_restorer = (a.sa_flags & SA_SIGINFO) 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (KERNEL_NSIG+7)/8); 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc < 0 && LSS_ERRNO == ENOSYS) { 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!act) { 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_a = NULL; 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oa.sa_handler_ = act->sa_handler_; 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef __mips__ 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oa.sa_restorer = act->sa_restorer; 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oa.sa_flags = act->sa_flags; 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!oldact) { 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_oa = NULL; 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = old_errno; 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc == 0 && oldact) { 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (act) { 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(oldact, act, sizeof(*act)); 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(oldact, 0, sizeof(*oldact)); 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldact->sa_handler_ = ptr_oa->sa_handler_; 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldact->sa_flags = ptr_oa->sa_flags; 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #ifndef __mips__ 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldact->sa_restorer = ptr_oa->sa_restorer; 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(sigprocmask)(int how, 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct kernel_sigset_t *set, 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct kernel_sigset_t *oldset) { 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int olderrno = LSS_ERRNO; 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc < 0 && LSS_ERRNO == ENOSYS) { 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = olderrno; 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (oldset) { 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_NAME(sigemptyset)(oldset); 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(_sigprocmask)(how, 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ? &set->sig[0] : NULL, 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldset ? &oldset->sig[0] : NULL); 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__PPC__) 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_0 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_0(dummy...) 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_1 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_1(arg1) \ 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_4 = (unsigned long) (arg1) 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_2 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_2(arg1, arg2) \ 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_1(arg1); \ 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_5 = (unsigned long) (arg2) 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_3 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_2(arg1, arg2); \ 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_6 = (unsigned long) (arg3) 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_4 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_7 = (unsigned long) (arg4) 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_LOADARGS_5 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_8 = (unsigned long) (arg5) 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #undef LSS_SC_BODY 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define LSS_SC_BODY(nr, type, opt, args...) \ 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long __sc_ret, __sc_err; \ 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { \ 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_3 __asm__ ("r3") = opt; \ 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_4 __asm__ ("r4"); \ 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_5 __asm__ ("r5"); \ 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_6 __asm__ ("r6"); \ 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_7 __asm__ ("r7"); \ 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __sc_8 __asm__ ("r8"); \ 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_LOADARGS_##nr(args); \ 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ \ 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ("stwu 1, -48(1)\n\t" \ 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 4, 20(1)\n\t" \ 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 5, 24(1)\n\t" \ 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 6, 28(1)\n\t" \ 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 7, 32(1)\n\t" \ 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stw 8, 36(1)\n\t" \ 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "addi 4, 1, 20\n\t" \ 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sc\n\t" \ 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mfcr %0" \ 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r" (__sc_0), \ 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_3), "=&r" (__sc_4), \ 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_5), "=&r" (__sc_6), \ 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "=&r" (__sc_7), "=&r" (__sc_8) \ 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : LSS_ASMINPUT_##nr \ 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "cr0", "ctr", "memory"); \ 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_ret = __sc_3; \ 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __sc_err = __sc_0; \ 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_RETURN(type, __sc_ret, __sc_err) 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_SC_BODY(3, int, 1, domain, type, protocol); 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || \ 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__arm__) && !defined(__ARM_EABI__)) || \ 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See sys_socketcall in net/socket.c in kernel source. 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It de-multiplexes on its first arg and unpacks the arglist 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array in its second arg. 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall2(long, socketcall, int, c, unsigned long*, a) 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long args[3] = { 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long) domain, 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long) type, 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (unsigned long) protocol 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(socketcall)(1, args); 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #elif defined(__ARM_EABI__) 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(int, socket, int, d, 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int, t, int, p) 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__i386__) || defined(__PPC__) || \ 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int*, s, int, o) 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #if defined(__mips__) 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* sys_pipe() on MIPS has non-standard calling conventions, as it returns 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both file handles through CPU registers. 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(pipe)(int *p) { 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v0 __asm__("$2") = __NR_pipe; 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __v1 __asm__("$3"); 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned long __r7 __asm__("$7"); 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asm__ __volatile__ ("syscall\n" 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "=&r"(__v0), "=&r"(__v1), "+r" (__r7) 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "0"(__v0) 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : "$8", "$9", "$10", "$11", "$12", 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$13", "$14", "$15", "$24", "memory"); 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (__r7) { 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = __v0; 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[0] = __v0; 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[1] = __v1; 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #else 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE _syscall1(int, pipe, int *, p) 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #endif 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE pid_t LSS_NAME(gettid)() { 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t tid = LSS_NAME(_gettid)(); 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tid != -1) { 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tid; 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LSS_NAME(getpid)(); 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t new_size, int flags, ...) { 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *new_address, *rc; 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start(ap, flags); 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_address = va_arg(ap, void *); 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(_mremap)(old_address, old_size, new_size, 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags, new_address); 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end(ap); 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) { 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* PTRACE_DETACH can sometimes forget to wake up the tracee and it 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then sends job control signals to the real parent, rather than to 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the tracer. We reduce the risk of this happening by starting a 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * whole new time slice, and then quickly sending a SIGCONT signal 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * right after detaching from the tracee. 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc, err; 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_NAME(sched_yield)(); 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = LSS_ERRNO; 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_NAME(kill)(pid, SIGCONT); 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LSS_ERRNO = err; 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2183