syscall_emul.hh revision 2665
16019Shines@cs.fsu.edu/* 211496Sandreas.sandberg@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 37093Sgblack@eecs.umich.edu * All rights reserved. 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67093Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77093Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97093Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117093Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127093Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137093Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 146019Shines@cs.fsu.edu * this software without specific prior written permission. 156019Shines@cs.fsu.edu * 166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019Shines@cs.fsu.edu * 286019Shines@cs.fsu.edu * Authors: Steve Reinhardt 296019Shines@cs.fsu.edu * Kevin Lim 306019Shines@cs.fsu.edu */ 316019Shines@cs.fsu.edu 326019Shines@cs.fsu.edu#ifndef __SIM_SYSCALL_EMUL_HH__ 336019Shines@cs.fsu.edu#define __SIM_SYSCALL_EMUL_HH__ 346019Shines@cs.fsu.edu 356019Shines@cs.fsu.edu#define BSD_HOST (defined(__APPLE__) || defined(__OpenBSD__) || \ 366019Shines@cs.fsu.edu defined(__FreeBSD__)) 376019Shines@cs.fsu.edu 386019Shines@cs.fsu.edu/// 396019Shines@cs.fsu.edu/// @file syscall_emul.hh 406019Shines@cs.fsu.edu/// 416735Sgblack@eecs.umich.edu/// This file defines objects used to emulate syscalls from the target 426735Sgblack@eecs.umich.edu/// application on the host machine. 4310037SARM gem5 Developers 4410037SARM gem5 Developers#include <errno.h> 456019Shines@cs.fsu.edu#include <string> 466019Shines@cs.fsu.edu#ifdef __CYGWIN32__ 476019Shines@cs.fsu.edu#include <sys/fcntl.h> // for O_BINARY 4811793Sbrandon.potter@amd.com#endif 4911793Sbrandon.potter@amd.com#include <sys/uio.h> 5010037SARM gem5 Developers 5110037SARM gem5 Developers#include "arch/isa_traits.hh" // for Addr 5210037SARM gem5 Developers#include "base/chunk_generator.hh" 538229Snate@binkert.org#include "base/intmath.hh" // for RoundUp 548229Snate@binkert.org#include "base/misc.hh" 556019Shines@cs.fsu.edu#include "base/trace.hh" 568232Snate@binkert.org#include "cpu/base.hh" 578782Sgblack@eecs.umich.edu#include "cpu/exec_context.hh" 586019Shines@cs.fsu.edu#include "mem/translating_port.hh" 596019Shines@cs.fsu.edu#include "mem/page_table.hh" 606019Shines@cs.fsu.edu#include "sim/process.hh" 616019Shines@cs.fsu.edu 6210037SARM gem5 Developers/// 6310037SARM gem5 Developers/// System call descriptor. 6410037SARM gem5 Developers/// 6510037SARM gem5 Developersclass SyscallDesc { 6610037SARM gem5 Developers 6710037SARM gem5 Developers public: 6810037SARM gem5 Developers 6910037SARM gem5 Developers /// Typedef for target syscall handler functions. 7010037SARM gem5 Developers typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, 7110037SARM gem5 Developers Process *, ExecContext *); 7210037SARM gem5 Developers 7310037SARM gem5 Developers const char *name; //!< Syscall name (e.g., "open"). 7410037SARM gem5 Developers FuncPtr funcPtr; //!< Pointer to emulation function. 7510037SARM gem5 Developers int flags; //!< Flags (see Flags enum). 7610037SARM gem5 Developers 7710037SARM gem5 Developers /// Flag values for controlling syscall behavior. 7810037SARM gem5 Developers enum Flags { 7910037SARM gem5 Developers /// Don't set return regs according to funcPtr return value. 8010037SARM gem5 Developers /// Used for syscalls with non-standard return conventions 8110037SARM gem5 Developers /// that explicitly set the ExecContext regs (e.g., 8210037SARM gem5 Developers /// sigreturn). 8310037SARM gem5 Developers SuppressReturnValue = 1 8410037SARM gem5 Developers }; 8510037SARM gem5 Developers 8610037SARM gem5 Developers /// Constructor. 8710037SARM gem5 Developers SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) 8810037SARM gem5 Developers : name(_name), funcPtr(_funcPtr), flags(_flags) 8910037SARM gem5 Developers { 9010037SARM gem5 Developers } 9110037SARM gem5 Developers 9210037SARM gem5 Developers /// Emulate the syscall. Public interface for calling through funcPtr. 9310037SARM gem5 Developers void doSyscall(int callnum, Process *proc, ExecContext *xc); 9410037SARM gem5 Developers}; 9510037SARM gem5 Developers 9610037SARM gem5 Developers 9710037SARM gem5 Developersclass BaseBufferArg { 9810037SARM gem5 Developers 9910037SARM gem5 Developers public: 10010037SARM gem5 Developers 10110037SARM gem5 Developers BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) 1026019Shines@cs.fsu.edu { 10310037SARM gem5 Developers bufPtr = new uint8_t[size]; 10410037SARM gem5 Developers // clear out buffer: in case we only partially populate this, 10510037SARM gem5 Developers // and then do a copyOut(), we want to make sure we don't 1066019Shines@cs.fsu.edu // introduce any random junk into the simulated address space 10710037SARM gem5 Developers memset(bufPtr, 0, size); 10810037SARM gem5 Developers } 10910037SARM gem5 Developers 11010037SARM gem5 Developers virtual ~BaseBufferArg() { delete [] bufPtr; } 11110037SARM gem5 Developers 11210037SARM gem5 Developers // 11310037SARM gem5 Developers // copy data into simulator space (read from target memory) 11410037SARM gem5 Developers // 11510037SARM gem5 Developers virtual bool copyIn(TranslatingPort *memport) 11610037SARM gem5 Developers { 11710037SARM gem5 Developers memport->readBlob(addr, bufPtr, size); 11810037SARM gem5 Developers return true; // no EFAULT detection for now 11910037SARM gem5 Developers } 12010037SARM gem5 Developers 12110037SARM gem5 Developers // 12210037SARM gem5 Developers // copy data out of simulator space (write to target memory) 12310037SARM gem5 Developers // 12410037SARM gem5 Developers virtual bool copyOut(TranslatingPort *memport) 12510037SARM gem5 Developers { 12610037SARM gem5 Developers memport->writeBlob(addr, bufPtr, size); 12710037SARM gem5 Developers return true; // no EFAULT detection for now 12810037SARM gem5 Developers } 12910037SARM gem5 Developers 13010037SARM gem5 Developers protected: 13110037SARM gem5 Developers Addr addr; 13210037SARM gem5 Developers int size; 13310037SARM gem5 Developers uint8_t *bufPtr; 13410037SARM gem5 Developers}; 13510037SARM gem5 Developers 13610037SARM gem5 Developers 13710037SARM gem5 Developersclass BufferArg : public BaseBufferArg 13810037SARM gem5 Developers{ 13910037SARM gem5 Developers public: 14010037SARM gem5 Developers BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 14110037SARM gem5 Developers void *bufferPtr() { return bufPtr; } 14210037SARM gem5 Developers}; 14310037SARM gem5 Developers 14410037SARM gem5 Developerstemplate <class T> 14510037SARM gem5 Developersclass TypedBufferArg : public BaseBufferArg 14610037SARM gem5 Developers{ 1476019Shines@cs.fsu.edu public: 14810037SARM gem5 Developers // user can optionally specify a specific number of bytes to 14910037SARM gem5 Developers // allocate to deal with those structs that have variable-size 15010037SARM gem5 Developers // arrays at the end 1516019Shines@cs.fsu.edu TypedBufferArg(Addr _addr, int _size = sizeof(T)) 15210037SARM gem5 Developers : BaseBufferArg(_addr, _size) 15310037SARM gem5 Developers { } 15410037SARM gem5 Developers 15510037SARM gem5 Developers // type case 15610037SARM gem5 Developers operator T*() { return (T *)bufPtr; } 15710037SARM gem5 Developers 15810037SARM gem5 Developers // dereference operators 15910037SARM gem5 Developers T &operator*() { return *((T *)bufPtr); } 16010037SARM gem5 Developers T* operator->() { return (T *)bufPtr; } 16110037SARM gem5 Developers T &operator[](int i) { return ((T *)bufPtr)[i]; } 16210037SARM gem5 Developers}; 16310037SARM gem5 Developers 16410037SARM gem5 Developers////////////////////////////////////////////////////////////////////// 16510037SARM gem5 Developers// 16610037SARM gem5 Developers// The following emulation functions are generic enough that they 16710037SARM gem5 Developers// don't need to be recompiled for different emulated OS's. They are 16810037SARM gem5 Developers// defined in sim/syscall_emul.cc. 16910037SARM gem5 Developers// 17010037SARM gem5 Developers////////////////////////////////////////////////////////////////////// 17110037SARM gem5 Developers 17210037SARM gem5 Developers 17310037SARM gem5 Developers/// Handler for unimplemented syscalls that we haven't thought about. 17410037SARM gem5 DevelopersSyscallReturn unimplementedFunc(SyscallDesc *desc, int num, 17510037SARM gem5 Developers Process *p, ExecContext *xc); 17610037SARM gem5 Developers 17710037SARM gem5 Developers/// Handler for unimplemented syscalls that we never intend to 17810037SARM gem5 Developers/// implement (signal handling, etc.) and should not affect the correct 17910037SARM gem5 Developers/// behavior of the program. Print a warning only if the appropriate 18010037SARM gem5 Developers/// trace flag is enabled. Return success to the target program. 18110037SARM gem5 DevelopersSyscallReturn ignoreFunc(SyscallDesc *desc, int num, 18210037SARM gem5 Developers Process *p, ExecContext *xc); 18310037SARM gem5 Developers 18410037SARM gem5 Developers/// Target exit() handler: terminate simulation. 18510037SARM gem5 DevelopersSyscallReturn exitFunc(SyscallDesc *desc, int num, 18610037SARM gem5 Developers Process *p, ExecContext *xc); 18710037SARM gem5 Developers 18810037SARM gem5 Developers/// Target getpagesize() handler. 18910037SARM gem5 DevelopersSyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, 19010037SARM gem5 Developers Process *p, ExecContext *xc); 19110037SARM gem5 Developers 19210037SARM gem5 Developers/// Target obreak() handler: set brk address. 1936019Shines@cs.fsu.eduSyscallReturn obreakFunc(SyscallDesc *desc, int num, 19410037SARM gem5 Developers Process *p, ExecContext *xc); 19510037SARM gem5 Developers 19610037SARM gem5 Developers/// Target close() handler. 1976019Shines@cs.fsu.eduSyscallReturn closeFunc(SyscallDesc *desc, int num, 19810037SARM gem5 Developers Process *p, ExecContext *xc); 19910037SARM gem5 Developers 20010037SARM gem5 Developers/// Target read() handler. 20110037SARM gem5 DevelopersSyscallReturn readFunc(SyscallDesc *desc, int num, 20210037SARM gem5 Developers Process *p, ExecContext *xc); 20310037SARM gem5 Developers 20410037SARM gem5 Developers/// Target write() handler. 20510037SARM gem5 DevelopersSyscallReturn writeFunc(SyscallDesc *desc, int num, 20610037SARM gem5 Developers Process *p, ExecContext *xc); 20710037SARM gem5 Developers 20810037SARM gem5 Developers/// Target lseek() handler. 20910037SARM gem5 DevelopersSyscallReturn lseekFunc(SyscallDesc *desc, int num, 21010037SARM gem5 Developers Process *p, ExecContext *xc); 21110037SARM gem5 Developers 21210037SARM gem5 Developers/// Target munmap() handler. 21310037SARM gem5 DevelopersSyscallReturn munmapFunc(SyscallDesc *desc, int num, 21410037SARM gem5 Developers Process *p, ExecContext *xc); 21510037SARM gem5 Developers 21610037SARM gem5 Developers/// Target gethostname() handler. 21710037SARM gem5 DevelopersSyscallReturn gethostnameFunc(SyscallDesc *desc, int num, 21810037SARM gem5 Developers Process *p, ExecContext *xc); 21910037SARM gem5 Developers 22010037SARM gem5 Developers/// Target unlink() handler. 22110037SARM gem5 DevelopersSyscallReturn unlinkFunc(SyscallDesc *desc, int num, 22210037SARM gem5 Developers Process *p, ExecContext *xc); 22310037SARM gem5 Developers 22410037SARM gem5 Developers/// Target rename() handler. 22510037SARM gem5 DevelopersSyscallReturn renameFunc(SyscallDesc *desc, int num, 22610037SARM gem5 Developers Process *p, ExecContext *xc); 22710037SARM gem5 Developers 22810037SARM gem5 Developers 22910037SARM gem5 Developers/// Target truncate() handler. 23010037SARM gem5 DevelopersSyscallReturn truncateFunc(SyscallDesc *desc, int num, 23110037SARM gem5 Developers Process *p, ExecContext *xc); 23210037SARM gem5 Developers 23310037SARM gem5 Developers 23410037SARM gem5 Developers/// Target ftruncate() handler. 23510037SARM gem5 DevelopersSyscallReturn ftruncateFunc(SyscallDesc *desc, int num, 23610037SARM gem5 Developers Process *p, ExecContext *xc); 23710037SARM gem5 Developers 23810037SARM gem5 Developers 23910037SARM gem5 Developers/// Target chown() handler. 24010037SARM gem5 DevelopersSyscallReturn chownFunc(SyscallDesc *desc, int num, 24110037SARM gem5 Developers Process *p, ExecContext *xc); 24210037SARM gem5 Developers 24310037SARM gem5 Developers 24410037SARM gem5 Developers/// Target fchown() handler. 24510037SARM gem5 DevelopersSyscallReturn fchownFunc(SyscallDesc *desc, int num, 24610037SARM gem5 Developers Process *p, ExecContext *xc); 24710037SARM gem5 Developers 24810037SARM gem5 Developers/// Target fnctl() handler. 24910037SARM gem5 DevelopersSyscallReturn fcntlFunc(SyscallDesc *desc, int num, 25010037SARM gem5 Developers Process *process, ExecContext *xc); 25110037SARM gem5 Developers 25210037SARM gem5 Developers/// Target setuid() handler. 25310037SARM gem5 DevelopersSyscallReturn setuidFunc(SyscallDesc *desc, int num, 25410037SARM gem5 Developers Process *p, ExecContext *xc); 25510037SARM gem5 Developers 25610037SARM gem5 Developers/// Target getpid() handler. 25710037SARM gem5 DevelopersSyscallReturn getpidFunc(SyscallDesc *desc, int num, 25810037SARM gem5 Developers Process *p, ExecContext *xc); 25910037SARM gem5 Developers 26010037SARM gem5 Developers/// Target getuid() handler. 26110037SARM gem5 DevelopersSyscallReturn getuidFunc(SyscallDesc *desc, int num, 26210037SARM gem5 Developers Process *p, ExecContext *xc); 26310037SARM gem5 Developers 26410037SARM gem5 Developers/// Target getgid() handler. 26510037SARM gem5 DevelopersSyscallReturn getgidFunc(SyscallDesc *desc, int num, 26610037SARM gem5 Developers Process *p, ExecContext *xc); 26710037SARM gem5 Developers 26810037SARM gem5 Developers/// Target getppid() handler. 26910037SARM gem5 DevelopersSyscallReturn getppidFunc(SyscallDesc *desc, int num, 27010037SARM gem5 Developers Process *p, ExecContext *xc); 27110037SARM gem5 Developers 27210037SARM gem5 Developers/// Target geteuid() handler. 27310037SARM gem5 DevelopersSyscallReturn geteuidFunc(SyscallDesc *desc, int num, 27410037SARM gem5 Developers Process *p, ExecContext *xc); 27510037SARM gem5 Developers 27610037SARM gem5 Developers/// Target getegid() handler. 27710037SARM gem5 DevelopersSyscallReturn getegidFunc(SyscallDesc *desc, int num, 27810037SARM gem5 Developers Process *p, ExecContext *xc); 27910037SARM gem5 Developers 28010037SARM gem5 Developers 28110037SARM gem5 Developers 28210037SARM gem5 Developers/// Pseudo Funcs - These functions use a different return convension, 28310037SARM gem5 Developers/// returning a second value in a register other than the normal return register 28410037SARM gem5 DevelopersSyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, 28510037SARM gem5 Developers Process *process, ExecContext *xc); 28610037SARM gem5 Developers 28710037SARM gem5 Developers/// Target getpidPseudo() handler. 28810037SARM gem5 DevelopersSyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, 28910037SARM gem5 Developers Process *p, ExecContext *xc); 29010037SARM gem5 Developers 29110037SARM gem5 Developers/// Target getuidPseudo() handler. 29210037SARM gem5 DevelopersSyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num, 29310037SARM gem5 Developers Process *p, ExecContext *xc); 29410037SARM gem5 Developers 29510037SARM gem5 Developers/// Target getgidPseudo() handler. 2966019Shines@cs.fsu.eduSyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, 29710037SARM gem5 Developers Process *p, ExecContext *xc); 2987362Sgblack@eecs.umich.edu 2996735Sgblack@eecs.umich.edu 30010037SARM gem5 Developers/// This struct is used to build an target-OS-dependent table that 3016019Shines@cs.fsu.edu/// maps the target's open() flags to the host open() flags. 30210037SARM gem5 Developersstruct OpenFlagTransTable { 30310037SARM gem5 Developers int tgtFlag; //!< Target system flag value. 3047400SAli.Saidi@ARM.com int hostFlag; //!< Corresponding host system flag value. 3056735Sgblack@eecs.umich.edu}; 3066735Sgblack@eecs.umich.edu 30710037SARM gem5 Developers 3086735Sgblack@eecs.umich.edu 30910037SARM gem5 Developers/// A readable name for 1,000,000, for converting microseconds to seconds. 31010037SARM gem5 Developersconst int one_million = 1000000; 31110037SARM gem5 Developers 31210037SARM gem5 Developers/// Approximate seconds since the epoch (1/1/1970). About a billion, 3137400SAli.Saidi@ARM.com/// by my reckoning. We want to keep this a constant (not use the 31410037SARM gem5 Developers/// real-world time) to keep simulations repeatable. 31510037SARM gem5 Developersconst unsigned seconds_since_epoch = 1000000000; 31610037SARM gem5 Developers 31710037SARM gem5 Developers/// Helper function to convert current elapsed time to seconds and 31810037SARM gem5 Developers/// microseconds. 31910037SARM gem5 Developerstemplate <class T1, class T2> 32010037SARM gem5 Developersvoid 32110037SARM gem5 DevelopersgetElapsedTime(T1 &sec, T2 &usec) 32210037SARM gem5 Developers{ 32310037SARM gem5 Developers int elapsed_usecs = curTick / Clock::Int::us; 32410037SARM gem5 Developers sec = elapsed_usecs / one_million; 32510037SARM gem5 Developers usec = elapsed_usecs % one_million; 32610037SARM gem5 Developers} 32710037SARM gem5 Developers 32810037SARM gem5 Developers////////////////////////////////////////////////////////////////////// 32910037SARM gem5 Developers// 33010037SARM gem5 Developers// The following emulation functions are generic, but need to be 3316019Shines@cs.fsu.edu// templated to account for differences in types, constants, etc. 3326019Shines@cs.fsu.edu// 33310037SARM gem5 Developers////////////////////////////////////////////////////////////////////// 33410037SARM gem5 Developers 33510037SARM gem5 Developers/// Target ioctl() handler. For the most part, programs call ioctl() 33610037SARM gem5 Developers/// only to find out if their stdout is a tty, to determine whether to 33710037SARM gem5 Developers/// do line or block buffering. 33810037SARM gem5 Developerstemplate <class OS> 33910037SARM gem5 DevelopersSyscallReturn 34010037SARM gem5 DevelopersioctlFunc(SyscallDesc *desc, int callnum, Process *process, 34110037SARM gem5 Developers ExecContext *xc) 34211574SCurtis.Dunham@arm.com{ 34311574SCurtis.Dunham@arm.com int fd = xc->getSyscallArg(0); 34411574SCurtis.Dunham@arm.com unsigned req = xc->getSyscallArg(1); 34511574SCurtis.Dunham@arm.com 34610037SARM gem5 Developers DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); 34710037SARM gem5 Developers 34810037SARM gem5 Developers if (fd < 0 || process->sim_fd(fd) < 0) { 34910037SARM gem5 Developers // doesn't map to any simulator fd: not a valid target fd 35010037SARM gem5 Developers return -EBADF; 35110037SARM gem5 Developers } 35210037SARM gem5 Developers 35310037SARM gem5 Developers switch (req) { 35410037SARM gem5 Developers case OS::TIOCISATTY: 35510037SARM gem5 Developers case OS::TIOCGETP: 35610037SARM gem5 Developers case OS::TIOCSETP: 35710037SARM gem5 Developers case OS::TIOCSETN: 35810037SARM gem5 Developers case OS::TIOCSETC: 35910037SARM gem5 Developers case OS::TIOCGETC: 36010037SARM gem5 Developers case OS::TIOCGETS: 36110037SARM gem5 Developers case OS::TIOCGETA: 36210037SARM gem5 Developers return -ENOTTY; 36310037SARM gem5 Developers 36410037SARM gem5 Developers default: 36510037SARM gem5 Developers fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", 36610037SARM gem5 Developers fd, req, xc->readPC()); 36710037SARM gem5 Developers } 36810037SARM gem5 Developers} 36910037SARM gem5 Developers 37010037SARM gem5 Developers/// Target open() handler. 37110037SARM gem5 Developerstemplate <class OS> 37210037SARM gem5 DevelopersSyscallReturn 37310037SARM gem5 DevelopersopenFunc(SyscallDesc *desc, int callnum, Process *process, 37410037SARM gem5 Developers ExecContext *xc) 37510037SARM gem5 Developers{ 37610037SARM gem5 Developers std::string path; 37710037SARM gem5 Developers 37810037SARM gem5 Developers if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 37910037SARM gem5 Developers return -EFAULT; 38010037SARM gem5 Developers 38110037SARM gem5 Developers if (path == "/dev/sysdev0") { 38210037SARM gem5 Developers // This is a memory-mapped high-resolution timer device on Alpha. 38310037SARM gem5 Developers // We don't support it, so just punt. 38410037SARM gem5 Developers warn("Ignoring open(%s, ...)\n", path); 38510037SARM gem5 Developers return -ENOENT; 38610037SARM gem5 Developers } 38710037SARM gem5 Developers 38810037SARM gem5 Developers int tgtFlags = xc->getSyscallArg(1); 38910037SARM gem5 Developers int mode = xc->getSyscallArg(2); 39010037SARM gem5 Developers int hostFlags = 0; 39110037SARM gem5 Developers 39210037SARM gem5 Developers // translate open flags 39310037SARM gem5 Developers for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { 39410037SARM gem5 Developers if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 39510037SARM gem5 Developers tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 39610037SARM gem5 Developers hostFlags |= OS::openFlagTable[i].hostFlag; 39710037SARM gem5 Developers } 39810037SARM gem5 Developers } 39910037SARM gem5 Developers 40010037SARM gem5 Developers // any target flags left? 40110037SARM gem5 Developers if (tgtFlags != 0) 40210037SARM gem5 Developers warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 40310037SARM gem5 Developers 40410037SARM gem5 Developers#ifdef __CYGWIN32__ 40510037SARM gem5 Developers hostFlags |= O_BINARY; 40610037SARM gem5 Developers#endif 40710037SARM gem5 Developers 40810037SARM gem5 Developers DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); 40910037SARM gem5 Developers 41010037SARM gem5 Developers // open the file 41110037SARM gem5 Developers int fd = open(path.c_str(), hostFlags, mode); 41210037SARM gem5 Developers 41310037SARM gem5 Developers return (fd == -1) ? -errno : process->alloc_fd(fd); 41410037SARM gem5 Developers} 41510037SARM gem5 Developers 41610037SARM gem5 Developers 41710037SARM gem5 Developers/// Target chmod() handler. 41810037SARM gem5 Developerstemplate <class OS> 41910037SARM gem5 DevelopersSyscallReturn 42010037SARM gem5 DeveloperschmodFunc(SyscallDesc *desc, int callnum, Process *process, 42110037SARM gem5 Developers ExecContext *xc) 42210037SARM gem5 Developers{ 42310037SARM gem5 Developers std::string path; 42410037SARM gem5 Developers 42510037SARM gem5 Developers if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 42610037SARM gem5 Developers return -EFAULT; 42710037SARM gem5 Developers 42810037SARM gem5 Developers uint32_t mode = xc->getSyscallArg(1); 42910417Sandreas.hansson@arm.com mode_t hostMode = 0; 4306019Shines@cs.fsu.edu 43110037SARM gem5 Developers // XXX translate mode flags via OS::something??? 43210037SARM gem5 Developers hostMode = mode; 43310037SARM gem5 Developers 43410037SARM gem5 Developers // do the chmod 43510037SARM gem5 Developers int result = chmod(path.c_str(), hostMode); 43610037SARM gem5 Developers if (result < 0) 43710037SARM gem5 Developers return -errno; 43810037SARM gem5 Developers 43910037SARM gem5 Developers return 0; 44010037SARM gem5 Developers} 44110037SARM gem5 Developers 44210037SARM gem5 Developers 44311578SDylan.Johnson@ARM.com/// Target fchmod() handler. 44411578SDylan.Johnson@ARM.comtemplate <class OS> 44510037SARM gem5 DevelopersSyscallReturn 44610037SARM gem5 DevelopersfchmodFunc(SyscallDesc *desc, int callnum, Process *process, 44710037SARM gem5 Developers ExecContext *xc) 44810037SARM gem5 Developers{ 44910037SARM gem5 Developers int fd = xc->getSyscallArg(0); 45010037SARM gem5 Developers if (fd < 0 || process->sim_fd(fd) < 0) { 45110037SARM gem5 Developers // doesn't map to any simulator fd: not a valid target fd 45210037SARM gem5 Developers return -EBADF; 45310037SARM gem5 Developers } 45410037SARM gem5 Developers 45510037SARM gem5 Developers uint32_t mode = xc->getSyscallArg(1); 45610037SARM gem5 Developers mode_t hostMode = 0; 45710037SARM gem5 Developers 45810037SARM gem5 Developers // XXX translate mode flags via OS::someting??? 45910037SARM gem5 Developers hostMode = mode; 46010037SARM gem5 Developers 46110037SARM gem5 Developers // do the fchmod 46210037SARM gem5 Developers int result = fchmod(process->sim_fd(fd), hostMode); 4636735Sgblack@eecs.umich.edu if (result < 0) 4648782Sgblack@eecs.umich.edu return -errno; 4658782Sgblack@eecs.umich.edu 4666735Sgblack@eecs.umich.edu return 0; 4676019Shines@cs.fsu.edu} 4686735Sgblack@eecs.umich.edu 46910037SARM gem5 Developers 4708303SAli.Saidi@ARM.com/// Target stat() handler. 47110338SCurtis.Dunham@arm.comtemplate <class OS> 47210338SCurtis.Dunham@arm.comSyscallReturn 47310338SCurtis.Dunham@arm.comstatFunc(SyscallDesc *desc, int callnum, Process *process, 47410338SCurtis.Dunham@arm.com ExecContext *xc) 4758303SAli.Saidi@ARM.com{ 4767720Sgblack@eecs.umich.edu std::string path; 4778205SAli.Saidi@ARM.com 4788205SAli.Saidi@ARM.com if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 4798205SAli.Saidi@ARM.com return -EFAULT; 4806735Sgblack@eecs.umich.edu 48110037SARM gem5 Developers struct stat hostBuf; 48210037SARM gem5 Developers int result = stat(path.c_str(), &hostBuf); 48310037SARM gem5 Developers 48410037SARM gem5 Developers if (result < 0) 48510037SARM gem5 Developers return -errno; 48610037SARM gem5 Developers 48710037SARM gem5 Developers OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 48810037SARM gem5 Developers 48910037SARM gem5 Developers return 0; 49010037SARM gem5 Developers} 49110037SARM gem5 Developers 49210037SARM gem5 Developers 49310037SARM gem5 Developers/// Target fstat64() handler. 49410037SARM gem5 Developerstemplate <class OS> 49510037SARM gem5 DevelopersSyscallReturn 49610037SARM gem5 Developersfstat64Func(SyscallDesc *desc, int callnum, Process *process, 49710037SARM gem5 Developers ExecContext *xc) 49810037SARM gem5 Developers{ 49910037SARM gem5 Developers int fd = xc->getSyscallArg(0); 50010037SARM gem5 Developers if (fd < 0 || process->sim_fd(fd) < 0) { 50110037SARM gem5 Developers // doesn't map to any simulator fd: not a valid target fd 50210037SARM gem5 Developers return -EBADF; 50310037SARM gem5 Developers } 50410037SARM gem5 Developers 50510037SARM gem5 Developers#if BSD_HOST 50610037SARM gem5 Developers struct stat hostBuf; 50710037SARM gem5 Developers int result = fstat(process->sim_fd(fd), &hostBuf); 50810037SARM gem5 Developers#else 50910037SARM gem5 Developers struct stat64 hostBuf; 51010037SARM gem5 Developers int result = fstat64(process->sim_fd(fd), &hostBuf); 51110037SARM gem5 Developers#endif 51210037SARM gem5 Developers 51310037SARM gem5 Developers if (result < 0) 51410037SARM gem5 Developers return -errno; 51510037SARM gem5 Developers 51610037SARM gem5 Developers OS::copyOutStat64Buf(xc->getMemPort(), fd, xc->getSyscallArg(1), &hostBuf); 51710037SARM gem5 Developers 51810037SARM gem5 Developers return 0; 51910037SARM gem5 Developers} 52010037SARM gem5 Developers 52110037SARM gem5 Developers 52210037SARM gem5 Developers/// Target lstat() handler. 52310037SARM gem5 Developerstemplate <class OS> 52410037SARM gem5 DevelopersSyscallReturn 52510037SARM gem5 DeveloperslstatFunc(SyscallDesc *desc, int callnum, Process *process, 52610037SARM gem5 Developers ExecContext *xc) 52710037SARM gem5 Developers{ 52810037SARM gem5 Developers std::string path; 5296735Sgblack@eecs.umich.edu 5306735Sgblack@eecs.umich.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 5316735Sgblack@eecs.umich.edu return -EFAULT; 53210037SARM gem5 Developers 5338518Sgeoffrey.blake@arm.com struct stat hostBuf; 5348518Sgeoffrey.blake@arm.com int result = lstat(path.c_str(), &hostBuf); 5356735Sgblack@eecs.umich.edu 53610037SARM gem5 Developers if (result < 0) 53710037SARM gem5 Developers return -errno; 53810037SARM gem5 Developers 53910037SARM gem5 Developers OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 54010037SARM gem5 Developers 54110037SARM gem5 Developers return 0; 54210037SARM gem5 Developers} 54310037SARM gem5 Developers 54410037SARM gem5 Developers/// Target lstat64() handler. 54510037SARM gem5 Developerstemplate <class OS> 54610037SARM gem5 DevelopersSyscallReturn 54710037SARM gem5 Developerslstat64Func(SyscallDesc *desc, int callnum, Process *process, 5486735Sgblack@eecs.umich.edu ExecContext *xc) 5496735Sgblack@eecs.umich.edu{ 5506735Sgblack@eecs.umich.edu std::string path; 5516735Sgblack@eecs.umich.edu 5526735Sgblack@eecs.umich.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 5536735Sgblack@eecs.umich.edu return -EFAULT; 5546735Sgblack@eecs.umich.edu 5556735Sgblack@eecs.umich.edu#if BSD_HOST 5566735Sgblack@eecs.umich.edu struct stat hostBuf; 55710037SARM gem5 Developers int result = lstat(path.c_str(), &hostBuf); 55810037SARM gem5 Developers#else 55910037SARM gem5 Developers struct stat64 hostBuf; 5606735Sgblack@eecs.umich.edu int result = lstat64(path.c_str(), &hostBuf); 5616735Sgblack@eecs.umich.edu#endif 5626735Sgblack@eecs.umich.edu 5636735Sgblack@eecs.umich.edu if (result < 0) 56410037SARM gem5 Developers return -errno; 56510037SARM gem5 Developers 56610037SARM gem5 Developers OS::copyOutStat64Buf(xc->getMemPort(), -1, xc->getSyscallArg(1), &hostBuf); 56710037SARM gem5 Developers 56810037SARM gem5 Developers return 0; 56910037SARM gem5 Developers} 57010037SARM gem5 Developers 57110037SARM gem5 Developers/// Target fstat() handler. 57210037SARM gem5 Developerstemplate <class OS> 57310037SARM gem5 DevelopersSyscallReturn 5746735Sgblack@eecs.umich.edufstatFunc(SyscallDesc *desc, int callnum, Process *process, 5756735Sgblack@eecs.umich.edu ExecContext *xc) 5767093Sgblack@eecs.umich.edu{ 5777093Sgblack@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 5787720Sgblack@eecs.umich.edu 5797585SAli.Saidi@arm.com DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); 5807720Sgblack@eecs.umich.edu 5817720Sgblack@eecs.umich.edu if (fd < 0) 5827720Sgblack@eecs.umich.edu return -EBADF; 5837720Sgblack@eecs.umich.edu 5847720Sgblack@eecs.umich.edu struct stat hostBuf; 5857720Sgblack@eecs.umich.edu int result = fstat(fd, &hostBuf); 58610037SARM gem5 Developers 58710037SARM gem5 Developers if (result < 0) 5887720Sgblack@eecs.umich.edu return -errno; 5896019Shines@cs.fsu.edu 5907189Sgblack@eecs.umich.edu OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 5917400SAli.Saidi@ARM.com 59210417Sandreas.hansson@arm.com return 0; 59310037SARM gem5 Developers} 59410037SARM gem5 Developers 59510037SARM gem5 Developers 59610037SARM gem5 Developers/// Target statfs() handler. 59710037SARM gem5 Developerstemplate <class OS> 59810037SARM gem5 DevelopersSyscallReturn 59910037SARM gem5 DevelopersstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 60010037SARM gem5 Developers ExecContext *xc) 60111574SCurtis.Dunham@arm.com{ 60211574SCurtis.Dunham@arm.com std::string path; 60311574SCurtis.Dunham@arm.com 60411574SCurtis.Dunham@arm.com if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 60511574SCurtis.Dunham@arm.com return -EFAULT; 60610037SARM gem5 Developers 60710037SARM gem5 Developers struct statfs hostBuf; 60810037SARM gem5 Developers int result = statfs(path.c_str(), &hostBuf); 60910037SARM gem5 Developers 61010037SARM gem5 Developers if (result < 0) 61110037SARM gem5 Developers return -errno; 61210037SARM gem5 Developers 61310037SARM gem5 Developers OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 61410037SARM gem5 Developers 61510037SARM gem5 Developers return 0; 61610037SARM gem5 Developers} 61710037SARM gem5 Developers 61810037SARM gem5 Developers 61910338SCurtis.Dunham@arm.com/// Target fstatfs() handler. 62010338SCurtis.Dunham@arm.comtemplate <class OS> 62110338SCurtis.Dunham@arm.comSyscallReturn 62210037SARM gem5 DevelopersfstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 62310037SARM gem5 Developers ExecContext *xc) 62410037SARM gem5 Developers{ 62510037SARM gem5 Developers int fd = process->sim_fd(xc->getSyscallArg(0)); 62610037SARM gem5 Developers 62710037SARM gem5 Developers if (fd < 0) 62810037SARM gem5 Developers return -EBADF; 62910037SARM gem5 Developers 63010037SARM gem5 Developers struct statfs hostBuf; 63110037SARM gem5 Developers int result = fstatfs(fd, &hostBuf); 63210338SCurtis.Dunham@arm.com 63310037SARM gem5 Developers if (result < 0) 63410037SARM gem5 Developers return -errno; 63510037SARM gem5 Developers 63610037SARM gem5 Developers OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); 63710037SARM gem5 Developers 63810037SARM gem5 Developers return 0; 63910037SARM gem5 Developers} 64010037SARM gem5 Developers 64110037SARM gem5 Developers 64210037SARM gem5 Developers/// Target writev() handler. 64310037SARM gem5 Developerstemplate <class OS> 64410037SARM gem5 DevelopersSyscallReturn 64510037SARM gem5 DeveloperswritevFunc(SyscallDesc *desc, int callnum, Process *process, 64610037SARM gem5 Developers ExecContext *xc) 64710037SARM gem5 Developers{ 64810037SARM gem5 Developers int fd = xc->getSyscallArg(0); 64910037SARM gem5 Developers if (fd < 0 || process->sim_fd(fd) < 0) { 65010037SARM gem5 Developers // doesn't map to any simulator fd: not a valid target fd 65110037SARM gem5 Developers return -EBADF; 65210037SARM gem5 Developers } 65310037SARM gem5 Developers 65410037SARM gem5 Developers TranslatingPort *p = xc->getMemPort(); 65510037SARM gem5 Developers uint64_t tiov_base = xc->getSyscallArg(1); 65610037SARM gem5 Developers size_t count = xc->getSyscallArg(2); 65710037SARM gem5 Developers struct iovec hiov[count]; 65810037SARM gem5 Developers for (int i = 0; i < count; ++i) 65910037SARM gem5 Developers { 66010037SARM gem5 Developers typename OS::tgt_iovec tiov; 66110037SARM gem5 Developers 66210037SARM gem5 Developers p->readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec), 66310037SARM gem5 Developers (uint8_t*)&tiov, sizeof(typename OS::tgt_iovec)); 66410037SARM gem5 Developers hiov[i].iov_len = gtoh(tiov.iov_len); 66510037SARM gem5 Developers hiov[i].iov_base = new char [hiov[i].iov_len]; 66610037SARM gem5 Developers p->readBlob(gtoh(tiov.iov_base), (uint8_t *)hiov[i].iov_base, 66710037SARM gem5 Developers hiov[i].iov_len); 66810037SARM gem5 Developers } 66910037SARM gem5 Developers 67010037SARM gem5 Developers int result = writev(process->sim_fd(fd), hiov, count); 67110037SARM gem5 Developers 67210037SARM gem5 Developers for (int i = 0; i < count; ++i) 67310037SARM gem5 Developers { 67410037SARM gem5 Developers delete [] (char *)hiov[i].iov_base; 67510037SARM gem5 Developers } 67610037SARM gem5 Developers 67710037SARM gem5 Developers if (result < 0) 67810037SARM gem5 Developers return -errno; 67910037SARM gem5 Developers 68010037SARM gem5 Developers return 0; 68110037SARM gem5 Developers} 68210417Sandreas.hansson@arm.com 6837400SAli.Saidi@ARM.com 6848782Sgblack@eecs.umich.edu/// Target mmap() handler. 68511150Smitch.hayenga@arm.com/// 6868782Sgblack@eecs.umich.edu/// We don't really handle mmap(). If the target is mmaping an 6878782Sgblack@eecs.umich.edu/// anonymous region or /dev/zero, we can get away with doing basically 68810037SARM gem5 Developers/// nothing (since memory is initialized to zero and the simulator 68910037SARM gem5 Developers/// doesn't really check addresses anyway). Always print a warning, 69010037SARM gem5 Developers/// since this could be seriously broken if we're not mapping 69110037SARM gem5 Developers/// /dev/zero. 69210037SARM gem5 Developers// 69310037SARM gem5 Developers/// Someday we should explicitly check for /dev/zero in open, flag the 69410037SARM gem5 Developers/// file descriptor, and fail (or implement!) a non-anonymous mmap to 69510037SARM gem5 Developers/// anything else. 69610037SARM gem5 Developerstemplate <class OS> 69710037SARM gem5 DevelopersSyscallReturn 69810037SARM gem5 DevelopersmmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 69910037SARM gem5 Developers{ 70010037SARM gem5 Developers Addr start = xc->getSyscallArg(0); 70110037SARM gem5 Developers uint64_t length = xc->getSyscallArg(1); 70210037SARM gem5 Developers // int prot = xc->getSyscallArg(2); 70310037SARM gem5 Developers int flags = xc->getSyscallArg(3); 70410037SARM gem5 Developers // int fd = p->sim_fd(xc->getSyscallArg(4)); 70510037SARM gem5 Developers // int offset = xc->getSyscallArg(5); 70610037SARM gem5 Developers 7077400SAli.Saidi@ARM.com if ((start % TheISA::VMPageSize) != 0 || 7087400SAli.Saidi@ARM.com (length % TheISA::VMPageSize) != 0) { 7097189Sgblack@eecs.umich.edu warn("mmap failing: arguments not page-aligned: " 71010417Sandreas.hansson@arm.com "start 0x%x length 0x%x", 7117189Sgblack@eecs.umich.edu start, length); 7128782Sgblack@eecs.umich.edu return -EINVAL; 7138782Sgblack@eecs.umich.edu } 7148806Sgblack@eecs.umich.edu 7158806Sgblack@eecs.umich.edu if (start != 0) { 7168806Sgblack@eecs.umich.edu warn("mmap: ignoring suggested map address 0x%x, using 0x%x", 7178806Sgblack@eecs.umich.edu start, p->mmap_end); 7188806Sgblack@eecs.umich.edu } 7198806Sgblack@eecs.umich.edu 7208806Sgblack@eecs.umich.edu // pick next address from our "mmap region" 7218806Sgblack@eecs.umich.edu start = p->mmap_end; 7228806Sgblack@eecs.umich.edu p->pTable->allocate(start, length); 7238806Sgblack@eecs.umich.edu p->mmap_end += length; 7248806Sgblack@eecs.umich.edu 7257189Sgblack@eecs.umich.edu if (!(flags & OS::TGT_MAP_ANONYMOUS)) { 7268806Sgblack@eecs.umich.edu warn("allowing mmap of file @ fd %d. " 7278806Sgblack@eecs.umich.edu "This will break if not /dev/zero.", xc->getSyscallArg(4)); 7287189Sgblack@eecs.umich.edu } 7297189Sgblack@eecs.umich.edu 7307189Sgblack@eecs.umich.edu return start; 73110037SARM gem5 Developers} 73210037SARM gem5 Developers 73310037SARM gem5 Developers/// Target getrlimit() handler. 73410037SARM gem5 Developerstemplate <class OS> 73510037SARM gem5 DevelopersSyscallReturn 73610037SARM gem5 DevelopersgetrlimitFunc(SyscallDesc *desc, int callnum, Process *process, 73710037SARM gem5 Developers ExecContext *xc) 73810037SARM gem5 Developers{ 73910037SARM gem5 Developers unsigned resource = xc->getSyscallArg(0); 74010037SARM gem5 Developers TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); 74110037SARM gem5 Developers 74210037SARM gem5 Developers switch (resource) { 74310037SARM gem5 Developers case OS::TGT_RLIMIT_STACK: 74410037SARM gem5 Developers // max stack size in bytes: make up a number (2MB for now) 74510037SARM gem5 Developers rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; 74610037SARM gem5 Developers rlp->rlim_cur = htog(rlp->rlim_cur); 74710037SARM gem5 Developers rlp->rlim_max = htog(rlp->rlim_max); 74810037SARM gem5 Developers break; 74910037SARM gem5 Developers 75010037SARM gem5 Developers default: 75110037SARM gem5 Developers std::cerr << "getrlimitFunc: unimplemented resource " << resource 75210037SARM gem5 Developers << std::endl; 75310037SARM gem5 Developers abort(); 75410037SARM gem5 Developers break; 75510037SARM gem5 Developers } 75610037SARM gem5 Developers 75710037SARM gem5 Developers rlp.copyOut(xc->getMemPort()); 75810037SARM gem5 Developers return 0; 75910037SARM gem5 Developers} 76010037SARM gem5 Developers 76110037SARM gem5 Developers/// Target gettimeofday() handler. 76210037SARM gem5 Developerstemplate <class OS> 76310037SARM gem5 DevelopersSyscallReturn 76410037SARM gem5 DevelopersgettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, 76510037SARM gem5 Developers ExecContext *xc) 76610037SARM gem5 Developers{ 76710037SARM gem5 Developers TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); 76810037SARM gem5 Developers 76910037SARM gem5 Developers getElapsedTime(tp->tv_sec, tp->tv_usec); 7707197Sgblack@eecs.umich.edu tp->tv_sec += seconds_since_epoch; 77110417Sandreas.hansson@arm.com tp->tv_sec = htog(tp->tv_sec); 7727197Sgblack@eecs.umich.edu tp->tv_usec = htog(tp->tv_usec); 7738782Sgblack@eecs.umich.edu 7748782Sgblack@eecs.umich.edu tp.copyOut(xc->getMemPort()); 7758806Sgblack@eecs.umich.edu 7768806Sgblack@eecs.umich.edu return 0; 7777197Sgblack@eecs.umich.edu} 7788806Sgblack@eecs.umich.edu 7798806Sgblack@eecs.umich.edu 7808806Sgblack@eecs.umich.edu/// Target utimes() handler. 78110037SARM gem5 Developerstemplate <class OS> 78210037SARM gem5 DevelopersSyscallReturn 78310037SARM gem5 DevelopersutimesFunc(SyscallDesc *desc, int callnum, Process *process, 78410037SARM gem5 Developers ExecContext *xc) 78510037SARM gem5 Developers{ 78610037SARM gem5 Developers std::string path; 7878806Sgblack@eecs.umich.edu 7888806Sgblack@eecs.umich.edu if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) 7898806Sgblack@eecs.umich.edu return -EFAULT; 7908806Sgblack@eecs.umich.edu 7918806Sgblack@eecs.umich.edu TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); 7928806Sgblack@eecs.umich.edu tp.copyIn(xc->getMemPort()); 7938806Sgblack@eecs.umich.edu 7947197Sgblack@eecs.umich.edu struct timeval hostTimeval[2]; 7957197Sgblack@eecs.umich.edu for (int i = 0; i < 2; ++i) 79610037SARM gem5 Developers { 79710037SARM gem5 Developers hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); 79810037SARM gem5 Developers hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); 79910037SARM gem5 Developers } 80010037SARM gem5 Developers int result = utimes(path.c_str(), hostTimeval); 80110037SARM gem5 Developers 80210037SARM gem5 Developers if (result < 0) 80310037SARM gem5 Developers return -errno; 80410037SARM gem5 Developers 80510037SARM gem5 Developers return 0; 80610037SARM gem5 Developers} 80710037SARM gem5 Developers/// Target getrusage() function. 80810037SARM gem5 Developerstemplate <class OS> 80910037SARM gem5 DevelopersSyscallReturn 81010037SARM gem5 DevelopersgetrusageFunc(SyscallDesc *desc, int callnum, Process *process, 81110037SARM gem5 Developers ExecContext *xc) 81210037SARM gem5 Developers{ 81310037SARM gem5 Developers int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN 81410037SARM gem5 Developers TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); 81510037SARM gem5 Developers 81610037SARM gem5 Developers if (who != OS::TGT_RUSAGE_SELF) { 81710037SARM gem5 Developers // don't really handle THREAD or CHILDREN, but just warn and 81810037SARM gem5 Developers // plow ahead 81910037SARM gem5 Developers warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", 82010037SARM gem5 Developers who); 82110037SARM gem5 Developers } 82210037SARM gem5 Developers 82310037SARM gem5 Developers getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); 82410037SARM gem5 Developers rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); 82510037SARM gem5 Developers rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); 82610037SARM gem5 Developers 82710037SARM gem5 Developers rup->ru_stime.tv_sec = 0; 82810037SARM gem5 Developers rup->ru_stime.tv_usec = 0; 82910037SARM gem5 Developers rup->ru_maxrss = 0; 83010037SARM gem5 Developers rup->ru_ixrss = 0; 83110037SARM gem5 Developers rup->ru_idrss = 0; 83210037SARM gem5 Developers rup->ru_isrss = 0; 83310037SARM gem5 Developers rup->ru_minflt = 0; 83410037SARM gem5 Developers rup->ru_majflt = 0; 83510037SARM gem5 Developers rup->ru_nswap = 0; 83610037SARM gem5 Developers rup->ru_inblock = 0; 83710037SARM gem5 Developers rup->ru_oublock = 0; 83810037SARM gem5 Developers rup->ru_msgsnd = 0; 83910037SARM gem5 Developers rup->ru_msgrcv = 0; 84010037SARM gem5 Developers rup->ru_nsignals = 0; 84110037SARM gem5 Developers rup->ru_nvcsw = 0; 84210037SARM gem5 Developers rup->ru_nivcsw = 0; 84310037SARM gem5 Developers 84410037SARM gem5 Developers rup.copyOut(xc->getMemPort()); 84510037SARM gem5 Developers 84610037SARM gem5 Developers return 0; 84711576SDylan.Johnson@ARM.com} 84811576SDylan.Johnson@ARM.com 84911576SDylan.Johnson@ARM.com 85011576SDylan.Johnson@ARM.com 85111576SDylan.Johnson@ARM.com 85211576SDylan.Johnson@ARM.com#endif // __SIM_SYSCALL_EMUL_HH__ 85310037SARM gem5 Developers