syscall_emul.cc revision 1706
15222Sksewell@umich.edu/*
25222Sksewell@umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
35222Sksewell@umich.edu * All rights reserved.
45222Sksewell@umich.edu *
55222Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
65222Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75222Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95222Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115222Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125222Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135222Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145222Sksewell@umich.edu * this software without specific prior written permission.
155222Sksewell@umich.edu *
165222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175222Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185222Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195222Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205222Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215222Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225222Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235222Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245222Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255222Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265222Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275222Sksewell@umich.edu */
285222Sksewell@umich.edu
295222Sksewell@umich.edu#include <unistd.h>
305222Sksewell@umich.edu
315222Sksewell@umich.edu#include <string>
325222Sksewell@umich.edu#include <iostream>
335222Sksewell@umich.edu
345222Sksewell@umich.edu#include "sim/syscall_emul.hh"
355222Sksewell@umich.edu#include "base/trace.hh"
365222Sksewell@umich.edu#include "cpu/exec_context.hh"
375222Sksewell@umich.edu#include "cpu/base_cpu.hh"
385222Sksewell@umich.edu#include "sim/process.hh"
395222Sksewell@umich.edu
405222Sksewell@umich.edu#include "sim/sim_events.hh"
415222Sksewell@umich.edu
425222Sksewell@umich.eduusing namespace std;
435222Sksewell@umich.edu
445222Sksewell@umich.eduvoid
455222Sksewell@umich.eduSyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
465222Sksewell@umich.edu{
475222Sksewell@umich.edu    DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
485222Sksewell@umich.edu             xc->cpu->name(), name);
495222Sksewell@umich.edu
505222Sksewell@umich.edu    SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
515222Sksewell@umich.edu
525222Sksewell@umich.edu    DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
535222Sksewell@umich.edu             xc->cpu->name(), name, retval.value());
545222Sksewell@umich.edu
555222Sksewell@umich.edu    if (!(flags & SyscallDesc::SuppressReturnValue))
565222Sksewell@umich.edu        xc->setSyscallReturn(retval);
575222Sksewell@umich.edu}
585222Sksewell@umich.edu
595222Sksewell@umich.edu
605222Sksewell@umich.eduSyscallReturn
615222Sksewell@umich.eduunimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
625222Sksewell@umich.edu                  ExecContext *xc)
635222Sksewell@umich.edu{
645222Sksewell@umich.edu    cerr << "Error: syscall " << desc->name
655222Sksewell@umich.edu         << " (#" << callnum << ") unimplemented.";
665222Sksewell@umich.edu    cerr << "  Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1)
675222Sksewell@umich.edu         << ", ..." << endl;
685222Sksewell@umich.edu
695222Sksewell@umich.edu    abort();
705222Sksewell@umich.edu}
715222Sksewell@umich.edu
725222Sksewell@umich.edu
735222Sksewell@umich.eduSyscallReturn
745222Sksewell@umich.eduignoreFunc(SyscallDesc *desc, int callnum, Process *process,
755222Sksewell@umich.edu           ExecContext *xc)
765222Sksewell@umich.edu{
775222Sksewell@umich.edu    DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name
785222Sksewell@umich.edu                           << "(" << xc->getSyscallArg(0)
795222Sksewell@umich.edu                           << ", " << xc->getSyscallArg(1)
805222Sksewell@umich.edu                           << ", ...)" << endl;
815222Sksewell@umich.edu
825222Sksewell@umich.edu    return 0;
835222Sksewell@umich.edu}
845222Sksewell@umich.edu
855222Sksewell@umich.edu
865222Sksewell@umich.eduSyscallReturn
875222Sksewell@umich.eduexitFunc(SyscallDesc *desc, int callnum, Process *process,
885222Sksewell@umich.edu         ExecContext *xc)
895222Sksewell@umich.edu{
905222Sksewell@umich.edu    new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
915222Sksewell@umich.edu
925222Sksewell@umich.edu    return 1;
935222Sksewell@umich.edu}
945222Sksewell@umich.edu
955222Sksewell@umich.edu
965222Sksewell@umich.eduSyscallReturn
975222Sksewell@umich.edugetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
985222Sksewell@umich.edu{
995222Sksewell@umich.edu    return VMPageSize;
1005222Sksewell@umich.edu}
1015222Sksewell@umich.edu
1025222Sksewell@umich.edu
103SyscallReturn
104obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
105{
106    // change brk addr to first arg
107    Addr new_brk = xc->getSyscallArg(0);
108    if (new_brk != 0)
109    {
110        p->brk_point = xc->getSyscallArg(0);
111    }
112    DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
113    return p->brk_point;
114}
115
116
117SyscallReturn
118closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
119{
120    int fd = p->sim_fd(xc->getSyscallArg(0));
121    return close(fd);
122}
123
124
125SyscallReturn
126readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
127{
128    int fd = p->sim_fd(xc->getSyscallArg(0));
129    int nbytes = xc->getSyscallArg(2);
130    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
131
132    int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
133
134    if (bytes_read != -1)
135        bufArg.copyOut(xc->mem);
136
137    return bytes_read;
138}
139
140SyscallReturn
141writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
142{
143    int fd = p->sim_fd(xc->getSyscallArg(0));
144    int nbytes = xc->getSyscallArg(2);
145    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
146
147    bufArg.copyIn(xc->mem);
148
149    int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
150
151    fsync(fd);
152
153    return bytes_written;
154}
155
156
157SyscallReturn
158lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
159{
160    int fd = p->sim_fd(xc->getSyscallArg(0));
161    uint64_t offs = xc->getSyscallArg(1);
162    int whence = xc->getSyscallArg(2);
163
164    off_t result = lseek(fd, offs, whence);
165
166    return (result == (off_t)-1) ? -errno : result;
167}
168
169
170SyscallReturn
171munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
172{
173    // given that we don't really implement mmap, munmap is really easy
174    return 0;
175}
176
177
178const char *hostname = "m5.eecs.umich.edu";
179
180SyscallReturn
181gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
182{
183    int name_len = xc->getSyscallArg(1);
184    BufferArg name(xc->getSyscallArg(0), name_len);
185
186    strncpy((char *)name.bufferPtr(), hostname, name_len);
187
188    name.copyOut(xc->mem);
189
190    return 0;
191}
192
193SyscallReturn
194unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
195{
196    string path;
197
198    if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
199        return (TheISA::IntReg)-EFAULT;
200
201    int result = unlink(path.c_str());
202    return (result == -1) ? -errno : result;
203}
204
205SyscallReturn
206renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
207{
208    string old_name;
209
210    if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault)
211        return -EFAULT;
212
213    string new_name;
214
215    if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault)
216        return -EFAULT;
217
218    int64_t result = rename(old_name.c_str(), new_name.c_str());
219    return (result == -1) ? -errno : result;
220}
221
222SyscallReturn
223truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
224{
225    string path;
226
227    if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
228        return -EFAULT;
229
230    off_t length = xc->getSyscallArg(1);
231
232    int result = truncate(path.c_str(), length);
233    return (result == -1) ? -errno : result;
234}
235
236SyscallReturn
237ftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
238{
239    int fd = process->sim_fd(xc->getSyscallArg(0));
240
241    if (fd < 0)
242        return -EBADF;
243
244    off_t length = xc->getSyscallArg(1);
245
246    int result = ftruncate(fd, length);
247    return (result == -1) ? -errno : result;
248}
249