syscall_emul.hh revision 2218
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 "arch/isa_traits.hh" // for Addr 512064SN/A 52360SN/A#include "base/trace.hh" 53360SN/A#include "cpu/exec_context.hh" 54360SN/A#include "sim/process.hh" 55360SN/A 56360SN/A/// 57360SN/A/// System call descriptor. 581809SN/A/// 595543Ssaidi@eecs.umich.educlass SyscallDesc { 6011392Sbrandon.potter@amd.com 611809SN/A public: 6211392Sbrandon.potter@amd.com 6311383Sbrandon.potter@amd.com /// Typedef for target syscall handler functions. 643113Sgblack@eecs.umich.edu typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, 658229Snate@binkert.org Process *, ExecContext *); 668229Snate@binkert.org 6711594Santhony.gutierrez@amd.com const char *name; //!< Syscall name (e.g., "open"). 687075Snate@binkert.org FuncPtr funcPtr; //!< Pointer to emulation function. 698229Snate@binkert.org int flags; //!< Flags (see Flags enum). 707075Snate@binkert.org 71360SN/A /// Flag values for controlling syscall behavior. 722474SN/A enum Flags { 735543Ssaidi@eecs.umich.edu /// Don't set return regs according to funcPtr return value. 7411392Sbrandon.potter@amd.com /// Used for syscalls with non-standard return conventions 752462SN/A /// that explicitly set the ExecContext regs (e.g., 761354SN/A /// sigreturn). 776216Snate@binkert.org SuppressReturnValue = 1 786658Snate@binkert.org }; 792474SN/A 802680Sktlim@umich.edu /// Constructor. 8111380Salexandru.dutu@amd.com SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) 828232Snate@binkert.org : name(_name), funcPtr(_funcPtr), flags(_flags) 838229Snate@binkert.org { 847678Sgblack@eecs.umich.edu } 8510496Ssteve.reinhardt@amd.com 868229Snate@binkert.org /// Emulate the syscall. Public interface for calling through funcPtr. 8710497Ssteve.reinhardt@amd.com void doSyscall(int callnum, Process *proc, ExecContext *xc); 888766Sgblack@eecs.umich.edu}; 896640Svince@csl.cornell.edu 90360SN/A 9111380Salexandru.dutu@amd.comclass BaseBufferArg { 9211380Salexandru.dutu@amd.com 9311380Salexandru.dutu@amd.com public: 9411380Salexandru.dutu@amd.com 9511380Salexandru.dutu@amd.com BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) 9611380Salexandru.dutu@amd.com { 9711380Salexandru.dutu@amd.com bufPtr = new uint8_t[size]; 9811380Salexandru.dutu@amd.com // clear out buffer: in case we only partially populate this, 99360SN/A // and then do a copyOut(), we want to make sure we don't 100360SN/A // 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 106378SN/A // 1071450SN/A // copy data into simulator space (read from target memory) 1083114Sgblack@eecs.umich.edu // 109360SN/A virtual bool copyIn(FunctionalMemory *mem) 1105543Ssaidi@eecs.umich.edu { 1115543Ssaidi@eecs.umich.edu mem->access(Read, addr, bufPtr, size); 1125543Ssaidi@eecs.umich.edu return true; // no EFAULT detection for now 11310831Ssteve.reinhardt@amd.com } 114360SN/A 115360SN/A // 116360SN/A // copy data out of simulator space (write to target memory) 117360SN/A // 118360SN/A virtual bool copyOut(FunctionalMemory *mem) 1192680Sktlim@umich.edu { 120360SN/A mem->access(Write, addr, bufPtr, size); 12110831Ssteve.reinhardt@amd.com return true; // no EFAULT detection for now 12210831Ssteve.reinhardt@amd.com } 123360SN/A 124360SN/A protected: 125360SN/A Addr addr; 126360SN/A int size; 12710831Ssteve.reinhardt@amd.com uint8_t *bufPtr; 128360SN/A}; 129360SN/A 130360SN/A 131360SN/Aclass BufferArg : public BaseBufferArg 1323114Sgblack@eecs.umich.edu{ 13310831Ssteve.reinhardt@amd.com public: 13410831Ssteve.reinhardt@amd.com BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 13510831Ssteve.reinhardt@amd.com void *bufferPtr() { return bufPtr; } 136360SN/A}; 137360SN/A 138360SN/Atemplate <class T> 139360SN/Aclass TypedBufferArg : public BaseBufferArg 140360SN/A{ 141360SN/A public: 142360SN/A // user can optionally specify a specific number of bytes to 143360SN/A // allocate to deal with those structs that have variable-size 144360SN/A // arrays at the end 145360SN/A TypedBufferArg(Addr _addr, int _size = sizeof(T)) 146360SN/A : BaseBufferArg(_addr, _size) 147360SN/A { } 148378SN/A 1491706SN/A // type case 1503114Sgblack@eecs.umich.edu operator T*() { return (T *)bufPtr; } 151378SN/A 152378SN/A // dereference operators 153378SN/A T &operator*() { return *((T *)bufPtr); } 154378SN/A T* operator->() { return (T *)bufPtr; } 155378SN/A T &operator[](int i) { return ((T *)bufPtr)[i]; } 1561706SN/A}; 1573114Sgblack@eecs.umich.edu 158360SN/A////////////////////////////////////////////////////////////////////// 1596109Ssanchezd@stanford.edu// 1601706SN/A// The following emulation functions are generic enough that they 1613114Sgblack@eecs.umich.edu// don't need to be recompiled for different emulated OS's. They are 162378SN/A// defined in sim/syscall_emul.cc. 1636109Ssanchezd@stanford.edu// 1646109Ssanchezd@stanford.edu////////////////////////////////////////////////////////////////////// 1656109Ssanchezd@stanford.edu 1666109Ssanchezd@stanford.edu 167378SN/A/// Handler for unimplemented syscalls that we haven't thought about. 1681706SN/ASyscallReturn unimplementedFunc(SyscallDesc *desc, int num, 1693114Sgblack@eecs.umich.edu Process *p, ExecContext *xc); 170378SN/A 1715748SSteve.Reinhardt@amd.com/// Handler for unimplemented syscalls that we never intend to 1725748SSteve.Reinhardt@amd.com/// implement (signal handling, etc.) and should not affect the correct 1735748SSteve.Reinhardt@amd.com/// behavior of the program. Print a warning only if the appropriate 174378SN/A/// trace flag is enabled. Return success to the target program. 175378SN/ASyscallReturn ignoreFunc(SyscallDesc *desc, int num, 1761706SN/A Process *p, ExecContext *xc); 1773114Sgblack@eecs.umich.edu 178378SN/A/// Target exit() handler: terminate simulation. 179378SN/ASyscallReturn exitFunc(SyscallDesc *desc, int num, 1801706SN/A Process *p, ExecContext *xc); 1813114Sgblack@eecs.umich.edu 182378SN/A/// Target getpagesize() handler. 183378SN/ASyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, 1841706SN/A Process *p, ExecContext *xc); 1853114Sgblack@eecs.umich.edu 186378SN/A/// Target obreak() handler: set brk address. 187378SN/ASyscallReturn obreakFunc(SyscallDesc *desc, int num, 1881706SN/A Process *p, ExecContext *xc); 1893114Sgblack@eecs.umich.edu 190378SN/A/// Target close() handler. 1914118Sgblack@eecs.umich.eduSyscallReturn closeFunc(SyscallDesc *desc, int num, 1924118Sgblack@eecs.umich.edu Process *p, ExecContext *xc); 1934118Sgblack@eecs.umich.edu 1944118Sgblack@eecs.umich.edu/// Target read() handler. 195378SN/ASyscallReturn readFunc(SyscallDesc *desc, int num, 1961706SN/A Process *p, ExecContext *xc); 1973114Sgblack@eecs.umich.edu 198378SN/A/// Target write() handler. 199378SN/ASyscallReturn writeFunc(SyscallDesc *desc, int num, 2001706SN/A Process *p, ExecContext *xc); 2013114Sgblack@eecs.umich.edu 202360SN/A/// Target lseek() handler. 2035513SMichael.Adler@intel.comSyscallReturn lseekFunc(SyscallDesc *desc, int num, 2045513SMichael.Adler@intel.com Process *p, ExecContext *xc); 2055513SMichael.Adler@intel.com 2065513SMichael.Adler@intel.com/// Target munmap() handler. 20710203SAli.Saidi@ARM.comSyscallReturn munmapFunc(SyscallDesc *desc, int num, 20810203SAli.Saidi@ARM.com Process *p, ExecContext *xc); 20910203SAli.Saidi@ARM.com 21010203SAli.Saidi@ARM.com/// Target gethostname() handler. 2115513SMichael.Adler@intel.comSyscallReturn gethostnameFunc(SyscallDesc *desc, int num, 2125513SMichael.Adler@intel.com Process *p, ExecContext *xc); 2135513SMichael.Adler@intel.com 214511SN/A/// Target unlink() handler. 21510633Smichaelupton@gmail.comSyscallReturn unlinkFunc(SyscallDesc *desc, int num, 21610633Smichaelupton@gmail.com Process *p, ExecContext *xc); 21710633Smichaelupton@gmail.com 2181706SN/A/// Target rename() handler. 2193114Sgblack@eecs.umich.eduSyscallReturn renameFunc(SyscallDesc *desc, int num, 220511SN/A Process *p, ExecContext *xc); 2215513SMichael.Adler@intel.com 2225513SMichael.Adler@intel.com 2235513SMichael.Adler@intel.com/// Target truncate() handler. 2245513SMichael.Adler@intel.comSyscallReturn truncateFunc(SyscallDesc *desc, int num, 225511SN/A Process *p, ExecContext *xc); 2261706SN/A 2273114Sgblack@eecs.umich.edu 2281706SN/A/// Target ftruncate() handler. 2291706SN/ASyscallReturn ftruncateFunc(SyscallDesc *desc, int num, 2301706SN/A Process *p, ExecContext *xc); 2311706SN/A 2323114Sgblack@eecs.umich.edu 2331706SN/A/// Target chown() handler. 2341706SN/ASyscallReturn chownFunc(SyscallDesc *desc, int num, 2351706SN/A Process *p, ExecContext *xc); 2361706SN/A 2373114Sgblack@eecs.umich.edu 2381706SN/A/// Target fchown() handler. 239511SN/ASyscallReturn fchownFunc(SyscallDesc *desc, int num, 2406703Svince@csl.cornell.edu Process *p, ExecContext *xc); 2416703Svince@csl.cornell.edu 2426703Svince@csl.cornell.edu/// Target fnctl() handler. 2436703Svince@csl.cornell.eduSyscallReturn fcntlFunc(SyscallDesc *desc, int num, 2446685Stjones1@inf.ed.ac.uk Process *process, ExecContext *xc); 2456685Stjones1@inf.ed.ac.uk 2466685Stjones1@inf.ed.ac.uk/// This struct is used to build an target-OS-dependent table that 2476685Stjones1@inf.ed.ac.uk/// maps the target's open() flags to the host open() flags. 2486685Stjones1@inf.ed.ac.ukstruct OpenFlagTransTable { 2495513SMichael.Adler@intel.com int tgtFlag; //!< Target system flag value. 2505513SMichael.Adler@intel.com int hostFlag; //!< Corresponding host system flag value. 2515513SMichael.Adler@intel.com}; 2525513SMichael.Adler@intel.com 2535513SMichael.Adler@intel.com 2541999SN/A 2551999SN/A/// A readable name for 1,000,000, for converting microseconds to seconds. 2563114Sgblack@eecs.umich.educonst int one_million = 1000000; 2571999SN/A 2581999SN/A/// Approximate seconds since the epoch (1/1/1970). About a billion, 2591999SN/A/// by my reckoning. We want to keep this a constant (not use the 2601999SN/A/// real-world time) to keep simulations repeatable. 2613114Sgblack@eecs.umich.educonst unsigned seconds_since_epoch = 1000000000; 2621999SN/A 2633079Sstever@eecs.umich.edu/// Helper function to convert current elapsed time to seconds and 2643079Sstever@eecs.umich.edu/// microseconds. 2653114Sgblack@eecs.umich.edutemplate <class T1, class T2> 2663079Sstever@eecs.umich.eduvoid 2672093SN/AgetElapsedTime(T1 &sec, T2 &usec) 2682093SN/A{ 2693114Sgblack@eecs.umich.edu int elapsed_usecs = curTick / Clock::Int::us; 2702093SN/A sec = elapsed_usecs / one_million; 2712687Sksewell@umich.edu usec = elapsed_usecs % one_million; 2722687Sksewell@umich.edu} 2733114Sgblack@eecs.umich.edu 2742687Sksewell@umich.edu////////////////////////////////////////////////////////////////////// 2752238SN/A// 2762238SN/A// The following emulation functions are generic, but need to be 2773114Sgblack@eecs.umich.edu// templated to account for differences in types, constants, etc. 2782238SN/A// 2792238SN/A////////////////////////////////////////////////////////////////////// 2802238SN/A 2813114Sgblack@eecs.umich.edu/// Target ioctl() handler. For the most part, programs call ioctl() 2822238SN/A/// only to find out if their stdout is a tty, to determine whether to 2832238SN/A/// do line or block buffering. 2842238SN/Atemplate <class OS> 2853114Sgblack@eecs.umich.eduSyscallReturn 2862238SN/AioctlFunc(SyscallDesc *desc, int callnum, Process *process, 2872238SN/A ExecContext *xc) 2882238SN/A{ 2893114Sgblack@eecs.umich.edu int fd = xc->getSyscallArg(0); 2902238SN/A unsigned req = xc->getSyscallArg(1); 2912238SN/A 2922238SN/A DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); 2933114Sgblack@eecs.umich.edu 2942238SN/A if (fd < 0 || process->sim_fd(fd) < 0) { 2952238SN/A // doesn't map to any simulator fd: not a valid target fd 2962238SN/A return -EBADF; 2973114Sgblack@eecs.umich.edu } 2982238SN/A 2992238SN/A switch (req) { 3002238SN/A case OS::TIOCISATTY: 3013114Sgblack@eecs.umich.edu case OS::TIOCGETP: 3022238SN/A case OS::TIOCSETP: 3036109Ssanchezd@stanford.edu case OS::TIOCSETN: 3046109Ssanchezd@stanford.edu case OS::TIOCSETC: 3056109Ssanchezd@stanford.edu case OS::TIOCGETC: 3062238SN/A case OS::TIOCGETS: 3079455Smitch.hayenga+gem5@gmail.com case OS::TIOCGETA: 3089455Smitch.hayenga+gem5@gmail.com return -ENOTTY; 3099455Smitch.hayenga+gem5@gmail.com 31010203SAli.Saidi@ARM.com default: 31110203SAli.Saidi@ARM.com fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", 31210203SAli.Saidi@ARM.com fd, req, xc->readPC()); 3139455Smitch.hayenga+gem5@gmail.com } 3149112Smarc.orr@gmail.com} 3159112Smarc.orr@gmail.com 3169112Smarc.orr@gmail.com/// Target open() handler. 3179112Smarc.orr@gmail.comtemplate <class OS> 3189112Smarc.orr@gmail.comSyscallReturn 3199112Smarc.orr@gmail.comopenFunc(SyscallDesc *desc, int callnum, Process *process, 3209112Smarc.orr@gmail.com ExecContext *xc) 3219112Smarc.orr@gmail.com{ 3229112Smarc.orr@gmail.com std::string path; 3239112Smarc.orr@gmail.com 3249112Smarc.orr@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 3259112Smarc.orr@gmail.com return -EFAULT; 3269112Smarc.orr@gmail.com 3279112Smarc.orr@gmail.com if (path == "/dev/sysdev0") { 3289112Smarc.orr@gmail.com // This is a memory-mapped high-resolution timer device on Alpha. 3299112Smarc.orr@gmail.com // We don't support it, so just punt. 3309112Smarc.orr@gmail.com warn("Ignoring open(%s, ...)\n", path); 3319112Smarc.orr@gmail.com return -ENOENT; 3329112Smarc.orr@gmail.com } 3339112Smarc.orr@gmail.com 3349112Smarc.orr@gmail.com int tgtFlags = xc->getSyscallArg(1); 3359112Smarc.orr@gmail.com int mode = xc->getSyscallArg(2); 3369112Smarc.orr@gmail.com int hostFlags = 0; 3379112Smarc.orr@gmail.com 3389238Slluc.alvarez@bsc.es // translate open flags 3399112Smarc.orr@gmail.com for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { 3409112Smarc.orr@gmail.com if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 3419112Smarc.orr@gmail.com tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 3429112Smarc.orr@gmail.com hostFlags |= OS::openFlagTable[i].hostFlag; 3439112Smarc.orr@gmail.com } 3449112Smarc.orr@gmail.com } 3459112Smarc.orr@gmail.com 3469112Smarc.orr@gmail.com // any target flags left? 3479112Smarc.orr@gmail.com if (tgtFlags != 0) 3489112Smarc.orr@gmail.com warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 34911367Sandreas.hansson@arm.com 3509112Smarc.orr@gmail.com#ifdef __CYGWIN32__ 35111321Ssteve.reinhardt@amd.com hostFlags |= O_BINARY; 3529112Smarc.orr@gmail.com#endif 3539112Smarc.orr@gmail.com 3549112Smarc.orr@gmail.com DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); 3559112Smarc.orr@gmail.com 3569112Smarc.orr@gmail.com // open the file 3579112Smarc.orr@gmail.com int fd = open(path.c_str(), hostFlags, mode); 3589112Smarc.orr@gmail.com 3599112Smarc.orr@gmail.com return (fd == -1) ? -errno : process->alloc_fd(fd); 3609112Smarc.orr@gmail.com} 3619112Smarc.orr@gmail.com 3629112Smarc.orr@gmail.com 3639112Smarc.orr@gmail.com/// Target chmod() handler. 3649112Smarc.orr@gmail.comtemplate <class OS> 3659112Smarc.orr@gmail.comSyscallReturn 3669112Smarc.orr@gmail.comchmodFunc(SyscallDesc *desc, int callnum, Process *process, 3679112Smarc.orr@gmail.com ExecContext *xc) 3689112Smarc.orr@gmail.com{ 3699112Smarc.orr@gmail.com std::string path; 3709112Smarc.orr@gmail.com 3719112Smarc.orr@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 3729112Smarc.orr@gmail.com return -EFAULT; 3739112Smarc.orr@gmail.com 3749112Smarc.orr@gmail.com uint32_t mode = xc->getSyscallArg(1); 3759112Smarc.orr@gmail.com mode_t hostMode = 0; 3769112Smarc.orr@gmail.com 3779112Smarc.orr@gmail.com // XXX translate mode flags via OS::something??? 3789112Smarc.orr@gmail.com hostMode = mode; 3799112Smarc.orr@gmail.com 3809112Smarc.orr@gmail.com // do the chmod 38111321Ssteve.reinhardt@amd.com int result = chmod(path.c_str(), hostMode); 3829112Smarc.orr@gmail.com if (result < 0) 3839112Smarc.orr@gmail.com return -errno; 3849112Smarc.orr@gmail.com 3859112Smarc.orr@gmail.com return 0; 3869112Smarc.orr@gmail.com} 3879112Smarc.orr@gmail.com 3889112Smarc.orr@gmail.com 3899112Smarc.orr@gmail.com/// Target fchmod() handler. 3909238Slluc.alvarez@bsc.estemplate <class OS> 3919112Smarc.orr@gmail.comSyscallReturn 3929112Smarc.orr@gmail.comfchmodFunc(SyscallDesc *desc, int callnum, Process *process, 3939112Smarc.orr@gmail.com ExecContext *xc) 3949112Smarc.orr@gmail.com{ 3959112Smarc.orr@gmail.com int fd = xc->getSyscallArg(0); 3962238SN/A if (fd < 0 || process->sim_fd(fd) < 0) { 3972238SN/A // doesn't map to any simulator fd: not a valid target fd 3982238SN/A return -EBADF; 3992238SN/A } 4003114Sgblack@eecs.umich.edu 4012238SN/A uint32_t mode = xc->getSyscallArg(1); 4022238SN/A mode_t hostMode = 0; 4032238SN/A 4043114Sgblack@eecs.umich.edu // XXX translate mode flags via OS::someting??? 4052238SN/A hostMode = mode; 4062238SN/A 4072238SN/A // do the fchmod 4083114Sgblack@eecs.umich.edu int result = fchmod(process->sim_fd(fd), hostMode); 4092238SN/A if (result < 0) 4102238SN/A return -errno; 4112238SN/A 4123114Sgblack@eecs.umich.edu return 0; 4132238SN/A} 4142238SN/A 4151354SN/A 4161354SN/A/// Target stat() handler. 41710796Sbrandon.potter@amd.comtemplate <class OS> 41810796Sbrandon.potter@amd.comSyscallReturn 4191354SN/AstatFunc(SyscallDesc *desc, int callnum, Process *process, 4201354SN/A ExecContext *xc) 4211354SN/A{ 4221354SN/A std::string path; 4231354SN/A 4241354SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 4251354SN/A return -EFAULT; 4261354SN/A 4271354SN/A struct stat hostBuf; 4281354SN/A int result = stat(path.c_str(), &hostBuf); 42910796Sbrandon.potter@amd.com 4301354SN/A if (result < 0) 43110796Sbrandon.potter@amd.com return -errno; 4321354SN/A 4331354SN/A OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 4341354SN/A 4351354SN/A return 0; 43610796Sbrandon.potter@amd.com} 43710796Sbrandon.potter@amd.com 43810796Sbrandon.potter@amd.com 43910796Sbrandon.potter@amd.com/// Target fstat64() handler. 44010796Sbrandon.potter@amd.comtemplate <class OS> 44110796Sbrandon.potter@amd.comSyscallReturn 44210796Sbrandon.potter@amd.comfstat64Func(SyscallDesc *desc, int callnum, Process *process, 44310796Sbrandon.potter@amd.com ExecContext *xc) 44410796Sbrandon.potter@amd.com{ 44510796Sbrandon.potter@amd.com int fd = xc->getSyscallArg(0); 44610796Sbrandon.potter@amd.com if (fd < 0 || process->sim_fd(fd) < 0) { 447360SN/A // doesn't map to any simulator fd: not a valid target fd 448360SN/A return -EBADF; 449360SN/A } 450360SN/A 451360SN/A#if BSD_HOST 452360SN/A struct stat hostBuf; 453360SN/A int result = fstat(process->sim_fd(fd), &hostBuf); 4543113Sgblack@eecs.umich.edu#else 4553113Sgblack@eecs.umich.edu struct stat64 hostBuf; 4563113Sgblack@eecs.umich.edu int result = fstat64(process->sim_fd(fd), &hostBuf); 4573113Sgblack@eecs.umich.edu#endif 4583113Sgblack@eecs.umich.edu 4593113Sgblack@eecs.umich.edu if (result < 0) 4603113Sgblack@eecs.umich.edu return -errno; 4613113Sgblack@eecs.umich.edu 4623113Sgblack@eecs.umich.edu OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); 4633113Sgblack@eecs.umich.edu 4643113Sgblack@eecs.umich.edu return 0; 4653113Sgblack@eecs.umich.edu} 4663113Sgblack@eecs.umich.edu 4673113Sgblack@eecs.umich.edu 4683113Sgblack@eecs.umich.edu/// Target lstat() handler. 4693113Sgblack@eecs.umich.edutemplate <class OS> 4704189Sgblack@eecs.umich.eduSyscallReturn 4714189Sgblack@eecs.umich.edulstatFunc(SyscallDesc *desc, int callnum, Process *process, 4723113Sgblack@eecs.umich.edu ExecContext *xc) 4733113Sgblack@eecs.umich.edu{ 4743113Sgblack@eecs.umich.edu std::string path; 4753113Sgblack@eecs.umich.edu 4768737Skoansin.tan@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 4773113Sgblack@eecs.umich.edu return -EFAULT; 4788737Skoansin.tan@gmail.com 4793277Sgblack@eecs.umich.edu struct stat hostBuf; 4805515SMichael.Adler@intel.com int result = lstat(path.c_str(), &hostBuf); 4815515SMichael.Adler@intel.com 4825515SMichael.Adler@intel.com if (result < 0) 4835515SMichael.Adler@intel.com return -errno; 4845515SMichael.Adler@intel.com 4858737Skoansin.tan@gmail.com OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 4863277Sgblack@eecs.umich.edu 4878737Skoansin.tan@gmail.com return 0; 4883277Sgblack@eecs.umich.edu} 4898737Skoansin.tan@gmail.com 4903277Sgblack@eecs.umich.edu/// Target lstat64() handler. 4918737Skoansin.tan@gmail.comtemplate <class OS> 4923113Sgblack@eecs.umich.eduSyscallReturn 4933113Sgblack@eecs.umich.edulstat64Func(SyscallDesc *desc, int callnum, Process *process, 4943113Sgblack@eecs.umich.edu ExecContext *xc) 4953113Sgblack@eecs.umich.edu{ 4968737Skoansin.tan@gmail.com std::string path; 4973113Sgblack@eecs.umich.edu 4988737Skoansin.tan@gmail.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 4993114Sgblack@eecs.umich.edu return -EFAULT; 5008737Skoansin.tan@gmail.com 5013114Sgblack@eecs.umich.edu#if BSD_HOST 5028737Skoansin.tan@gmail.com struct stat hostBuf; 5033114Sgblack@eecs.umich.edu int result = lstat(path.c_str(), &hostBuf); 5048737Skoansin.tan@gmail.com#else 5054061Sgblack@eecs.umich.edu struct stat64 hostBuf; 5064061Sgblack@eecs.umich.edu int result = lstat64(path.c_str(), &hostBuf); 5074061Sgblack@eecs.umich.edu#endif 5088737Skoansin.tan@gmail.com 5093113Sgblack@eecs.umich.edu if (result < 0) 5108737Skoansin.tan@gmail.com return -errno; 5113113Sgblack@eecs.umich.edu 5123113Sgblack@eecs.umich.edu OS::copyOutStat64Buf(xc->mem, -1, xc->getSyscallArg(1), &hostBuf); 5133113Sgblack@eecs.umich.edu 5143113Sgblack@eecs.umich.edu return 0; 5153113Sgblack@eecs.umich.edu} 5163113Sgblack@eecs.umich.edu 5173113Sgblack@eecs.umich.edu/// Target fstat() handler. 5183113Sgblack@eecs.umich.edutemplate <class OS> 5194189Sgblack@eecs.umich.eduSyscallReturn 5204189Sgblack@eecs.umich.edufstatFunc(SyscallDesc *desc, int callnum, Process *process, 5213113Sgblack@eecs.umich.edu ExecContext *xc) 5223113Sgblack@eecs.umich.edu{ 5233113Sgblack@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 5248737Skoansin.tan@gmail.com 5253113Sgblack@eecs.umich.edu DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); 5268737Skoansin.tan@gmail.com 5273113Sgblack@eecs.umich.edu if (fd < 0) 5288737Skoansin.tan@gmail.com return -EBADF; 5293113Sgblack@eecs.umich.edu 5303113Sgblack@eecs.umich.edu struct stat hostBuf; 5313113Sgblack@eecs.umich.edu int result = fstat(fd, &hostBuf); 5323113Sgblack@eecs.umich.edu 5333113Sgblack@eecs.umich.edu if (result < 0) 5343113Sgblack@eecs.umich.edu return -errno; 5353113Sgblack@eecs.umich.edu 5363113Sgblack@eecs.umich.edu OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 5373113Sgblack@eecs.umich.edu return 0; 5383113Sgblack@eecs.umich.edu} 5398852Sandreas.hansson@arm.com 5403113Sgblack@eecs.umich.edu 5413113Sgblack@eecs.umich.edu/// Target statfs() handler. 5423113Sgblack@eecs.umich.edutemplate <class OS> 5433113Sgblack@eecs.umich.eduSyscallReturn 5443113Sgblack@eecs.umich.edustatfsFunc(SyscallDesc *desc, int callnum, Process *process, 5453113Sgblack@eecs.umich.edu ExecContext *xc) 5463113Sgblack@eecs.umich.edu{ 5473113Sgblack@eecs.umich.edu std::string path; 5483113Sgblack@eecs.umich.edu 5493113Sgblack@eecs.umich.edu if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 5508852Sandreas.hansson@arm.com return -EFAULT; 5513113Sgblack@eecs.umich.edu 5523113Sgblack@eecs.umich.edu struct statfs hostBuf; 5533113Sgblack@eecs.umich.edu int result = statfs(path.c_str(), &hostBuf); 5543113Sgblack@eecs.umich.edu 5556686Stjones1@inf.ed.ac.uk if (result < 0) 5563113Sgblack@eecs.umich.edu return -errno; 5573113Sgblack@eecs.umich.edu 5583113Sgblack@eecs.umich.edu OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 559378SN/A 560378SN/A return 0; 5619141Smarc.orr@gmail.com} 5629141Smarc.orr@gmail.com 563360SN/A 5641450SN/A/// Target fstatfs() handler. 5653114Sgblack@eecs.umich.edutemplate <class OS> 5662680Sktlim@umich.eduSyscallReturn 567360SN/AfstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 5686701Sgblack@eecs.umich.edu ExecContext *xc) 56910930Sbrandon.potter@amd.com{ 5706701Sgblack@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 571360SN/A 57210930Sbrandon.potter@amd.com if (fd < 0) 573360SN/A return -EBADF; 57410932Sbrandon.potter@amd.com 57510496Ssteve.reinhardt@amd.com struct statfs hostBuf; 57610930Sbrandon.potter@amd.com int result = fstatfs(fd, &hostBuf); 577360SN/A 5781458SN/A if (result < 0) 579360SN/A return -errno; 580360SN/A 58110930Sbrandon.potter@amd.com OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 58210930Sbrandon.potter@amd.com 58310496Ssteve.reinhardt@amd.com return 0; 58410496Ssteve.reinhardt@amd.com} 5859141Smarc.orr@gmail.com 5861458SN/A 5879141Smarc.orr@gmail.com/// Target writev() handler. 588360SN/Atemplate <class OS> 5899141Smarc.orr@gmail.comSyscallReturn 59010930Sbrandon.potter@amd.comwritevFunc(SyscallDesc *desc, int callnum, Process *process, 5919141Smarc.orr@gmail.com ExecContext *xc) 592360SN/A{ 593360SN/A int fd = xc->getSyscallArg(0); 594360SN/A if (fd < 0 || process->sim_fd(fd) < 0) { 59510027SChris.Adeniyi-Jones@arm.com // doesn't map to any simulator fd: not a valid target fd 5963114Sgblack@eecs.umich.edu return -EBADF; 59710027SChris.Adeniyi-Jones@arm.com } 598360SN/A 599360SN/A uint64_t tiov_base = xc->getSyscallArg(1); 600360SN/A size_t count = xc->getSyscallArg(2); 6018852Sandreas.hansson@arm.com struct iovec hiov[count]; 6026701Sgblack@eecs.umich.edu for (int i = 0; i < count; ++i) 6031458SN/A { 604360SN/A typename OS::tgt_iovec tiov; 6056701Sgblack@eecs.umich.edu xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), 6066701Sgblack@eecs.umich.edu &tiov, sizeof(typename OS::tgt_iovec)); 607360SN/A hiov[i].iov_len = gtoh(tiov.iov_len); 608360SN/A hiov[i].iov_base = new char [hiov[i].iov_len]; 609360SN/A xc->mem->access(Read, gtoh(tiov.iov_base), 610360SN/A hiov[i].iov_base, hiov[i].iov_len); 611360SN/A } 612360SN/A 613360SN/A int result = writev(process->sim_fd(fd), hiov, count); 614360SN/A 615360SN/A for (int i = 0; i < count; ++i) 616360SN/A { 617360SN/A delete [] (char *)hiov[i].iov_base; 618360SN/A } 6191706SN/A 620360SN/A if (result < 0) 621360SN/A return -errno; 622360SN/A 623360SN/A return 0; 624360SN/A} 6253669Sbinkertn@umich.edu 6263669Sbinkertn@umich.edu 6273669Sbinkertn@umich.edu/// Target mmap() handler. 6281706SN/A/// 6291706SN/A/// We don't really handle mmap(). If the target is mmaping an 63010496Ssteve.reinhardt@amd.com/// anonymous region or /dev/zero, we can get away with doing basically 63110496Ssteve.reinhardt@amd.com/// nothing (since memory is initialized to zero and the simulator 63210496Ssteve.reinhardt@amd.com/// doesn't really check addresses anyway). Always print a warning, 63310496Ssteve.reinhardt@amd.com/// since this could be seriously broken if we're not mapping 63410496Ssteve.reinhardt@amd.com/// /dev/zero. 63510496Ssteve.reinhardt@amd.com// 63610496Ssteve.reinhardt@amd.com/// Someday we should explicitly check for /dev/zero in open, flag the 63710496Ssteve.reinhardt@amd.com/// file descriptor, and fail (or implement!) a non-anonymous mmap to 63810496Ssteve.reinhardt@amd.com/// anything else. 63910496Ssteve.reinhardt@amd.comtemplate <class OS> 64010496Ssteve.reinhardt@amd.comSyscallReturn 64110496Ssteve.reinhardt@amd.commmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 64210496Ssteve.reinhardt@amd.com{ 64310496Ssteve.reinhardt@amd.com Addr start = xc->getSyscallArg(0); 64410496Ssteve.reinhardt@amd.com uint64_t length = xc->getSyscallArg(1); 64510496Ssteve.reinhardt@amd.com // int prot = xc->getSyscallArg(2); 64610496Ssteve.reinhardt@amd.com int flags = xc->getSyscallArg(3); 64710496Ssteve.reinhardt@amd.com // int fd = p->sim_fd(xc->getSyscallArg(4)); 64810496Ssteve.reinhardt@amd.com // int offset = xc->getSyscallArg(5); 64910496Ssteve.reinhardt@amd.com 6505795Ssaidi@eecs.umich.edu if (start == 0) { 6519143Ssteve.reinhardt@amd.com // user didn't give an address... pick one from our "mmap region" 6529142Ssteve.reinhardt@amd.com start = p->mmap_end; 6539142Ssteve.reinhardt@amd.com p->mmap_end += roundUp(length, TheISA::VMPageSize); 6549143Ssteve.reinhardt@amd.com if (p->nxm_start != 0) { 6555795Ssaidi@eecs.umich.edu //If we have an nxm space, make sure we haven't colided 6569143Ssteve.reinhardt@amd.com assert(p->mmap_end < p->nxm_start); 6575795Ssaidi@eecs.umich.edu } 6585795Ssaidi@eecs.umich.edu } 6595795Ssaidi@eecs.umich.edu 6609143Ssteve.reinhardt@amd.com if (!(flags & OS::TGT_MAP_ANONYMOUS)) { 6615795Ssaidi@eecs.umich.edu warn("allowing mmap of file @ fd %d. " 662360SN/A "This will break if not /dev/zero.", xc->getSyscallArg(4)); 6639143Ssteve.reinhardt@amd.com } 6649143Ssteve.reinhardt@amd.com 6659143Ssteve.reinhardt@amd.com return start; 66610932Sbrandon.potter@amd.com} 667360SN/A 668360SN/A/// Target getrlimit() handler. 66910027SChris.Adeniyi-Jones@arm.comtemplate <class OS> 67010027SChris.Adeniyi-Jones@arm.comSyscallReturn 67110027SChris.Adeniyi-Jones@arm.comgetrlimitFunc(SyscallDesc *desc, int callnum, Process *process, 67210027SChris.Adeniyi-Jones@arm.com ExecContext *xc) 67310027SChris.Adeniyi-Jones@arm.com{ 67410027SChris.Adeniyi-Jones@arm.com unsigned resource = xc->getSyscallArg(0); 67510027SChris.Adeniyi-Jones@arm.com TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); 67610027SChris.Adeniyi-Jones@arm.com 67710027SChris.Adeniyi-Jones@arm.com switch (resource) { 67810027SChris.Adeniyi-Jones@arm.com case OS::TGT_RLIMIT_STACK: 67910027SChris.Adeniyi-Jones@arm.com // max stack size in bytes: make up a number (2MB for now) 68010027SChris.Adeniyi-Jones@arm.com rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; 68110027SChris.Adeniyi-Jones@arm.com rlp->rlim_cur = htog(rlp->rlim_cur); 68210027SChris.Adeniyi-Jones@arm.com rlp->rlim_max = htog(rlp->rlim_max); 68310027SChris.Adeniyi-Jones@arm.com break; 68410027SChris.Adeniyi-Jones@arm.com 68510027SChris.Adeniyi-Jones@arm.com default: 68610027SChris.Adeniyi-Jones@arm.com std::cerr << "getrlimitFunc: unimplemented resource " << resource 68710027SChris.Adeniyi-Jones@arm.com << std::endl; 68810027SChris.Adeniyi-Jones@arm.com abort(); 68910027SChris.Adeniyi-Jones@arm.com break; 69010027SChris.Adeniyi-Jones@arm.com } 69110633Smichaelupton@gmail.com 69210633Smichaelupton@gmail.com rlp.copyOut(xc->mem); 69310633Smichaelupton@gmail.com return 0; 69410633Smichaelupton@gmail.com} 69510633Smichaelupton@gmail.com 69610633Smichaelupton@gmail.com/// Target gettimeofday() handler. 69710633Smichaelupton@gmail.comtemplate <class OS> 69810633Smichaelupton@gmail.comSyscallReturn 69910633Smichaelupton@gmail.comgettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, 70010633Smichaelupton@gmail.com ExecContext *xc) 70110633Smichaelupton@gmail.com{ 70210633Smichaelupton@gmail.com TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); 70310633Smichaelupton@gmail.com 70410633Smichaelupton@gmail.com getElapsedTime(tp->tv_sec, tp->tv_usec); 70510203SAli.Saidi@ARM.com tp->tv_sec += seconds_since_epoch; 70610203SAli.Saidi@ARM.com tp->tv_sec = htog(tp->tv_sec); 70710203SAli.Saidi@ARM.com tp->tv_usec = htog(tp->tv_usec); 70810203SAli.Saidi@ARM.com 70910203SAli.Saidi@ARM.com tp.copyOut(xc->mem); 71010203SAli.Saidi@ARM.com 71110203SAli.Saidi@ARM.com return 0; 71210203SAli.Saidi@ARM.com} 71310203SAli.Saidi@ARM.com 71410203SAli.Saidi@ARM.com 71510203SAli.Saidi@ARM.com/// Target utimes() handler. 71610203SAli.Saidi@ARM.comtemplate <class OS> 71710203SAli.Saidi@ARM.comSyscallReturn 71810203SAli.Saidi@ARM.comutimesFunc(SyscallDesc *desc, int callnum, Process *process, 71910203SAli.Saidi@ARM.com ExecContext *xc) 72010203SAli.Saidi@ARM.com{ 72110203SAli.Saidi@ARM.com std::string path; 72210203SAli.Saidi@ARM.com 72310203SAli.Saidi@ARM.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 72410203SAli.Saidi@ARM.com return -EFAULT; 72510203SAli.Saidi@ARM.com 72610203SAli.Saidi@ARM.com TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); 72710203SAli.Saidi@ARM.com tp.copyIn(xc->mem); 72810203SAli.Saidi@ARM.com 72910203SAli.Saidi@ARM.com struct timeval hostTimeval[2]; 73010203SAli.Saidi@ARM.com for (int i = 0; i < 2; ++i) 73110850SGiacomo.Gabrielli@arm.com { 73210850SGiacomo.Gabrielli@arm.com hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); 73310850SGiacomo.Gabrielli@arm.com hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); 73410850SGiacomo.Gabrielli@arm.com } 73510850SGiacomo.Gabrielli@arm.com int result = utimes(path.c_str(), hostTimeval); 73610850SGiacomo.Gabrielli@arm.com 73710850SGiacomo.Gabrielli@arm.com if (result < 0) 73810850SGiacomo.Gabrielli@arm.com return -errno; 73910850SGiacomo.Gabrielli@arm.com 74010850SGiacomo.Gabrielli@arm.com return 0; 74110850SGiacomo.Gabrielli@arm.com} 74210850SGiacomo.Gabrielli@arm.com/// Target getrusage() function. 74310850SGiacomo.Gabrielli@arm.comtemplate <class OS> 74410850SGiacomo.Gabrielli@arm.comSyscallReturn 74510850SGiacomo.Gabrielli@arm.comgetrusageFunc(SyscallDesc *desc, int callnum, Process *process, 74610850SGiacomo.Gabrielli@arm.com ExecContext *xc) 74710850SGiacomo.Gabrielli@arm.com{ 74810850SGiacomo.Gabrielli@arm.com int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN 74910850SGiacomo.Gabrielli@arm.com TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); 75010850SGiacomo.Gabrielli@arm.com 75110850SGiacomo.Gabrielli@arm.com if (who != OS::TGT_RUSAGE_SELF) { 75210850SGiacomo.Gabrielli@arm.com // don't really handle THREAD or CHILDREN, but just warn and 75310850SGiacomo.Gabrielli@arm.com // plow ahead 75410850SGiacomo.Gabrielli@arm.com warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", 75510850SGiacomo.Gabrielli@arm.com who); 75610850SGiacomo.Gabrielli@arm.com } 75710850SGiacomo.Gabrielli@arm.com 75810850SGiacomo.Gabrielli@arm.com getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); 75910850SGiacomo.Gabrielli@arm.com rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); 76010850SGiacomo.Gabrielli@arm.com rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); 76110850SGiacomo.Gabrielli@arm.com 76210850SGiacomo.Gabrielli@arm.com rup->ru_stime.tv_sec = 0; 76310850SGiacomo.Gabrielli@arm.com rup->ru_stime.tv_usec = 0; 76410850SGiacomo.Gabrielli@arm.com rup->ru_maxrss = 0; 76510850SGiacomo.Gabrielli@arm.com rup->ru_ixrss = 0; 76610850SGiacomo.Gabrielli@arm.com rup->ru_idrss = 0; 7676640Svince@csl.cornell.edu rup->ru_isrss = 0; 7686640Svince@csl.cornell.edu rup->ru_minflt = 0; 7696640Svince@csl.cornell.edu rup->ru_majflt = 0; 7706640Svince@csl.cornell.edu rup->ru_nswap = 0; 7716640Svince@csl.cornell.edu rup->ru_inblock = 0; 7726640Svince@csl.cornell.edu rup->ru_oublock = 0; 7736640Svince@csl.cornell.edu rup->ru_msgsnd = 0; 7746701Sgblack@eecs.umich.edu rup->ru_msgrcv = 0; 7756701Sgblack@eecs.umich.edu rup->ru_nsignals = 0; 77610793Sbrandon.potter@amd.com rup->ru_nvcsw = 0; 7776640Svince@csl.cornell.edu rup->ru_nivcsw = 0; 7786701Sgblack@eecs.umich.edu 7796701Sgblack@eecs.umich.edu rup.copyOut(xc->mem); 7806640Svince@csl.cornell.edu 7818706Sandreas.hansson@arm.com return 0; 7826640Svince@csl.cornell.edu} 7836701Sgblack@eecs.umich.edu 7846640Svince@csl.cornell.edu#endif // __SIM_SYSCALL_EMUL_HH__ 785360SN/A