2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "sim/syscall_emul.hh"
35 #include "base/trace.hh"
36 #include "cpu/exec_context.hh"
37 #include "cpu/base.hh"
38 #include "sim/process.hh"
40 #include "sim/sim_events.hh"
45 SyscallDesc::doSyscall(int callnum
, Process
*process
, ExecContext
*xc
)
47 DPRINTFR(SyscallVerbose
, "%s: syscall %s called\n",
48 xc
->cpu
->name(), name
);
50 SyscallReturn retval
= (*funcPtr
)(this, callnum
, process
, xc
);
52 DPRINTFR(SyscallVerbose
, "%s: syscall %s returns %d\n",
53 xc
->cpu
->name(), name
, retval
.value());
55 if (!(flags
& SyscallDesc::SuppressReturnValue
))
56 xc
->setSyscallReturn(retval
);
61 unimplementedFunc(SyscallDesc
*desc
, int callnum
, Process
*process
,
64 fatal("syscall %s (#%d) unimplemented.", desc
->name
, callnum
);
69 ignoreFunc(SyscallDesc
*desc
, int callnum
, Process
*process
,
72 warn("ignoring syscall %s(%d, %d, ...)", desc
->name
,
73 xc
->getSyscallArg(0), xc
->getSyscallArg(1));
80 exitFunc(SyscallDesc
*desc
, int callnum
, Process
*process
,
83 new SimExitEvent("syscall caused exit", xc
->getSyscallArg(0) & 0xff);
90 getpagesizeFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
97 obreakFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
99 // change brk addr to first arg
100 Addr new_brk
= xc
->getSyscallArg(0);
103 p
->brk_point
= xc
->getSyscallArg(0);
105 DPRINTF(SyscallVerbose
, "Break Point changed to: %#X\n", p
->brk_point
);
111 closeFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
113 int target_fd
= xc
->getSyscallArg(0);
114 int status
= close(p
->sim_fd(target_fd
));
116 p
->free_fd(target_fd
);
122 readFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
124 int fd
= p
->sim_fd(xc
->getSyscallArg(0));
125 int nbytes
= xc
->getSyscallArg(2);
126 BufferArg
bufArg(xc
->getSyscallArg(1), nbytes
);
128 int bytes_read
= read(fd
, bufArg
.bufferPtr(), nbytes
);
130 if (bytes_read
!= -1)
131 bufArg
.copyOut(xc
->mem
);
137 writeFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
139 int fd
= p
->sim_fd(xc
->getSyscallArg(0));
140 int nbytes
= xc
->getSyscallArg(2);
141 BufferArg
bufArg(xc
->getSyscallArg(1), nbytes
);
143 bufArg
.copyIn(xc
->mem
);
145 int bytes_written
= write(fd
, bufArg
.bufferPtr(), nbytes
);
149 return bytes_written
;
154 lseekFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
156 int fd
= p
->sim_fd(xc
->getSyscallArg(0));
157 uint64_t offs
= xc
->getSyscallArg(1);
158 int whence
= xc
->getSyscallArg(2);
160 off_t result
= lseek(fd
, offs
, whence
);
162 return (result
== (off_t
)-1) ? -errno
: result
;
167 munmapFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
169 // given that we don't really implement mmap, munmap is really easy
174 const char *hostname
= "m5.eecs.umich.edu";
177 gethostnameFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
179 int name_len
= xc
->getSyscallArg(1);
180 BufferArg
name(xc
->getSyscallArg(0), name_len
);
182 strncpy((char *)name
.bufferPtr(), hostname
, name_len
);
184 name
.copyOut(xc
->mem
);
190 unlinkFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
194 if (xc
->mem
->readString(path
, xc
->getSyscallArg(0)) != No_Fault
)
195 return (TheISA::IntReg
)-EFAULT
;
197 int result
= unlink(path
.c_str());
198 return (result
== -1) ? -errno
: result
;
202 renameFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
206 if (xc
->mem
->readString(old_name
, xc
->getSyscallArg(0)) != No_Fault
)
211 if (xc
->mem
->readString(new_name
, xc
->getSyscallArg(1)) != No_Fault
)
214 int64_t result
= rename(old_name
.c_str(), new_name
.c_str());
215 return (result
== -1) ? -errno
: result
;
219 truncateFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
223 if (xc
->mem
->readString(path
, xc
->getSyscallArg(0)) != No_Fault
)
226 off_t length
= xc
->getSyscallArg(1);
228 int result
= truncate(path
.c_str(), length
);
229 return (result
== -1) ? -errno
: result
;
233 ftruncateFunc(SyscallDesc
*desc
, int num
, Process
*process
, ExecContext
*xc
)
235 int fd
= process
->sim_fd(xc
->getSyscallArg(0));
240 off_t length
= xc
->getSyscallArg(1);
242 int result
= ftruncate(fd
, length
);
243 return (result
== -1) ? -errno
: result
;
247 chownFunc(SyscallDesc
*desc
, int num
, Process
*p
, ExecContext
*xc
)
251 if (xc
->mem
->readString(path
, xc
->getSyscallArg(0)) != No_Fault
)
255 uint32_t owner
= xc
->getSyscallArg(1);
256 uid_t hostOwner
= owner
;
257 uint32_t group
= xc
->getSyscallArg(2);
258 gid_t hostGroup
= group
;
260 int result
= chown(path
.c_str(), hostOwner
, hostGroup
);
261 return (result
== -1) ? -errno
: result
;
265 fchownFunc(SyscallDesc
*desc
, int num
, Process
*process
, ExecContext
*xc
)
267 int fd
= process
->sim_fd(xc
->getSyscallArg(0));
273 uint32_t owner
= xc
->getSyscallArg(1);
274 uid_t hostOwner
= owner
;
275 uint32_t group
= xc
->getSyscallArg(2);
276 gid_t hostGroup
= group
;
278 int result
= fchown(fd
, hostOwner
, hostGroup
);
279 return (result
== -1) ? -errno
: result
;