syscall_emul.cc revision 1458
1360SN/A/*
21458SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/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.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#include <unistd.h>
30360SN/A
31360SN/A#include <string>
3211793Sbrandon.potter@amd.com#include <iostream>
3311793Sbrandon.potter@amd.com
342093SN/A#include "sim/syscall_emul.hh"
35360SN/A#include "base/trace.hh"
36360SN/A#include "cpu/exec_context.hh"
376712Snate@binkert.org#include "cpu/base_cpu.hh"
38360SN/A#include "sim/process.hh"
39360SN/A
407680Sgblack@eecs.umich.edu#include "sim/sim_events.hh"
412474SN/A
42360SN/Ausing namespace std;
436658Snate@binkert.org
442680Sktlim@umich.eduvoid
452474SN/ASyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
46360SN/A{
478229Snate@binkert.org    DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
4811794Sbrandon.potter@amd.com             xc->cpu->name(), name);
4911794Sbrandon.potter@amd.com
506029Ssteve.reinhardt@amd.com    SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
51360SN/A
52360SN/A    DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
532107SN/A             xc->cpu->name(), name, retval.value());
54360SN/A
551450SN/A    if (!(flags & SyscallDesc::SuppressReturnValue))
5611851Sbrandon.potter@amd.com        xc->setSyscallReturn(retval);
572680Sktlim@umich.edu}
58360SN/A
5911794Sbrandon.potter@amd.com
602484SN/ASyscallReturn
612484SN/AunimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
62360SN/A                  ExecContext *xc)
63360SN/A{
64360SN/A    cerr << "Error: syscall " << desc->name
651450SN/A         << " (#" << callnum << ") unimplemented.";
6611851Sbrandon.potter@amd.com    cerr << "  Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1)
672680Sktlim@umich.edu         << ", ..." << endl;
68360SN/A
6911794Sbrandon.potter@amd.com    abort();
7011794Sbrandon.potter@amd.com}
7111794Sbrandon.potter@amd.com
7210831Ssteve.reinhardt@amd.com
73360SN/ASyscallReturn
748149SChris.Emmons@ARM.comignoreFunc(SyscallDesc *desc, int callnum, Process *process,
758149SChris.Emmons@ARM.com           ExecContext *xc)
768149SChris.Emmons@ARM.com{
778149SChris.Emmons@ARM.com    DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name
788149SChris.Emmons@ARM.com                           << "(" << xc->getSyscallArg(0)
7911851Sbrandon.potter@amd.com                           << ", " << xc->getSyscallArg(1)
802680Sktlim@umich.edu                           << ", ...)" << endl;
81360SN/A
826029Ssteve.reinhardt@amd.com    return 0;
836029Ssteve.reinhardt@amd.com}
846701Sgblack@eecs.umich.edu
855958Sgblack@eecs.umich.edu
866701Sgblack@eecs.umich.eduSyscallReturn
876029Ssteve.reinhardt@amd.comexitFunc(SyscallDesc *desc, int callnum, Process *process,
886029Ssteve.reinhardt@amd.com         ExecContext *xc)
896029Ssteve.reinhardt@amd.com{
902834Sksewell@umich.edu    new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
91360SN/A
921458SN/A    return 1;
93360SN/A}
94360SN/A
95360SN/A
961450SN/ASyscallReturn
9711851Sbrandon.potter@amd.comgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
986109Ssanchezd@stanford.edu{
996109Ssanchezd@stanford.edu    return VMPageSize;
10010483Swiseveri@student.ethz.ch}
10110483Swiseveri@student.ethz.ch
10210483Swiseveri@student.ethz.ch
10310483Swiseveri@student.ethz.chSyscallReturn
10410483Swiseveri@student.ethz.chobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
10510483Swiseveri@student.ethz.ch{
10610483Swiseveri@student.ethz.ch    // change brk addr to first arg
10710483Swiseveri@student.ethz.ch    Addr new_brk = xc->getSyscallArg(0);
10810483Swiseveri@student.ethz.ch    if (new_brk != 0)
10910483Swiseveri@student.ethz.ch    {
11010483Swiseveri@student.ethz.ch        p->brk_point = xc->getSyscallArg(0);
1116109Ssanchezd@stanford.edu    }
1126109Ssanchezd@stanford.edu    DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
1136109Ssanchezd@stanford.edu    return p->brk_point;
1146109Ssanchezd@stanford.edu}
1156109Ssanchezd@stanford.edu
1166109Ssanchezd@stanford.edu
11711851Sbrandon.potter@amd.comSyscallReturn
118360SN/AcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
11910318Sandreas.hansson@arm.com{
120360SN/A    int fd = p->sim_fd(xc->getSyscallArg(0));
121360SN/A    return close(fd);
122360SN/A}
1231450SN/A
12411851Sbrandon.potter@amd.com
125360SN/ASyscallReturn
126360SN/AreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1276701Sgblack@eecs.umich.edu{
1286701Sgblack@eecs.umich.edu    int fd = p->sim_fd(xc->getSyscallArg(0));
1295748SSteve.Reinhardt@amd.com    int nbytes = xc->getSyscallArg(2);
1305748SSteve.Reinhardt@amd.com    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
1315748SSteve.Reinhardt@amd.com
1325748SSteve.Reinhardt@amd.com    int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
1335748SSteve.Reinhardt@amd.com
1345748SSteve.Reinhardt@amd.com    if (bytes_read != -1)
1355748SSteve.Reinhardt@amd.com        bufArg.copyOut(xc->mem);
1365748SSteve.Reinhardt@amd.com
1372474SN/A    return bytes_read;
13810318Sandreas.hansson@arm.com}
1395748SSteve.Reinhardt@amd.com
14010318Sandreas.hansson@arm.comSyscallReturn
1416687Stjones1@inf.ed.ac.ukwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1426687Stjones1@inf.ed.ac.uk{
1436687Stjones1@inf.ed.ac.uk    int fd = p->sim_fd(xc->getSyscallArg(0));
1446687Stjones1@inf.ed.ac.uk    int nbytes = xc->getSyscallArg(2);
1458852Sandreas.hansson@arm.com    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
1466687Stjones1@inf.ed.ac.uk
1476687Stjones1@inf.ed.ac.uk    bufArg.copyIn(xc->mem);
14810318Sandreas.hansson@arm.com
1496687Stjones1@inf.ed.ac.uk    int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
1508852Sandreas.hansson@arm.com
15110318Sandreas.hansson@arm.com    fsync(fd);
1526687Stjones1@inf.ed.ac.uk
1536687Stjones1@inf.ed.ac.uk    return bytes_written;
1546687Stjones1@inf.ed.ac.uk}
15510318Sandreas.hansson@arm.com
1568852Sandreas.hansson@arm.com
1576687Stjones1@inf.ed.ac.ukSyscallReturn
1586687Stjones1@inf.ed.ac.uklseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1592474SN/A{
1601450SN/A    int fd = p->sim_fd(xc->getSyscallArg(0));
1615748SSteve.Reinhardt@amd.com    uint64_t offs = xc->getSyscallArg(1);
1625748SSteve.Reinhardt@amd.com    int whence = xc->getSyscallArg(2);
16311380Salexandru.dutu@amd.com
16411380Salexandru.dutu@amd.com    off_t result = lseek(fd, offs, whence);
1651458SN/A
166360SN/A    return (result == (off_t)-1) ? -errno : result;
167360SN/A}
168360SN/A
1691450SN/A
17011851Sbrandon.potter@amd.comSyscallReturn
171360SN/AmunmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1726701Sgblack@eecs.umich.edu{
17310931Sbrandon.potter@amd.com    // given that we don't really implement mmap, munmap is really easy
17410931Sbrandon.potter@amd.com    return 0;
17511856Sbrandon.potter@amd.com}
176360SN/A
177360SN/A
178360SN/Aconst char *hostname = "m5.eecs.umich.edu";
1791450SN/A
18011851Sbrandon.potter@amd.comSyscallReturn
181360SN/AgethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
1826701Sgblack@eecs.umich.edu{
18310931Sbrandon.potter@amd.com    int name_len = xc->getSyscallArg(1);
1846701Sgblack@eecs.umich.edu    BufferArg name(xc->getSyscallArg(0), name_len);
1856701Sgblack@eecs.umich.edu
18611856Sbrandon.potter@amd.com    strncpy((char *)name.bufferPtr(), hostname, name_len);
18711856Sbrandon.potter@amd.com
18811856Sbrandon.potter@amd.com    name.copyOut(xc->mem);
18911856Sbrandon.potter@amd.com
19011856Sbrandon.potter@amd.com    return 0;
19111856Sbrandon.potter@amd.com}
1926701Sgblack@eecs.umich.edu
19310931Sbrandon.potter@amd.comSyscallReturn
194360SN/AunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
19511684Snderumigny@gmail.com{
1968706Sandreas.hansson@arm.com    std::string path;
197360SN/A
1981458SN/A    if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
199360SN/A        return (TheISA::IntReg)-EFAULT;
200360SN/A
2011450SN/A    int result = unlink(path.c_str());
20211851Sbrandon.potter@amd.com    return (result == -1) ? -errno : result;
203360SN/A}
2046701Sgblack@eecs.umich.edu
20510931Sbrandon.potter@amd.comSyscallReturn
2066701Sgblack@eecs.umich.edurenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
2076701Sgblack@eecs.umich.edu{
20811856Sbrandon.potter@amd.com    std::string old_name;
20911856Sbrandon.potter@amd.com
21011856Sbrandon.potter@amd.com    if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault)
21111856Sbrandon.potter@amd.com        return -EFAULT;
21211856Sbrandon.potter@amd.com
21311856Sbrandon.potter@amd.com    std::string new_name;
2146701Sgblack@eecs.umich.edu
2158706Sandreas.hansson@arm.com    if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault)
216360SN/A        return -EFAULT;
21710931Sbrandon.potter@amd.com
218360SN/A    int64_t result = rename(old_name.c_str(),new_name.c_str());
21910931Sbrandon.potter@amd.com    return (result == -1) ? -errno : result;
220360SN/A}
2211458SN/A
222360SN/A