syscall_emul.hh revision 2553
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 "arch/isa_traits.hh" // for Addr 4912018Sandreas.sandberg@arm.com#include "base/chunk_generator.hh" 5012018Sandreas.sandberg@arm.com#include "base/intmath.hh" // for RoundUp 5112018Sandreas.sandberg@arm.com#include "base/misc.hh" 5212018Sandreas.sandberg@arm.com#include "base/trace.hh" 5312018Sandreas.sandberg@arm.com#include "cpu/base.hh" 5412018Sandreas.sandberg@arm.com#include "cpu/exec_context.hh" 552064SN/A#include "mem/translating_port.hh" 56360SN/A#include "mem/page_table.hh" 57360SN/A#include "sim/process.hh" 58360SN/A 59360SN/A/// 60360SN/A/// System call descriptor. 61360SN/A/// 6213936SAndrea.Mondelli@ucf.educlass SyscallDesc { 6313933Sbrandon.potter@amd.com 6413933Sbrandon.potter@amd.com public: 6513933Sbrandon.potter@amd.com 6613936SAndrea.Mondelli@ucf.edu /// Typedef for target syscall handler functions. 6713936SAndrea.Mondelli@ucf.edu typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, 6813936SAndrea.Mondelli@ucf.edu Process *, ExecContext *); 6913933Sbrandon.potter@amd.com 7013933Sbrandon.potter@amd.com const char *name; //!< Syscall name (e.g., "open"). 711809SN/A FuncPtr funcPtr; //!< Pointer to emulation function. 7211800Sbrandon.potter@amd.com int flags; //!< Flags (see Flags enum). 7311392Sbrandon.potter@amd.com 741809SN/A /// Flag values for controlling syscall behavior. 7511392Sbrandon.potter@amd.com enum Flags { 7613902Sbrandon.potter@amd.com /// Don't set return regs according to funcPtr return value. 7713570Sbrandon.potter@amd.com /// Used for syscalls with non-standard return conventions 7813902Sbrandon.potter@amd.com /// that explicitly set the ExecContext regs (e.g., 7911383Sbrandon.potter@amd.com /// sigreturn). 8013568Sbrandon.potter@amd.com SuppressReturnValue = 1 813113Sgblack@eecs.umich.edu }; 828229Snate@binkert.org 8313570Sbrandon.potter@amd.com /// Constructor. 848229Snate@binkert.org SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) 8511594Santhony.gutierrez@amd.com : name(_name), funcPtr(_funcPtr), flags(_flags) 867075Snate@binkert.org { 878229Snate@binkert.org } 8811856Sbrandon.potter@amd.com 897075Snate@binkert.org /// Emulate the syscall. Public interface for calling through funcPtr. 90360SN/A void doSyscall(int callnum, Process *proc, ExecContext *xc); 9112461Sgabeblack@google.com}; 9211886Sbrandon.potter@amd.com 9311800Sbrandon.potter@amd.com 9411392Sbrandon.potter@amd.comclass BaseBufferArg { 9512334Sgabeblack@google.com 961354SN/A public: 976216Snate@binkert.org 986658Snate@binkert.org BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) 992474SN/A { 1002680Sktlim@umich.edu bufPtr = new uint8_t[size]; 1018229Snate@binkert.org // clear out buffer: in case we only partially populate this, 10211886Sbrandon.potter@amd.com // and then do a copyOut(), we want to make sure we don't 10310496Ssteve.reinhardt@amd.com // introduce any random junk into the simulated address space 10411911SBrandon.Potter@amd.com memset(bufPtr, 0, size); 1058229Snate@binkert.org } 10611794Sbrandon.potter@amd.com 10711886Sbrandon.potter@amd.com virtual ~BaseBufferArg() { delete [] bufPtr; } 10810497Ssteve.reinhardt@amd.com 10911794Sbrandon.potter@amd.com // 110360SN/A // copy data into simulator space (read from target memory) 11113629SAndrea.Mondelli@ucf.edu // 11213629SAndrea.Mondelli@ucf.edu virtual bool copyIn(TranslatingPort *memport) 11313629SAndrea.Mondelli@ucf.edu { 11413629SAndrea.Mondelli@ucf.edu memport->readBlob(addr, bufPtr, size); 115360SN/A return true; // no EFAULT detection for now 116360SN/A } 117360SN/A 118360SN/A // 119360SN/A // copy data out of simulator space (write to target memory) 120360SN/A // 121360SN/A virtual bool copyOut(TranslatingPort *memport) 122360SN/A { 12313933Sbrandon.potter@amd.com memport->writeBlob(addr, bufPtr, size); 124360SN/A return true; // no EFAULT detection for now 125378SN/A } 12613995Sbrandon.potter@amd.com 127378SN/A protected: 128378SN/A Addr addr; 129378SN/A int size; 130378SN/A uint8_t *bufPtr; 131378SN/A}; 13213995Sbrandon.potter@amd.com 133360SN/A 13411760Sbrandon.potter@amd.comclass BufferArg : public BaseBufferArg 13513995Sbrandon.potter@amd.com{ 13611760Sbrandon.potter@amd.com public: 1376109Ssanchezd@stanford.edu BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 13813995Sbrandon.potter@amd.com void *bufferPtr() { return bufPtr; } 139378SN/A}; 1406109Ssanchezd@stanford.edu 14113995Sbrandon.potter@amd.comtemplate <class T> 1426109Ssanchezd@stanford.educlass TypedBufferArg : public BaseBufferArg 14311886Sbrandon.potter@amd.com{ 14413995Sbrandon.potter@amd.com public: 14511886Sbrandon.potter@amd.com // user can optionally specify a specific number of bytes to 146378SN/A // allocate to deal with those structs that have variable-size 14713995Sbrandon.potter@amd.com // arrays at the end 148378SN/A TypedBufferArg(Addr _addr, int _size = sizeof(T)) 1495748SSteve.Reinhardt@amd.com : BaseBufferArg(_addr, _size) 15013995Sbrandon.potter@amd.com { } 151378SN/A 152378SN/A // type case 15313995Sbrandon.potter@amd.com operator T*() { return (T *)bufPtr; } 154378SN/A 155378SN/A // dereference operators 15613995Sbrandon.potter@amd.com T &operator*() { return *((T *)bufPtr); } 157378SN/A T* operator->() { return (T *)bufPtr; } 1584118Sgblack@eecs.umich.edu T &operator[](int i) { return ((T *)bufPtr)[i]; } 15913995Sbrandon.potter@amd.com}; 1604118Sgblack@eecs.umich.edu 161378SN/A////////////////////////////////////////////////////////////////////// 16213995Sbrandon.potter@amd.com// 163378SN/A// The following emulation functions are generic enough that they 16413568Sbrandon.potter@amd.com// don't need to be recompiled for different emulated OS's. They are 16513995Sbrandon.potter@amd.com// defined in sim/syscall_emul.cc. 16613568Sbrandon.potter@amd.com// 167378SN/A////////////////////////////////////////////////////////////////////// 16813995Sbrandon.potter@amd.com 169360SN/A 1705513SMichael.Adler@intel.com/// Handler for unimplemented syscalls that we haven't thought about. 17113995Sbrandon.potter@amd.comSyscallReturn unimplementedFunc(SyscallDesc *desc, int num, 1725513SMichael.Adler@intel.com Process *p, ExecContext *xc); 17310203SAli.Saidi@ARM.com 17413995Sbrandon.potter@amd.com/// Handler for unimplemented syscalls that we never intend to 17510203SAli.Saidi@ARM.com/// implement (signal handling, etc.) and should not affect the correct 17613995Sbrandon.potter@amd.com/// behavior of the program. Print a warning only if the appropriate 1775513SMichael.Adler@intel.com/// trace flag is enabled. Return success to the target program. 178511SN/ASyscallReturn ignoreFunc(SyscallDesc *desc, int num, 17913995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 18010633Smichaelupton@gmail.com 18113995Sbrandon.potter@amd.com/// Target exit() handler: terminate simulation. 182511SN/ASyscallReturn exitFunc(SyscallDesc *desc, int num, 18312795Smattdsinclair@gmail.com Process *p, ExecContext *xc); 18413995Sbrandon.potter@amd.com 18512795Smattdsinclair@gmail.com/// Target getpagesize() handler. 18612796Smattdsinclair@gmail.comSyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, 18713995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 18812796Smattdsinclair@gmail.com 1895513SMichael.Adler@intel.com/// Target obreak() handler: set brk address. 19013995Sbrandon.potter@amd.comSyscallReturn obreakFunc(SyscallDesc *desc, int num, 1915513SMichael.Adler@intel.com Process *p, ExecContext *xc); 19213031Sbrandon.potter@amd.com 19313995Sbrandon.potter@amd.com/// Target close() handler. 19413031Sbrandon.potter@amd.comSyscallReturn closeFunc(SyscallDesc *desc, int num, 19513031Sbrandon.potter@amd.com Process *p, ExecContext *xc); 19613995Sbrandon.potter@amd.com 19713031Sbrandon.potter@amd.com/// Target read() handler. 19813031Sbrandon.potter@amd.comSyscallReturn readFunc(SyscallDesc *desc, int num, 19913995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 20013031Sbrandon.potter@amd.com 201511SN/A/// Target write() handler. 20213995Sbrandon.potter@amd.comSyscallReturn writeFunc(SyscallDesc *desc, int num, 2031706SN/A Process *p, ExecContext *xc); 2041706SN/A 2051706SN/A/// Target lseek() handler. 20613995Sbrandon.potter@amd.comSyscallReturn lseekFunc(SyscallDesc *desc, int num, 2071706SN/A Process *p, ExecContext *xc); 2081706SN/A 2091706SN/A/// Target munmap() handler. 21013995Sbrandon.potter@amd.comSyscallReturn munmapFunc(SyscallDesc *desc, int num, 2111706SN/A Process *p, ExecContext *xc); 212511SN/A 2136703Svince@csl.cornell.edu/// Target gethostname() handler. 21413995Sbrandon.potter@amd.comSyscallReturn gethostnameFunc(SyscallDesc *desc, int num, 2156703Svince@csl.cornell.edu Process *p, ExecContext *xc); 2166685Stjones1@inf.ed.ac.uk 21713995Sbrandon.potter@amd.com/// Target unlink() handler. 2186685Stjones1@inf.ed.ac.ukSyscallReturn unlinkFunc(SyscallDesc *desc, int num, 2196685Stjones1@inf.ed.ac.uk Process *p, ExecContext *xc); 2205513SMichael.Adler@intel.com 22113995Sbrandon.potter@amd.com/// Target rename() handler. 2225513SMichael.Adler@intel.comSyscallReturn renameFunc(SyscallDesc *desc, int num, 22311885Sbrandon.potter@amd.com Process *p, ExecContext *xc); 22413995Sbrandon.potter@amd.com 2255513SMichael.Adler@intel.com 2261999SN/A/// Target truncate() handler. 22713995Sbrandon.potter@amd.comSyscallReturn truncateFunc(SyscallDesc *desc, int num, 2281999SN/A Process *p, ExecContext *xc); 22911885Sbrandon.potter@amd.com 23013995Sbrandon.potter@amd.com 2311999SN/A/// Target ftruncate() handler. 2321999SN/ASyscallReturn ftruncateFunc(SyscallDesc *desc, int num, 23313995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 2341999SN/A 2353079Sstever@eecs.umich.edu 23613995Sbrandon.potter@amd.com/// Target chown() handler. 2373079Sstever@eecs.umich.eduSyscallReturn chownFunc(SyscallDesc *desc, int num, 23811908SBrandon.Potter@amd.com Process *p, ExecContext *xc); 23913995Sbrandon.potter@amd.com 24011908SBrandon.Potter@amd.com 24111875Sbrandon.potter@amd.com/// Target fchown() handler. 24213995Sbrandon.potter@amd.comSyscallReturn fchownFunc(SyscallDesc *desc, int num, 2432093SN/A Process *p, ExecContext *xc); 2442687Sksewell@umich.edu 24513995Sbrandon.potter@amd.com/// Target fnctl() handler. 2462687Sksewell@umich.eduSyscallReturn fcntlFunc(SyscallDesc *desc, int num, 2472238SN/A Process *process, ExecContext *xc); 24813995Sbrandon.potter@amd.com 2492238SN/A/// Target setuid() handler. 25011908SBrandon.Potter@amd.comSyscallReturn setuidFunc(SyscallDesc *desc, int num, 25113995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 25211908SBrandon.Potter@amd.com 25311908SBrandon.Potter@amd.com/// Target getpid() handler. 25413995Sbrandon.potter@amd.comSyscallReturn getpidFunc(SyscallDesc *desc, int num, 25514129Smatthew.sinclair@amd.com Process *p, ExecContext *xc); 25614129Smatthew.sinclair@amd.com 25714129Smatthew.sinclair@amd.com/// Target getuid() handler. 25814129Smatthew.sinclair@amd.comSyscallReturn getuidFunc(SyscallDesc *desc, int num, 25911908SBrandon.Potter@amd.com Process *p, ExecContext *xc); 2602238SN/A 26113995Sbrandon.potter@amd.com/// Target getgid() handler. 2622238SN/ASyscallReturn getgidFunc(SyscallDesc *desc, int num, 26313571Sbrandon.potter@amd.com Process *p, ExecContext *xc); 26413995Sbrandon.potter@amd.com 26513571Sbrandon.potter@amd.com/// Target getppid() handler. 26613568Sbrandon.potter@amd.comSyscallReturn getppidFunc(SyscallDesc *desc, int num, 26713995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 26813568Sbrandon.potter@amd.com 26913568Sbrandon.potter@amd.com/// Target geteuid() handler. 27013995Sbrandon.potter@amd.comSyscallReturn geteuidFunc(SyscallDesc *desc, int num, 27113568Sbrandon.potter@amd.com Process *p, ExecContext *xc); 27213568Sbrandon.potter@amd.com 27313995Sbrandon.potter@amd.com/// Target getegid() handler. 27413568Sbrandon.potter@amd.comSyscallReturn getegidFunc(SyscallDesc *desc, int num, 27513448Sciro.santilli@arm.com Process *p, ExecContext *xc); 27613031Sbrandon.potter@amd.com 27713995Sbrandon.potter@amd.com 27813448Sciro.santilli@arm.com 27913031Sbrandon.potter@amd.com/// Pseudo Funcs - These functions use a different return convension, 28013539Sjavier.setoain@arm.com/// returning a second value in a register other than the normal return register 28113539Sjavier.setoain@arm.comSyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, 28213995Sbrandon.potter@amd.com Process *process, ExecContext *xc); 28313539Sjavier.setoain@arm.com 28413539Sjavier.setoain@arm.com/// Target getpidPseudo() handler. 28513569Sbrandon.potter@amd.comSyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, 28613995Sbrandon.potter@amd.com Process *p, ExecContext *xc); 28713569Sbrandon.potter@amd.com 28813569Sbrandon.potter@amd.com/// Target getuidPseudo() handler. 28913995Sbrandon.potter@amd.comSyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num, 29013569Sbrandon.potter@amd.com Process *p, ExecContext *xc); 29113569Sbrandon.potter@amd.com 29213995Sbrandon.potter@amd.com/// Target getgidPseudo() handler. 29313569Sbrandon.potter@amd.comSyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, 29413569Sbrandon.potter@amd.com Process *p, ExecContext *xc); 29513995Sbrandon.potter@amd.com 29613569Sbrandon.potter@amd.com 29713031Sbrandon.potter@amd.com/// This struct is used to build an target-OS-dependent table that 29813995Sbrandon.potter@amd.com/// maps the target's open() flags to the host open() flags. 2992238SN/Astruct OpenFlagTransTable { 3002238SN/A int tgtFlag; //!< Target system flag value. 30113995Sbrandon.potter@amd.com int hostFlag; //!< Corresponding host system flag value. 3022238SN/A}; 3032238SN/A 30413995Sbrandon.potter@amd.com 3052238SN/A 3062238SN/A/// A readable name for 1,000,000, for converting microseconds to seconds. 30713995Sbrandon.potter@amd.comconst int one_million = 1000000; 3082238SN/A 3092238SN/A/// Approximate seconds since the epoch (1/1/1970). About a billion, 31013995Sbrandon.potter@amd.com/// by my reckoning. We want to keep this a constant (not use the 3112238SN/A/// real-world time) to keep simulations repeatable. 3129455Smitch.hayenga+gem5@gmail.comconst unsigned seconds_since_epoch = 1000000000; 31313995Sbrandon.potter@amd.com 31413995Sbrandon.potter@amd.com/// Helper function to convert current elapsed time to seconds and 31511851Sbrandon.potter@amd.com/// microseconds. 3169455Smitch.hayenga+gem5@gmail.comtemplate <class T1, class T2> 31713571Sbrandon.potter@amd.comvoid 31813995Sbrandon.potter@amd.comgetElapsedTime(T1 &sec, T2 &usec) 31913571Sbrandon.potter@amd.com{ 32013571Sbrandon.potter@amd.com int elapsed_usecs = curTick / Clock::Int::us; 32113995Sbrandon.potter@amd.com sec = elapsed_usecs / one_million; 32213571Sbrandon.potter@amd.com usec = elapsed_usecs % one_million; 32313571Sbrandon.potter@amd.com} 32413995Sbrandon.potter@amd.com 32513571Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////// 3269112Smarc.orr@gmail.com// 32711906SBrandon.Potter@amd.com// The following emulation functions are generic, but need to be 32811906SBrandon.Potter@amd.com// templated to account for differences in types, constants, etc. 3299112Smarc.orr@gmail.com// 3309112Smarc.orr@gmail.com////////////////////////////////////////////////////////////////////// 33113995Sbrandon.potter@amd.com 3329112Smarc.orr@gmail.com/// Target ioctl() handler. For the most part, programs call ioctl() 33311911SBrandon.Potter@amd.com/// only to find out if their stdout is a tty, to determine whether to 3349112Smarc.orr@gmail.com/// do line or block buffering. 33511911SBrandon.Potter@amd.comtemplate <class OS> 33613995Sbrandon.potter@amd.comSyscallReturn 33713995Sbrandon.potter@amd.comioctlFunc(SyscallDesc *desc, int callnum, Process *process, 33811911SBrandon.Potter@amd.com ExecContext *xc) 33911911SBrandon.Potter@amd.com{ 34011911SBrandon.Potter@amd.com int fd = xc->getSyscallArg(0); 34113642Sqtt2@cornell.edu unsigned req = xc->getSyscallArg(1); 34213642Sqtt2@cornell.edu 34313642Sqtt2@cornell.edu DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); 3449112Smarc.orr@gmail.com 34511911SBrandon.Potter@amd.com if (fd < 0 || process->sim_fd(fd) < 0) { 34611911SBrandon.Potter@amd.com // doesn't map to any simulator fd: not a valid target fd 34711911SBrandon.Potter@amd.com return -EBADF; 34811911SBrandon.Potter@amd.com } 3499238Slluc.alvarez@bsc.es 35013642Sqtt2@cornell.edu switch (req) { 3519112Smarc.orr@gmail.com case OS::TIOCISATTY: 35211911SBrandon.Potter@amd.com case OS::TIOCGETP: 3539112Smarc.orr@gmail.com case OS::TIOCSETP: 35413642Sqtt2@cornell.edu case OS::TIOCSETN: 35511911SBrandon.Potter@amd.com case OS::TIOCSETC: 35611911SBrandon.Potter@amd.com case OS::TIOCGETC: 35714024Sgabeblack@google.com case OS::TIOCGETS: 35811911SBrandon.Potter@amd.com case OS::TIOCGETA: 3599112Smarc.orr@gmail.com return -ENOTTY; 36011911SBrandon.Potter@amd.com 36111911SBrandon.Potter@amd.com default: 36211911SBrandon.Potter@amd.com fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", 36311911SBrandon.Potter@amd.com fd, req, xc->readPC()); 36411911SBrandon.Potter@amd.com } 36511911SBrandon.Potter@amd.com} 3669112Smarc.orr@gmail.com 3679112Smarc.orr@gmail.com/// Target open() handler. 36813642Sqtt2@cornell.edutemplate <class OS> 36913642Sqtt2@cornell.eduSyscallReturn 37013642Sqtt2@cornell.eduopenFunc(SyscallDesc *desc, int callnum, Process *process, 37113642Sqtt2@cornell.edu ExecContext *xc) 37213642Sqtt2@cornell.edu{ 37311911SBrandon.Potter@amd.com std::string path; 3749112Smarc.orr@gmail.com 37511911SBrandon.Potter@amd.com if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 37611911SBrandon.Potter@amd.com return -EFAULT; 37713642Sqtt2@cornell.edu 37813642Sqtt2@cornell.edu if (path == "/dev/sysdev0") { 37913650Smw828@cornell.edu // This is a memory-mapped high-resolution timer device on Alpha. 38013650Smw828@cornell.edu // We don't support it, so just punt. 38113650Smw828@cornell.edu warn("Ignoring open(%s, ...)\n", path); 38213650Smw828@cornell.edu return -ENOENT; 38313650Smw828@cornell.edu } 38414024Sgabeblack@google.com 38513650Smw828@cornell.edu int tgtFlags = xc->getSyscallArg(1); 38613650Smw828@cornell.edu int mode = xc->getSyscallArg(2); 38713650Smw828@cornell.edu int hostFlags = 0; 38813650Smw828@cornell.edu 38913650Smw828@cornell.edu // translate open flags 39013650Smw828@cornell.edu for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { 39113650Smw828@cornell.edu if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 39213650Smw828@cornell.edu tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 39313651Smw828@cornell.edu hostFlags |= OS::openFlagTable[i].hostFlag; 39413651Smw828@cornell.edu } 39513651Smw828@cornell.edu } 39613651Smw828@cornell.edu 39713651Smw828@cornell.edu // any target flags left? 39813651Smw828@cornell.edu if (tgtFlags != 0) 39913651Smw828@cornell.edu warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 40013651Smw828@cornell.edu 40113651Smw828@cornell.edu#ifdef __CYGWIN32__ 40213651Smw828@cornell.edu hostFlags |= O_BINARY; 40313651Smw828@cornell.edu#endif 40413651Smw828@cornell.edu 40513651Smw828@cornell.edu DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); 40613651Smw828@cornell.edu 40713651Smw828@cornell.edu // open the file 40813651Smw828@cornell.edu int fd = open(path.c_str(), hostFlags, mode); 40913651Smw828@cornell.edu 41013651Smw828@cornell.edu return (fd == -1) ? -errno : process->alloc_fd(fd); 41113651Smw828@cornell.edu} 41213651Smw828@cornell.edu 41313651Smw828@cornell.edu 41413651Smw828@cornell.edu/// Target chmod() handler. 41513651Smw828@cornell.edutemplate <class OS> 41613651Smw828@cornell.eduSyscallReturn 41714024Sgabeblack@google.comchmodFunc(SyscallDesc *desc, int callnum, Process *process, 41813651Smw828@cornell.edu ExecContext *xc) 41913651Smw828@cornell.edu{ 42013651Smw828@cornell.edu std::string path; 42113651Smw828@cornell.edu 42213651Smw828@cornell.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 42313651Smw828@cornell.edu return -EFAULT; 42413651Smw828@cornell.edu 42513651Smw828@cornell.edu uint32_t mode = xc->getSyscallArg(1); 42613651Smw828@cornell.edu mode_t hostMode = 0; 42713651Smw828@cornell.edu 42813651Smw828@cornell.edu // XXX translate mode flags via OS::something??? 42913651Smw828@cornell.edu hostMode = mode; 43013651Smw828@cornell.edu 43113651Smw828@cornell.edu // do the chmod 43213651Smw828@cornell.edu int result = chmod(path.c_str(), hostMode); 43313651Smw828@cornell.edu if (result < 0) 43413651Smw828@cornell.edu return -errno; 43513651Smw828@cornell.edu 43613651Smw828@cornell.edu return 0; 43713651Smw828@cornell.edu} 43813651Smw828@cornell.edu 43913651Smw828@cornell.edu 44013651Smw828@cornell.edu/// Target fchmod() handler. 44114024Sgabeblack@google.comtemplate <class OS> 44213651Smw828@cornell.eduSyscallReturn 44313651Smw828@cornell.edufchmodFunc(SyscallDesc *desc, int callnum, Process *process, 44413651Smw828@cornell.edu ExecContext *xc) 44513651Smw828@cornell.edu{ 44613651Smw828@cornell.edu int fd = xc->getSyscallArg(0); 44713651Smw828@cornell.edu if (fd < 0 || process->sim_fd(fd) < 0) { 44813651Smw828@cornell.edu // doesn't map to any simulator fd: not a valid target fd 44913651Smw828@cornell.edu return -EBADF; 45013651Smw828@cornell.edu } 45113651Smw828@cornell.edu 45213651Smw828@cornell.edu uint32_t mode = xc->getSyscallArg(1); 45313651Smw828@cornell.edu mode_t hostMode = 0; 45413651Smw828@cornell.edu 45513651Smw828@cornell.edu // XXX translate mode flags via OS::someting??? 45613651Smw828@cornell.edu hostMode = mode; 45713651Smw828@cornell.edu 45813651Smw828@cornell.edu // do the fchmod 45913651Smw828@cornell.edu int result = fchmod(process->sim_fd(fd), hostMode); 46013651Smw828@cornell.edu if (result < 0) 46113651Smw828@cornell.edu return -errno; 46213651Smw828@cornell.edu 46313651Smw828@cornell.edu return 0; 4649112Smarc.orr@gmail.com} 46511911SBrandon.Potter@amd.com 46611911SBrandon.Potter@amd.com 4679112Smarc.orr@gmail.com/// Target stat() handler. 4689112Smarc.orr@gmail.comtemplate <class OS> 4692238SN/ASyscallReturn 4702238SN/AstatFunc(SyscallDesc *desc, int callnum, Process *process, 4712238SN/A ExecContext *xc) 47213995Sbrandon.potter@amd.com{ 4732238SN/A std::string path; 4742238SN/A 47513995Sbrandon.potter@amd.com if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 4762238SN/A return -EFAULT; 4772238SN/A 47813995Sbrandon.potter@amd.com struct stat hostBuf; 4792238SN/A int result = stat(path.c_str(), &hostBuf); 4802238SN/A 48113995Sbrandon.potter@amd.com if (result < 0) 4822238SN/A return -errno; 4832238SN/A 4841354SN/A OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 4851354SN/A 48610796Sbrandon.potter@amd.com return 0; 48710796Sbrandon.potter@amd.com} 4881354SN/A 4891354SN/A 4901354SN/A/// Target fstat64() handler. 4911354SN/Atemplate <class OS> 4921354SN/ASyscallReturn 4931354SN/Afstat64Func(SyscallDesc *desc, int callnum, Process *process, 4941354SN/A ExecContext *xc) 4951354SN/A{ 4961354SN/A int fd = xc->getSyscallArg(0); 4971354SN/A if (fd < 0 || process->sim_fd(fd) < 0) { 49810796Sbrandon.potter@amd.com // doesn't map to any simulator fd: not a valid target fd 4991354SN/A return -EBADF; 50010796Sbrandon.potter@amd.com } 5011354SN/A 5021354SN/A#if BSD_HOST 5031354SN/A struct stat hostBuf; 5041354SN/A int result = fstat(process->sim_fd(fd), &hostBuf); 50510796Sbrandon.potter@amd.com#else 50610796Sbrandon.potter@amd.com struct stat64 hostBuf; 50710796Sbrandon.potter@amd.com int result = fstat64(process->sim_fd(fd), &hostBuf); 50810796Sbrandon.potter@amd.com#endif 50910796Sbrandon.potter@amd.com 51010796Sbrandon.potter@amd.com if (result < 0) 51110796Sbrandon.potter@amd.com return -errno; 51210796Sbrandon.potter@amd.com 51310796Sbrandon.potter@amd.com OS::copyOutStat64Buf(xc->getMemPort(), fd, xc->getSyscallArg(1), &hostBuf); 51410796Sbrandon.potter@amd.com 51510796Sbrandon.potter@amd.com return 0; 516360SN/A} 517360SN/A 518360SN/A 519360SN/A/// Target lstat() handler. 520360SN/Atemplate <class OS> 521360SN/ASyscallReturn 522360SN/AlstatFunc(SyscallDesc *desc, int callnum, Process *process, 52311759Sbrandon.potter@amd.com ExecContext *xc) 5243113Sgblack@eecs.umich.edu{ 5253113Sgblack@eecs.umich.edu std::string path; 5263113Sgblack@eecs.umich.edu 5273113Sgblack@eecs.umich.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 5283113Sgblack@eecs.umich.edu return -EFAULT; 5293113Sgblack@eecs.umich.edu 5303113Sgblack@eecs.umich.edu struct stat hostBuf; 5313113Sgblack@eecs.umich.edu int result = lstat(path.c_str(), &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->getMemPort(), xc->getSyscallArg(1), &hostBuf); 53712032Sandreas.sandberg@arm.com 5383113Sgblack@eecs.umich.edu return 0; 5393113Sgblack@eecs.umich.edu} 5404189Sgblack@eecs.umich.edu 5414189Sgblack@eecs.umich.edu/// Target lstat64() handler. 5423113Sgblack@eecs.umich.edutemplate <class OS> 5433113Sgblack@eecs.umich.eduSyscallReturn 5443113Sgblack@eecs.umich.edulstat64Func(SyscallDesc *desc, int callnum, Process *process, 5453113Sgblack@eecs.umich.edu ExecContext *xc) 5468737Skoansin.tan@gmail.com{ 5473113Sgblack@eecs.umich.edu std::string path; 5488737Skoansin.tan@gmail.com 5493277Sgblack@eecs.umich.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 5505515SMichael.Adler@intel.com return -EFAULT; 5515515SMichael.Adler@intel.com 5525515SMichael.Adler@intel.com#if BSD_HOST 5535515SMichael.Adler@intel.com struct stat hostBuf; 5545515SMichael.Adler@intel.com int result = lstat(path.c_str(), &hostBuf); 5558737Skoansin.tan@gmail.com#else 5563277Sgblack@eecs.umich.edu struct stat64 hostBuf; 5578737Skoansin.tan@gmail.com int result = lstat64(path.c_str(), &hostBuf); 5583277Sgblack@eecs.umich.edu#endif 5598737Skoansin.tan@gmail.com 5603277Sgblack@eecs.umich.edu if (result < 0) 5618737Skoansin.tan@gmail.com return -errno; 5623113Sgblack@eecs.umich.edu 5633113Sgblack@eecs.umich.edu OS::copyOutStat64Buf(xc->getMemPort(), -1, xc->getSyscallArg(1), &hostBuf); 5643113Sgblack@eecs.umich.edu 5653113Sgblack@eecs.umich.edu return 0; 5668737Skoansin.tan@gmail.com} 5673113Sgblack@eecs.umich.edu 5688737Skoansin.tan@gmail.com/// Target fstat() handler. 5693114Sgblack@eecs.umich.edutemplate <class OS> 5708737Skoansin.tan@gmail.comSyscallReturn 5713114Sgblack@eecs.umich.edufstatFunc(SyscallDesc *desc, int callnum, Process *process, 5728737Skoansin.tan@gmail.com ExecContext *xc) 5733114Sgblack@eecs.umich.edu{ 5748737Skoansin.tan@gmail.com int fd = process->sim_fd(xc->getSyscallArg(0)); 57511906SBrandon.Potter@amd.com 5764061Sgblack@eecs.umich.edu DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); 5774061Sgblack@eecs.umich.edu 5788737Skoansin.tan@gmail.com if (fd < 0) 5793113Sgblack@eecs.umich.edu return -EBADF; 5808737Skoansin.tan@gmail.com 5813113Sgblack@eecs.umich.edu struct stat hostBuf; 5823113Sgblack@eecs.umich.edu int result = fstat(fd, &hostBuf); 5833113Sgblack@eecs.umich.edu 5843113Sgblack@eecs.umich.edu if (result < 0) 5853113Sgblack@eecs.umich.edu return -errno; 58612032Sandreas.sandberg@arm.com 5873113Sgblack@eecs.umich.edu OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 5883113Sgblack@eecs.umich.edu 5894189Sgblack@eecs.umich.edu return 0; 5904189Sgblack@eecs.umich.edu} 5913113Sgblack@eecs.umich.edu 5923113Sgblack@eecs.umich.edu 5933113Sgblack@eecs.umich.edu/// Target statfs() handler. 5948737Skoansin.tan@gmail.comtemplate <class OS> 5953113Sgblack@eecs.umich.eduSyscallReturn 5968737Skoansin.tan@gmail.comstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 5973113Sgblack@eecs.umich.edu ExecContext *xc) 5988737Skoansin.tan@gmail.com{ 5993113Sgblack@eecs.umich.edu std::string path; 6003113Sgblack@eecs.umich.edu 6013113Sgblack@eecs.umich.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 6023113Sgblack@eecs.umich.edu return -EFAULT; 6033113Sgblack@eecs.umich.edu 6043113Sgblack@eecs.umich.edu struct statfs hostBuf; 6053113Sgblack@eecs.umich.edu int result = statfs(path.c_str(), &hostBuf); 60611906SBrandon.Potter@amd.com 6073113Sgblack@eecs.umich.edu if (result < 0) 60812032Sandreas.sandberg@arm.com return -errno; 60914020Sgabeblack@google.com 61011906SBrandon.Potter@amd.com OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 6113113Sgblack@eecs.umich.edu 6123113Sgblack@eecs.umich.edu return 0; 6133113Sgblack@eecs.umich.edu} 6143113Sgblack@eecs.umich.edu 6153113Sgblack@eecs.umich.edu 6163113Sgblack@eecs.umich.edu/// Target fstatfs() handler. 6173113Sgblack@eecs.umich.edutemplate <class OS> 6183113Sgblack@eecs.umich.eduSyscallReturn 61912032Sandreas.sandberg@arm.comfstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 62014020Sgabeblack@google.com ExecContext *xc) 62111906SBrandon.Potter@amd.com{ 6223113Sgblack@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 6233113Sgblack@eecs.umich.edu 6243113Sgblack@eecs.umich.edu if (fd < 0) 6256686Stjones1@inf.ed.ac.uk return -EBADF; 6263113Sgblack@eecs.umich.edu 6273113Sgblack@eecs.umich.edu struct statfs hostBuf; 6283113Sgblack@eecs.umich.edu int result = fstatfs(fd, &hostBuf); 62911759Sbrandon.potter@amd.com 63012032Sandreas.sandberg@arm.com if (result < 0) 63114020Sgabeblack@google.com return -errno; 63211759Sbrandon.potter@amd.com 63311759Sbrandon.potter@amd.com OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 63411759Sbrandon.potter@amd.com 63511759Sbrandon.potter@amd.com return 0; 63611812Sbaz21@cam.ac.uk} 63711812Sbaz21@cam.ac.uk 63811812Sbaz21@cam.ac.uk 63911759Sbrandon.potter@amd.com/// Target writev() handler. 64011812Sbaz21@cam.ac.uktemplate <class OS> 64111759Sbrandon.potter@amd.comSyscallReturn 64211759Sbrandon.potter@amd.comwritevFunc(SyscallDesc *desc, int callnum, Process *process, 64311759Sbrandon.potter@amd.com ExecContext *xc) 64411759Sbrandon.potter@amd.com{ 64511759Sbrandon.potter@amd.com int fd = xc->getSyscallArg(0); 64611759Sbrandon.potter@amd.com if (fd < 0 || process->sim_fd(fd) < 0) { 64711759Sbrandon.potter@amd.com // doesn't map to any simulator fd: not a valid target fd 64811812Sbaz21@cam.ac.uk return -EBADF; 64911812Sbaz21@cam.ac.uk } 65011812Sbaz21@cam.ac.uk 65111812Sbaz21@cam.ac.uk TranslatingPort *p = xc->getMemPort(); 65211812Sbaz21@cam.ac.uk uint64_t tiov_base = xc->getSyscallArg(1); 65311812Sbaz21@cam.ac.uk size_t count = xc->getSyscallArg(2); 65411812Sbaz21@cam.ac.uk struct iovec hiov[count]; 65511759Sbrandon.potter@amd.com for (int i = 0; i < count; ++i) 65611759Sbrandon.potter@amd.com { 65711812Sbaz21@cam.ac.uk typename OS::tgt_iovec tiov; 65811812Sbaz21@cam.ac.uk 65911759Sbrandon.potter@amd.com p->readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec), 66011812Sbaz21@cam.ac.uk (uint8_t*)&tiov, sizeof(typename OS::tgt_iovec)); 66111812Sbaz21@cam.ac.uk hiov[i].iov_len = gtoh(tiov.iov_len); 66211812Sbaz21@cam.ac.uk hiov[i].iov_base = new char [hiov[i].iov_len]; 66311812Sbaz21@cam.ac.uk p->readBlob(gtoh(tiov.iov_base), (uint8_t *)hiov[i].iov_base, 66411812Sbaz21@cam.ac.uk hiov[i].iov_len); 66511812Sbaz21@cam.ac.uk } 66611812Sbaz21@cam.ac.uk 66711759Sbrandon.potter@amd.com int result = writev(process->sim_fd(fd), hiov, count); 66811759Sbrandon.potter@amd.com 66911759Sbrandon.potter@amd.com for (int i = 0; i < count; ++i) 67011759Sbrandon.potter@amd.com { 671378SN/A delete [] (char *)hiov[i].iov_base; 672378SN/A } 6739141Smarc.orr@gmail.com 6749141Smarc.orr@gmail.com if (result < 0) 675360SN/A return -errno; 6761450SN/A 67713995Sbrandon.potter@amd.com return 0; 678360SN/A} 6796701Sgblack@eecs.umich.edu 68013995Sbrandon.potter@amd.com 68113995Sbrandon.potter@amd.com/// Target mmap() handler. 68211856Sbrandon.potter@amd.com/// 68311856Sbrandon.potter@amd.com/// We don't really handle mmap(). If the target is mmaping an 684360SN/A/// anonymous region or /dev/zero, we can get away with doing basically 68513907Salexandru.dutu@amd.com/// nothing (since memory is initialized to zero and the simulator 686360SN/A/// doesn't really check addresses anyway). Always print a warning, 68711856Sbrandon.potter@amd.com/// since this could be seriously broken if we're not mapping 68811856Sbrandon.potter@amd.com/// /dev/zero. 68910496Ssteve.reinhardt@amd.com// 69011856Sbrandon.potter@amd.com/// Someday we should explicitly check for /dev/zero in open, flag the 69113902Sbrandon.potter@amd.com/// file descriptor, and fail (or implement!) a non-anonymous mmap to 69213902Sbrandon.potter@amd.com/// anything else. 69313902Sbrandon.potter@amd.comtemplate <class OS> 69413995Sbrandon.potter@amd.comSyscallReturn 69513902Sbrandon.potter@amd.commmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 69613902Sbrandon.potter@amd.com{ 69713902Sbrandon.potter@amd.com Addr start = xc->getSyscallArg(0); 69813902Sbrandon.potter@amd.com uint64_t length = xc->getSyscallArg(1); 69913902Sbrandon.potter@amd.com // int prot = xc->getSyscallArg(2); 70013902Sbrandon.potter@amd.com int flags = xc->getSyscallArg(3); 70113902Sbrandon.potter@amd.com // int fd = p->sim_fd(xc->getSyscallArg(4)); 70213902Sbrandon.potter@amd.com // int offset = xc->getSyscallArg(5); 70313902Sbrandon.potter@amd.com 70413902Sbrandon.potter@amd.com if ((start % TheISA::VMPageSize) != 0 || 70514024Sgabeblack@google.com (length % TheISA::VMPageSize) != 0) { 70613902Sbrandon.potter@amd.com warn("mmap failing: arguments not page-aligned: " 70713902Sbrandon.potter@amd.com "start 0x%x length 0x%x", 70813902Sbrandon.potter@amd.com start, length); 70913902Sbrandon.potter@amd.com return -EINVAL; 71014024Sgabeblack@google.com } 71113902Sbrandon.potter@amd.com 71213902Sbrandon.potter@amd.com if (start != 0) { 71313902Sbrandon.potter@amd.com warn("mmap: ignoring suggested map address 0x%x, using 0x%x", 71413902Sbrandon.potter@amd.com start, p->mmap_end); 71513902Sbrandon.potter@amd.com } 71613902Sbrandon.potter@amd.com 71714024Sgabeblack@google.com // pick next address from our "mmap region" 71814024Sgabeblack@google.com start = p->mmap_end; 71913902Sbrandon.potter@amd.com p->pTable->allocate(start, length); 72013902Sbrandon.potter@amd.com p->mmap_end += length; 72113902Sbrandon.potter@amd.com 72213902Sbrandon.potter@amd.com if (!(flags & OS::TGT_MAP_ANONYMOUS)) { 72313902Sbrandon.potter@amd.com warn("allowing mmap of file @ fd %d. " 72413936SAndrea.Mondelli@ucf.edu "This will break if not /dev/zero.", xc->getSyscallArg(4)); 72513902Sbrandon.potter@amd.com } 72613902Sbrandon.potter@amd.com 72713902Sbrandon.potter@amd.com return start; 72813902Sbrandon.potter@amd.com} 72913936SAndrea.Mondelli@ucf.edu 73013902Sbrandon.potter@amd.com/// Target getrlimit() handler. 73113902Sbrandon.potter@amd.comtemplate <class OS> 73213902Sbrandon.potter@amd.comSyscallReturn 73313902Sbrandon.potter@amd.comgetrlimitFunc(SyscallDesc *desc, int callnum, Process *process, 73413902Sbrandon.potter@amd.com ExecContext *xc) 73514024Sgabeblack@google.com{ 73613902Sbrandon.potter@amd.com unsigned resource = xc->getSyscallArg(0); 73713902Sbrandon.potter@amd.com TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); 73813902Sbrandon.potter@amd.com 73914024Sgabeblack@google.com switch (resource) { 74013902Sbrandon.potter@amd.com case OS::TGT_RLIMIT_STACK: 74113902Sbrandon.potter@amd.com // max stack size in bytes: make up a number (2MB for now) 74213902Sbrandon.potter@amd.com rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; 74313902Sbrandon.potter@amd.com rlp->rlim_cur = htog(rlp->rlim_cur); 74410496Ssteve.reinhardt@amd.com rlp->rlim_max = htog(rlp->rlim_max); 74511856Sbrandon.potter@amd.com break; 74611856Sbrandon.potter@amd.com 74711856Sbrandon.potter@amd.com default: 74811856Sbrandon.potter@amd.com std::cerr << "getrlimitFunc: unimplemented resource " << resource 74911856Sbrandon.potter@amd.com << std::endl; 75010930Sbrandon.potter@amd.com abort(); 7519141Smarc.orr@gmail.com break; 752360SN/A } 753360SN/A 754360SN/A rlp.copyOut(xc->getMemPort()); 75511907SBrandon.Potter@amd.com return 0; 75613995Sbrandon.potter@amd.com} 757360SN/A 75811907SBrandon.Potter@amd.com/// Target gettimeofday() handler. 75913995Sbrandon.potter@amd.comtemplate <class OS> 76011907SBrandon.Potter@amd.comSyscallReturn 76111907SBrandon.Potter@amd.comgettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, 76211907SBrandon.Potter@amd.com ExecContext *xc) 76311907SBrandon.Potter@amd.com{ 76411907SBrandon.Potter@amd.com TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); 76511907SBrandon.Potter@amd.com 76611907SBrandon.Potter@amd.com getElapsedTime(tp->tv_sec, tp->tv_usec); 76711907SBrandon.Potter@amd.com tp->tv_sec += seconds_since_epoch; 76811907SBrandon.Potter@amd.com tp->tv_sec = htog(tp->tv_sec); 76911907SBrandon.Potter@amd.com tp->tv_usec = htog(tp->tv_usec); 77011907SBrandon.Potter@amd.com 77111907SBrandon.Potter@amd.com tp.copyOut(xc->getMemPort()); 77211907SBrandon.Potter@amd.com 773360SN/A return 0; 77414024Sgabeblack@google.com} 7751458SN/A 776360SN/A 77711907SBrandon.Potter@amd.com/// Target utimes() handler. 77811907SBrandon.Potter@amd.comtemplate <class OS> 77911907SBrandon.Potter@amd.comSyscallReturn 78011907SBrandon.Potter@amd.comutimesFunc(SyscallDesc *desc, int callnum, Process *process, 78111907SBrandon.Potter@amd.com ExecContext *xc) 78211907SBrandon.Potter@amd.com{ 78311907SBrandon.Potter@amd.com std::string path; 78411907SBrandon.Potter@amd.com 78511907SBrandon.Potter@amd.com if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 78611907SBrandon.Potter@amd.com return -EFAULT; 787360SN/A 78811907SBrandon.Potter@amd.com TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); 78911907SBrandon.Potter@amd.com tp.copyIn(xc->getMemPort()); 79011907SBrandon.Potter@amd.com 791360SN/A struct timeval hostTimeval[2]; 792360SN/A for (int i = 0; i < 2; ++i) 79311907SBrandon.Potter@amd.com { 79411907SBrandon.Potter@amd.com hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); 79511907SBrandon.Potter@amd.com hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); 79611907SBrandon.Potter@amd.com } 797360SN/A int result = utimes(path.c_str(), hostTimeval); 79811907SBrandon.Potter@amd.com 799360SN/A if (result < 0) 800360SN/A return -errno; 80111907SBrandon.Potter@amd.com 8023669Sbinkertn@umich.edu return 0; 80311907SBrandon.Potter@amd.com} 80411907SBrandon.Potter@amd.com/// Target getrusage() function. 80511907SBrandon.Potter@amd.comtemplate <class OS> 80611907SBrandon.Potter@amd.comSyscallReturn 80711907SBrandon.Potter@amd.comgetrusageFunc(SyscallDesc *desc, int callnum, Process *process, 80811907SBrandon.Potter@amd.com ExecContext *xc) 80911907SBrandon.Potter@amd.com{ 81011907SBrandon.Potter@amd.com int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN 81111907SBrandon.Potter@amd.com TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); 81211907SBrandon.Potter@amd.com 81311907SBrandon.Potter@amd.com if (who != OS::TGT_RUSAGE_SELF) { 81411907SBrandon.Potter@amd.com // don't really handle THREAD or CHILDREN, but just warn and 81513883Sdavid.hashe@amd.com // plow ahead 81613883Sdavid.hashe@amd.com warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", 81713883Sdavid.hashe@amd.com who); 81813883Sdavid.hashe@amd.com } 81913883Sdavid.hashe@amd.com 82011907SBrandon.Potter@amd.com getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); 82111907SBrandon.Potter@amd.com rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); 82211907SBrandon.Potter@amd.com rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); 82311907SBrandon.Potter@amd.com 82411907SBrandon.Potter@amd.com rup->ru_stime.tv_sec = 0; 82513883Sdavid.hashe@amd.com rup->ru_stime.tv_usec = 0; 82613883Sdavid.hashe@amd.com rup->ru_maxrss = 0; 82711907SBrandon.Potter@amd.com rup->ru_ixrss = 0; 8281706SN/A rup->ru_idrss = 0; 82911907SBrandon.Potter@amd.com rup->ru_isrss = 0; 83011907SBrandon.Potter@amd.com rup->ru_minflt = 0; 83111907SBrandon.Potter@amd.com rup->ru_majflt = 0; 83211907SBrandon.Potter@amd.com rup->ru_nswap = 0; 83311907SBrandon.Potter@amd.com rup->ru_inblock = 0; 83411907SBrandon.Potter@amd.com rup->ru_oublock = 0; 83513883Sdavid.hashe@amd.com rup->ru_msgsnd = 0; 83613883Sdavid.hashe@amd.com rup->ru_msgrcv = 0; 83711907SBrandon.Potter@amd.com rup->ru_nsignals = 0; 83811907SBrandon.Potter@amd.com rup->ru_nvcsw = 0; 83911907SBrandon.Potter@amd.com rup->ru_nivcsw = 0; 84011907SBrandon.Potter@amd.com 84113883Sdavid.hashe@amd.com rup.copyOut(xc->getMemPort()); 84213995Sbrandon.potter@amd.com 84310496Ssteve.reinhardt@amd.com return 0; 84411907SBrandon.Potter@amd.com} 84511907SBrandon.Potter@amd.com 84611907SBrandon.Potter@amd.com 84711907SBrandon.Potter@amd.com 84810496Ssteve.reinhardt@amd.com 84910496Ssteve.reinhardt@amd.com#endif // __SIM_SYSCALL_EMUL_HH__ 85011907SBrandon.Potter@amd.com