syscall_emul.hh revision 2238
1955SN/A/* 2955SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 312230Sgiacomo.travaglini@arm.com * All rights reserved. 49812Sandreas.hansson@arm.com * 59812Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69812Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79812Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99812Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119812Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129812Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139812Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 149812Sandreas.hansson@arm.com * this software without specific prior written permission. 157816Ssteve.reinhardt@amd.com * 165871Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171762SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A */ 28955SN/A 29955SN/A#ifndef __SIM_SYSCALL_EMUL_HH__ 30955SN/A#define __SIM_SYSCALL_EMUL_HH__ 31955SN/A 32955SN/A#define BSD_HOST (defined(__APPLE__) || defined(__OpenBSD__) || \ 33955SN/A defined(__FreeBSD__)) 34955SN/A 35955SN/A/// 36955SN/A/// @file syscall_emul.hh 37955SN/A/// 38955SN/A/// This file defines objects used to emulate syscalls from the target 39955SN/A/// application on the host machine. 40955SN/A 41955SN/A#include <errno.h> 422665Ssaidi@eecs.umich.edu#include <string> 432665Ssaidi@eecs.umich.edu#ifdef __CYGWIN32__ 445863Snate@binkert.org#include <sys/fcntl.h> // for O_BINARY 45955SN/A#endif 46955SN/A#include <sys/uio.h> 47955SN/A 48955SN/A#include "base/intmath.hh" // for RoundUp 49955SN/A#include "mem/functional/functional.hh" 508878Ssteve.reinhardt@amd.com#include "arch/isa_traits.hh" // for Addr 512632Sstever@eecs.umich.edu 528878Ssteve.reinhardt@amd.com#include "base/trace.hh" 532632Sstever@eecs.umich.edu#include "cpu/exec_context.hh" 54955SN/A#include "sim/process.hh" 558878Ssteve.reinhardt@amd.com 562632Sstever@eecs.umich.edu/// 572761Sstever@eecs.umich.edu/// System call descriptor. 582632Sstever@eecs.umich.edu/// 592632Sstever@eecs.umich.educlass SyscallDesc { 602632Sstever@eecs.umich.edu 612761Sstever@eecs.umich.edu public: 622761Sstever@eecs.umich.edu 632761Sstever@eecs.umich.edu /// Typedef for target syscall handler functions. 648878Ssteve.reinhardt@amd.com typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, 658878Ssteve.reinhardt@amd.com Process *, ExecContext *); 662761Sstever@eecs.umich.edu 672761Sstever@eecs.umich.edu const char *name; //!< Syscall name (e.g., "open"). 682761Sstever@eecs.umich.edu FuncPtr funcPtr; //!< Pointer to emulation function. 692761Sstever@eecs.umich.edu int flags; //!< Flags (see Flags enum). 702761Sstever@eecs.umich.edu 718878Ssteve.reinhardt@amd.com /// Flag values for controlling syscall behavior. 728878Ssteve.reinhardt@amd.com enum Flags { 732632Sstever@eecs.umich.edu /// Don't set return regs according to funcPtr return value. 742632Sstever@eecs.umich.edu /// Used for syscalls with non-standard return conventions 758878Ssteve.reinhardt@amd.com /// that explicitly set the ExecContext regs (e.g., 768878Ssteve.reinhardt@amd.com /// sigreturn). 772632Sstever@eecs.umich.edu SuppressReturnValue = 1 78955SN/A }; 79955SN/A 80955SN/A /// Constructor. 8112563Sgabeblack@google.com SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) 8212563Sgabeblack@google.com : name(_name), funcPtr(_funcPtr), flags(_flags) 836654Snate@binkert.org { 8410196SCurtis.Dunham@arm.com } 85955SN/A 865396Ssaidi@eecs.umich.edu /// Emulate the syscall. Public interface for calling through funcPtr. 8711401Sandreas.sandberg@arm.com void doSyscall(int callnum, Process *proc, ExecContext *xc); 885863Snate@binkert.org}; 895863Snate@binkert.org 904202Sbinkertn@umich.edu 915863Snate@binkert.orgclass BaseBufferArg { 925863Snate@binkert.org 935863Snate@binkert.org public: 945863Snate@binkert.org 9513541Sandrea.mondelli@ucf.edu BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) 96955SN/A { 976654Snate@binkert.org bufPtr = new uint8_t[size]; 985273Sstever@gmail.com // clear out buffer: in case we only partially populate this, 995871Snate@binkert.org // and then do a copyOut(), we want to make sure we don't 1005273Sstever@gmail.com // introduce any random junk into the simulated address space 1016654Snate@binkert.org memset(bufPtr, 0, size); 1025396Ssaidi@eecs.umich.edu } 1038120Sgblack@eecs.umich.edu 1048120Sgblack@eecs.umich.edu virtual ~BaseBufferArg() { delete [] bufPtr; } 1058120Sgblack@eecs.umich.edu 1068120Sgblack@eecs.umich.edu // 1078120Sgblack@eecs.umich.edu // copy data into simulator space (read from target memory) 1088120Sgblack@eecs.umich.edu // 1098120Sgblack@eecs.umich.edu virtual bool copyIn(FunctionalMemory *mem) 1108120Sgblack@eecs.umich.edu { 1118879Ssteve.reinhardt@amd.com mem->access(Read, addr, bufPtr, size); 1128879Ssteve.reinhardt@amd.com return true; // no EFAULT detection for now 1138879Ssteve.reinhardt@amd.com } 1148879Ssteve.reinhardt@amd.com 1158879Ssteve.reinhardt@amd.com // 1168879Ssteve.reinhardt@amd.com // copy data out of simulator space (write to target memory) 1178879Ssteve.reinhardt@amd.com // 1188879Ssteve.reinhardt@amd.com virtual bool copyOut(FunctionalMemory *mem) 1198879Ssteve.reinhardt@amd.com { 1208879Ssteve.reinhardt@amd.com mem->access(Write, addr, bufPtr, size); 1218879Ssteve.reinhardt@amd.com return true; // no EFAULT detection for now 1228879Ssteve.reinhardt@amd.com } 1238879Ssteve.reinhardt@amd.com 1248120Sgblack@eecs.umich.edu protected: 1258120Sgblack@eecs.umich.edu Addr addr; 1268120Sgblack@eecs.umich.edu int size; 1278120Sgblack@eecs.umich.edu uint8_t *bufPtr; 1288120Sgblack@eecs.umich.edu}; 1298120Sgblack@eecs.umich.edu 1308120Sgblack@eecs.umich.edu 1318120Sgblack@eecs.umich.educlass BufferArg : public BaseBufferArg 1328120Sgblack@eecs.umich.edu{ 1338120Sgblack@eecs.umich.edu public: 1348120Sgblack@eecs.umich.edu BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 1358120Sgblack@eecs.umich.edu void *bufferPtr() { return bufPtr; } 1368120Sgblack@eecs.umich.edu}; 1378120Sgblack@eecs.umich.edu 1388879Ssteve.reinhardt@amd.comtemplate <class T> 1398879Ssteve.reinhardt@amd.comclass TypedBufferArg : public BaseBufferArg 1408879Ssteve.reinhardt@amd.com{ 1418879Ssteve.reinhardt@amd.com public: 14210458Sandreas.hansson@arm.com // user can optionally specify a specific number of bytes to 14310458Sandreas.hansson@arm.com // allocate to deal with those structs that have variable-size 14410458Sandreas.hansson@arm.com // arrays at the end 1458879Ssteve.reinhardt@amd.com TypedBufferArg(Addr _addr, int _size = sizeof(T)) 1468879Ssteve.reinhardt@amd.com : BaseBufferArg(_addr, _size) 1478879Ssteve.reinhardt@amd.com { } 1488879Ssteve.reinhardt@amd.com 14913421Sciro.santilli@arm.com // type case 15013421Sciro.santilli@arm.com operator T*() { return (T *)bufPtr; } 1519227Sandreas.hansson@arm.com 1529227Sandreas.hansson@arm.com // dereference operators 15312063Sgabeblack@google.com T &operator*() { return *((T *)bufPtr); } 15412063Sgabeblack@google.com T* operator->() { return (T *)bufPtr; } 15512063Sgabeblack@google.com T &operator[](int i) { return ((T *)bufPtr)[i]; } 1568879Ssteve.reinhardt@amd.com}; 1578879Ssteve.reinhardt@amd.com 1588879Ssteve.reinhardt@amd.com////////////////////////////////////////////////////////////////////// 1598879Ssteve.reinhardt@amd.com// 16010453SAndrew.Bardsley@arm.com// The following emulation functions are generic enough that they 16110453SAndrew.Bardsley@arm.com// don't need to be recompiled for different emulated OS's. They are 16210453SAndrew.Bardsley@arm.com// defined in sim/syscall_emul.cc. 16310456SCurtis.Dunham@arm.com// 16410456SCurtis.Dunham@arm.com////////////////////////////////////////////////////////////////////// 16510456SCurtis.Dunham@arm.com 16610457Sandreas.hansson@arm.com 16710457Sandreas.hansson@arm.com/// Handler for unimplemented syscalls that we haven't thought about. 16811342Sandreas.hansson@arm.comSyscallReturn unimplementedFunc(SyscallDesc *desc, int num, 16911342Sandreas.hansson@arm.com Process *p, ExecContext *xc); 1708120Sgblack@eecs.umich.edu 17112063Sgabeblack@google.com/// Handler for unimplemented syscalls that we never intend to 17212563Sgabeblack@google.com/// implement (signal handling, etc.) and should not affect the correct 17312063Sgabeblack@google.com/// behavior of the program. Print a warning only if the appropriate 17412063Sgabeblack@google.com/// trace flag is enabled. Return success to the target program. 1755871Snate@binkert.orgSyscallReturn ignoreFunc(SyscallDesc *desc, int num, 1765871Snate@binkert.org Process *p, ExecContext *xc); 1776121Snate@binkert.org 1785871Snate@binkert.org/// Target exit() handler: terminate simulation. 1795871Snate@binkert.orgSyscallReturn exitFunc(SyscallDesc *desc, int num, 1809926Sstan.czerniawski@arm.com Process *p, ExecContext *xc); 18112243Sgabeblack@google.com 1821533SN/A/// Target getpagesize() handler. 18312246Sgabeblack@google.comSyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, 18412246Sgabeblack@google.com Process *p, ExecContext *xc); 18512246Sgabeblack@google.com 18612246Sgabeblack@google.com/// Target obreak() handler: set brk address. 1879239Sandreas.hansson@arm.comSyscallReturn obreakFunc(SyscallDesc *desc, int num, 1889239Sandreas.hansson@arm.com Process *p, ExecContext *xc); 1899239Sandreas.hansson@arm.com 1909239Sandreas.hansson@arm.com/// Target close() handler. 19112563Sgabeblack@google.comSyscallReturn closeFunc(SyscallDesc *desc, int num, 1929239Sandreas.hansson@arm.com Process *p, ExecContext *xc); 1939239Sandreas.hansson@arm.com 194955SN/A/// Target read() handler. 195955SN/ASyscallReturn readFunc(SyscallDesc *desc, int num, 1962632Sstever@eecs.umich.edu Process *p, ExecContext *xc); 1972632Sstever@eecs.umich.edu 198955SN/A/// Target write() handler. 199955SN/ASyscallReturn writeFunc(SyscallDesc *desc, int num, 200955SN/A Process *p, ExecContext *xc); 201955SN/A 2028878Ssteve.reinhardt@amd.com/// Target lseek() handler. 203955SN/ASyscallReturn lseekFunc(SyscallDesc *desc, int num, 2042632Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2052632Sstever@eecs.umich.edu 2062632Sstever@eecs.umich.edu/// Target munmap() handler. 2072632Sstever@eecs.umich.eduSyscallReturn munmapFunc(SyscallDesc *desc, int num, 2082632Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2092632Sstever@eecs.umich.edu 2102632Sstever@eecs.umich.edu/// Target gethostname() handler. 2118268Ssteve.reinhardt@amd.comSyscallReturn gethostnameFunc(SyscallDesc *desc, int num, 2128268Ssteve.reinhardt@amd.com Process *p, ExecContext *xc); 2138268Ssteve.reinhardt@amd.com 2148268Ssteve.reinhardt@amd.com/// Target unlink() handler. 2158268Ssteve.reinhardt@amd.comSyscallReturn unlinkFunc(SyscallDesc *desc, int num, 2168268Ssteve.reinhardt@amd.com Process *p, ExecContext *xc); 2178268Ssteve.reinhardt@amd.com 2182632Sstever@eecs.umich.edu/// Target rename() handler. 2192632Sstever@eecs.umich.eduSyscallReturn renameFunc(SyscallDesc *desc, int num, 2202632Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2212632Sstever@eecs.umich.edu 2228268Ssteve.reinhardt@amd.com 2232632Sstever@eecs.umich.edu/// Target truncate() handler. 2248268Ssteve.reinhardt@amd.comSyscallReturn truncateFunc(SyscallDesc *desc, int num, 2258268Ssteve.reinhardt@amd.com Process *p, ExecContext *xc); 2268268Ssteve.reinhardt@amd.com 2278268Ssteve.reinhardt@amd.com 2283718Sstever@eecs.umich.edu/// Target ftruncate() handler. 2292634Sstever@eecs.umich.eduSyscallReturn ftruncateFunc(SyscallDesc *desc, int num, 2302634Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2315863Snate@binkert.org 2322638Sstever@eecs.umich.edu 2338268Ssteve.reinhardt@amd.com/// Target chown() handler. 2342632Sstever@eecs.umich.eduSyscallReturn chownFunc(SyscallDesc *desc, int num, 2352632Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2362632Sstever@eecs.umich.edu 2372632Sstever@eecs.umich.edu 23812563Sgabeblack@google.com/// Target fchown() handler. 2391858SN/ASyscallReturn fchownFunc(SyscallDesc *desc, int num, 2403716Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2412638Sstever@eecs.umich.edu 2422638Sstever@eecs.umich.edu/// Target fnctl() handler. 2432638Sstever@eecs.umich.eduSyscallReturn fcntlFunc(SyscallDesc *desc, int num, 2442638Sstever@eecs.umich.edu Process *process, ExecContext *xc); 24512563Sgabeblack@google.com 24612563Sgabeblack@google.com/// Target setuid() handler. 2472638Sstever@eecs.umich.eduSyscallReturn setuidFunc(SyscallDesc *desc, int num, 2485863Snate@binkert.org Process *p, ExecContext *xc); 2495863Snate@binkert.org 2505863Snate@binkert.org/// Target getpid() handler. 251955SN/ASyscallReturn getpidFunc(SyscallDesc *desc, int num, 2525341Sstever@gmail.com Process *p, ExecContext *xc); 2535341Sstever@gmail.com 2545863Snate@binkert.org/// Target getuid() handler. 2557756SAli.Saidi@ARM.comSyscallReturn getuidFunc(SyscallDesc *desc, int num, 2565341Sstever@gmail.com Process *p, ExecContext *xc); 2576121Snate@binkert.org 2584494Ssaidi@eecs.umich.edu/// Target getgid() handler. 2596121Snate@binkert.orgSyscallReturn getgidFunc(SyscallDesc *desc, int num, 2601105SN/A Process *p, ExecContext *xc); 2612667Sstever@eecs.umich.edu 2622667Sstever@eecs.umich.edu/// Target getppid() handler. 2632667Sstever@eecs.umich.eduSyscallReturn getppidFunc(SyscallDesc *desc, int num, 2642667Sstever@eecs.umich.edu Process *p, ExecContext *xc); 2656121Snate@binkert.org 2662667Sstever@eecs.umich.edu/// Target geteuid() handler. 2675341Sstever@gmail.comSyscallReturn geteuidFunc(SyscallDesc *desc, int num, 2685863Snate@binkert.org Process *p, ExecContext *xc); 2695341Sstever@gmail.com 2705341Sstever@gmail.com/// Target getegid() handler. 2715341Sstever@gmail.comSyscallReturn getegidFunc(SyscallDesc *desc, int num, 2728120Sgblack@eecs.umich.edu Process *p, ExecContext *xc); 2735341Sstever@gmail.com 2748120Sgblack@eecs.umich.edu 2755341Sstever@gmail.com 2768120Sgblack@eecs.umich.edu/// Pseudo Funcs - These functions use a different return convension, 2776121Snate@binkert.org/// returning a second value in a register other than the normal return register 2786121Snate@binkert.orgSyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, 2799396Sandreas.hansson@arm.com Process *process, ExecContext *xc); 2805397Ssaidi@eecs.umich.edu 2815397Ssaidi@eecs.umich.edu/// Target getpidPseudo() handler. 2827727SAli.Saidi@ARM.comSyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, 2838268Ssteve.reinhardt@amd.com Process *p, ExecContext *xc); 2846168Snate@binkert.org 2855341Sstever@gmail.com/// Target getuidPseudo() handler. 2868120Sgblack@eecs.umich.eduSyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num, 2878120Sgblack@eecs.umich.edu Process *p, ExecContext *xc); 2888120Sgblack@eecs.umich.edu 2896814Sgblack@eecs.umich.edu/// Target getgidPseudo() handler. 2905863Snate@binkert.orgSyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, 2918120Sgblack@eecs.umich.edu Process *p, ExecContext *xc); 2925341Sstever@gmail.com 2935863Snate@binkert.org 2948268Ssteve.reinhardt@amd.com/// This struct is used to build an target-OS-dependent table that 2956121Snate@binkert.org/// maps the target's open() flags to the host open() flags. 2966121Snate@binkert.orgstruct OpenFlagTransTable { 2978268Ssteve.reinhardt@amd.com int tgtFlag; //!< Target system flag value. 2985742Snate@binkert.org int hostFlag; //!< Corresponding host system flag value. 2995742Snate@binkert.org}; 3005341Sstever@gmail.com 3015742Snate@binkert.org 3025742Snate@binkert.org 3035341Sstever@gmail.com/// A readable name for 1,000,000, for converting microseconds to seconds. 3046017Snate@binkert.orgconst int one_million = 1000000; 3056121Snate@binkert.org 3066017Snate@binkert.org/// Approximate seconds since the epoch (1/1/1970). About a billion, 30712158Sandreas.sandberg@arm.com/// by my reckoning. We want to keep this a constant (not use the 30812158Sandreas.sandberg@arm.com/// real-world time) to keep simulations repeatable. 30912158Sandreas.sandberg@arm.comconst unsigned seconds_since_epoch = 1000000000; 3108120Sgblack@eecs.umich.edu 3117756SAli.Saidi@ARM.com/// Helper function to convert current elapsed time to seconds and 3127756SAli.Saidi@ARM.com/// microseconds. 3137756SAli.Saidi@ARM.comtemplate <class T1, class T2> 3147756SAli.Saidi@ARM.comvoid 3157816Ssteve.reinhardt@amd.comgetElapsedTime(T1 &sec, T2 &usec) 3167816Ssteve.reinhardt@amd.com{ 3177816Ssteve.reinhardt@amd.com int elapsed_usecs = curTick / Clock::Int::us; 3187816Ssteve.reinhardt@amd.com sec = elapsed_usecs / one_million; 3197816Ssteve.reinhardt@amd.com usec = elapsed_usecs % one_million; 32011979Sgabeblack@google.com} 3217816Ssteve.reinhardt@amd.com 3227816Ssteve.reinhardt@amd.com////////////////////////////////////////////////////////////////////// 3237816Ssteve.reinhardt@amd.com// 3247816Ssteve.reinhardt@amd.com// The following emulation functions are generic, but need to be 3257756SAli.Saidi@ARM.com// templated to account for differences in types, constants, etc. 3267756SAli.Saidi@ARM.com// 3279227Sandreas.hansson@arm.com////////////////////////////////////////////////////////////////////// 3289227Sandreas.hansson@arm.com 3299227Sandreas.hansson@arm.com/// Target ioctl() handler. For the most part, programs call ioctl() 3309227Sandreas.hansson@arm.com/// only to find out if their stdout is a tty, to determine whether to 3319590Sandreas@sandberg.pp.se/// do line or block buffering. 3329590Sandreas@sandberg.pp.setemplate <class OS> 3339590Sandreas@sandberg.pp.seSyscallReturn 3349590Sandreas@sandberg.pp.seioctlFunc(SyscallDesc *desc, int callnum, Process *process, 3359590Sandreas@sandberg.pp.se ExecContext *xc) 3369590Sandreas@sandberg.pp.se{ 3376654Snate@binkert.org int fd = xc->getSyscallArg(0); 3386654Snate@binkert.org unsigned req = xc->getSyscallArg(1); 3395871Snate@binkert.org 3406121Snate@binkert.org DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); 3418946Sandreas.hansson@arm.com 3429419Sandreas.hansson@arm.com if (fd < 0 || process->sim_fd(fd) < 0) { 34312563Sgabeblack@google.com // doesn't map to any simulator fd: not a valid target fd 3443918Ssaidi@eecs.umich.edu return -EBADF; 3453918Ssaidi@eecs.umich.edu } 3461858SN/A 3479556Sandreas.hansson@arm.com switch (req) { 3489556Sandreas.hansson@arm.com case OS::TIOCISATTY: 3499556Sandreas.hansson@arm.com case OS::TIOCGETP: 3509556Sandreas.hansson@arm.com case OS::TIOCSETP: 35111294Sandreas.hansson@arm.com case OS::TIOCSETN: 35211294Sandreas.hansson@arm.com case OS::TIOCSETC: 35311294Sandreas.hansson@arm.com case OS::TIOCGETC: 35411294Sandreas.hansson@arm.com case OS::TIOCGETS: 35510878Sandreas.hansson@arm.com case OS::TIOCGETA: 35610878Sandreas.hansson@arm.com return -ENOTTY; 35711811Sbaz21@cam.ac.uk 35811811Sbaz21@cam.ac.uk default: 35911811Sbaz21@cam.ac.uk fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", 36011982Sgabeblack@google.com fd, req, xc->readPC()); 36111982Sgabeblack@google.com } 36211982Sgabeblack@google.com} 36313421Sciro.santilli@arm.com 36413421Sciro.santilli@arm.com/// Target open() handler. 36511982Sgabeblack@google.comtemplate <class OS> 36611992Sgabeblack@google.comSyscallReturn 36711982Sgabeblack@google.comopenFunc(SyscallDesc *desc, int callnum, Process *process, 36811982Sgabeblack@google.com ExecContext *xc) 36912305Sgabeblack@google.com{ 37012305Sgabeblack@google.com std::string path; 37112305Sgabeblack@google.com 37212305Sgabeblack@google.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 37312305Sgabeblack@google.com return -EFAULT; 37412305Sgabeblack@google.com 37512305Sgabeblack@google.com if (path == "/dev/sysdev0") { 3769556Sandreas.hansson@arm.com // This is a memory-mapped high-resolution timer device on Alpha. 37712563Sgabeblack@google.com // We don't support it, so just punt. 37812563Sgabeblack@google.com warn("Ignoring open(%s, ...)\n", path); 37912563Sgabeblack@google.com return -ENOENT; 38012563Sgabeblack@google.com } 3819556Sandreas.hansson@arm.com 38212563Sgabeblack@google.com int tgtFlags = xc->getSyscallArg(1); 38312563Sgabeblack@google.com int mode = xc->getSyscallArg(2); 3849556Sandreas.hansson@arm.com int hostFlags = 0; 38512563Sgabeblack@google.com 38612563Sgabeblack@google.com // translate open flags 38712563Sgabeblack@google.com for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { 38812563Sgabeblack@google.com if (tgtFlags & OS::openFlagTable[i].tgtFlag) { 38912563Sgabeblack@google.com tgtFlags &= ~OS::openFlagTable[i].tgtFlag; 39012563Sgabeblack@google.com hostFlags |= OS::openFlagTable[i].hostFlag; 39112563Sgabeblack@google.com } 39212563Sgabeblack@google.com } 3939556Sandreas.hansson@arm.com 3949556Sandreas.hansson@arm.com // any target flags left? 3956121Snate@binkert.org if (tgtFlags != 0) 39611500Sandreas.hansson@arm.com warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); 39710238Sandreas.hansson@arm.com 39810878Sandreas.hansson@arm.com#ifdef __CYGWIN32__ 3999420Sandreas.hansson@arm.com hostFlags |= O_BINARY; 40011500Sandreas.hansson@arm.com#endif 40112563Sgabeblack@google.com 40212563Sgabeblack@google.com DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); 4039420Sandreas.hansson@arm.com 4049420Sandreas.hansson@arm.com // open the file 4059420Sandreas.hansson@arm.com int fd = open(path.c_str(), hostFlags, mode); 4069420Sandreas.hansson@arm.com 40712063Sgabeblack@google.com return (fd == -1) ? -errno : process->alloc_fd(fd); 40812063Sgabeblack@google.com} 40912063Sgabeblack@google.com 41012063Sgabeblack@google.com 41112063Sgabeblack@google.com/// Target chmod() handler. 41212063Sgabeblack@google.comtemplate <class OS> 41312063Sgabeblack@google.comSyscallReturn 41412063Sgabeblack@google.comchmodFunc(SyscallDesc *desc, int callnum, Process *process, 41512063Sgabeblack@google.com ExecContext *xc) 41612063Sgabeblack@google.com{ 41712063Sgabeblack@google.com std::string path; 41812063Sgabeblack@google.com 41912063Sgabeblack@google.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 42012063Sgabeblack@google.com return -EFAULT; 42112063Sgabeblack@google.com 42212063Sgabeblack@google.com uint32_t mode = xc->getSyscallArg(1); 42312063Sgabeblack@google.com mode_t hostMode = 0; 42412063Sgabeblack@google.com 42512063Sgabeblack@google.com // XXX translate mode flags via OS::something??? 42612063Sgabeblack@google.com hostMode = mode; 42712063Sgabeblack@google.com 42812063Sgabeblack@google.com // do the chmod 42910457Sandreas.hansson@arm.com int result = chmod(path.c_str(), hostMode); 43010457Sandreas.hansson@arm.com if (result < 0) 43110457Sandreas.hansson@arm.com return -errno; 43210457Sandreas.hansson@arm.com 43310457Sandreas.hansson@arm.com return 0; 43412563Sgabeblack@google.com} 43512563Sgabeblack@google.com 43612563Sgabeblack@google.com 43710457Sandreas.hansson@arm.com/// Target fchmod() handler. 43812063Sgabeblack@google.comtemplate <class OS> 43912063Sgabeblack@google.comSyscallReturn 44012063Sgabeblack@google.comfchmodFunc(SyscallDesc *desc, int callnum, Process *process, 44112563Sgabeblack@google.com ExecContext *xc) 44212563Sgabeblack@google.com{ 44312563Sgabeblack@google.com int fd = xc->getSyscallArg(0); 44412563Sgabeblack@google.com if (fd < 0 || process->sim_fd(fd) < 0) { 44512563Sgabeblack@google.com // doesn't map to any simulator fd: not a valid target fd 44612563Sgabeblack@google.com return -EBADF; 44712063Sgabeblack@google.com } 44812063Sgabeblack@google.com 44910238Sandreas.hansson@arm.com uint32_t mode = xc->getSyscallArg(1); 45010238Sandreas.hansson@arm.com mode_t hostMode = 0; 45110238Sandreas.hansson@arm.com 45212063Sgabeblack@google.com // XXX translate mode flags via OS::someting??? 45310238Sandreas.hansson@arm.com hostMode = mode; 45410238Sandreas.hansson@arm.com 45510416Sandreas.hansson@arm.com // do the fchmod 45610238Sandreas.hansson@arm.com int result = fchmod(process->sim_fd(fd), hostMode); 4579227Sandreas.hansson@arm.com if (result < 0) 45810238Sandreas.hansson@arm.com return -errno; 45910416Sandreas.hansson@arm.com 46010416Sandreas.hansson@arm.com return 0; 4619227Sandreas.hansson@arm.com} 4629590Sandreas@sandberg.pp.se 4639590Sandreas@sandberg.pp.se 4649590Sandreas@sandberg.pp.se/// Target stat() handler. 46512304Sgabeblack@google.comtemplate <class OS> 46612304Sgabeblack@google.comSyscallReturn 46712304Sgabeblack@google.comstatFunc(SyscallDesc *desc, int callnum, Process *process, 46812688Sgiacomo.travaglini@arm.com ExecContext *xc) 46912688Sgiacomo.travaglini@arm.com{ 47012688Sgiacomo.travaglini@arm.com std::string path; 47113020Sshunhsingou@google.com 47212304Sgabeblack@google.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 47312688Sgiacomo.travaglini@arm.com return -EFAULT; 47412688Sgiacomo.travaglini@arm.com 47513020Sshunhsingou@google.com struct stat hostBuf; 47612304Sgabeblack@google.com int result = stat(path.c_str(), &hostBuf); 47712304Sgabeblack@google.com 47812304Sgabeblack@google.com if (result < 0) 47912304Sgabeblack@google.com return -errno; 48012688Sgiacomo.travaglini@arm.com 48112688Sgiacomo.travaglini@arm.com OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 48212688Sgiacomo.travaglini@arm.com 48312304Sgabeblack@google.com return 0; 4848737Skoansin.tan@gmail.com} 48510878Sandreas.hansson@arm.com 48611500Sandreas.hansson@arm.com 4879420Sandreas.hansson@arm.com/// Target fstat64() handler. 4888737Skoansin.tan@gmail.comtemplate <class OS> 48910106SMitch.Hayenga@arm.comSyscallReturn 4908737Skoansin.tan@gmail.comfstat64Func(SyscallDesc *desc, int callnum, Process *process, 4918737Skoansin.tan@gmail.com ExecContext *xc) 49210878Sandreas.hansson@arm.com{ 49312563Sgabeblack@google.com int fd = xc->getSyscallArg(0); 49412563Sgabeblack@google.com if (fd < 0 || process->sim_fd(fd) < 0) { 4958737Skoansin.tan@gmail.com // doesn't map to any simulator fd: not a valid target fd 4968737Skoansin.tan@gmail.com return -EBADF; 49712563Sgabeblack@google.com } 4988737Skoansin.tan@gmail.com 4998737Skoansin.tan@gmail.com#if BSD_HOST 50011294Sandreas.hansson@arm.com struct stat hostBuf; 5019556Sandreas.hansson@arm.com int result = fstat(process->sim_fd(fd), &hostBuf); 5029556Sandreas.hansson@arm.com#else 5039556Sandreas.hansson@arm.com struct stat64 hostBuf; 50411294Sandreas.hansson@arm.com int result = fstat64(process->sim_fd(fd), &hostBuf); 50510278SAndreas.Sandberg@ARM.com#endif 50610278SAndreas.Sandberg@ARM.com 50710278SAndreas.Sandberg@ARM.com if (result < 0) 50810278SAndreas.Sandberg@ARM.com return -errno; 50910278SAndreas.Sandberg@ARM.com 51010278SAndreas.Sandberg@ARM.com OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); 5119556Sandreas.hansson@arm.com 5129590Sandreas@sandberg.pp.se return 0; 5139590Sandreas@sandberg.pp.se} 5149420Sandreas.hansson@arm.com 5159846Sandreas.hansson@arm.com 5169846Sandreas.hansson@arm.com/// Target lstat() handler. 5179846Sandreas.hansson@arm.comtemplate <class OS> 5189846Sandreas.hansson@arm.comSyscallReturn 5198946Sandreas.hansson@arm.comlstatFunc(SyscallDesc *desc, int callnum, Process *process, 52011811Sbaz21@cam.ac.uk ExecContext *xc) 52111811Sbaz21@cam.ac.uk{ 52211811Sbaz21@cam.ac.uk std::string path; 52311811Sbaz21@cam.ac.uk 52412304Sgabeblack@google.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 52512304Sgabeblack@google.com return -EFAULT; 52612304Sgabeblack@google.com 52712304Sgabeblack@google.com struct stat hostBuf; 52813020Sshunhsingou@google.com int result = lstat(path.c_str(), &hostBuf); 52913020Sshunhsingou@google.com 53012304Sgabeblack@google.com if (result < 0) 53112304Sgabeblack@google.com return -errno; 53213020Sshunhsingou@google.com 53313020Sshunhsingou@google.com OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 53412304Sgabeblack@google.com 53512304Sgabeblack@google.com return 0; 53613020Sshunhsingou@google.com} 53713020Sshunhsingou@google.com 53812304Sgabeblack@google.com/// Target lstat64() handler. 53912304Sgabeblack@google.comtemplate <class OS> 5403918Ssaidi@eecs.umich.eduSyscallReturn 54112563Sgabeblack@google.comlstat64Func(SyscallDesc *desc, int callnum, Process *process, 54212563Sgabeblack@google.com ExecContext *xc) 54312563Sgabeblack@google.com{ 54412563Sgabeblack@google.com std::string path; 5459068SAli.Saidi@ARM.com 54612563Sgabeblack@google.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 54712563Sgabeblack@google.com return -EFAULT; 5489068SAli.Saidi@ARM.com 54912563Sgabeblack@google.com#if BSD_HOST 55012563Sgabeblack@google.com struct stat hostBuf; 55112563Sgabeblack@google.com int result = lstat(path.c_str(), &hostBuf); 55212563Sgabeblack@google.com#else 55312563Sgabeblack@google.com struct stat64 hostBuf; 55412563Sgabeblack@google.com int result = lstat64(path.c_str(), &hostBuf); 55512563Sgabeblack@google.com#endif 55612563Sgabeblack@google.com 5573918Ssaidi@eecs.umich.edu if (result < 0) 5583918Ssaidi@eecs.umich.edu return -errno; 5596157Snate@binkert.org 5606157Snate@binkert.org OS::copyOutStat64Buf(xc->mem, -1, xc->getSyscallArg(1), &hostBuf); 5616157Snate@binkert.org 5626157Snate@binkert.org return 0; 5635397Ssaidi@eecs.umich.edu} 5645397Ssaidi@eecs.umich.edu 5656121Snate@binkert.org/// Target fstat() handler. 5666121Snate@binkert.orgtemplate <class OS> 5676121Snate@binkert.orgSyscallReturn 5686121Snate@binkert.orgfstatFunc(SyscallDesc *desc, int callnum, Process *process, 5696121Snate@binkert.org ExecContext *xc) 5706121Snate@binkert.org{ 5715397Ssaidi@eecs.umich.edu int fd = process->sim_fd(xc->getSyscallArg(0)); 5721851SN/A 5731851SN/A DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); 5747739Sgblack@eecs.umich.edu 575955SN/A if (fd < 0) 5769396Sandreas.hansson@arm.com return -EBADF; 5779396Sandreas.hansson@arm.com 5789396Sandreas.hansson@arm.com struct stat hostBuf; 5799396Sandreas.hansson@arm.com int result = fstat(fd, &hostBuf); 5809396Sandreas.hansson@arm.com 5819396Sandreas.hansson@arm.com if (result < 0) 58212563Sgabeblack@google.com return -errno; 58312563Sgabeblack@google.com 58412563Sgabeblack@google.com OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 58512563Sgabeblack@google.com return 0; 5869396Sandreas.hansson@arm.com} 5879396Sandreas.hansson@arm.com 5889396Sandreas.hansson@arm.com 5899396Sandreas.hansson@arm.com/// Target statfs() handler. 5909396Sandreas.hansson@arm.comtemplate <class OS> 5919396Sandreas.hansson@arm.comSyscallReturn 59212563Sgabeblack@google.comstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 59312563Sgabeblack@google.com ExecContext *xc) 59412563Sgabeblack@google.com{ 59512563Sgabeblack@google.com std::string path; 59612563Sgabeblack@google.com 5979477Sandreas.hansson@arm.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 5989477Sandreas.hansson@arm.com return -EFAULT; 5999477Sandreas.hansson@arm.com 6009477Sandreas.hansson@arm.com struct statfs hostBuf; 6019477Sandreas.hansson@arm.com int result = statfs(path.c_str(), &hostBuf); 6029477Sandreas.hansson@arm.com 6039477Sandreas.hansson@arm.com if (result < 0) 6049477Sandreas.hansson@arm.com return -errno; 6059477Sandreas.hansson@arm.com 6069477Sandreas.hansson@arm.com OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 6079477Sandreas.hansson@arm.com 6089477Sandreas.hansson@arm.com return 0; 6099477Sandreas.hansson@arm.com} 6109477Sandreas.hansson@arm.com 61112563Sgabeblack@google.com 61212563Sgabeblack@google.com/// Target fstatfs() handler. 61312563Sgabeblack@google.comtemplate <class OS> 6149396Sandreas.hansson@arm.comSyscallReturn 6152667Sstever@eecs.umich.edufstatfsFunc(SyscallDesc *desc, int callnum, Process *process, 61610710Sandreas.hansson@arm.com ExecContext *xc) 61710710Sandreas.hansson@arm.com{ 61810710Sandreas.hansson@arm.com int fd = process->sim_fd(xc->getSyscallArg(0)); 61911811Sbaz21@cam.ac.uk 62011811Sbaz21@cam.ac.uk if (fd < 0) 62111811Sbaz21@cam.ac.uk return -EBADF; 62211811Sbaz21@cam.ac.uk 62311811Sbaz21@cam.ac.uk struct statfs hostBuf; 62411811Sbaz21@cam.ac.uk int result = fstatfs(fd, &hostBuf); 62510710Sandreas.hansson@arm.com 62610710Sandreas.hansson@arm.com if (result < 0) 62710710Sandreas.hansson@arm.com return -errno; 62810710Sandreas.hansson@arm.com 62910384SCurtis.Dunham@arm.com OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); 6309986Sandreas@sandberg.pp.se 6319986Sandreas@sandberg.pp.se return 0; 6329986Sandreas@sandberg.pp.se} 6339986Sandreas@sandberg.pp.se 6349986Sandreas@sandberg.pp.se 6359986Sandreas@sandberg.pp.se/// Target writev() handler. 6369986Sandreas@sandberg.pp.setemplate <class OS> 6379986Sandreas@sandberg.pp.seSyscallReturn 6389986Sandreas@sandberg.pp.sewritevFunc(SyscallDesc *desc, int callnum, Process *process, 6399986Sandreas@sandberg.pp.se ExecContext *xc) 6409986Sandreas@sandberg.pp.se{ 6419986Sandreas@sandberg.pp.se int fd = xc->getSyscallArg(0); 6429986Sandreas@sandberg.pp.se if (fd < 0 || process->sim_fd(fd) < 0) { 6439986Sandreas@sandberg.pp.se // doesn't map to any simulator fd: not a valid target fd 6449986Sandreas@sandberg.pp.se return -EBADF; 6459986Sandreas@sandberg.pp.se } 6469986Sandreas@sandberg.pp.se 6479986Sandreas@sandberg.pp.se uint64_t tiov_base = xc->getSyscallArg(1); 6489986Sandreas@sandberg.pp.se size_t count = xc->getSyscallArg(2); 6499986Sandreas@sandberg.pp.se struct iovec hiov[count]; 6502638Sstever@eecs.umich.edu for (int i = 0; i < count; ++i) 6512638Sstever@eecs.umich.edu { 6526121Snate@binkert.org typename OS::tgt_iovec tiov; 6533716Sstever@eecs.umich.edu xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), 6545522Snate@binkert.org &tiov, sizeof(typename OS::tgt_iovec)); 6559986Sandreas@sandberg.pp.se hiov[i].iov_len = gtoh(tiov.iov_len); 6569986Sandreas@sandberg.pp.se hiov[i].iov_base = new char [hiov[i].iov_len]; 6579986Sandreas@sandberg.pp.se xc->mem->access(Read, gtoh(tiov.iov_base), 6585522Snate@binkert.org hiov[i].iov_base, hiov[i].iov_len); 6595227Ssaidi@eecs.umich.edu } 6605227Ssaidi@eecs.umich.edu 6615227Ssaidi@eecs.umich.edu int result = writev(process->sim_fd(fd), hiov, count); 6625227Ssaidi@eecs.umich.edu 6636654Snate@binkert.org for (int i = 0; i < count; ++i) 6646654Snate@binkert.org { 6657769SAli.Saidi@ARM.com delete [] (char *)hiov[i].iov_base; 6667769SAli.Saidi@ARM.com } 6677769SAli.Saidi@ARM.com 6687769SAli.Saidi@ARM.com if (result < 0) 6695227Ssaidi@eecs.umich.edu return -errno; 6705227Ssaidi@eecs.umich.edu 6715227Ssaidi@eecs.umich.edu return 0; 6725204Sstever@gmail.com} 6735204Sstever@gmail.com 6745204Sstever@gmail.com 6755204Sstever@gmail.com/// Target mmap() handler. 6765204Sstever@gmail.com/// 6775204Sstever@gmail.com/// We don't really handle mmap(). If the target is mmaping an 6785204Sstever@gmail.com/// anonymous region or /dev/zero, we can get away with doing basically 6795204Sstever@gmail.com/// nothing (since memory is initialized to zero and the simulator 6805204Sstever@gmail.com/// doesn't really check addresses anyway). Always print a warning, 6815204Sstever@gmail.com/// since this could be seriously broken if we're not mapping 6825204Sstever@gmail.com/// /dev/zero. 6835204Sstever@gmail.com// 6845204Sstever@gmail.com/// Someday we should explicitly check for /dev/zero in open, flag the 6855204Sstever@gmail.com/// file descriptor, and fail (or implement!) a non-anonymous mmap to 6865204Sstever@gmail.com/// anything else. 6875204Sstever@gmail.comtemplate <class OS> 6885204Sstever@gmail.comSyscallReturn 6896121Snate@binkert.orgmmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 6905204Sstever@gmail.com{ 6917727SAli.Saidi@ARM.com Addr start = xc->getSyscallArg(0); 6927727SAli.Saidi@ARM.com uint64_t length = xc->getSyscallArg(1); 69312563Sgabeblack@google.com // int prot = xc->getSyscallArg(2); 6947727SAli.Saidi@ARM.com int flags = xc->getSyscallArg(3); 6957727SAli.Saidi@ARM.com // int fd = p->sim_fd(xc->getSyscallArg(4)); 69611988Sandreas.sandberg@arm.com // int offset = xc->getSyscallArg(5); 69711988Sandreas.sandberg@arm.com 69810453SAndrew.Bardsley@arm.com if (start == 0) { 69910453SAndrew.Bardsley@arm.com // user didn't give an address... pick one from our "mmap region" 70010453SAndrew.Bardsley@arm.com start = p->mmap_end; 70110453SAndrew.Bardsley@arm.com p->mmap_end += roundUp(length, TheISA::VMPageSize); 70210453SAndrew.Bardsley@arm.com if (p->nxm_start != 0) { 70310453SAndrew.Bardsley@arm.com //If we have an nxm space, make sure we haven't colided 70410453SAndrew.Bardsley@arm.com assert(p->mmap_end < p->nxm_start); 70510453SAndrew.Bardsley@arm.com } 70610453SAndrew.Bardsley@arm.com } 70710453SAndrew.Bardsley@arm.com 70810160Sandreas.hansson@arm.com if (!(flags & OS::TGT_MAP_ANONYMOUS)) { 70910453SAndrew.Bardsley@arm.com warn("allowing mmap of file @ fd %d. " 71010453SAndrew.Bardsley@arm.com "This will break if not /dev/zero.", xc->getSyscallArg(4)); 71110453SAndrew.Bardsley@arm.com } 71210453SAndrew.Bardsley@arm.com 71310453SAndrew.Bardsley@arm.com return start; 71413541Sandrea.mondelli@ucf.edu} 71510453SAndrew.Bardsley@arm.com 71610453SAndrew.Bardsley@arm.com/// Target getrlimit() handler. 71713541Sandrea.mondelli@ucf.edutemplate <class OS> 71813541Sandrea.mondelli@ucf.eduSyscallReturn 7199812Sandreas.hansson@arm.comgetrlimitFunc(SyscallDesc *desc, int callnum, Process *process, 72010453SAndrew.Bardsley@arm.com ExecContext *xc) 72110453SAndrew.Bardsley@arm.com{ 72210453SAndrew.Bardsley@arm.com unsigned resource = xc->getSyscallArg(0); 72310453SAndrew.Bardsley@arm.com TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); 72410453SAndrew.Bardsley@arm.com 72510453SAndrew.Bardsley@arm.com switch (resource) { 72610453SAndrew.Bardsley@arm.com case OS::TGT_RLIMIT_STACK: 72710453SAndrew.Bardsley@arm.com // max stack size in bytes: make up a number (2MB for now) 72810453SAndrew.Bardsley@arm.com rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; 72910453SAndrew.Bardsley@arm.com rlp->rlim_cur = htog(rlp->rlim_cur); 73010453SAndrew.Bardsley@arm.com rlp->rlim_max = htog(rlp->rlim_max); 73110453SAndrew.Bardsley@arm.com break; 7327727SAli.Saidi@ARM.com 73310453SAndrew.Bardsley@arm.com default: 73410453SAndrew.Bardsley@arm.com std::cerr << "getrlimitFunc: unimplemented resource " << resource 73512790Smatteo.fusi@bsc.es << std::endl; 73612790Smatteo.fusi@bsc.es abort(); 73712790Smatteo.fusi@bsc.es break; 73812790Smatteo.fusi@bsc.es } 73912790Smatteo.fusi@bsc.es 74012790Smatteo.fusi@bsc.es rlp.copyOut(xc->mem); 74112790Smatteo.fusi@bsc.es return 0; 74210453SAndrew.Bardsley@arm.com} 7433118Sstever@eecs.umich.edu 74410453SAndrew.Bardsley@arm.com/// Target gettimeofday() handler. 74510453SAndrew.Bardsley@arm.comtemplate <class OS> 74612563Sgabeblack@google.comSyscallReturn 74710453SAndrew.Bardsley@arm.comgettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, 7483118Sstever@eecs.umich.edu ExecContext *xc) 7493483Ssaidi@eecs.umich.edu{ 7503494Ssaidi@eecs.umich.edu TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); 7513494Ssaidi@eecs.umich.edu 75212563Sgabeblack@google.com getElapsedTime(tp->tv_sec, tp->tv_usec); 7533483Ssaidi@eecs.umich.edu tp->tv_sec += seconds_since_epoch; 7543483Ssaidi@eecs.umich.edu tp->tv_sec = htog(tp->tv_sec); 7553053Sstever@eecs.umich.edu tp->tv_usec = htog(tp->tv_usec); 7563053Sstever@eecs.umich.edu 7573918Ssaidi@eecs.umich.edu tp.copyOut(xc->mem); 75812563Sgabeblack@google.com 75912563Sgabeblack@google.com return 0; 76012563Sgabeblack@google.com} 7613053Sstever@eecs.umich.edu 7623053Sstever@eecs.umich.edu 7639396Sandreas.hansson@arm.com/// Target utimes() handler. 7649396Sandreas.hansson@arm.comtemplate <class OS> 7659396Sandreas.hansson@arm.comSyscallReturn 7669396Sandreas.hansson@arm.comutimesFunc(SyscallDesc *desc, int callnum, Process *process, 7679396Sandreas.hansson@arm.com ExecContext *xc) 7689396Sandreas.hansson@arm.com{ 7699396Sandreas.hansson@arm.com std::string path; 7709396Sandreas.hansson@arm.com 7719396Sandreas.hansson@arm.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) 77212920Sgabeblack@google.com return -EFAULT; 77312920Sgabeblack@google.com 77412920Sgabeblack@google.com TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); 77512920Sgabeblack@google.com tp.copyIn(xc->mem); 7769477Sandreas.hansson@arm.com 7779396Sandreas.hansson@arm.com struct timeval hostTimeval[2]; 77812563Sgabeblack@google.com for (int i = 0; i < 2; ++i) 77912563Sgabeblack@google.com { 78012563Sgabeblack@google.com hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); 78112563Sgabeblack@google.com hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); 7829396Sandreas.hansson@arm.com } 7837840Snate@binkert.org int result = utimes(path.c_str(), hostTimeval); 7847865Sgblack@eecs.umich.edu 7857865Sgblack@eecs.umich.edu if (result < 0) 7867865Sgblack@eecs.umich.edu return -errno; 7877865Sgblack@eecs.umich.edu 7887865Sgblack@eecs.umich.edu return 0; 7897840Snate@binkert.org} 7909900Sandreas@sandberg.pp.se/// Target getrusage() function. 7919900Sandreas@sandberg.pp.setemplate <class OS> 7929900Sandreas@sandberg.pp.seSyscallReturn 7939900Sandreas@sandberg.pp.segetrusageFunc(SyscallDesc *desc, int callnum, Process *process, 79410456SCurtis.Dunham@arm.com ExecContext *xc) 79510456SCurtis.Dunham@arm.com{ 79610456SCurtis.Dunham@arm.com int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN 79710456SCurtis.Dunham@arm.com TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); 79810456SCurtis.Dunham@arm.com 79910456SCurtis.Dunham@arm.com if (who != OS::TGT_RUSAGE_SELF) { 80012563Sgabeblack@google.com // don't really handle THREAD or CHILDREN, but just warn and 80112563Sgabeblack@google.com // plow ahead 80212563Sgabeblack@google.com warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", 80312563Sgabeblack@google.com who); 8049045SAli.Saidi@ARM.com } 80511235Sandreas.sandberg@arm.com 80611235Sandreas.sandberg@arm.com getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); 80711235Sandreas.sandberg@arm.com rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); 80811235Sandreas.sandberg@arm.com rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); 80911235Sandreas.sandberg@arm.com 81012485Sjang.hanhwi@gmail.com rup->ru_stime.tv_sec = 0; 81112485Sjang.hanhwi@gmail.com rup->ru_stime.tv_usec = 0; 81212485Sjang.hanhwi@gmail.com rup->ru_maxrss = 0; 81311235Sandreas.sandberg@arm.com rup->ru_ixrss = 0; 81411811Sbaz21@cam.ac.uk rup->ru_idrss = 0; 81512485Sjang.hanhwi@gmail.com rup->ru_isrss = 0; 81611811Sbaz21@cam.ac.uk rup->ru_minflt = 0; 81711811Sbaz21@cam.ac.uk rup->ru_majflt = 0; 81811811Sbaz21@cam.ac.uk rup->ru_nswap = 0; 81911235Sandreas.sandberg@arm.com rup->ru_inblock = 0; 82011235Sandreas.sandberg@arm.com rup->ru_oublock = 0; 82111235Sandreas.sandberg@arm.com rup->ru_msgsnd = 0; 82212563Sgabeblack@google.com rup->ru_msgrcv = 0; 82312563Sgabeblack@google.com rup->ru_nsignals = 0; 82412563Sgabeblack@google.com rup->ru_nvcsw = 0; 82511235Sandreas.sandberg@arm.com rup->ru_nivcsw = 0; 8267840Snate@binkert.org 82712563Sgabeblack@google.com rup.copyOut(xc->mem); 8287840Snate@binkert.org 8291858SN/A return 0; 8301858SN/A} 8311858SN/A 83212563Sgabeblack@google.com#endif // __SIM_SYSCALL_EMUL_HH__ 83312563Sgabeblack@google.com