syscall_emul.cc revision 1458
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
1411308Santhony.gutierrez@amd.com * this software without specific prior written permission.
1511308Santhony.gutierrez@amd.com *
1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711308Santhony.gutierrez@amd.com */
2811308Santhony.gutierrez@amd.com
2911308Santhony.gutierrez@amd.com#include <unistd.h>
3011308Santhony.gutierrez@amd.com
3111308Santhony.gutierrez@amd.com#include <string>
3211308Santhony.gutierrez@amd.com#include <iostream>
3311308Santhony.gutierrez@amd.com
3411308Santhony.gutierrez@amd.com#include "sim/syscall_emul.hh"
3511308Santhony.gutierrez@amd.com#include "base/trace.hh"
3611308Santhony.gutierrez@amd.com#include "cpu/exec_context.hh"
3711308Santhony.gutierrez@amd.com#include "cpu/base_cpu.hh"
3811308Santhony.gutierrez@amd.com#include "sim/process.hh"
3911308Santhony.gutierrez@amd.com
4011308Santhony.gutierrez@amd.com#include "sim/sim_events.hh"
4111308Santhony.gutierrez@amd.com
4211308Santhony.gutierrez@amd.comusing namespace std;
4311308Santhony.gutierrez@amd.com
4411308Santhony.gutierrez@amd.comvoid
4511534Sjohn.kalamatianos@amd.comSyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
4611308Santhony.gutierrez@amd.com{
4711308Santhony.gutierrez@amd.com    DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
4811308Santhony.gutierrez@amd.com             xc->cpu->name(), name);
4911308Santhony.gutierrez@amd.com
5011308Santhony.gutierrez@amd.com    SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
5111308Santhony.gutierrez@amd.com
5211308Santhony.gutierrez@amd.com    DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
5311308Santhony.gutierrez@amd.com             xc->cpu->name(), name, retval.value());
5411308Santhony.gutierrez@amd.com
5511308Santhony.gutierrez@amd.com    if (!(flags & SyscallDesc::SuppressReturnValue))
5611308Santhony.gutierrez@amd.com        xc->setSyscallReturn(retval);
5711308Santhony.gutierrez@amd.com}
5811308Santhony.gutierrez@amd.com
5911308Santhony.gutierrez@amd.com
6011308Santhony.gutierrez@amd.comSyscallReturn
6111308Santhony.gutierrez@amd.comunimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
6211308Santhony.gutierrez@amd.com                  ExecContext *xc)
6311308Santhony.gutierrez@amd.com{
6411308Santhony.gutierrez@amd.com    cerr << "Error: syscall " << desc->name
6511308Santhony.gutierrez@amd.com         << " (#" << callnum << ") unimplemented.";
6611308Santhony.gutierrez@amd.com    cerr << "  Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1)
6711308Santhony.gutierrez@amd.com         << ", ..." << endl;
6811308Santhony.gutierrez@amd.com
6911308Santhony.gutierrez@amd.com    abort();
7011308Santhony.gutierrez@amd.com}
7111308Santhony.gutierrez@amd.com
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.comSyscallReturn
7411308Santhony.gutierrez@amd.comignoreFunc(SyscallDesc *desc, int callnum, Process *process,
7511308Santhony.gutierrez@amd.com           ExecContext *xc)
7611308Santhony.gutierrez@amd.com{
7711308Santhony.gutierrez@amd.com    DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name
7811308Santhony.gutierrez@amd.com                           << "(" << xc->getSyscallArg(0)
7911308Santhony.gutierrez@amd.com                           << ", " << xc->getSyscallArg(1)
8011308Santhony.gutierrez@amd.com                           << ", ...)" << endl;
8111308Santhony.gutierrez@amd.com
8211308Santhony.gutierrez@amd.com    return 0;
8311308Santhony.gutierrez@amd.com}
8411308Santhony.gutierrez@amd.com
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.comSyscallReturn
8711308Santhony.gutierrez@amd.comexitFunc(SyscallDesc *desc, int callnum, Process *process,
8811308Santhony.gutierrez@amd.com         ExecContext *xc)
8911308Santhony.gutierrez@amd.com{
9011308Santhony.gutierrez@amd.com    new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
9111308Santhony.gutierrez@amd.com
9211308Santhony.gutierrez@amd.com    return 1;
9311308Santhony.gutierrez@amd.com}
9411308Santhony.gutierrez@amd.com
9511308Santhony.gutierrez@amd.com
9611308Santhony.gutierrez@amd.comSyscallReturn
9711308Santhony.gutierrez@amd.comgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
9811308Santhony.gutierrez@amd.com{
9911308Santhony.gutierrez@amd.com    return VMPageSize;
10011308Santhony.gutierrez@amd.com}
10111308Santhony.gutierrez@amd.com
10211308Santhony.gutierrez@amd.com
10311308Santhony.gutierrez@amd.comSyscallReturn
10411308Santhony.gutierrez@amd.comobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
10511308Santhony.gutierrez@amd.com{
10611308Santhony.gutierrez@amd.com    // change brk addr to first arg
10711308Santhony.gutierrez@amd.com    Addr new_brk = xc->getSyscallArg(0);
10811308Santhony.gutierrez@amd.com    if (new_brk != 0)
10911308Santhony.gutierrez@amd.com    {
11011308Santhony.gutierrez@amd.com        p->brk_point = xc->getSyscallArg(0);
11111308Santhony.gutierrez@amd.com    }
11211308Santhony.gutierrez@amd.com    DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
11311308Santhony.gutierrez@amd.com    return p->brk_point;
11411308Santhony.gutierrez@amd.com}
11511308Santhony.gutierrez@amd.com
11611308Santhony.gutierrez@amd.com
11711308Santhony.gutierrez@amd.comSyscallReturn
11811308Santhony.gutierrez@amd.comcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
11911308Santhony.gutierrez@amd.com{
12011308Santhony.gutierrez@amd.com    int fd = p->sim_fd(xc->getSyscallArg(0));
12111308Santhony.gutierrez@amd.com    return close(fd);
12211308Santhony.gutierrez@amd.com}
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com
12511308Santhony.gutierrez@amd.comSyscallReturn
12611308Santhony.gutierrez@amd.comreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
12711308Santhony.gutierrez@amd.com{
12811308Santhony.gutierrez@amd.com    int fd = p->sim_fd(xc->getSyscallArg(0));
12911308Santhony.gutierrez@amd.com    int nbytes = xc->getSyscallArg(2);
13011308Santhony.gutierrez@amd.com    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.com    int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
13311308Santhony.gutierrez@amd.com
13411308Santhony.gutierrez@amd.com    if (bytes_read != -1)
13511308Santhony.gutierrez@amd.com        bufArg.copyOut(xc->mem);
13611308Santhony.gutierrez@amd.com
13711308Santhony.gutierrez@amd.com    return bytes_read;
13811308Santhony.gutierrez@amd.com}
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.comSyscallReturn
14111308Santhony.gutierrez@amd.comwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
14211308Santhony.gutierrez@amd.com{
14311308Santhony.gutierrez@amd.com    int fd = p->sim_fd(xc->getSyscallArg(0));
14411308Santhony.gutierrez@amd.com    int nbytes = xc->getSyscallArg(2);
14511308Santhony.gutierrez@amd.com    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
14611308Santhony.gutierrez@amd.com
14711308Santhony.gutierrez@amd.com    bufArg.copyIn(xc->mem);
14811308Santhony.gutierrez@amd.com
14911308Santhony.gutierrez@amd.com    int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com    fsync(fd);
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.com    return bytes_written;
15411308Santhony.gutierrez@amd.com}
15511308Santhony.gutierrez@amd.com
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.comSyscallReturn
15811308Santhony.gutierrez@amd.comlseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
15911308Santhony.gutierrez@amd.com{
16011308Santhony.gutierrez@amd.com    int fd = p->sim_fd(xc->getSyscallArg(0));
16111308Santhony.gutierrez@amd.com    uint64_t offs = xc->getSyscallArg(1);
16211308Santhony.gutierrez@amd.com    int whence = xc->getSyscallArg(2);
16311308Santhony.gutierrez@amd.com
16411308Santhony.gutierrez@amd.com    off_t result = lseek(fd, offs, whence);
16511308Santhony.gutierrez@amd.com
16611308Santhony.gutierrez@amd.com    return (result == (off_t)-1) ? -errno : result;
16711308Santhony.gutierrez@amd.com}
16811308Santhony.gutierrez@amd.com
16911308Santhony.gutierrez@amd.com
17011308Santhony.gutierrez@amd.comSyscallReturn
17111308Santhony.gutierrez@amd.communmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
17211308Santhony.gutierrez@amd.com{
17311308Santhony.gutierrez@amd.com    // given that we don't really implement mmap, munmap is really easy
17411308Santhony.gutierrez@amd.com    return 0;
17511308Santhony.gutierrez@amd.com}
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.com
17811308Santhony.gutierrez@amd.comconst char *hostname = "m5.eecs.umich.edu";
17911308Santhony.gutierrez@amd.com
18011308Santhony.gutierrez@amd.comSyscallReturn
18111308Santhony.gutierrez@amd.comgethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
18211308Santhony.gutierrez@amd.com{
18311308Santhony.gutierrez@amd.com    int name_len = xc->getSyscallArg(1);
18411308Santhony.gutierrez@amd.com    BufferArg name(xc->getSyscallArg(0), name_len);
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com    strncpy((char *)name.bufferPtr(), hostname, name_len);
18711308Santhony.gutierrez@amd.com
18811308Santhony.gutierrez@amd.com    name.copyOut(xc->mem);
18911308Santhony.gutierrez@amd.com
19011308Santhony.gutierrez@amd.com    return 0;
19111308Santhony.gutierrez@amd.com}
19211308Santhony.gutierrez@amd.com
19311308Santhony.gutierrez@amd.comSyscallReturn
19411308Santhony.gutierrez@amd.comunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
19511308Santhony.gutierrez@amd.com{
19611308Santhony.gutierrez@amd.com    std::string path;
19711308Santhony.gutierrez@amd.com
19811308Santhony.gutierrez@amd.com    if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
19911308Santhony.gutierrez@amd.com        return (TheISA::IntReg)-EFAULT;
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com    int result = unlink(path.c_str());
20211308Santhony.gutierrez@amd.com    return (result == -1) ? -errno : result;
20311308Santhony.gutierrez@amd.com}
20411308Santhony.gutierrez@amd.com
20511308Santhony.gutierrez@amd.comSyscallReturn
20611308Santhony.gutierrez@amd.comrenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
20711308Santhony.gutierrez@amd.com{
20811308Santhony.gutierrez@amd.com    std::string old_name;
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com    if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault)
21111308Santhony.gutierrez@amd.com        return -EFAULT;
21211308Santhony.gutierrez@amd.com
21311308Santhony.gutierrez@amd.com    std::string new_name;
21411308Santhony.gutierrez@amd.com
21511308Santhony.gutierrez@amd.com    if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault)
21611308Santhony.gutierrez@amd.com        return -EFAULT;
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com    int64_t result = rename(old_name.c_str(),new_name.c_str());
21911308Santhony.gutierrez@amd.com    return (result == -1) ? -errno : result;
22011308Santhony.gutierrez@amd.com}
22111308Santhony.gutierrez@amd.com
22211308Santhony.gutierrez@amd.com