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