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 4812018Sandreas.sandberg@arm.com#include "base/intmath.hh" // for RoundUp 4912018Sandreas.sandberg@arm.com#include "mem/functional/functional.hh" 5012018Sandreas.sandberg@arm.com#include "targetarch/isa_traits.hh" // for Addr 5112018Sandreas.sandberg@arm.com 5212018Sandreas.sandberg@arm.com#include "base/trace.hh" 5312018Sandreas.sandberg@arm.com#include "cpu/exec_context.hh" 5412018Sandreas.sandberg@arm.com#include "sim/process.hh" 552064SN/A 56360SN/A/// 57360SN/A/// System call descriptor. 58360SN/A/// 59360SN/Aclass SyscallDesc { 60360SN/A 61360SN/A public: 6213936SAndrea.Mondelli@ucf.edu 6313933Sbrandon.potter@amd.com /// Typedef for target syscall handler functions. 6413933Sbrandon.potter@amd.com typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, 6513933Sbrandon.potter@amd.com Process *, ExecContext *); 6613936SAndrea.Mondelli@ucf.edu 6713936SAndrea.Mondelli@ucf.edu const char *name; //!< Syscall name (e.g., "open"). 6813936SAndrea.Mondelli@ucf.edu FuncPtr funcPtr; //!< Pointer to emulation function. 6913933Sbrandon.potter@amd.com int flags; //!< Flags (see Flags enum). 7013933Sbrandon.potter@amd.com 711809SN/A /// Flag values for controlling syscall behavior. 7211800Sbrandon.potter@amd.com enum Flags { 7311392Sbrandon.potter@amd.com /// Don't set return regs according to funcPtr return value. 741809SN/A /// Used for syscalls with non-standard return conventions 7511392Sbrandon.potter@amd.com /// that explicitly set the ExecContext regs (e.g., 7613902Sbrandon.potter@amd.com /// sigreturn). 7713570Sbrandon.potter@amd.com SuppressReturnValue = 1 7813902Sbrandon.potter@amd.com }; 7911383Sbrandon.potter@amd.com 8013568Sbrandon.potter@amd.com /// Constructor. 813113Sgblack@eecs.umich.edu SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) 828229Snate@binkert.org : name(_name), funcPtr(_funcPtr), flags(_flags) 8313570Sbrandon.potter@amd.com { 848229Snate@binkert.org } 8511594Santhony.gutierrez@amd.com 867075Snate@binkert.org /// Emulate the syscall. Public interface for calling through funcPtr. 878229Snate@binkert.org void doSyscall(int callnum, Process *proc, ExecContext *xc); 8811856Sbrandon.potter@amd.com}; 897075Snate@binkert.org 90360SN/A 9112461Sgabeblack@google.comclass BaseBufferArg { 9211886Sbrandon.potter@amd.com 9311800Sbrandon.potter@amd.com public: 9411392Sbrandon.potter@amd.com 9512334Sgabeblack@google.com BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) 961354SN/A { 976216Snate@binkert.org bufPtr = new uint8_t[size]; 986658Snate@binkert.org // clear out buffer: in case we only partially populate this, 992474SN/A // and then do a copyOut(), we want to make sure we don't 1002680Sktlim@umich.edu // introduce any random junk into the simulated address space 1018229Snate@binkert.org memset(bufPtr, 0, size); 10211886Sbrandon.potter@amd.com } 10310496Ssteve.reinhardt@amd.com 10411911SBrandon.Potter@amd.com virtual ~BaseBufferArg() { delete [] bufPtr; } 1058229Snate@binkert.org 10611794Sbrandon.potter@amd.com // 10711886Sbrandon.potter@amd.com // copy data into simulator space (read from target memory) 10810497Ssteve.reinhardt@amd.com // 10911794Sbrandon.potter@amd.com virtual bool copyIn(FunctionalMemory *mem) 110360SN/A { 11113629SAndrea.Mondelli@ucf.edu mem->access(Read, addr, bufPtr, size); 11213629SAndrea.Mondelli@ucf.edu return true; // no EFAULT detection for now 11313629SAndrea.Mondelli@ucf.edu } 11413629SAndrea.Mondelli@ucf.edu 115360SN/A // 116360SN/A // copy data out of simulator space (write to target memory) 117360SN/A // 118360SN/A virtual bool copyOut(FunctionalMemory *mem) 119360SN/A { 120360SN/A mem->access(Write, addr, bufPtr, size); 121360SN/A return true; // no EFAULT detection for now 122360SN/A } 12313933Sbrandon.potter@amd.com 124360SN/A protected: 125378SN/A Addr addr; 12613995Sbrandon.potter@amd.com int size; 127378SN/A uint8_t *bufPtr; 128378SN/A}; 129378SN/A 130378SN/A 131378SN/Aclass BufferArg : public BaseBufferArg 13213995Sbrandon.potter@amd.com{ 133360SN/A public: 13411760Sbrandon.potter@amd.com BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 13513995Sbrandon.potter@amd.com void *bufferPtr() { return bufPtr; } 13611760Sbrandon.potter@amd.com}; 1376109Ssanchezd@stanford.edu 13813995Sbrandon.potter@amd.comtemplate <class T> 139378SN/Aclass TypedBufferArg : public BaseBufferArg 1406109Ssanchezd@stanford.edu{ 14113995Sbrandon.potter@amd.com public: 1426109Ssanchezd@stanford.edu // user can optionally specify a specific number of bytes to 14311886Sbrandon.potter@amd.com // allocate to deal with those structs that have variable-size 14413995Sbrandon.potter@amd.com // arrays at the end 14511886Sbrandon.potter@amd.com TypedBufferArg(Addr _addr, int _size = sizeof(T)) 146378SN/A : BaseBufferArg(_addr, _size) 14713995Sbrandon.potter@amd.com { } 148378SN/A 1495748SSteve.Reinhardt@amd.com // type case 15013995Sbrandon.potter@amd.com operator T*() { return (T *)bufPtr; } 151378SN/A 152378SN/A // dereference operators 15313995Sbrandon.potter@amd.com T &operator*() { return *((T *)bufPtr); } 154378SN/A T* operator->() { return (T *)bufPtr; } 155378SN/A T &operator[](int i) { return ((T *)bufPtr)[i]; } 15613995Sbrandon.potter@amd.com}; 157378SN/A 1584118Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////// 15913995Sbrandon.potter@amd.com// 1604118Sgblack@eecs.umich.edu// The following emulation functions are generic enough that they 161378SN/A// don't need to be recompiled for different emulated OS's. They are 16213995Sbrandon.potter@amd.com// defined in sim/syscall_emul.cc. 163378SN/A// 16413568Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////// 16513995Sbrandon.potter@amd.com 16613568Sbrandon.potter@amd.com 167378SN/A/// Handler for unimplemented syscalls that we haven't thought about. 16813995Sbrandon.potter@amd.comSyscallReturn unimplementedFunc(SyscallDesc *desc, int num, 169360SN/A Process *p, ExecContext *xc); 1705513SMichael.Adler@intel.com 17113995Sbrandon.potter@amd.com/// Handler for unimplemented syscalls that we never intend to 1725513SMichael.Adler@intel.com/// implement (signal handling, etc.) and should not affect the correct 17310203SAli.Saidi@ARM.com/// behavior of the program. Print a warning only if the appropriate 17413995Sbrandon.potter@amd.com/// trace flag is enabled. Return success to the target program. 17510203SAli.Saidi@ARM.comSyscallReturn ignoreFunc(SyscallDesc *desc, int num, 17613995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 1775513SMichael.Adler@intel.com 178511SN/A/// Target exit() handler: terminate simulation. 17913995Sbrandon.potter@amd.comSyscallReturn exitFunc(SyscallDesc *desc, int num, 18010633Smichaelupton@gmail.com Process *p, ExecContext *xc); 18113995Sbrandon.potter@amd.com 182511SN/A/// Target getpagesize() handler. 18312795Smattdsinclair@gmail.comSyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, 18413995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 18512795Smattdsinclair@gmail.com 18612796Smattdsinclair@gmail.com/// Target obreak() handler: set brk address. 18713995Sbrandon.potter@amd.comSyscallReturn obreakFunc(SyscallDesc *desc, int num, 18812796Smattdsinclair@gmail.com Process *p, ExecContext *xc); 1895513SMichael.Adler@intel.com 19013995Sbrandon.potter@amd.com/// Target close() handler. 1915513SMichael.Adler@intel.comSyscallReturn closeFunc(SyscallDesc *desc, int num, 19213031Sbrandon.potter@amd.com Process *p, ExecContext *xc); 19313995Sbrandon.potter@amd.com 19413031Sbrandon.potter@amd.com/// Target read() handler. 19513031Sbrandon.potter@amd.comSyscallReturn readFunc(SyscallDesc *desc, int num, 19613995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 19713031Sbrandon.potter@amd.com 19813031Sbrandon.potter@amd.com/// Target write() handler. 19913995Sbrandon.potter@amd.comSyscallReturn writeFunc(SyscallDesc *desc, int num, 20013031Sbrandon.potter@amd.com Process *p, ExecContext *xc); 201511SN/A 20213995Sbrandon.potter@amd.com/// Target lseek() handler. 2031706SN/ASyscallReturn lseekFunc(SyscallDesc *desc, int num, 2041706SN/A Process *p, ExecContext *xc); 2051706SN/A 20613995Sbrandon.potter@amd.com/// Target munmap() handler. 2071706SN/ASyscallReturn munmapFunc(SyscallDesc *desc, int num, 2081706SN/A Process *p, ExecContext *xc); 2091706SN/A 21013995Sbrandon.potter@amd.com/// Target gethostname() handler. 2111706SN/ASyscallReturn gethostnameFunc(SyscallDesc *desc, int num, 212511SN/A Process *p, ExecContext *xc); 2136703Svince@csl.cornell.edu 21413995Sbrandon.potter@amd.com/// Target unlink() handler. 2156703Svince@csl.cornell.eduSyscallReturn unlinkFunc(SyscallDesc *desc, int num, 2166685Stjones1@inf.ed.ac.uk Process *p, ExecContext *xc); 21713995Sbrandon.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); 22113995Sbrandon.potter@amd.com 2225513SMichael.Adler@intel.com 22311885Sbrandon.potter@amd.com/// Target truncate() handler. 22413995Sbrandon.potter@amd.comSyscallReturn truncateFunc(SyscallDesc *desc, int num, 2255513SMichael.Adler@intel.com Process *p, ExecContext *xc); 2261999SN/A 22713995Sbrandon.potter@amd.com 2281999SN/A/// Target ftruncate() handler. 22911885Sbrandon.potter@amd.comSyscallReturn ftruncateFunc(SyscallDesc *desc, int num, 23013995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 2311999SN/A 2321999SN/A 23313995Sbrandon.potter@amd.com/// Target chown() handler. 2341999SN/ASyscallReturn chownFunc(SyscallDesc *desc, int num, 2353079Sstever@eecs.umich.edu Process *p, ExecContext *xc); 23613995Sbrandon.potter@amd.com 2373079Sstever@eecs.umich.edu 23811908SBrandon.Potter@amd.com/// Target fchown() handler. 23913995Sbrandon.potter@amd.comSyscallReturn fchownFunc(SyscallDesc *desc, int num, 24011908SBrandon.Potter@amd.com Process *p, ExecContext *xc); 24111875Sbrandon.potter@amd.com 24213995Sbrandon.potter@amd.com/// This struct is used to build an target-OS-dependent table that 2432093SN/A/// maps the target's open() flags to the host open() flags. 2442687Sksewell@umich.edustruct OpenFlagTransTable { 24513995Sbrandon.potter@amd.com int tgtFlag; //!< Target system flag value. 2462687Sksewell@umich.edu int hostFlag; //!< Corresponding host system flag value. 2472238SN/A}; 24813995Sbrandon.potter@amd.com 2492238SN/A 25011908SBrandon.Potter@amd.com 25113995Sbrandon.potter@amd.com/// A readable name for 1,000,000, for converting microseconds to seconds. 25211908SBrandon.Potter@amd.comconst int one_million = 1000000; 25311908SBrandon.Potter@amd.com 25413995Sbrandon.potter@amd.com/// Approximate seconds since the epoch (1/1/1970). About a billion, 25513995Sbrandon.potter@amd.com/// by my reckoning. We want to keep this a constant (not use the 25611908SBrandon.Potter@amd.com/// real-world time) to keep simulations repeatable. 2572238SN/Aconst unsigned seconds_since_epoch = 1000000000; 25813995Sbrandon.potter@amd.com 2592238SN/A/// Helper function to convert current elapsed time to seconds and 26013571Sbrandon.potter@amd.com/// microseconds. 26113995Sbrandon.potter@amd.comtemplate <class T1, class T2> 26213571Sbrandon.potter@amd.comvoid 26313568Sbrandon.potter@amd.comgetElapsedTime(T1 &sec, T2 &usec) 26413995Sbrandon.potter@amd.com{ 26513568Sbrandon.potter@amd.com int elapsed_usecs = curTick / Clock::Int::us; 26613568Sbrandon.potter@amd.com sec = elapsed_usecs / one_million; 26713995Sbrandon.potter@amd.com usec = elapsed_usecs % one_million; 26813568Sbrandon.potter@amd.com} 26913568Sbrandon.potter@amd.com 27013995Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////// 27113568Sbrandon.potter@amd.com// 27213448Sciro.santilli@arm.com// The following emulation functions are generic, but need to be 27313031Sbrandon.potter@amd.com// templated to account for differences in types, constants, etc. 27413995Sbrandon.potter@amd.com// 27513448Sciro.santilli@arm.com////////////////////////////////////////////////////////////////////// 27613031Sbrandon.potter@amd.com 27713539Sjavier.setoain@arm.com/// Target ioctl() handler. For the most part, programs call ioctl() 27813539Sjavier.setoain@arm.com/// only to find out if their stdout is a tty, to determine whether to 27913995Sbrandon.potter@amd.com/// do line or block buffering. 28013539Sjavier.setoain@arm.comtemplate <class OS> 28113539Sjavier.setoain@arm.comSyscallReturn 28213569Sbrandon.potter@amd.comioctlFunc(SyscallDesc *desc, int callnum, Process *process, 28313995Sbrandon.potter@amd.com ExecContext *xc) 28413569Sbrandon.potter@amd.com{ 28513569Sbrandon.potter@amd.com int fd = xc->getSyscallArg(0); 28613995Sbrandon.potter@amd.com unsigned req = xc->getSyscallArg(1); 28713569Sbrandon.potter@amd.com 28813569Sbrandon.potter@amd.com DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); 28913995Sbrandon.potter@amd.com 29013569Sbrandon.potter@amd.com if (fd < 0 || process->sim_fd(fd) < 0) { 29113569Sbrandon.potter@amd.com // doesn't map to any simulator fd: not a valid target fd 29213995Sbrandon.potter@amd.com return -EBADF; 29313569Sbrandon.potter@amd.com } 29413031Sbrandon.potter@amd.com 29513995Sbrandon.potter@amd.com switch (req) { 2962238SN/A case OS::TIOCISATTY: 2972238SN/A case OS::TIOCGETP: 29813995Sbrandon.potter@amd.com case OS::TIOCSETP: 2992238SN/A case OS::TIOCSETN: 3002238SN/A case OS::TIOCSETC: 30113995Sbrandon.potter@amd.com case OS::TIOCGETC: 3022238SN/A case OS::TIOCGETS: 3032238SN/A case OS::TIOCGETA: 30413995Sbrandon.potter@amd.com return -ENOTTY; 3052238SN/A 3062238SN/A default: 30713995Sbrandon.potter@amd.com fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", 3082238SN/A fd, req, xc->readPC()); 3099455Smitch.hayenga+gem5@gmail.com } 31013995Sbrandon.potter@amd.com} 31113995Sbrandon.potter@amd.com 31211851Sbrandon.potter@amd.com/// Target open() handler. 3139455Smitch.hayenga+gem5@gmail.comtemplate <class OS> 31413571Sbrandon.potter@amd.comSyscallReturn 31513995Sbrandon.potter@amd.comopenFunc(SyscallDesc *desc, int callnum, Process *process, 31613571Sbrandon.potter@amd.com ExecContext *xc) 31713571Sbrandon.potter@amd.com{ 31813995Sbrandon.potter@amd.com std::string path; 31913571Sbrandon.potter@amd.com 32013571Sbrandon.potter@amd.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 32113995Sbrandon.potter@amd.com return -EFAULT; 32213571Sbrandon.potter@amd.com 3239112Smarc.orr@gmail.com if (path == "/dev/sysdev0") { 32411906SBrandon.Potter@amd.com // This is a memory-mapped high-resolution timer device on Alpha. 32511906SBrandon.Potter@amd.com // We don't support it, so just punt. 3269112Smarc.orr@gmail.com warn("Ignoring open(%s, ...)\n", path); 3279112Smarc.orr@gmail.com return -ENOENT; 32813995Sbrandon.potter@amd.com } 3299112Smarc.orr@gmail.com 33011911SBrandon.Potter@amd.com int tgtFlags = xc->getSyscallArg(1); 3319112Smarc.orr@gmail.com int mode = xc->getSyscallArg(2); 33211911SBrandon.Potter@amd.com int hostFlags = 0; 33313995Sbrandon.potter@amd.com 33413995Sbrandon.potter@amd.com // translate open flags 33511911SBrandon.Potter@amd.com for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { 33611911SBrandon.Potter@amd.com if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 33711911SBrandon.Potter@amd.com tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 33813642Sqtt2@cornell.edu hostFlags |= OS::openFlagTable[i].hostFlag; 33913642Sqtt2@cornell.edu } 34013642Sqtt2@cornell.edu } 3419112Smarc.orr@gmail.com 34211911SBrandon.Potter@amd.com // any target flags left? 34311911SBrandon.Potter@amd.com if (tgtFlags != 0) 34411911SBrandon.Potter@amd.com warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 34511911SBrandon.Potter@amd.com 3469238Slluc.alvarez@bsc.es#ifdef __CYGWIN32__ 34713642Sqtt2@cornell.edu hostFlags |= O_BINARY; 3489112Smarc.orr@gmail.com#endif 34911911SBrandon.Potter@amd.com 3509112Smarc.orr@gmail.com DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); 35113642Sqtt2@cornell.edu 35211911SBrandon.Potter@amd.com // open the file 35311911SBrandon.Potter@amd.com int fd = open(path.c_str(), hostFlags, mode); 35411911SBrandon.Potter@amd.com 35511911SBrandon.Potter@amd.com return (fd == -1) ? -errno : process->alloc_fd(fd); 3569112Smarc.orr@gmail.com} 35711911SBrandon.Potter@amd.com 35811911SBrandon.Potter@amd.com 35911911SBrandon.Potter@amd.com/// Target chmod() handler. 36011911SBrandon.Potter@amd.comtemplate <class OS> 36111911SBrandon.Potter@amd.comSyscallReturn 36211911SBrandon.Potter@amd.comchmodFunc(SyscallDesc *desc, int callnum, Process *process, 3639112Smarc.orr@gmail.com ExecContext *xc) 3649112Smarc.orr@gmail.com{ 36513642Sqtt2@cornell.edu std::string path; 36613642Sqtt2@cornell.edu 36713642Sqtt2@cornell.edu if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 36813642Sqtt2@cornell.edu return -EFAULT; 36913642Sqtt2@cornell.edu 37011911SBrandon.Potter@amd.com uint32_t mode = xc->getSyscallArg(1); 3719112Smarc.orr@gmail.com mode_t hostMode = 0; 37211911SBrandon.Potter@amd.com 37311911SBrandon.Potter@amd.com // XXX translate mode flags via OS::something??? 37413642Sqtt2@cornell.edu hostMode = mode; 37513642Sqtt2@cornell.edu 37613650Smw828@cornell.edu // do the chmod 37713650Smw828@cornell.edu int result = chmod(path.c_str(), hostMode); 37813650Smw828@cornell.edu if (result < 0) 37913650Smw828@cornell.edu return errno; 38013650Smw828@cornell.edu 38113650Smw828@cornell.edu return 0; 38213650Smw828@cornell.edu} 38313650Smw828@cornell.edu 38413650Smw828@cornell.edu 38513650Smw828@cornell.edu/// Target fchmod() handler. 38613650Smw828@cornell.edutemplate <class OS> 38713650Smw828@cornell.eduSyscallReturn 38813650Smw828@cornell.edufchmodFunc(SyscallDesc *desc, int callnum, Process *process, 38913650Smw828@cornell.edu ExecContext *xc) 39013651Smw828@cornell.edu{ 39113651Smw828@cornell.edu int fd = xc->getSyscallArg(0); 39213651Smw828@cornell.edu if (fd < 0 || process->sim_fd(fd) < 0) { 39313651Smw828@cornell.edu // doesn't map to any simulator fd: not a valid target fd 39413651Smw828@cornell.edu return -EBADF; 39513651Smw828@cornell.edu } 39613651Smw828@cornell.edu 39713651Smw828@cornell.edu uint32_t mode = xc->getSyscallArg(1); 39813651Smw828@cornell.edu mode_t hostMode = 0; 39913651Smw828@cornell.edu 40013651Smw828@cornell.edu // XXX translate mode flags via OS::someting??? 40113651Smw828@cornell.edu hostMode = mode; 40213651Smw828@cornell.edu 40313651Smw828@cornell.edu // do the fchmod 40413651Smw828@cornell.edu int result = fchmod(process->sim_fd(fd), hostMode); 40513651Smw828@cornell.edu if (result < 0) 40613651Smw828@cornell.edu return errno; 40713651Smw828@cornell.edu 40813651Smw828@cornell.edu return 0; 40913651Smw828@cornell.edu} 41013651Smw828@cornell.edu 41113651Smw828@cornell.edu 41213651Smw828@cornell.edu/// Target stat() handler. 41313651Smw828@cornell.edutemplate <class OS> 41413651Smw828@cornell.eduSyscallReturn 41513651Smw828@cornell.edustatFunc(SyscallDesc *desc, int callnum, Process *process, 41613651Smw828@cornell.edu ExecContext *xc) 41713651Smw828@cornell.edu{ 41813651Smw828@cornell.edu std::string path; 41913651Smw828@cornell.edu 42013651Smw828@cornell.edu if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 42113651Smw828@cornell.edu return -EFAULT; 42213651Smw828@cornell.edu 42313651Smw828@cornell.edu struct stat hostBuf; 42413651Smw828@cornell.edu int result = stat(path.c_str(), &hostBuf); 42513651Smw828@cornell.edu 42613651Smw828@cornell.edu if (result < 0) 42713651Smw828@cornell.edu return errno; 42813651Smw828@cornell.edu 42913651Smw828@cornell.edu OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 43013651Smw828@cornell.edu 43113651Smw828@cornell.edu return 0; 43213651Smw828@cornell.edu} 43313651Smw828@cornell.edu 43413651Smw828@cornell.edu 43513651Smw828@cornell.edu/// Target fstat64() handler. 43613651Smw828@cornell.edutemplate <class OS> 43713651Smw828@cornell.eduSyscallReturn 43813651Smw828@cornell.edufstat64Func(SyscallDesc *desc, int callnum, Process *process, 43913651Smw828@cornell.edu ExecContext *xc) 44013651Smw828@cornell.edu{ 44113651Smw828@cornell.edu int fd = xc->getSyscallArg(0); 44213651Smw828@cornell.edu if (fd < 0 || process->sim_fd(fd) < 0) { 44313651Smw828@cornell.edu // doesn't map to any simulator fd: not a valid target fd 44413651Smw828@cornell.edu return -EBADF; 44513651Smw828@cornell.edu } 44613651Smw828@cornell.edu 44713651Smw828@cornell.edu#ifdef BSD_HOST 44813651Smw828@cornell.edu struct stat hostBuf; 44913651Smw828@cornell.edu int result = fstat(process->sim_fd(fd), &hostBuf); 45013651Smw828@cornell.edu#else 45113651Smw828@cornell.edu struct stat64 hostBuf; 45213651Smw828@cornell.edu int result = fstat64(process->sim_fd(fd), &hostBuf); 45313651Smw828@cornell.edu#endif 45413651Smw828@cornell.edu 45513651Smw828@cornell.edu if (result < 0) 45613651Smw828@cornell.edu return errno; 45713651Smw828@cornell.edu 45813651Smw828@cornell.edu OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); 45913651Smw828@cornell.edu 46013651Smw828@cornell.edu return 0; 4619112Smarc.orr@gmail.com} 46211911SBrandon.Potter@amd.com 46311911SBrandon.Potter@amd.com 4649112Smarc.orr@gmail.com/// Target lstat() handler. 4659112Smarc.orr@gmail.comtemplate <class OS> 4662238SN/ASyscallReturn 4672238SN/AlstatFunc(SyscallDesc *desc, int callnum, Process *process, 4682238SN/A ExecContext *xc) 46913995Sbrandon.potter@amd.com{ 4702238SN/A std::string path; 4712238SN/A 47213995Sbrandon.potter@amd.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 4732238SN/A return -EFAULT; 4742238SN/A 47513995Sbrandon.potter@amd.com struct stat hostBuf; 4762238SN/A int result = lstat(path.c_str(), &hostBuf); 4772238SN/A 47813995Sbrandon.potter@amd.com if (result < 0) 4792238SN/A return -errno; 4802238SN/A 4811354SN/A OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 4821354SN/A 48310796Sbrandon.potter@amd.com return 0; 48410796Sbrandon.potter@amd.com} 4851354SN/A 4861354SN/A/// Target lstat64() handler. 4871354SN/Atemplate <class OS> 4881354SN/ASyscallReturn 4891354SN/Alstat64Func(SyscallDesc *desc, int callnum, Process *process, 4901354SN/A ExecContext *xc) 4911354SN/A{ 4921354SN/A std::string path; 4931354SN/A 4941354SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 49510796Sbrandon.potter@amd.com return -EFAULT; 4961354SN/A 49710796Sbrandon.potter@amd.com#ifdef BSD_HOST 4981354SN/A struct stat hostBuf; 4991354SN/A int result = lstat(path.c_str(), &hostBuf); 5001354SN/A#else 5011354SN/A struct stat64 hostBuf; 50210796Sbrandon.potter@amd.com int result = lstat64(path.c_str(), &hostBuf); 50310796Sbrandon.potter@amd.com#endif 50410796Sbrandon.potter@amd.com 50510796Sbrandon.potter@amd.com if (result < 0) 50610796Sbrandon.potter@amd.com return -errno; 50710796Sbrandon.potter@amd.com 50810796Sbrandon.potter@amd.com OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); 50910796Sbrandon.potter@amd.com 51010796Sbrandon.potter@amd.com return 0; 51110796Sbrandon.potter@amd.com} 51210796Sbrandon.potter@amd.com 513360SN/A/// Target fstat() handler. 514360SN/Atemplate <class OS> 515360SN/ASyscallReturn 516360SN/AfstatFunc(SyscallDesc *desc, int callnum, Process *process, 517360SN/A ExecContext *xc) 518360SN/A{ 519360SN/A int fd = process->sim_fd(xc->getSyscallArg(0)); 52011759Sbrandon.potter@amd.com 5213113Sgblack@eecs.umich.edu DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); 5223113Sgblack@eecs.umich.edu 5233113Sgblack@eecs.umich.edu if (fd < 0) 5243113Sgblack@eecs.umich.edu return -EBADF; 5253113Sgblack@eecs.umich.edu 5263113Sgblack@eecs.umich.edu struct stat hostBuf; 5273113Sgblack@eecs.umich.edu 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; 53412032Sandreas.sandberg@arm.com} 5353113Sgblack@eecs.umich.edu 5363113Sgblack@eecs.umich.edu 5374189Sgblack@eecs.umich.edu/// Target statfs() handler. 5384189Sgblack@eecs.umich.edutemplate <class OS> 5393113Sgblack@eecs.umich.eduSyscallReturn 5403113Sgblack@eecs.umich.edustatfsFunc(SyscallDesc *desc, int callnum, Process *process, 5413113Sgblack@eecs.umich.edu ExecContext *xc) 5423113Sgblack@eecs.umich.edu{ 5438737Skoansin.tan@gmail.com std::string path; 5443113Sgblack@eecs.umich.edu 5458737Skoansin.tan@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 5463277Sgblack@eecs.umich.edu return -EFAULT; 5475515SMichael.Adler@intel.com 5485515SMichael.Adler@intel.com struct statfs hostBuf; 5495515SMichael.Adler@intel.com int result = statfs(path.c_str(), &hostBuf); 5505515SMichael.Adler@intel.com 5515515SMichael.Adler@intel.com if (result < 0) 5528737Skoansin.tan@gmail.com return errno; 5533277Sgblack@eecs.umich.edu 5548737Skoansin.tan@gmail.com OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 5553277Sgblack@eecs.umich.edu 5568737Skoansin.tan@gmail.com return 0; 5573277Sgblack@eecs.umich.edu} 5588737Skoansin.tan@gmail.com 5593113Sgblack@eecs.umich.edu 5603113Sgblack@eecs.umich.edu/// Target fstatfs() handler. 5613113Sgblack@eecs.umich.edutemplate <class OS> 5623113Sgblack@eecs.umich.eduSyscallReturn 5638737Skoansin.tan@gmail.comfstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 5643113Sgblack@eecs.umich.edu ExecContext *xc) 5658737Skoansin.tan@gmail.com{ 5663114Sgblack@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 5678737Skoansin.tan@gmail.com 5683114Sgblack@eecs.umich.edu if (fd < 0) 5698737Skoansin.tan@gmail.com return -EBADF; 5703114Sgblack@eecs.umich.edu 5718737Skoansin.tan@gmail.com struct statfs hostBuf; 57211906SBrandon.Potter@amd.com int result = fstatfs(fd, &hostBuf); 5734061Sgblack@eecs.umich.edu 5744061Sgblack@eecs.umich.edu if (result < 0) 5758737Skoansin.tan@gmail.com return errno; 5763113Sgblack@eecs.umich.edu 5778737Skoansin.tan@gmail.com OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 5783113Sgblack@eecs.umich.edu 5793113Sgblack@eecs.umich.edu return 0; 5803113Sgblack@eecs.umich.edu} 5813113Sgblack@eecs.umich.edu 5823113Sgblack@eecs.umich.edu 58312032Sandreas.sandberg@arm.com/// Target writev() handler. 5843113Sgblack@eecs.umich.edutemplate <class OS> 5853113Sgblack@eecs.umich.eduSyscallReturn 5864189Sgblack@eecs.umich.eduwritevFunc(SyscallDesc *desc, int callnum, Process *process, 5874189Sgblack@eecs.umich.edu ExecContext *xc) 5883113Sgblack@eecs.umich.edu{ 5893113Sgblack@eecs.umich.edu int fd = xc->getSyscallArg(0); 5903113Sgblack@eecs.umich.edu if (fd < 0 || process->sim_fd(fd) < 0) { 5918737Skoansin.tan@gmail.com // doesn't map to any simulator fd: not a valid target fd 5923113Sgblack@eecs.umich.edu return -EBADF; 5938737Skoansin.tan@gmail.com } 5943113Sgblack@eecs.umich.edu 5958737Skoansin.tan@gmail.com uint64_t tiov_base = xc->getSyscallArg(1); 5963113Sgblack@eecs.umich.edu size_t count = xc->getSyscallArg(2); 5973113Sgblack@eecs.umich.edu struct iovec hiov[count]; 5983113Sgblack@eecs.umich.edu for (int i = 0; i < count; ++i) 5993113Sgblack@eecs.umich.edu { 6003113Sgblack@eecs.umich.edu typename OS::tgt_iovec tiov; 6013113Sgblack@eecs.umich.edu xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), 6023113Sgblack@eecs.umich.edu &tiov, sizeof(typename OS::tgt_iovec)); 60311906SBrandon.Potter@amd.com hiov[i].iov_len = tiov.iov_len; 6043113Sgblack@eecs.umich.edu hiov[i].iov_base = new char [hiov[i].iov_len]; 60512032Sandreas.sandberg@arm.com xc->mem->access(Read, tiov.iov_base, 60614020Sgabeblack@google.com hiov[i].iov_base, hiov[i].iov_len); 60711906SBrandon.Potter@amd.com } 6083113Sgblack@eecs.umich.edu 6093113Sgblack@eecs.umich.edu int result = writev(process->sim_fd(fd), hiov, count); 6103113Sgblack@eecs.umich.edu 6113113Sgblack@eecs.umich.edu for (int i = 0; i < count; ++i) 6123113Sgblack@eecs.umich.edu { 6133113Sgblack@eecs.umich.edu delete [] (char *)hiov[i].iov_base; 6143113Sgblack@eecs.umich.edu } 6153113Sgblack@eecs.umich.edu 61612032Sandreas.sandberg@arm.com if (result < 0) 61714020Sgabeblack@google.com return errno; 61811906SBrandon.Potter@amd.com 6193113Sgblack@eecs.umich.edu return 0; 6203113Sgblack@eecs.umich.edu} 6213113Sgblack@eecs.umich.edu 6226686Stjones1@inf.ed.ac.uk 6233113Sgblack@eecs.umich.edu/// Target mmap() handler. 6243113Sgblack@eecs.umich.edu/// 6253113Sgblack@eecs.umich.edu/// We don't really handle mmap(). If the target is mmaping an 62611759Sbrandon.potter@amd.com/// anonymous region or /dev/zero, we can get away with doing basically 62712032Sandreas.sandberg@arm.com/// nothing (since memory is initialized to zero and the simulator 62814020Sgabeblack@google.com/// doesn't really check addresses anyway). Always print a warning, 62911759Sbrandon.potter@amd.com/// since this could be seriously broken if we're not mapping 63011759Sbrandon.potter@amd.com/// /dev/zero. 63111759Sbrandon.potter@amd.com// 63211759Sbrandon.potter@amd.com/// Someday we should explicitly check for /dev/zero in open, flag the 63311812Sbaz21@cam.ac.uk/// file descriptor, and fail (or implement!) a non-anonymous mmap to 63411812Sbaz21@cam.ac.uk/// anything else. 63511812Sbaz21@cam.ac.uktemplate <class OS> 63611759Sbrandon.potter@amd.comSyscallReturn 63711812Sbaz21@cam.ac.ukmmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 63811759Sbrandon.potter@amd.com{ 63911759Sbrandon.potter@amd.com Addr start = xc->getSyscallArg(0); 64011759Sbrandon.potter@amd.com uint64_t length = xc->getSyscallArg(1); 64111759Sbrandon.potter@amd.com // int prot = xc->getSyscallArg(2); 64211759Sbrandon.potter@amd.com int flags = xc->getSyscallArg(3); 64311759Sbrandon.potter@amd.com // int fd = p->sim_fd(xc->getSyscallArg(4)); 64411759Sbrandon.potter@amd.com // int offset = xc->getSyscallArg(5); 64511812Sbaz21@cam.ac.uk 64611812Sbaz21@cam.ac.uk if (start == 0) { 64711812Sbaz21@cam.ac.uk // user didn't give an address... pick one from our "mmap region" 64811812Sbaz21@cam.ac.uk start = p->mmap_end; 64911812Sbaz21@cam.ac.uk p->mmap_end += roundUp(length, VMPageSize); 65011812Sbaz21@cam.ac.uk if (p->nxm_start != 0) { 65111812Sbaz21@cam.ac.uk //If we have an nxm space, make sure we haven't colided 65211759Sbrandon.potter@amd.com assert(p->mmap_end < p->nxm_start); 65311759Sbrandon.potter@amd.com } 65411812Sbaz21@cam.ac.uk } 65511812Sbaz21@cam.ac.uk 65611759Sbrandon.potter@amd.com if (!(flags & OS::TGT_MAP_ANONYMOUS)) { 65711812Sbaz21@cam.ac.uk warn("allowing mmap of file @ fd %d. " 65811812Sbaz21@cam.ac.uk "This will break if not /dev/zero.", xc->getSyscallArg(4)); 65911812Sbaz21@cam.ac.uk } 66011812Sbaz21@cam.ac.uk 66111812Sbaz21@cam.ac.uk return start; 66211812Sbaz21@cam.ac.uk} 66311812Sbaz21@cam.ac.uk 66411759Sbrandon.potter@amd.com/// Target getrlimit() handler. 66511759Sbrandon.potter@amd.comtemplate <class OS> 66611759Sbrandon.potter@amd.comSyscallReturn 66711759Sbrandon.potter@amd.comgetrlimitFunc(SyscallDesc *desc, int callnum, Process *process, 668378SN/A ExecContext *xc) 669378SN/A{ 6709141Smarc.orr@gmail.com unsigned resource = xc->getSyscallArg(0); 6719141Smarc.orr@gmail.com TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); 672360SN/A 6731450SN/A switch (resource) { 67413995Sbrandon.potter@amd.com case OS::TGT_RLIMIT_STACK: 675360SN/A // max stack size in bytes: make up a number (2MB for now) 6766701Sgblack@eecs.umich.edu rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; 67713995Sbrandon.potter@amd.com break; 67813995Sbrandon.potter@amd.com 67911856Sbrandon.potter@amd.com default: 68011856Sbrandon.potter@amd.com std::cerr << "getrlimitFunc: unimplemented resource " << resource 681360SN/A << std::endl; 68213907Salexandru.dutu@amd.com abort(); 683360SN/A break; 68411856Sbrandon.potter@amd.com } 68511856Sbrandon.potter@amd.com 68610496Ssteve.reinhardt@amd.com rlp.copyOut(xc->mem); 68711856Sbrandon.potter@amd.com return 0; 68813902Sbrandon.potter@amd.com} 68913902Sbrandon.potter@amd.com 69013902Sbrandon.potter@amd.com/// Target gettimeofday() handler. 69113995Sbrandon.potter@amd.comtemplate <class OS> 69213902Sbrandon.potter@amd.comSyscallReturn 69313902Sbrandon.potter@amd.comgettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, 69413902Sbrandon.potter@amd.com ExecContext *xc) 69513902Sbrandon.potter@amd.com{ 69613902Sbrandon.potter@amd.com TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); 69713902Sbrandon.potter@amd.com 69813902Sbrandon.potter@amd.com getElapsedTime(tp->tv_sec, tp->tv_usec); 69913902Sbrandon.potter@amd.com tp->tv_sec += seconds_since_epoch; 70013902Sbrandon.potter@amd.com 70113902Sbrandon.potter@amd.com tp.copyOut(xc->mem); 70213902Sbrandon.potter@amd.com 70313902Sbrandon.potter@amd.com return 0; 70413902Sbrandon.potter@amd.com} 70513902Sbrandon.potter@amd.com 70613902Sbrandon.potter@amd.com 70713902Sbrandon.potter@amd.com/// Target utimes() handler. 70813902Sbrandon.potter@amd.comtemplate <class OS> 70913902Sbrandon.potter@amd.comSyscallReturn 71013902Sbrandon.potter@amd.comutimesFunc(SyscallDesc *desc, int callnum, Process *process, 71113902Sbrandon.potter@amd.com ExecContext *xc) 71213902Sbrandon.potter@amd.com{ 71313902Sbrandon.potter@amd.com std::string path; 71413902Sbrandon.potter@amd.com 71513902Sbrandon.potter@amd.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 71613902Sbrandon.potter@amd.com return -EFAULT; 71713902Sbrandon.potter@amd.com 71813902Sbrandon.potter@amd.com TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); 71913902Sbrandon.potter@amd.com tp.copyIn(xc->mem); 72013902Sbrandon.potter@amd.com 72113936SAndrea.Mondelli@ucf.edu struct timeval hostTimeval[2]; 72213902Sbrandon.potter@amd.com for (int i = 0; i < 2; ++i) 72313902Sbrandon.potter@amd.com { 72413902Sbrandon.potter@amd.com hostTimeval[i].tv_sec = (*tp)[i].tv_sec; 72513902Sbrandon.potter@amd.com hostTimeval[i].tv_usec = (*tp)[i].tv_usec; 72613936SAndrea.Mondelli@ucf.edu } 72713902Sbrandon.potter@amd.com int result = utimes(path.c_str(), hostTimeval); 72813902Sbrandon.potter@amd.com 72913902Sbrandon.potter@amd.com if (result < 0) 73013902Sbrandon.potter@amd.com return -errno; 73113902Sbrandon.potter@amd.com 73213902Sbrandon.potter@amd.com return 0; 73313902Sbrandon.potter@amd.com} 73413902Sbrandon.potter@amd.com/// Target getrusage() function. 73513902Sbrandon.potter@amd.comtemplate <class OS> 73613902Sbrandon.potter@amd.comSyscallReturn 73713902Sbrandon.potter@amd.comgetrusageFunc(SyscallDesc *desc, int callnum, Process *process, 73813902Sbrandon.potter@amd.com ExecContext *xc) 73913902Sbrandon.potter@amd.com{ 74013902Sbrandon.potter@amd.com int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN 74110496Ssteve.reinhardt@amd.com TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); 74211856Sbrandon.potter@amd.com 74311856Sbrandon.potter@amd.com if (who != OS::TGT_RUSAGE_SELF) { 74411856Sbrandon.potter@amd.com // don't really handle THREAD or CHILDREN, but just warn and 74511856Sbrandon.potter@amd.com // plow ahead 74611856Sbrandon.potter@amd.com warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", 74710930Sbrandon.potter@amd.com who); 7489141Smarc.orr@gmail.com } 749360SN/A 750360SN/A getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); 751360SN/A rup->ru_stime.tv_sec = 0; 75211907SBrandon.Potter@amd.com rup->ru_stime.tv_usec = 0; 75313995Sbrandon.potter@amd.com rup->ru_maxrss = 0; 754360SN/A rup->ru_ixrss = 0; 75511907SBrandon.Potter@amd.com rup->ru_idrss = 0; 75613995Sbrandon.potter@amd.com rup->ru_isrss = 0; 75711907SBrandon.Potter@amd.com rup->ru_minflt = 0; 75811907SBrandon.Potter@amd.com rup->ru_majflt = 0; 75911907SBrandon.Potter@amd.com rup->ru_nswap = 0; 76011907SBrandon.Potter@amd.com rup->ru_inblock = 0; 76111907SBrandon.Potter@amd.com rup->ru_oublock = 0; 76211907SBrandon.Potter@amd.com rup->ru_msgsnd = 0; 76311907SBrandon.Potter@amd.com rup->ru_msgrcv = 0; 76411907SBrandon.Potter@amd.com rup->ru_nsignals = 0; 76511907SBrandon.Potter@amd.com rup->ru_nvcsw = 0; 76611907SBrandon.Potter@amd.com rup->ru_nivcsw = 0; 76711907SBrandon.Potter@amd.com 76811907SBrandon.Potter@amd.com rup.copyOut(xc->mem); 76911907SBrandon.Potter@amd.com 770360SN/A return 0; 77111907SBrandon.Potter@amd.com} 7721458SN/A 773360SN/A#endif // __SIM_SYSCALL_EMUL_HH__ 77411907SBrandon.Potter@amd.com