gem5/sim/syscall_emul.cc
Ali Saidi 232134a816 Changed all syscalls to use syscall return object.
arch/alpha/alpha_linux_process.cc:
arch/alpha/alpha_tru64_process.cc:
cpu/exec_context.hh:
sim/process.hh:
sim/syscall_emul.cc:
sim/syscall_emul.hh:
    Changed all syscalls to use syscall return object
arch/alpha/isa_traits.hh:
    Added syscall return object that packages return value and return
    status into an object.
sim/process.cc:
    renamed variable name to nm so base class function name() can be called

--HG--
extra : convert_revision : 6609c5ffecc9e3519d7a0cd160879fd21d54abfc
2005-03-09 15:52:10 -05:00

221 lines
6.2 KiB
C++

/*
* Copyright (c) 2003-2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <unistd.h>
#include <string>
#include <iostream>
#include "sim/syscall_emul.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/base_cpu.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
using namespace std;
void
SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
{
DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
xc->cpu->name(), name);
SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
xc->cpu->name(), name, retval.value());
if (!(flags & SyscallDesc::SuppressReturnValue))
xc->setSyscallReturn(retval);
}
SyscallReturn
unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
cerr << "Error: syscall " << desc->name
<< " (#" << callnum << ") unimplemented.";
cerr << " Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1)
<< ", ..." << endl;
abort();
}
SyscallReturn
ignoreFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name
<< "(" << xc->getSyscallArg(0)
<< ", " << xc->getSyscallArg(1)
<< ", ...)" << endl;
return SyscallReturn(0);
}
SyscallReturn
exitFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
{
new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
return SyscallReturn(1);
}
SyscallReturn
getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
return SyscallReturn(VMPageSize);
}
SyscallReturn
obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
// change brk addr to first arg
Addr new_brk = xc->getSyscallArg(0);
if (new_brk != 0)
{
p->brk_point = xc->getSyscallArg(0);
}
return SyscallReturn(p->brk_point);
}
SyscallReturn
closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
int fd = p->sim_fd(xc->getSyscallArg(0));
return SyscallReturn(close(fd));
}
SyscallReturn
readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
int fd = p->sim_fd(xc->getSyscallArg(0));
int nbytes = xc->getSyscallArg(2);
BufferArg bufArg(xc->getSyscallArg(1), nbytes);
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
if (bytes_read != -1)
bufArg.copyOut(xc->mem);
return SyscallReturn(bytes_read);
}
SyscallReturn
writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
int fd = p->sim_fd(xc->getSyscallArg(0));
int nbytes = xc->getSyscallArg(2);
BufferArg bufArg(xc->getSyscallArg(1), nbytes);
bufArg.copyIn(xc->mem);
int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
fsync(fd);
return SyscallReturn(bytes_written);
}
SyscallReturn
lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
int fd = p->sim_fd(xc->getSyscallArg(0));
uint64_t offs = xc->getSyscallArg(1);
int whence = xc->getSyscallArg(2);
off_t result = lseek(fd, offs, whence);
return (result == (off_t)-1) ? SyscallReturn(-errno) :
SyscallReturn(result);
}
SyscallReturn
munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
// given that we don't really implement mmap, munmap is really easy
return SyscallReturn(0);
}
const char *hostname = "m5.eecs.umich.edu";
SyscallReturn
gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
int name_len = xc->getSyscallArg(1);
BufferArg name(xc->getSyscallArg(0), name_len);
strncpy((char *)name.bufferPtr(), hostname, name_len);
name.copyOut(xc->mem);
return SyscallReturn(0);
}
SyscallReturn
unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
std::string path;
if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
return (TheISA::IntReg)-EFAULT;
int result = unlink(path.c_str());
return (result == -1) ? SyscallReturn(-errno) : SyscallReturn(result);
}
SyscallReturn
renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
std::string old_name;
if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault)
return SyscallReturn(-EFAULT);
std::string new_name;
if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault)
return SyscallReturn(-EFAULT);
int64_t result = rename(old_name.c_str(),new_name.c_str());
return (result == -1) ? SyscallReturn(-errno) : SyscallReturn(result);
}