syscall_emul.hh revision 2064
1360SN/A/* 210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 310796Sbrandon.potter@amd.com * All rights reserved. 410027SChris.Adeniyi-Jones@arm.com * 510027SChris.Adeniyi-Jones@arm.com * Redistribution and use in source and binary forms, with or without 610027SChris.Adeniyi-Jones@arm.com * modification, are permitted provided that the following conditions are 710027SChris.Adeniyi-Jones@arm.com * met: redistributions of source code must retain the above copyright 810027SChris.Adeniyi-Jones@arm.com * notice, this list of conditions and the following disclaimer; 910027SChris.Adeniyi-Jones@arm.com * redistributions in binary form must reproduce the above copyright 1010027SChris.Adeniyi-Jones@arm.com * notice, this list of conditions and the following disclaimer in the 1110027SChris.Adeniyi-Jones@arm.com * documentation and/or other materials provided with the distribution; 1210027SChris.Adeniyi-Jones@arm.com * neither the name of the copyright holders nor the names of its 1310027SChris.Adeniyi-Jones@arm.com * contributors may be used to endorse or promote products derived from 1410027SChris.Adeniyi-Jones@arm.com * this software without specific prior written permission. 151458SN/A * 16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27360SN/A */ 28360SN/A 29360SN/A#ifndef __SIM_SYSCALL_EMUL_HH__ 30360SN/A#define __SIM_SYSCALL_EMUL_HH__ 31360SN/A 32360SN/A#define BSD_HOST (defined(__APPLE__) || defined(__OpenBSD__) || \ 33360SN/A defined(__FreeBSD__)) 34360SN/A 35360SN/A/// 36360SN/A/// @file syscall_emul.hh 37360SN/A/// 38360SN/A/// This file defines objects used to emulate syscalls from the target 39360SN/A/// application on the host machine. 402665Ssaidi@eecs.umich.edu 412665Ssaidi@eecs.umich.edu#include <errno.h> 422665Ssaidi@eecs.umich.edu#include <string> 43360SN/A#ifdef __CYGWIN32__ 44360SN/A#include <sys/fcntl.h> // for O_BINARY 451354SN/A#endif 461354SN/A#include <sys/uio.h> 47360SN/A 482764Sstever@eecs.umich.edu#include "base/intmath.hh" // for RoundUp 499202Spalle@lyckegaard.dk#include "mem/functional/functional.hh" 509202Spalle@lyckegaard.dk#include "targetarch/isa_traits.hh" // for Addr 512064SN/A 5211799Sbrandon.potter@amd.com#include "base/trace.hh" 5311799Sbrandon.potter@amd.com#include "cpu/exec_context.hh" 5411799Sbrandon.potter@amd.com#include "sim/process.hh" 5511799Sbrandon.potter@amd.com 5611799Sbrandon.potter@amd.com/// 5711799Sbrandon.potter@amd.com/// System call descriptor. 58360SN/A/// 59360SN/Aclass SyscallDesc { 60360SN/A 61360SN/A public: 62360SN/A 63360SN/A /// Typedef for target syscall handler functions. 641809SN/A typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, 6511800Sbrandon.potter@amd.com Process *, ExecContext *); 6611392Sbrandon.potter@amd.com 671809SN/A const char *name; //!< Syscall name (e.g., "open"). 6811392Sbrandon.potter@amd.com FuncPtr funcPtr; //!< Pointer to emulation function. 6911383Sbrandon.potter@amd.com int flags; //!< Flags (see Flags enum). 703113Sgblack@eecs.umich.edu 7111799Sbrandon.potter@amd.com /// Flag values for controlling syscall behavior. 7211759Sbrandon.potter@amd.com enum Flags { 7311812Sbaz21@cam.ac.uk /// Don't set return regs according to funcPtr return value. 7411812Sbaz21@cam.ac.uk /// Used for syscalls with non-standard return conventions 7511799Sbrandon.potter@amd.com /// that explicitly set the ExecContext regs (e.g., 768229Snate@binkert.org /// sigreturn). 778229Snate@binkert.org SuppressReturnValue = 1 7811594Santhony.gutierrez@amd.com }; 797075Snate@binkert.org 808229Snate@binkert.org /// Constructor. 8111856Sbrandon.potter@amd.com SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) 827075Snate@binkert.org : name(_name), funcPtr(_funcPtr), flags(_flags) 83360SN/A { 8411886Sbrandon.potter@amd.com } 8511800Sbrandon.potter@amd.com 8611392Sbrandon.potter@amd.com /// Emulate the syscall. Public interface for calling through funcPtr. 872462SN/A void doSyscall(int callnum, Process *proc, ExecContext *xc); 881354SN/A}; 896216Snate@binkert.org 906658Snate@binkert.org 912474SN/Aclass BaseBufferArg { 922680Sktlim@umich.edu 938229Snate@binkert.org public: 9411886Sbrandon.potter@amd.com 9510496Ssteve.reinhardt@amd.com BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) 968229Snate@binkert.org { 9711794Sbrandon.potter@amd.com bufPtr = new uint8_t[size]; 9811886Sbrandon.potter@amd.com // clear out buffer: in case we only partially populate this, 9910497Ssteve.reinhardt@amd.com // and then do a copyOut(), we want to make sure we don't 10011794Sbrandon.potter@amd.com // introduce any random junk into the simulated address space 101360SN/A memset(bufPtr, 0, size); 102360SN/A } 103360SN/A 104360SN/A virtual ~BaseBufferArg() { delete [] bufPtr; } 105360SN/A 106360SN/A // 107360SN/A // copy data into simulator space (read from target memory) 108360SN/A // 109360SN/A virtual bool copyIn(FunctionalMemory *mem) 110360SN/A { 111378SN/A mem->access(Read, addr, bufPtr, size); 1121706SN/A return true; // no EFAULT detection for now 11311851Sbrandon.potter@amd.com } 114378SN/A 115378SN/A // 116378SN/A // copy data out of simulator space (write to target memory) 117378SN/A // 118378SN/A virtual bool copyOut(FunctionalMemory *mem) 1191706SN/A { 12011851Sbrandon.potter@amd.com mem->access(Write, addr, bufPtr, size); 121360SN/A return true; // no EFAULT detection for now 12211760Sbrandon.potter@amd.com } 12311760Sbrandon.potter@amd.com 12411851Sbrandon.potter@amd.com protected: 12511760Sbrandon.potter@amd.com Addr addr; 1266109Ssanchezd@stanford.edu int size; 1271706SN/A uint8_t *bufPtr; 12811851Sbrandon.potter@amd.com}; 129378SN/A 1306109Ssanchezd@stanford.edu 1316109Ssanchezd@stanford.educlass BufferArg : public BaseBufferArg 13211851Sbrandon.potter@amd.com{ 1336109Ssanchezd@stanford.edu public: 13411886Sbrandon.potter@amd.com BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 13511886Sbrandon.potter@amd.com void *bufferPtr() { return bufPtr; } 13611886Sbrandon.potter@amd.com}; 13711886Sbrandon.potter@amd.com 138378SN/Atemplate <class T> 1391706SN/Aclass TypedBufferArg : public BaseBufferArg 14011851Sbrandon.potter@amd.com{ 141378SN/A public: 1425748SSteve.Reinhardt@amd.com // user can optionally specify a specific number of bytes to 1435748SSteve.Reinhardt@amd.com // allocate to deal with those structs that have variable-size 14411851Sbrandon.potter@amd.com // arrays at the end 145378SN/A TypedBufferArg(Addr _addr, int _size = sizeof(T)) 146378SN/A : BaseBufferArg(_addr, _size) 1471706SN/A { } 14811851Sbrandon.potter@amd.com 149378SN/A // type case 15011886Sbrandon.potter@amd.com operator T*() { return (T *)bufPtr; } 1511706SN/A 15211851Sbrandon.potter@amd.com // dereference operators 153378SN/A T &operator*() { return *((T *)bufPtr); } 154378SN/A T* operator->() { return (T *)bufPtr; } 1551706SN/A T &operator[](int i) { return ((T *)bufPtr)[i]; } 15611851Sbrandon.potter@amd.com}; 157378SN/A 158378SN/A////////////////////////////////////////////////////////////////////// 1591706SN/A// 16011851Sbrandon.potter@amd.com// The following emulation functions are generic enough that they 161378SN/A// don't need to be recompiled for different emulated OS's. They are 1624118Sgblack@eecs.umich.edu// defined in sim/syscall_emul.cc. 1634118Sgblack@eecs.umich.edu// 16411851Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////// 1654118Sgblack@eecs.umich.edu 166378SN/A 1671706SN/A/// Handler for unimplemented syscalls that we haven't thought about. 16811851Sbrandon.potter@amd.comSyscallReturn unimplementedFunc(SyscallDesc *desc, int num, 169378SN/A Process *p, ExecContext *xc); 170378SN/A 1711706SN/A/// Handler for unimplemented syscalls that we never intend to 17211851Sbrandon.potter@amd.com/// implement (signal handling, etc.) and should not affect the correct 173360SN/A/// behavior of the program. Print a warning only if the appropriate 1745513SMichael.Adler@intel.com/// trace flag is enabled. Return success to the target program. 1755513SMichael.Adler@intel.comSyscallReturn ignoreFunc(SyscallDesc *desc, int num, 17611851Sbrandon.potter@amd.com Process *p, ExecContext *xc); 1775513SMichael.Adler@intel.com 17810203SAli.Saidi@ARM.com/// Target exit() handler: terminate simulation. 17910203SAli.Saidi@ARM.comSyscallReturn exitFunc(SyscallDesc *desc, int num, 18011851Sbrandon.potter@amd.com Process *p, ExecContext *xc); 18110203SAli.Saidi@ARM.com 1825513SMichael.Adler@intel.com/// Target getpagesize() handler. 18311851Sbrandon.potter@amd.comSyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, 1845513SMichael.Adler@intel.com Process *p, ExecContext *xc); 185511SN/A 18610633Smichaelupton@gmail.com/// Target obreak() handler: set brk address. 18711851Sbrandon.potter@amd.comSyscallReturn obreakFunc(SyscallDesc *desc, int num, 18810633Smichaelupton@gmail.com Process *p, ExecContext *xc); 1891706SN/A 19011851Sbrandon.potter@amd.com/// Target close() handler. 191511SN/ASyscallReturn closeFunc(SyscallDesc *desc, int num, 1925513SMichael.Adler@intel.com Process *p, ExecContext *xc); 1935513SMichael.Adler@intel.com 19411851Sbrandon.potter@amd.com/// Target read() handler. 1955513SMichael.Adler@intel.comSyscallReturn readFunc(SyscallDesc *desc, int num, 196511SN/A Process *p, ExecContext *xc); 1971706SN/A 19811851Sbrandon.potter@amd.com/// Target write() handler. 1991706SN/ASyscallReturn writeFunc(SyscallDesc *desc, int num, 2001706SN/A Process *p, ExecContext *xc); 2011706SN/A 2021706SN/A/// Target lseek() handler. 20311851Sbrandon.potter@amd.comSyscallReturn lseekFunc(SyscallDesc *desc, int num, 2041706SN/A Process *p, ExecContext *xc); 2051706SN/A 2061706SN/A/// Target munmap() handler. 2071706SN/ASyscallReturn munmapFunc(SyscallDesc *desc, int num, 20811851Sbrandon.potter@amd.com Process *p, ExecContext *xc); 2091706SN/A 210511SN/A/// Target gethostname() handler. 2116703Svince@csl.cornell.eduSyscallReturn gethostnameFunc(SyscallDesc *desc, int num, 2126703Svince@csl.cornell.edu Process *p, ExecContext *xc); 21311851Sbrandon.potter@amd.com 2146703Svince@csl.cornell.edu/// Target unlink() handler. 2156685Stjones1@inf.ed.ac.ukSyscallReturn unlinkFunc(SyscallDesc *desc, int num, 2166685Stjones1@inf.ed.ac.uk Process *p, ExecContext *xc); 21711851Sbrandon.potter@amd.com 2186685Stjones1@inf.ed.ac.uk/// Target rename() handler. 2196685Stjones1@inf.ed.ac.ukSyscallReturn renameFunc(SyscallDesc *desc, int num, 2205513SMichael.Adler@intel.com Process *p, ExecContext *xc); 2215513SMichael.Adler@intel.com 22211851Sbrandon.potter@amd.com 2235513SMichael.Adler@intel.com/// Target truncate() handler. 22411885Sbrandon.potter@amd.comSyscallReturn truncateFunc(SyscallDesc *desc, int num, 22511885Sbrandon.potter@amd.com Process *p, ExecContext *xc); 22611885Sbrandon.potter@amd.com 2275513SMichael.Adler@intel.com 2281999SN/A/// Target ftruncate() handler. 2291999SN/ASyscallReturn ftruncateFunc(SyscallDesc *desc, int num, 23011851Sbrandon.potter@amd.com Process *p, ExecContext *xc); 2311999SN/A 23211885Sbrandon.potter@amd.com 23311885Sbrandon.potter@amd.com/// Target chown() handler. 23411885Sbrandon.potter@amd.comSyscallReturn chownFunc(SyscallDesc *desc, int num, 2351999SN/A Process *p, ExecContext *xc); 2361999SN/A 2371999SN/A 23811851Sbrandon.potter@amd.com/// Target fchown() handler. 2391999SN/ASyscallReturn fchownFunc(SyscallDesc *desc, int num, 2403079Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2413079Sstever@eecs.umich.edu 24211851Sbrandon.potter@amd.com/// This struct is used to build an target-OS-dependent table that 2433079Sstever@eecs.umich.edu/// maps the target's open() flags to the host open() flags. 24411908SBrandon.Potter@amd.comstruct OpenFlagTransTable { 24511908SBrandon.Potter@amd.com int tgtFlag; //!< Target system flag value. 24611908SBrandon.Potter@amd.com int hostFlag; //!< Corresponding host system flag value. 24711908SBrandon.Potter@amd.com}; 24811875Sbrandon.potter@amd.com 2492093SN/A 25011851Sbrandon.potter@amd.com 2512093SN/A/// A readable name for 1,000,000, for converting microseconds to seconds. 2522687Sksewell@umich.educonst int one_million = 1000000; 2532687Sksewell@umich.edu 25411851Sbrandon.potter@amd.com/// Approximate seconds since the epoch (1/1/1970). About a billion, 2552687Sksewell@umich.edu/// by my reckoning. We want to keep this a constant (not use the 2562238SN/A/// real-world time) to keep simulations repeatable. 2572238SN/Aconst unsigned seconds_since_epoch = 1000000000; 25811851Sbrandon.potter@amd.com 2592238SN/A/// Helper function to convert current elapsed time to seconds and 26011908SBrandon.Potter@amd.com/// microseconds. 26111908SBrandon.Potter@amd.comtemplate <class T1, class T2> 26211908SBrandon.Potter@amd.comvoid 26311908SBrandon.Potter@amd.comgetElapsedTime(T1 &sec, T2 &usec) 26411908SBrandon.Potter@amd.com{ 26511908SBrandon.Potter@amd.com int elapsed_usecs = curTick / Clock::Int::us; 26611908SBrandon.Potter@amd.com sec = elapsed_usecs / one_million; 26711908SBrandon.Potter@amd.com usec = elapsed_usecs % one_million; 2682238SN/A} 2692238SN/A 27011851Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////// 2712238SN/A// 2722238SN/A// The following emulation functions are generic, but need to be 2732238SN/A// templated to account for differences in types, constants, etc. 27411851Sbrandon.potter@amd.com// 2752238SN/A////////////////////////////////////////////////////////////////////// 2762238SN/A 2772238SN/A/// Target ioctl() handler. For the most part, programs call ioctl() 27811851Sbrandon.potter@amd.com/// only to find out if their stdout is a tty, to determine whether to 2792238SN/A/// do line or block buffering. 2802238SN/Atemplate <class OS> 2812238SN/ASyscallReturn 28211851Sbrandon.potter@amd.comioctlFunc(SyscallDesc *desc, int callnum, Process *process, 2832238SN/A ExecContext *xc) 2842238SN/A{ 2852238SN/A int fd = xc->getSyscallArg(0); 28611851Sbrandon.potter@amd.com unsigned req = xc->getSyscallArg(1); 2872238SN/A 2882238SN/A DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); 2892238SN/A 29011851Sbrandon.potter@amd.com if (fd < 0 || process->sim_fd(fd) < 0) { 2912238SN/A // doesn't map to any simulator fd: not a valid target fd 2929455Smitch.hayenga+gem5@gmail.com return -EBADF; 2939455Smitch.hayenga+gem5@gmail.com } 29411851Sbrandon.potter@amd.com 29510203SAli.Saidi@ARM.com switch (req) { 29611851Sbrandon.potter@amd.com case OS::TIOCISATTY: 29711851Sbrandon.potter@amd.com case OS::TIOCGETP: 2989455Smitch.hayenga+gem5@gmail.com case OS::TIOCSETP: 2999112Smarc.orr@gmail.com case OS::TIOCSETN: 30011906SBrandon.Potter@amd.com case OS::TIOCSETC: 30111906SBrandon.Potter@amd.com case OS::TIOCGETC: 3029112Smarc.orr@gmail.com case OS::TIOCGETS: 3039112Smarc.orr@gmail.com case OS::TIOCGETA: 30411851Sbrandon.potter@amd.com return -ENOTTY; 3059112Smarc.orr@gmail.com 3069112Smarc.orr@gmail.com default: 3079112Smarc.orr@gmail.com fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", 3089112Smarc.orr@gmail.com fd, req, xc->readPC()); 3099112Smarc.orr@gmail.com } 3109112Smarc.orr@gmail.com} 3119112Smarc.orr@gmail.com 3129112Smarc.orr@gmail.com/// Target open() handler. 3139112Smarc.orr@gmail.comtemplate <class OS> 3149112Smarc.orr@gmail.comSyscallReturn 3159112Smarc.orr@gmail.comopenFunc(SyscallDesc *desc, int callnum, Process *process, 3169112Smarc.orr@gmail.com ExecContext *xc) 3179112Smarc.orr@gmail.com{ 3189112Smarc.orr@gmail.com std::string path; 3199112Smarc.orr@gmail.com 32011886Sbrandon.potter@amd.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 3219112Smarc.orr@gmail.com return -EFAULT; 3229112Smarc.orr@gmail.com 3239238Slluc.alvarez@bsc.es if (path == "/dev/sysdev0") { 3249112Smarc.orr@gmail.com // This is a memory-mapped high-resolution timer device on Alpha. 3259112Smarc.orr@gmail.com // We don't support it, so just punt. 3269112Smarc.orr@gmail.com warn("Ignoring open(%s, ...)\n", path); 32711886Sbrandon.potter@amd.com return -ENOENT; 3289112Smarc.orr@gmail.com } 3299112Smarc.orr@gmail.com 3309112Smarc.orr@gmail.com int tgtFlags = xc->getSyscallArg(1); 3319112Smarc.orr@gmail.com int mode = xc->getSyscallArg(2); 3329112Smarc.orr@gmail.com int hostFlags = 0; 3339112Smarc.orr@gmail.com 33411367Sandreas.hansson@arm.com // translate open flags 3359112Smarc.orr@gmail.com for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { 33611321Ssteve.reinhardt@amd.com if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 33711886Sbrandon.potter@amd.com tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 3389112Smarc.orr@gmail.com hostFlags |= OS::openFlagTable[i].hostFlag; 3399112Smarc.orr@gmail.com } 3409112Smarc.orr@gmail.com } 3419112Smarc.orr@gmail.com 3429112Smarc.orr@gmail.com // any target flags left? 3439112Smarc.orr@gmail.com if (tgtFlags != 0) 3449112Smarc.orr@gmail.com warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 3459112Smarc.orr@gmail.com 3469112Smarc.orr@gmail.com#ifdef __CYGWIN32__ 3479112Smarc.orr@gmail.com hostFlags |= O_BINARY; 3489112Smarc.orr@gmail.com#endif 3499112Smarc.orr@gmail.com 3509112Smarc.orr@gmail.com DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); 3519112Smarc.orr@gmail.com 35211886Sbrandon.potter@amd.com // open the file 35311886Sbrandon.potter@amd.com int fd = open(path.c_str(), hostFlags, mode); 3549112Smarc.orr@gmail.com 3559112Smarc.orr@gmail.com return (fd == -1) ? -errno : process->alloc_fd(fd); 3569112Smarc.orr@gmail.com} 3579112Smarc.orr@gmail.com 3589112Smarc.orr@gmail.com 3599112Smarc.orr@gmail.com/// Target chmod() handler. 3609112Smarc.orr@gmail.comtemplate <class OS> 3619112Smarc.orr@gmail.comSyscallReturn 3629112Smarc.orr@gmail.comchmodFunc(SyscallDesc *desc, int callnum, Process *process, 3639112Smarc.orr@gmail.com ExecContext *xc) 3649112Smarc.orr@gmail.com{ 3659112Smarc.orr@gmail.com std::string path; 36611321Ssteve.reinhardt@amd.com 3679112Smarc.orr@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 3689112Smarc.orr@gmail.com return -EFAULT; 3699112Smarc.orr@gmail.com 3709112Smarc.orr@gmail.com uint32_t mode = xc->getSyscallArg(1); 37111886Sbrandon.potter@amd.com mode_t hostMode = 0; 37211886Sbrandon.potter@amd.com 37311886Sbrandon.potter@amd.com // XXX translate mode flags via OS::something??? 3749112Smarc.orr@gmail.com hostMode = mode; 3759112Smarc.orr@gmail.com 37611886Sbrandon.potter@amd.com // do the chmod 3779112Smarc.orr@gmail.com int result = chmod(path.c_str(), hostMode); 3789112Smarc.orr@gmail.com if (result < 0) 3799112Smarc.orr@gmail.com return errno; 3809112Smarc.orr@gmail.com 3819112Smarc.orr@gmail.com return 0; 3822238SN/A} 3832238SN/A 3842238SN/A 3852238SN/A/// Target fchmod() handler. 38611851Sbrandon.potter@amd.comtemplate <class OS> 3872238SN/ASyscallReturn 3882238SN/AfchmodFunc(SyscallDesc *desc, int callnum, Process *process, 3892238SN/A ExecContext *xc) 39011851Sbrandon.potter@amd.com{ 3912238SN/A int fd = xc->getSyscallArg(0); 3922238SN/A if (fd < 0 || process->sim_fd(fd) < 0) { 3932238SN/A // doesn't map to any simulator fd: not a valid target fd 39411851Sbrandon.potter@amd.com return -EBADF; 3952238SN/A } 3962238SN/A 3972238SN/A uint32_t mode = xc->getSyscallArg(1); 39811851Sbrandon.potter@amd.com mode_t hostMode = 0; 3992238SN/A 4002238SN/A // XXX translate mode flags via OS::someting??? 4011354SN/A hostMode = mode; 4021354SN/A 40310796Sbrandon.potter@amd.com // do the fchmod 40410796Sbrandon.potter@amd.com int result = fchmod(process->sim_fd(fd), hostMode); 4051354SN/A if (result < 0) 4061354SN/A return errno; 4071354SN/A 4081354SN/A return 0; 4091354SN/A} 4101354SN/A 4111354SN/A 4121354SN/A/// Target stat() handler. 4131354SN/Atemplate <class OS> 4141354SN/ASyscallReturn 41510796Sbrandon.potter@amd.comstatFunc(SyscallDesc *desc, int callnum, Process *process, 4161354SN/A ExecContext *xc) 41710796Sbrandon.potter@amd.com{ 4181354SN/A std::string path; 4191354SN/A 4201354SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 4211354SN/A return -EFAULT; 42210796Sbrandon.potter@amd.com 42310796Sbrandon.potter@amd.com struct stat hostBuf; 42410796Sbrandon.potter@amd.com int result = stat(path.c_str(), &hostBuf); 42510796Sbrandon.potter@amd.com 42610796Sbrandon.potter@amd.com if (result < 0) 42710796Sbrandon.potter@amd.com return errno; 42810796Sbrandon.potter@amd.com 42910796Sbrandon.potter@amd.com OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 43010796Sbrandon.potter@amd.com 43110796Sbrandon.potter@amd.com return 0; 43210796Sbrandon.potter@amd.com} 433360SN/A 434360SN/A 435360SN/A/// Target fstat64() handler. 436360SN/Atemplate <class OS> 437360SN/ASyscallReturn 438360SN/Afstat64Func(SyscallDesc *desc, int callnum, Process *process, 439360SN/A ExecContext *xc) 44011759Sbrandon.potter@amd.com{ 4413113Sgblack@eecs.umich.edu int fd = xc->getSyscallArg(0); 4423113Sgblack@eecs.umich.edu if (fd < 0 || process->sim_fd(fd) < 0) { 4433113Sgblack@eecs.umich.edu // doesn't map to any simulator fd: not a valid target fd 4443113Sgblack@eecs.umich.edu return -EBADF; 4453113Sgblack@eecs.umich.edu } 4463113Sgblack@eecs.umich.edu 4473113Sgblack@eecs.umich.edu#ifdef BSD_HOST 4483113Sgblack@eecs.umich.edu struct stat hostBuf; 4493113Sgblack@eecs.umich.edu int result = fstat(process->sim_fd(fd), &hostBuf); 4503113Sgblack@eecs.umich.edu#else 4513113Sgblack@eecs.umich.edu struct stat64 hostBuf; 4523113Sgblack@eecs.umich.edu int result = fstat64(process->sim_fd(fd), &hostBuf); 4533113Sgblack@eecs.umich.edu#endif 4543113Sgblack@eecs.umich.edu 4553113Sgblack@eecs.umich.edu if (result < 0) 4563113Sgblack@eecs.umich.edu return errno; 4574189Sgblack@eecs.umich.edu 4584189Sgblack@eecs.umich.edu OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); 4593113Sgblack@eecs.umich.edu 4603113Sgblack@eecs.umich.edu return 0; 4613113Sgblack@eecs.umich.edu} 4623113Sgblack@eecs.umich.edu 4638737Skoansin.tan@gmail.com 4643113Sgblack@eecs.umich.edu/// Target lstat() handler. 4658737Skoansin.tan@gmail.comtemplate <class OS> 4663277Sgblack@eecs.umich.eduSyscallReturn 4675515SMichael.Adler@intel.comlstatFunc(SyscallDesc *desc, int callnum, Process *process, 4685515SMichael.Adler@intel.com ExecContext *xc) 4695515SMichael.Adler@intel.com{ 4705515SMichael.Adler@intel.com std::string path; 4715515SMichael.Adler@intel.com 4728737Skoansin.tan@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 4733277Sgblack@eecs.umich.edu return -EFAULT; 4748737Skoansin.tan@gmail.com 4753277Sgblack@eecs.umich.edu struct stat hostBuf; 4768737Skoansin.tan@gmail.com int result = lstat(path.c_str(), &hostBuf); 4773277Sgblack@eecs.umich.edu 4788737Skoansin.tan@gmail.com if (result < 0) 4793113Sgblack@eecs.umich.edu return -errno; 4803113Sgblack@eecs.umich.edu 4813113Sgblack@eecs.umich.edu OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 4823113Sgblack@eecs.umich.edu 4838737Skoansin.tan@gmail.com return 0; 4843113Sgblack@eecs.umich.edu} 4858737Skoansin.tan@gmail.com 4863114Sgblack@eecs.umich.edu/// Target lstat64() handler. 4878737Skoansin.tan@gmail.comtemplate <class OS> 4883114Sgblack@eecs.umich.eduSyscallReturn 4898737Skoansin.tan@gmail.comlstat64Func(SyscallDesc *desc, int callnum, Process *process, 4903114Sgblack@eecs.umich.edu ExecContext *xc) 4918737Skoansin.tan@gmail.com{ 49211906SBrandon.Potter@amd.com std::string path; 4934061Sgblack@eecs.umich.edu 4944061Sgblack@eecs.umich.edu if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 4958737Skoansin.tan@gmail.com return -EFAULT; 4963113Sgblack@eecs.umich.edu 4978737Skoansin.tan@gmail.com#ifdef BSD_HOST 4983113Sgblack@eecs.umich.edu struct stat hostBuf; 4993113Sgblack@eecs.umich.edu int result = lstat(path.c_str(), &hostBuf); 5003113Sgblack@eecs.umich.edu#else 5013113Sgblack@eecs.umich.edu struct stat64 hostBuf; 5023113Sgblack@eecs.umich.edu int result = lstat64(path.c_str(), &hostBuf); 5033113Sgblack@eecs.umich.edu#endif 5043113Sgblack@eecs.umich.edu 5053113Sgblack@eecs.umich.edu if (result < 0) 5064189Sgblack@eecs.umich.edu return -errno; 5074189Sgblack@eecs.umich.edu 5083113Sgblack@eecs.umich.edu OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); 5093113Sgblack@eecs.umich.edu 5103113Sgblack@eecs.umich.edu return 0; 5118737Skoansin.tan@gmail.com} 5123113Sgblack@eecs.umich.edu 5138737Skoansin.tan@gmail.com/// Target fstat() handler. 5143113Sgblack@eecs.umich.edutemplate <class OS> 5158737Skoansin.tan@gmail.comSyscallReturn 5163113Sgblack@eecs.umich.edufstatFunc(SyscallDesc *desc, int callnum, Process *process, 5173113Sgblack@eecs.umich.edu ExecContext *xc) 5183113Sgblack@eecs.umich.edu{ 5193113Sgblack@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 5203113Sgblack@eecs.umich.edu 5213113Sgblack@eecs.umich.edu DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); 5223113Sgblack@eecs.umich.edu 52311906SBrandon.Potter@amd.com if (fd < 0) 5243113Sgblack@eecs.umich.edu return -EBADF; 5253113Sgblack@eecs.umich.edu 5268852Sandreas.hansson@arm.com struct stat hostBuf; 52711906SBrandon.Potter@amd.com int result = fstat(fd, &hostBuf); 5283113Sgblack@eecs.umich.edu 5293113Sgblack@eecs.umich.edu if (result < 0) 5303113Sgblack@eecs.umich.edu return -errno; 5313113Sgblack@eecs.umich.edu 5323113Sgblack@eecs.umich.edu OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 5333113Sgblack@eecs.umich.edu return 0; 5343113Sgblack@eecs.umich.edu} 5353113Sgblack@eecs.umich.edu 5363113Sgblack@eecs.umich.edu 5378852Sandreas.hansson@arm.com/// Target statfs() handler. 53811906SBrandon.Potter@amd.comtemplate <class OS> 5393113Sgblack@eecs.umich.eduSyscallReturn 5403113Sgblack@eecs.umich.edustatfsFunc(SyscallDesc *desc, int callnum, Process *process, 5413113Sgblack@eecs.umich.edu ExecContext *xc) 5426686Stjones1@inf.ed.ac.uk{ 5433113Sgblack@eecs.umich.edu std::string path; 5443113Sgblack@eecs.umich.edu 5453113Sgblack@eecs.umich.edu if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 54611759Sbrandon.potter@amd.com return -EFAULT; 54711759Sbrandon.potter@amd.com 54811759Sbrandon.potter@amd.com struct statfs hostBuf; 54911759Sbrandon.potter@amd.com int result = statfs(path.c_str(), &hostBuf); 55011759Sbrandon.potter@amd.com 55111759Sbrandon.potter@amd.com if (result < 0) 55211759Sbrandon.potter@amd.com return errno; 55311812Sbaz21@cam.ac.uk 55411812Sbaz21@cam.ac.uk OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 55511812Sbaz21@cam.ac.uk 55611759Sbrandon.potter@amd.com return 0; 55711812Sbaz21@cam.ac.uk} 55811759Sbrandon.potter@amd.com 55911759Sbrandon.potter@amd.com 56011759Sbrandon.potter@amd.com/// Target fstatfs() handler. 56111759Sbrandon.potter@amd.comtemplate <class OS> 56211759Sbrandon.potter@amd.comSyscallReturn 56311759Sbrandon.potter@amd.comfstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 56411759Sbrandon.potter@amd.com ExecContext *xc) 56511812Sbaz21@cam.ac.uk{ 56611812Sbaz21@cam.ac.uk int fd = process->sim_fd(xc->getSyscallArg(0)); 56711812Sbaz21@cam.ac.uk 56811812Sbaz21@cam.ac.uk if (fd < 0) 56911812Sbaz21@cam.ac.uk return -EBADF; 57011812Sbaz21@cam.ac.uk 57111812Sbaz21@cam.ac.uk struct statfs hostBuf; 57211759Sbrandon.potter@amd.com int result = fstatfs(fd, &hostBuf); 57311759Sbrandon.potter@amd.com 57411812Sbaz21@cam.ac.uk if (result < 0) 57511812Sbaz21@cam.ac.uk return errno; 57611759Sbrandon.potter@amd.com 57711812Sbaz21@cam.ac.uk OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 57811812Sbaz21@cam.ac.uk 57911812Sbaz21@cam.ac.uk return 0; 58011812Sbaz21@cam.ac.uk} 58111812Sbaz21@cam.ac.uk 58211812Sbaz21@cam.ac.uk 58311812Sbaz21@cam.ac.uk/// Target writev() handler. 58411759Sbrandon.potter@amd.comtemplate <class OS> 58511759Sbrandon.potter@amd.comSyscallReturn 58611759Sbrandon.potter@amd.comwritevFunc(SyscallDesc *desc, int callnum, Process *process, 58711759Sbrandon.potter@amd.com ExecContext *xc) 588378SN/A{ 589378SN/A int fd = xc->getSyscallArg(0); 5909141Smarc.orr@gmail.com if (fd < 0 || process->sim_fd(fd) < 0) { 5919141Smarc.orr@gmail.com // doesn't map to any simulator fd: not a valid target fd 592360SN/A return -EBADF; 5931450SN/A } 59411856Sbrandon.potter@amd.com 595360SN/A uint64_t tiov_base = xc->getSyscallArg(1); 5966701Sgblack@eecs.umich.edu size_t count = xc->getSyscallArg(2); 59711856Sbrandon.potter@amd.com struct iovec hiov[count]; 59811856Sbrandon.potter@amd.com for (int i = 0; i < count; ++i) 599360SN/A { 60010930Sbrandon.potter@amd.com typename OS::tgt_iovec tiov; 601360SN/A xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), 60211856Sbrandon.potter@amd.com &tiov, sizeof(typename OS::tgt_iovec)); 60311856Sbrandon.potter@amd.com hiov[i].iov_len = tiov.iov_len; 60410496Ssteve.reinhardt@amd.com hiov[i].iov_base = new char [hiov[i].iov_len]; 60511856Sbrandon.potter@amd.com xc->mem->access(Read, tiov.iov_base, 60611856Sbrandon.potter@amd.com hiov[i].iov_base, hiov[i].iov_len); 6071458SN/A } 608360SN/A 60911856Sbrandon.potter@amd.com int result = writev(process->sim_fd(fd), hiov, count); 61011856Sbrandon.potter@amd.com 61111856Sbrandon.potter@amd.com for (int i = 0; i < count; ++i) 61211856Sbrandon.potter@amd.com { 61311856Sbrandon.potter@amd.com delete [] (char *)hiov[i].iov_base; 61411856Sbrandon.potter@amd.com } 61511856Sbrandon.potter@amd.com 61611856Sbrandon.potter@amd.com if (result < 0) 61710496Ssteve.reinhardt@amd.com return errno; 61811856Sbrandon.potter@amd.com 61911856Sbrandon.potter@amd.com return 0; 62011856Sbrandon.potter@amd.com} 62111856Sbrandon.potter@amd.com 62211856Sbrandon.potter@amd.com 62310930Sbrandon.potter@amd.com/// Target mmap() handler. 6249141Smarc.orr@gmail.com/// 625360SN/A/// We don't really handle mmap(). If the target is mmaping an 626360SN/A/// anonymous region or /dev/zero, we can get away with doing basically 627360SN/A/// nothing (since memory is initialized to zero and the simulator 62811907SBrandon.Potter@amd.com/// doesn't really check addresses anyway). Always print a warning, 62911907SBrandon.Potter@amd.com/// since this could be seriously broken if we're not mapping 63011907SBrandon.Potter@amd.com/// /dev/zero. 631360SN/A// 63211907SBrandon.Potter@amd.com/// Someday we should explicitly check for /dev/zero in open, flag the 63311907SBrandon.Potter@amd.com/// file descriptor, and fail (or implement!) a non-anonymous mmap to 63411907SBrandon.Potter@amd.com/// anything else. 63511907SBrandon.Potter@amd.comtemplate <class OS> 63611907SBrandon.Potter@amd.comSyscallReturn 63711907SBrandon.Potter@amd.commmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 63811907SBrandon.Potter@amd.com{ 63911907SBrandon.Potter@amd.com Addr start = xc->getSyscallArg(0); 64011907SBrandon.Potter@amd.com uint64_t length = xc->getSyscallArg(1); 64111907SBrandon.Potter@amd.com // int prot = xc->getSyscallArg(2); 64211907SBrandon.Potter@amd.com int flags = xc->getSyscallArg(3); 64311907SBrandon.Potter@amd.com // int fd = p->sim_fd(xc->getSyscallArg(4)); 64411907SBrandon.Potter@amd.com // int offset = xc->getSyscallArg(5); 64511907SBrandon.Potter@amd.com 646360SN/A if (start == 0) { 64711907SBrandon.Potter@amd.com // user didn't give an address... pick one from our "mmap region" 6481458SN/A start = p->mmap_end; 649360SN/A p->mmap_end += roundUp(length, VMPageSize); 65011907SBrandon.Potter@amd.com if (p->nxm_start != 0) { 65111907SBrandon.Potter@amd.com //If we have an nxm space, make sure we haven't colided 65211907SBrandon.Potter@amd.com assert(p->mmap_end < p->nxm_start); 65311907SBrandon.Potter@amd.com } 65411907SBrandon.Potter@amd.com } 65511907SBrandon.Potter@amd.com 65611907SBrandon.Potter@amd.com if (!(flags & OS::TGT_MAP_ANONYMOUS)) { 65711907SBrandon.Potter@amd.com warn("allowing mmap of file @ fd %d. " 65811907SBrandon.Potter@amd.com "This will break if not /dev/zero.", xc->getSyscallArg(4)); 65911907SBrandon.Potter@amd.com } 660360SN/A 66111907SBrandon.Potter@amd.com return start; 66211907SBrandon.Potter@amd.com} 66311907SBrandon.Potter@amd.com 664360SN/A/// Target getrlimit() handler. 665360SN/Atemplate <class OS> 66611907SBrandon.Potter@amd.comSyscallReturn 66711907SBrandon.Potter@amd.comgetrlimitFunc(SyscallDesc *desc, int callnum, Process *process, 66811907SBrandon.Potter@amd.com ExecContext *xc) 66911907SBrandon.Potter@amd.com{ 670360SN/A unsigned resource = xc->getSyscallArg(0); 67111907SBrandon.Potter@amd.com TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); 672360SN/A 673360SN/A switch (resource) { 67411907SBrandon.Potter@amd.com case OS::TGT_RLIMIT_STACK: 6753669Sbinkertn@umich.edu // max stack size in bytes: make up a number (2MB for now) 67611907SBrandon.Potter@amd.com rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; 67711907SBrandon.Potter@amd.com break; 67811907SBrandon.Potter@amd.com 67911907SBrandon.Potter@amd.com default: 68011907SBrandon.Potter@amd.com std::cerr << "getrlimitFunc: unimplemented resource " << resource 68111907SBrandon.Potter@amd.com << std::endl; 68211907SBrandon.Potter@amd.com abort(); 68311907SBrandon.Potter@amd.com break; 68411907SBrandon.Potter@amd.com } 68511907SBrandon.Potter@amd.com 68611907SBrandon.Potter@amd.com rlp.copyOut(xc->mem); 68711907SBrandon.Potter@amd.com return 0; 68811907SBrandon.Potter@amd.com} 68911907SBrandon.Potter@amd.com 69011907SBrandon.Potter@amd.com/// Target gettimeofday() handler. 69111907SBrandon.Potter@amd.comtemplate <class OS> 69211907SBrandon.Potter@amd.comSyscallReturn 69311907SBrandon.Potter@amd.comgettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, 69411907SBrandon.Potter@amd.com ExecContext *xc) 69511907SBrandon.Potter@amd.com{ 69611907SBrandon.Potter@amd.com TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); 6971706SN/A 69811907SBrandon.Potter@amd.com getElapsedTime(tp->tv_sec, tp->tv_usec); 69911907SBrandon.Potter@amd.com tp->tv_sec += seconds_since_epoch; 70011907SBrandon.Potter@amd.com 70111907SBrandon.Potter@amd.com tp.copyOut(xc->mem); 70211907SBrandon.Potter@amd.com 70311907SBrandon.Potter@amd.com return 0; 70410496Ssteve.reinhardt@amd.com} 70510496Ssteve.reinhardt@amd.com 70611907SBrandon.Potter@amd.com 70711907SBrandon.Potter@amd.com/// Target utimes() handler. 70811907SBrandon.Potter@amd.comtemplate <class OS> 70911907SBrandon.Potter@amd.comSyscallReturn 71011907SBrandon.Potter@amd.comutimesFunc(SyscallDesc *desc, int callnum, Process *process, 71111907SBrandon.Potter@amd.com ExecContext *xc) 71210496Ssteve.reinhardt@amd.com{ 71311907SBrandon.Potter@amd.com std::string path; 71411907SBrandon.Potter@amd.com 71511907SBrandon.Potter@amd.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 71611907SBrandon.Potter@amd.com return -EFAULT; 71710496Ssteve.reinhardt@amd.com 71810496Ssteve.reinhardt@amd.com TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); 71911907SBrandon.Potter@amd.com tp.copyIn(xc->mem); 72011907SBrandon.Potter@amd.com 72111907SBrandon.Potter@amd.com struct timeval hostTimeval[2]; 72211907SBrandon.Potter@amd.com for (int i = 0; i < 2; ++i) 72311907SBrandon.Potter@amd.com { 72411907SBrandon.Potter@amd.com hostTimeval[i].tv_sec = (*tp)[i].tv_sec; 72511907SBrandon.Potter@amd.com hostTimeval[i].tv_usec = (*tp)[i].tv_usec; 72611907SBrandon.Potter@amd.com } 72711907SBrandon.Potter@amd.com int result = utimes(path.c_str(), hostTimeval); 72811907SBrandon.Potter@amd.com 72911907SBrandon.Potter@amd.com if (result < 0) 73011907SBrandon.Potter@amd.com return -errno; 73111907SBrandon.Potter@amd.com 73211907SBrandon.Potter@amd.com return 0; 73311907SBrandon.Potter@amd.com} 73411907SBrandon.Potter@amd.com/// Target getrusage() function. 73511907SBrandon.Potter@amd.comtemplate <class OS> 73611907SBrandon.Potter@amd.comSyscallReturn 73711907SBrandon.Potter@amd.comgetrusageFunc(SyscallDesc *desc, int callnum, Process *process, 73811907SBrandon.Potter@amd.com ExecContext *xc) 73911907SBrandon.Potter@amd.com{ 74011907SBrandon.Potter@amd.com int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN 74111907SBrandon.Potter@amd.com TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); 74211907SBrandon.Potter@amd.com 74311907SBrandon.Potter@amd.com if (who != OS::TGT_RUSAGE_SELF) { 744360SN/A // don't really handle THREAD or CHILDREN, but just warn and 74511907SBrandon.Potter@amd.com // plow ahead 74611907SBrandon.Potter@amd.com warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", 74711907SBrandon.Potter@amd.com who); 74811907SBrandon.Potter@amd.com } 74911907SBrandon.Potter@amd.com 75011907SBrandon.Potter@amd.com getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); 75111907SBrandon.Potter@amd.com rup->ru_stime.tv_sec = 0; 75211907SBrandon.Potter@amd.com rup->ru_stime.tv_usec = 0; 75311907SBrandon.Potter@amd.com rup->ru_maxrss = 0; 75411907SBrandon.Potter@amd.com rup->ru_ixrss = 0; 75511907SBrandon.Potter@amd.com rup->ru_idrss = 0; 75611907SBrandon.Potter@amd.com rup->ru_isrss = 0; 75711907SBrandon.Potter@amd.com rup->ru_minflt = 0; 758360SN/A rup->ru_majflt = 0; 759360SN/A rup->ru_nswap = 0; 76010027SChris.Adeniyi-Jones@arm.com rup->ru_inblock = 0; 76110027SChris.Adeniyi-Jones@arm.com rup->ru_oublock = 0; 76210027SChris.Adeniyi-Jones@arm.com rup->ru_msgsnd = 0; 76311851Sbrandon.potter@amd.com rup->ru_msgrcv = 0; 76410027SChris.Adeniyi-Jones@arm.com rup->ru_nsignals = 0; 76510027SChris.Adeniyi-Jones@arm.com rup->ru_nvcsw = 0; 76611907SBrandon.Potter@amd.com rup->ru_nivcsw = 0; 76710027SChris.Adeniyi-Jones@arm.com 76810027SChris.Adeniyi-Jones@arm.com rup.copyOut(xc->mem); 76910027SChris.Adeniyi-Jones@arm.com 77010027SChris.Adeniyi-Jones@arm.com return 0; 77110027SChris.Adeniyi-Jones@arm.com} 77211851Sbrandon.potter@amd.com 77311851Sbrandon.potter@amd.com#endif // __SIM_SYSCALL_EMUL_HH__ 77410027SChris.Adeniyi-Jones@arm.com