syscall_emul.cc revision 1458
112SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
312SN/A * All rights reserved.
412SN/A *
512SN/A * Redistribution and use in source and binary forms, with or without
612SN/A * modification, are permitted provided that the following conditions are
712SN/A * met: redistributions of source code must retain the above copyright
812SN/A * notice, this list of conditions and the following disclaimer;
912SN/A * redistributions in binary form must reproduce the above copyright
1012SN/A * notice, this list of conditions and the following disclaimer in the
1112SN/A * documentation and/or other materials provided with the distribution;
1212SN/A * neither the name of the copyright holders nor the names of its
1312SN/A * contributors may be used to endorse or promote products derived from
1412SN/A * this software without specific prior written permission.
1512SN/A *
1612SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#include <unistd.h>
3012SN/A
3112SN/A#include <string>
3212SN/A#include <iostream>
3312SN/A
34468SN/A#include "sim/syscall_emul.hh"
35468SN/A#include "base/trace.hh"
36468SN/A#include "cpu/exec_context.hh"
37661SN/A#include "cpu/base_cpu.hh"
38468SN/A#include "sim/process.hh"
392634Sstever@eecs.umich.edu
40468SN/A#include "sim/sim_events.hh"
4156SN/A
422439SN/Ausing namespace std;
4312SN/A
4456SN/Avoid
4512SN/ASyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
4656SN/A{
4712SN/A    DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
482423SN/A             xc->cpu->name(), name);
492423SN/A
5012SN/A    SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
5112SN/A
5212SN/A    DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
5312SN/A             xc->cpu->name(), name, retval.value());
5412SN/A
5512SN/A    if (!(flags & SyscallDesc::SuppressReturnValue))
56443SN/A        xc->setSyscallReturn(retval);
57443SN/A}
582207SN/A
592207SN/A
60443SN/ASyscallReturn
61468SN/AunimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
621708SN/A                  ExecContext *xc)
631708SN/A{
64443SN/A    cerr << "Error: syscall " << desc->name
65468SN/A         << " (#" << callnum << ") unimplemented.";
66443SN/A    cerr << "  Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1)
67468SN/A         << ", ..." << endl;
68443SN/A
69443SN/A    abort();
70468SN/A}
71468SN/A
72443SN/A
73443SN/ASyscallReturn
74443SN/AignoreFunc(SyscallDesc *desc, int callnum, Process *process,
752476SN/A           ExecContext *xc)
762207SN/A{
772207SN/A    DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name
782207SN/A                           << "(" << xc->getSyscallArg(0)
792207SN/A                           << ", " << xc->getSyscallArg(1)
802207SN/A                           << ", ...)" << endl;
812207SN/A
822620SN/A    return 0;
832207SN/A}
842207SN/A
852207SN/A
862472SN/ASyscallReturn
872207SN/AexitFunc(SyscallDesc *desc, int callnum, Process *process,
882207SN/A         ExecContext *xc)
892207SN/A{
902600SN/A    new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
912207SN/A
922207SN/A    return 1;
932207SN/A}
942207SN/A
952207SN/A
962207SN/ASyscallReturn
972238SN/AgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
982207SN/A{
992207SN/A    return VMPageSize;
1002207SN/A}
1012207SN/A
1022207SN/A
1032238SN/ASyscallReturn
1042207SN/AobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1052207SN/A{
1062238SN/A    // change brk addr to first arg
1072207SN/A    Addr new_brk = xc->getSyscallArg(0);
1082207SN/A    if (new_brk != 0)
1092207SN/A    {
1102207SN/A        p->brk_point = xc->getSyscallArg(0);
1112238SN/A    }
1122238SN/A    DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
1132600SN/A    return p->brk_point;
1142238SN/A}
1152238SN/A
1162238SN/A
1172238SN/ASyscallReturn
1182238SN/AcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1192238SN/A{
1202238SN/A    int fd = p->sim_fd(xc->getSyscallArg(0));
1212238SN/A    return close(fd);
1222238SN/A}
1232238SN/A
1242600SN/A
1252238SN/ASyscallReturn
1262238SN/AreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1272238SN/A{
1282238SN/A    int fd = p->sim_fd(xc->getSyscallArg(0));
1292238SN/A    int nbytes = xc->getSyscallArg(2);
1302238SN/A    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
1312238SN/A
1322238SN/A    int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
1332238SN/A
1342238SN/A    if (bytes_read != -1)
1352238SN/A        bufArg.copyOut(xc->mem);
1362238SN/A
1372238SN/A    return bytes_read;
1382238SN/A}
1392238SN/A
1402238SN/ASyscallReturn
1412238SN/AwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1422238SN/A{
1432238SN/A    int fd = p->sim_fd(xc->getSyscallArg(0));
1442238SN/A    int nbytes = xc->getSyscallArg(2);
1452238SN/A    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
1462238SN/A
1472600SN/A    bufArg.copyIn(xc->mem);
1482600SN/A
1492600SN/A    int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
1502600SN/A
1512600SN/A    fsync(fd);
1522238SN/A
1532238SN/A    return bytes_written;
1542238SN/A}
1552472SN/A
1562238SN/A
1572207SN/ASyscallReturn
15812SN/AlseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
15912SN/A{
16012SN/A    int fd = p->sim_fd(xc->getSyscallArg(0));
16112SN/A    uint64_t offs = xc->getSyscallArg(1);
16212SN/A    int whence = xc->getSyscallArg(2);
163360SN/A
164360SN/A    off_t result = lseek(fd, offs, whence);
165360SN/A
166443SN/A    return (result == (off_t)-1) ? -errno : result;
16712SN/A}
168443SN/A
169443SN/A
17012SN/ASyscallReturn
171468SN/AmunmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1721708SN/A{
1731708SN/A    // given that we don't really implement mmap, munmap is really easy
17412SN/A    return 0;
175468SN/A}
176443SN/A
177468SN/A
178443SN/Aconst char *hostname = "m5.eecs.umich.edu";
17912SN/A
180468SN/ASyscallReturn
181468SN/AgethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
182443SN/A{
18312SN/A    int name_len = xc->getSyscallArg(1);
18412SN/A    BufferArg name(xc->getSyscallArg(0), name_len);
185468SN/A
18612SN/A    strncpy((char *)name.bufferPtr(), hostname, name_len);
1872472SN/A
188468SN/A    name.copyOut(xc->mem);
189468SN/A
190468SN/A    return 0;
191468SN/A}
192468SN/A
193468SN/ASyscallReturn
194468SN/AunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
195468SN/A{
196468SN/A    std::string path;
197468SN/A
198468SN/A    if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
199468SN/A        return (TheISA::IntReg)-EFAULT;
200468SN/A
201468SN/A    int result = unlink(path.c_str());
202468SN/A    return (result == -1) ? -errno : result;
203468SN/A}
204468SN/A
205468SN/ASyscallReturn
2062420SN/ArenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
207468SN/A{
208468SN/A    std::string old_name;
209468SN/A
210468SN/A    if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault)
211468SN/A        return -EFAULT;
212468SN/A
2132420SN/A    std::string new_name;
2142476SN/A
215468SN/A    if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault)
216468SN/A        return -EFAULT;
2172420SN/A
218468SN/A    int64_t result = rename(old_name.c_str(),new_name.c_str());
219468SN/A    return (result == -1) ? -errno : result;
220468SN/A}
221468SN/A
222468SN/A