1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Doing syscalls. m_syscall.c ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2000-2013 Julian Seward 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jseward@acm.org 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h" 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vkiscnums.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syscall.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Building syscall return values. 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a SysRes value from a syscall return value. This is 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Linux-specific. 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown From: 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/ 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown linux/i386/sysdep.h? 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Linux uses a negative return value to indicate syscall errors, 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unlike most Unices, which use the condition codes' carry flag. 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Since version 2.1 the return value of a system call might be 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown negative even if the call succeeded. E.g., the 'lseek' system call 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown might return a large offset. Therefore we must not anymore test 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for < 0, but test for a real error by making sure the value in %eax 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is a real error number. Linus said he will make sure the no 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown syscall returns a value in -1 .. -4095 as a valid result so we can 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown safely test with -4095. 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_x86_linux) ( Int val ) { 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = 0; /* unused except on mips-linux */ 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._isError = val >= -4095 && val <= -1; 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (res._isError) { 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = (UInt)(-val); 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = (UInt)val; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Similarly .. */ 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_amd64_linux) ( Long val ) { 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = 0; /* unused except on mips-linux */ 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._isError = val >= -4095 && val <= -1; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (res._isError) { 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = (ULong)(-val); 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = (ULong)val; 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PPC uses the CR7.SO bit to flag an error (CR0 in IBM-speak) */ 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Note this must be in the bottom bit of the second arg */ 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so ) { 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = 0; /* unused except on mips-linux */ 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._isError = (cr0so & 1) != 0; 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = val; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* As per ppc32 version, cr0.so must be in l.s.b. of 2nd arg */ 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so ) { 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = 0; /* unused except on mips-linux */ 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._isError = (cr0so & 1) != 0; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = val; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovSysRes VG_(mk_SysRes_s390x_linux) ( Long val ) { 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SysRes res; 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = 0; /* unused except on mips-linux */ 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res._isError = val >= -4095 && val <= -1; 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (res._isError) { 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res._val = -val; 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res._val = val; 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return res; 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_arm_linux) ( Int val ) { 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = 0; /* unused except on mips-linux */ 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._isError = val >= -4095 && val <= -1; 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (res._isError) { 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = (UInt)(-val); 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._val = (UInt)val; 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovSysRes VG_(mk_SysRes_arm64_linux) ( Long val ) { 132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SysRes res; 133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._valEx = 0; /* unused except on mips-linux */ 134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._isError = val >= -4095 && val <= -1; 135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (res._isError) { 136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._val = (ULong)(-val); 137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._val = (ULong)val; 139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return res; 141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* MIPS uses a3 != 0 to flag an error */ 144663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengSysRes VG_(mk_SysRes_mips32_linux) ( UWord v0, UWord v1, UWord a3 ) { 145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SysRes res; 146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._isError = (a3 != (UWord)0); 147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._val = v0; 148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng res._valEx = v1; 149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return res; 150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* MIPS uses a3 != 0 to flag an error */ 153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovSysRes VG_(mk_SysRes_mips64_linux) ( ULong v0, ULong v1, ULong a3 ) { 154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SysRes res; 155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._isError = (a3 != (ULong)0); 156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._val = v0; 157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov res._valEx = v1; 158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return res; 159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generic constructors. */ 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_Error) ( UWord err ) { 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes r; 164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r._valEx = 0; /* unused except on mips-linux */ 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._isError = True; 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._val = err; 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_Success) ( UWord res ) { 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes r; 172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng r._valEx = 0; /* unused except on mips-linux */ 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._isError = False; 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._val = res; 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Darwin: Some syscalls return a double-word result. */ 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_x86_darwin) ( UChar scclass, Bool isErr, 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt wHI, UInt wLO ) 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wHI = 0; 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = 0; 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = 0; /* invalid */ 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(isErr == False || isErr == True); 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(UWord) == sizeof(UInt)); 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (scclass) { 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_UNIX: 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = wLO; 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wHI = wHI; 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = isErr ? SysRes_UNIX_ERR : SysRes_UNIX_OK; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MACH: 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!isErr); 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(wHI == 0); 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = wLO; 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = SysRes_MACH; 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MDEP: 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!isErr); 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(wHI == 0); 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = wLO; 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = SysRes_MDEP; 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_amd64_darwin) ( UChar scclass, Bool isErr, 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong wHI, ULong wLO ) 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wHI = 0; 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = 0; 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = 0; /* invalid */ 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(isErr == False || isErr == True); 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(UWord) == sizeof(ULong)); 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (scclass) { 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_UNIX: 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = wLO; 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wHI = wHI; 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = isErr ? SysRes_UNIX_ERR : SysRes_UNIX_OK; 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MACH: 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!isErr); 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(wHI == 0); 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = wLO; 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = SysRes_MACH; 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MDEP: 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!isErr); 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(wHI == 0); 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._wLO = wLO; 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res._mode = SysRes_MDEP; 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generic constructors. We assume (without checking if this makes 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any sense, from the caller's point of view) that these are for the 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UNIX style of syscall. */ 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_Error) ( UWord err ) { 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes r; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._wHI = 0; 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._wLO = err; 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._mode = SysRes_UNIX_ERR; 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(mk_SysRes_Success) ( UWord res ) { 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes r; 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._wHI = 0; 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._wLO = res; 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r._mode = SysRes_UNIX_OK; 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error "Unknown OS" 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(do_syscall): A function for doing syscalls. 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_x86_linux) 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Incoming args (syscall number + up to 6 args) come on the stack. 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ie. the C calling convention). 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The syscall number goes in %eax. The args are passed to the syscall in 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the regs %ebx, %ecx, %edx, %esi, %edi, %ebp, ie. the kernel's syscall 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown calling convention. 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %eax gets the return value. Not sure which registers the kernel 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clobbers, so we preserve all the callee-save regs (%esi, %edi, %ebx, 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %ebp). 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern UWord do_syscall_WRK ( 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no, 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a1, UWord a2, UWord a3, 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm( 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".text\n" 296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".globl do_syscall_WRK\n" 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"do_syscall_WRK:\n" 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" push %esi\n" 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" push %edi\n" 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" push %ebx\n" 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" push %ebp\n" 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+ 4(%esp),%eax\n" 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+ 8(%esp),%ebx\n" 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+12(%esp),%ecx\n" 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+16(%esp),%edx\n" 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+20(%esp),%esi\n" 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+24(%esp),%edi\n" 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movl 16+28(%esp),%ebp\n" 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" int $0x80\n" 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" popl %ebp\n" 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" popl %ebx\n" 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" popl %edi\n" 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" popl %esi\n" 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ret\n" 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".previous\n" 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_linux) 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Incoming args (syscall number + up to 6 args) come in %rdi, %rsi, 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %rdx, %rcx, %r8, %r9, and the last one on the stack (ie. the C 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown calling convention). 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The syscall number goes in %rax. The args are passed to the syscall in 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the regs %rdi, %rsi, %rdx, %r10, %r8, %r9 (yes, really %r10, not %rcx), 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ie. the kernel's syscall calling convention. 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %rax gets the return value. %rcx and %r11 are clobbered by the syscall; 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown no matter, they are caller-save (the syscall clobbers no callee-save 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs, so we don't have to do any register saving/restoring). 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern UWord do_syscall_WRK ( 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no, 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a1, UWord a2, UWord a3, 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm( 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".text\n" 338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".globl do_syscall_WRK\n" 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"do_syscall_WRK:\n" 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Convert function calling convention --> syscall calling 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convention */ 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq %rdi, %rax\n" 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq %rsi, %rdi\n" 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq %rdx, %rsi\n" 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq %rcx, %rdx\n" 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq %r8, %r10\n" 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq %r9, %r8\n" 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" movq 8(%rsp), %r9\n" /* last arg from stack */ 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" syscall\n" 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ret\n" 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".previous\n" 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_ppc32_linux) 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Incoming args (syscall number + up to 6 args) come in %r3:%r9. 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The syscall number goes in %r0. The args are passed to the syscall in 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the regs %r3:%r8, i.e. the kernel's syscall calling convention. 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The %cr0.so bit flags an error. 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We return the syscall return value in %r3, and the %cr0.so in 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the lowest bit of %r4. 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We return a ULong, of which %r3 is the high word, and %r4 the low. 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown No callee-save regs are clobbered, so no saving/restoring is needed. 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern ULong do_syscall_WRK ( 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no, 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a1, UWord a2, UWord a3, 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm( 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".text\n" 373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".globl do_syscall_WRK\n" 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"do_syscall_WRK:\n" 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 0,3\n" 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 3,4\n" 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 4,5\n" 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 5,6\n" 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 6,7\n" 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 7,8\n" 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mr 8,9\n" 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" sc\n" /* syscall: sets %cr0.so on error */ 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mfcr 4\n" /* %cr -> low word of return var */ 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" rlwinm 4,4,4,31,31\n" /* rotate flag bit so to lsb, and mask it */ 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" blr\n" /* and return */ 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".previous\n" 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_ppc64_linux) 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Due to the need to return 65 bits of result, this is completely 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown different from the ppc32 case. The single arg register points to a 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7-word block containing the syscall # and the 6 args. The syscall 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result proper is put in [0] of the block, and %cr0.so is in the 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bottom bit of [1]. */ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void do_syscall_WRK ( ULong* argblock ); 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm( 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".align 2\n" 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".globl do_syscall_WRK\n" 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".section \".opd\",\"aw\"\n" 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".align 3\n" 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"do_syscall_WRK:\n" 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".quad .do_syscall_WRK,.TOC.@tocbase,0\n" 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".previous\n" 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".type .do_syscall_WRK,@function\n" 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".globl .do_syscall_WRK\n" 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".do_syscall_WRK:\n" 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" std 3,-16(1)\n" /* stash arg */ 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 8, 48(3)\n" /* sc arg 6 */ 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 7, 40(3)\n" /* sc arg 5 */ 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 6, 32(3)\n" /* sc arg 4 */ 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 5, 24(3)\n" /* sc arg 3 */ 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 4, 16(3)\n" /* sc arg 2 */ 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 0, 0(3)\n" /* sc number */ 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 3, 8(3)\n" /* sc arg 1 */ 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" sc\n" /* result in r3 and cr0.so */ 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ld 5,-16(1)\n" /* reacquire argblock ptr (r5 is caller-save) */ 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" std 3,0(5)\n" /* argblock[0] = r3 */ 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" mfcr 3\n" 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" srwi 3,3,28\n" 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" andi. 3,3,1\n" 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" std 3,8(5)\n" /* argblock[1] = cr0.s0 & 1 */ 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" blr\n" 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_arm_linux) 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* I think the conventions are: 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args in r0 r1 r2 r3 r4 r5 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sysno in r7 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return value in r0, w/ same conventions as x86-linux, viz r0 in 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -4096 .. -1 is an error value. All other values are success 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown values. 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern UWord do_syscall_WRK ( 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a1, UWord a2, UWord a3, 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm( 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".text\n" 440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".globl do_syscall_WRK\n" 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"do_syscall_WRK:\n" 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" push {r4, r5, r7}\n" 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ldr r4, [sp, #12]\n" 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ldr r5, [sp, #16]\n" 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" ldr r7, [sp, #20]\n" 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" svc 0x0\n" 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" pop {r4, r5, r7}\n" 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" bx lr\n" 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown".previous\n" 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_arm64_linux) 453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* I think the conventions are: 454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov args in r0 r1 r2 r3 r4 r5 455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sysno in r8 456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return value in r0, w/ same conventions as x86-linux, viz r0 in 457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov -4096 .. -1 is an error value. All other values are success 458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov values. 459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r0 to r5 remain unchanged, but syscall_no is in r6 and needs 461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov to be moved to r8 (??) 462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern UWord do_syscall_WRK ( 464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord a1, UWord a2, UWord a3, 465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord a4, UWord a5, UWord a6, 466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord syscall_no 467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ); 468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovasm( 469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov".text\n" 470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov".globl do_syscall_WRK\n" 471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"do_syscall_WRK:\n" 472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mov x8, x6\n" 473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mov x6, 0\n" 474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mov x7, 0\n" 475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" svc 0\n" 476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ret\n" 477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov".previous\n" 478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov); 479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_x86_darwin) 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Incoming args (syscall number + up to 8 args) come in on the stack 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The kernel's syscall calling convention is: 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the syscall number goes in eax 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the args are passed to the syscall on the stack, 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pushed onto the stack R->L (that is, the usual x86 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown calling conventions, with the leftmost arg at the lowest 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address) 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Call instruction: 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * UNIX: sysenter 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * UNIX: int $0x80 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * MACH: int $0x81 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * MDEP: int $0x82 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that the call type can be determined from the syscall number; 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there is no need to inspect the actual instruction. Although obviously 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the instruction must match. 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return value: 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * MACH,MDEP: the return value comes back in eax 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * UNIX: the return value comes back in edx:eax (hi32:lo32) 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Error: 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * MACH,MDEP: no error is returned 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * UNIX: the carry flag indicates success or failure 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nb here, sizeof(UWord) == sizeof(UInt) 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__private_extern__ ULong 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndo_syscall_unix_WRK ( UWord a1, UWord a2, UWord a3, /* 4(esp)..12(esp) */ 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, /* 16(esp)..24(esp) */ 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a7, UWord a8, /* 28(esp)..32(esp) */ 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no, /* 36(esp) */ 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/UInt* errflag /* 40(esp) */ ); 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Unix syscall: 64-bit return in edx:eax, with LSB in eax 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// error indicated by carry flag: clear=good, set=bad 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm(".private_extern _do_syscall_unix_WRK\n" 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "_do_syscall_unix_WRK:\n" 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl 40(%esp), %ecx \n" /* assume syscall success */ 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl $0, (%ecx) \n" 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl 36(%esp), %eax \n" 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " int $0x80 \n" 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " jnc 1f \n" /* jump if success */ 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl 40(%esp), %ecx \n" /* syscall failed - set *errflag */ 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl $1, (%ecx) \n" 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " 1: ret \n" 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__private_extern__ UInt 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndo_syscall_mach_WRK ( UWord a1, UWord a2, UWord a3, /* 4(esp)..12(esp) */ 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, /* 16(esp)..24(esp) */ 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a7, UWord a8, /* 28(esp)..32(esp) */ 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no /* 36(esp) */ ); 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Mach trap: 32-bit result in %eax, no error flag 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm(".private_extern _do_syscall_mach_WRK\n" 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "_do_syscall_mach_WRK:\n" 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl 36(%esp), %eax \n" 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " int $0x81 \n" 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " ret \n" 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__private_extern__ UInt 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndo_syscall_mdep_WRK ( UWord a1, UWord a2, UWord a3, /* 4(esp)..12(esp) */ 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, /* 16(esp)..24(esp) */ 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a7, UWord a8, /* 28(esp)..32(esp) */ 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no /* 36(esp) */ ); 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// mdep trap: 32-bit result in %eax, no error flag 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm( 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ".private_extern _do_syscall_mdep_WRK\n" 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "_do_syscall_mdep_WRK:\n" 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movl 36(%esp), %eax \n" 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " int $0x82 \n" 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " ret \n" 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_darwin) 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Incoming args (syscall number + up to 8 args) come in registers and stack 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The kernel's syscall calling convention is: 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the syscall number goes in rax 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the args are passed to the syscall in registers and the stack 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the call instruction is 'syscall' 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Return value: 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * MACH,MDEP: the return value comes back in rax 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * UNIX: the return value comes back in rdx:rax (hi64:lo64) 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Error: 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * MACH,MDEP: no error is returned 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * UNIX: the carry flag indicates success or failure 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nb here, sizeof(UWord) == sizeof(ULong) 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__private_extern__ UWord 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndo_syscall_unix_WRK ( UWord a1, UWord a2, UWord a3, /* rdi, rsi, rdx */ 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, /* rcx, r8, r9 */ 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a7, UWord a8, /* 8(rsp), 16(rsp) */ 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no, /* 24(rsp) */ 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/ULong* errflag, /* 32(rsp) */ 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/ULong* res2 ); /* 40(rsp) */ 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Unix syscall: 128-bit return in rax:rdx, with LSB in rax 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// error indicated by carry flag: clear=good, set=bad 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm(".private_extern _do_syscall_unix_WRK\n" 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "_do_syscall_unix_WRK:\n" 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq %rcx, %r10 \n" /* pass rcx in r10 instead */ 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq 32(%rsp), %rax \n" /* assume syscall success */ 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq $0, (%rax) \n" 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq 24(%rsp), %rax \n" /* load syscall_no */ 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " syscall \n" 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " jnc 1f \n" /* jump if success */ 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq 32(%rsp), %rcx \n" /* syscall failed - set *errflag */ 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq $1, (%rcx) \n" 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " 1: movq 40(%rsp), %rcx \n" /* save 2nd result word */ 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq %rdx, (%rcx) \n" 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " retq \n" /* return 1st result word */ 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__private_extern__ UWord 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndo_syscall_mach_WRK ( UWord a1, UWord a2, UWord a3, /* rdi, rsi, rdx */ 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, /* rcx, r8, r9 */ 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a7, UWord a8, /* 8(rsp), 16(rsp) */ 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord syscall_no ); /* 24(rsp) */ 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Mach trap: 64-bit result, no error flag 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownasm(".private_extern _do_syscall_mach_WRK\n" 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "_do_syscall_mach_WRK:\n" 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq %rcx, %r10 \n" /* pass rcx in r10 instead */ 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " movq 24(%rsp), %rax \n" /* load syscall_no */ 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " syscall \n" 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " retq \n" 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_s390x_linux) 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UWord do_syscall_WRK ( 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord syscall_no, 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord arg1, UWord arg2, UWord arg3, 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord arg4, UWord arg5, UWord arg6 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ) 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register UWord __arg1 asm("2") = arg1; 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register UWord __arg2 asm("3") = arg2; 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register UWord __arg3 asm("4") = arg3; 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register UWord __arg4 asm("5") = arg4; 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register UWord __arg5 asm("6") = arg5; 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register UWord __arg6 asm("7") = arg6; 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov register ULong __svcres asm("2"); 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ __volatile__ ( 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "lgr %%r1,%1\n\t" 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "svc 0\n\t" 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=d" (__svcres) 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "a" (syscall_no), 633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "0" (__arg1), 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "d" (__arg2), 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "d" (__arg3), 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "d" (__arg4), 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "d" (__arg5), 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "d" (__arg6) 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "1", "cc", "memory"); 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (UWord) (__svcres); 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGP_mips32_linux) 645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Incoming args (syscall number + up to 6 args) come in a0 - a3 and stack. 646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng The syscall number goes in v0. The args are passed to the syscall in 648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the regs a0 - a3 and stack, i.e. the kernel's syscall calling convention. 649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (a3 != 0) flags an error. 651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng We return the syscall return value in v0. 652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MIPS version 653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern int do_syscall_WRK ( 655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int a1, int a2, int a3, 656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int a4, int a5, int a6, int syscall_no, UWord *err, 657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord *valHi, UWord* valLo 658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); 659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengasm( 660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".globl do_syscall_WRK\n" 661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".ent do_syscall_WRK\n" 662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".text\n" 663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"do_syscall_WRK:\n" 664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" lw $2, 24($29)\n" 665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" syscall\n" 666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" lw $8, 28($29)\n" 667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" sw $7, ($8)\n" 668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" lw $8, 32($29)\n" 669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" sw $3, ($8)\n" // store valHi 670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" lw $8, 36($29)\n" 671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" sw $2, ($8)\n" // store valLo 672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" jr $31\n" 673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" nop\n" 674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".previous\n" 675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng".end do_syscall_WRK\n" 676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng); 677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_mips64_linux) 679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern UWord do_syscall_WRK ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, 680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord a6, UWord syscall_no, ULong* V1_val ); 681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovasm ( 682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov".text\n" 683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov".globl do_syscall_WRK\n" 684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"do_syscall_WRK:\n" 685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" daddiu $29, $29, -8\n" 686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" sd $11, 0($29)\n" 687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" move $2, $10\n" 688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" syscall\n" 689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ld $11, 0($29)\n" 690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" daddiu $29, $29, 8\n" 691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" sd $3, 0($11)\n" /* store vale of v1 in last param */ 692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" sd $7, 8($11)\n" /* store vale of a3 in last param */ 693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" jr $31\n" 694436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov".previous\n" 695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov); 696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown platform 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Finally, the generic code. This sends the call to the right 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown helper. */ 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3, 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a4, UWord a5, UWord a6, 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord a7, UWord a8 ) 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(VGP_x86_linux) 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6); 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_x86_linux)( val ); 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_amd64_linux) 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6); 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_amd64_linux)( val ); 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_ppc32_linux) 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong ret = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6); 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt val = (UInt)(ret>>32); 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt cr0so = (UInt)(ret); 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_ppc32_linux)( val, cr0so ); 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_ppc64_linux) 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong argblock[7]; 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[0] = sysno; 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[1] = a1; 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[2] = a2; 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[3] = a3; 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[4] = a4; 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[5] = a5; 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argblock[6] = a6; 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_syscall_WRK( &argblock[0] ); 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_ppc64_linux)( argblock[0], argblock[1] ); 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_arm_linux) 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord val = do_syscall_WRK(a1,a2,a3,a4,a5,a6,sysno); 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_arm_linux)( val ); 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 739436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# elif defined(VGP_arm64_linux) 740436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord val = do_syscall_WRK(a1,a2,a3,a4,a5,a6,sysno); 741436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return VG_(mk_SysRes_arm64_linux)( val ); 742436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_x86_darwin) 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt wLO = 0, wHI = 0, err = 0; 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u64; 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar scclass = VG_DARWIN_SYSNO_CLASS(sysno); 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (scclass) { 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_UNIX: 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u64 = do_syscall_unix_WRK(a1,a2,a3,a4,a5,a6,a7,a8, 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_DARWIN_SYSNO_FOR_KERNEL(sysno), &err); 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wLO = (UInt)u64; 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wHI = (UInt)(u64 >> 32); 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MACH: 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wLO = do_syscall_mach_WRK(a1,a2,a3,a4,a5,a6,a7,a8, 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_DARWIN_SYSNO_FOR_KERNEL(sysno)); 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown err = 0; 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MDEP: 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wLO = do_syscall_mdep_WRK(a1,a2,a3,a4,a5,a6,a7,a8, 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_DARWIN_SYSNO_FOR_KERNEL(sysno)); 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown err = 0; 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_x86_darwin)( scclass, err ? True : False, wHI, wLO ); 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_amd64_darwin) 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong wLO = 0, wHI = 0, err = 0; 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar scclass = VG_DARWIN_SYSNO_CLASS(sysno); 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (scclass) { 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_UNIX: 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wLO = do_syscall_unix_WRK(a1,a2,a3,a4,a5,a6,a7,a8, 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_DARWIN_SYSNO_FOR_KERNEL(sysno), &err, &wHI); 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MACH: 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VG_DARWIN_SYSCALL_CLASS_MDEP: 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wLO = do_syscall_mach_WRK(a1,a2,a3,a4,a5,a6,a7,a8, 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_DARWIN_SYSNO_FOR_KERNEL(sysno)); 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown err = 0; 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(mk_SysRes_amd64_darwin)( scclass, err ? True : False, wHI, wLO ); 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_s390x_linux) 791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord val; 792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (sysno == __NR_mmap) { 794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong argbuf[6]; 795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argbuf[0] = a1; 797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argbuf[1] = a2; 798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argbuf[2] = a3; 799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argbuf[3] = a4; 800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argbuf[4] = a5; 801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argbuf[5] = a6; 802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = do_syscall_WRK(sysno,(UWord)&argbuf[0],0,0,0,0,0); 803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6); 805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return VG_(mk_SysRes_s390x_linux)( val ); 808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGP_mips32_linux) 810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord err = 0; 811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord valHi = 0; 812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord valLo = 0; 813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (void) do_syscall_WRK(a1,a2,a3,a4,a5,a6, sysno,&err,&valHi,&valLo); 814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return VG_(mk_SysRes_mips32_linux)( valLo, valHi, (ULong)err ); 815436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 816436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_mips64_linux) 817436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong v1_a3[2]; 818436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v1_a3[0] = 0xFF00; 819436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov v1_a3[1] = 0xFF00; 820436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong V0 = do_syscall_WRK(a1,a2,a3,a4,a5,a6,sysno,v1_a3); 821436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong V1 = (ULong)v1_a3[0]; 822436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong A3 = (ULong)v1_a3[1]; 823436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return VG_(mk_SysRes_mips64_linux)( V0, V1, A3 ); 824436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown platform 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Names of errors. 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return a string which gives the name of an error value. Note, 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unlike the standard C syserror fn, the returned string is not 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown malloc-allocated or writable -- treat it as a constant. 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TODO: implement this properly. */ 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst HChar* VG_(strerror) ( UWord errnum ) 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (errnum) { 842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EPERM: return "Operation not permitted"; 843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOENT: return "No such file or directory"; 844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ESRCH: return "No such process"; 845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EINTR: return "Interrupted system call"; 846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EIO: return "Input/output error"; 847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENXIO: return "No such device or address"; 848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_E2BIG: return "Argument list too long"; 849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOEXEC: return "Exec format error"; 850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EBADF: return "Bad file descriptor"; 851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ECHILD: return "No child processes"; 852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EAGAIN: return "Resource temporarily unavailable"; 853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOMEM: return "Cannot allocate memory"; 854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EACCES: return "Permission denied"; 855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EFAULT: return "Bad address"; 856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOTBLK: return "Block device required"; 857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EBUSY: return "Device or resource busy"; 858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EEXIST: return "File exists"; 859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EXDEV: return "Invalid cross-device link"; 860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENODEV: return "No such device"; 861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOTDIR: return "Not a directory"; 862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EISDIR: return "Is a directory"; 863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EINVAL: return "Invalid argument"; 864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENFILE: return "Too many open files in system"; 865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EMFILE: return "Too many open files"; 866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOTTY: return "Inappropriate ioctl for device"; 867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ETXTBSY: return "Text file busy"; 868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EFBIG: return "File too large"; 869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOSPC: return "No space left on device"; 870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ESPIPE: return "Illegal seek"; 871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EROFS: return "Read-only file system"; 872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EMLINK: return "Too many links"; 873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EPIPE: return "Broken pipe"; 874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EDOM: return "Numerical argument out of domain"; 875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ERANGE: return "Numerical result out of range"; 876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_ENOSYS: return "Function not implemented"; 878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VKI_EOVERFLOW: return "Value too large for defined data type"; 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(VKI_ERESTARTSYS) 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VKI_ERESTARTSYS: return "ERESTARTSYS"; 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: return "VG_(strerror): unknown error"; 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*--- end ---*/ 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 890