Get rid of the xc from the alphaAccess/alphaConsole backdoor device.
[gem5.git] / sim / syscall_emul.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 */
28
29 #include <unistd.h>
30
31 #include <string>
32 #include <iostream>
33
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"
39
40 #include "sim/sim_events.hh"
41
42 using namespace std;
43
44 void
45 SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
46 {
47 DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
48 xc->cpu->name(), name);
49
50 SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
51
52 DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
53 xc->cpu->name(), name, retval.value());
54
55 if (!(flags & SyscallDesc::SuppressReturnValue))
56 xc->setSyscallReturn(retval);
57 }
58
59
60 SyscallReturn
61 unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
62 ExecContext *xc)
63 {
64 fatal("syscall %s (#%d) unimplemented.", desc->name, callnum);
65 }
66
67
68 SyscallReturn
69 ignoreFunc(SyscallDesc *desc, int callnum, Process *process,
70 ExecContext *xc)
71 {
72 warn("ignoring syscall %s(%d, %d, ...)", desc->name,
73 xc->getSyscallArg(0), xc->getSyscallArg(1));
74
75 return 0;
76 }
77
78
79 SyscallReturn
80 exitFunc(SyscallDesc *desc, int callnum, Process *process,
81 ExecContext *xc)
82 {
83 new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff);
84
85 return 1;
86 }
87
88
89 SyscallReturn
90 getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
91 {
92 return VMPageSize;
93 }
94
95
96 SyscallReturn
97 obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
98 {
99 // change brk addr to first arg
100 Addr new_brk = xc->getSyscallArg(0);
101 if (new_brk != 0)
102 {
103 p->brk_point = xc->getSyscallArg(0);
104 }
105 DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
106 return p->brk_point;
107 }
108
109
110 SyscallReturn
111 closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
112 {
113 int target_fd = xc->getSyscallArg(0);
114 int status = close(p->sim_fd(target_fd));
115 if (status >= 0)
116 p->free_fd(target_fd);
117 return status;
118 }
119
120
121 SyscallReturn
122 readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
123 {
124 int fd = p->sim_fd(xc->getSyscallArg(0));
125 int nbytes = xc->getSyscallArg(2);
126 BufferArg bufArg(xc->getSyscallArg(1), nbytes);
127
128 int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
129
130 if (bytes_read != -1)
131 bufArg.copyOut(xc->mem);
132
133 return bytes_read;
134 }
135
136 SyscallReturn
137 writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
138 {
139 int fd = p->sim_fd(xc->getSyscallArg(0));
140 int nbytes = xc->getSyscallArg(2);
141 BufferArg bufArg(xc->getSyscallArg(1), nbytes);
142
143 bufArg.copyIn(xc->mem);
144
145 int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
146
147 fsync(fd);
148
149 return bytes_written;
150 }
151
152
153 SyscallReturn
154 lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
155 {
156 int fd = p->sim_fd(xc->getSyscallArg(0));
157 uint64_t offs = xc->getSyscallArg(1);
158 int whence = xc->getSyscallArg(2);
159
160 off_t result = lseek(fd, offs, whence);
161
162 return (result == (off_t)-1) ? -errno : result;
163 }
164
165
166 SyscallReturn
167 munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
168 {
169 // given that we don't really implement mmap, munmap is really easy
170 return 0;
171 }
172
173
174 const char *hostname = "m5.eecs.umich.edu";
175
176 SyscallReturn
177 gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
178 {
179 int name_len = xc->getSyscallArg(1);
180 BufferArg name(xc->getSyscallArg(0), name_len);
181
182 strncpy((char *)name.bufferPtr(), hostname, name_len);
183
184 name.copyOut(xc->mem);
185
186 return 0;
187 }
188
189 SyscallReturn
190 unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
191 {
192 string path;
193
194 if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
195 return (TheISA::IntReg)-EFAULT;
196
197 int result = unlink(path.c_str());
198 return (result == -1) ? -errno : result;
199 }
200
201 SyscallReturn
202 renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
203 {
204 string old_name;
205
206 if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault)
207 return -EFAULT;
208
209 string new_name;
210
211 if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault)
212 return -EFAULT;
213
214 int64_t result = rename(old_name.c_str(), new_name.c_str());
215 return (result == -1) ? -errno : result;
216 }
217
218 SyscallReturn
219 truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
220 {
221 string path;
222
223 if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
224 return -EFAULT;
225
226 off_t length = xc->getSyscallArg(1);
227
228 int result = truncate(path.c_str(), length);
229 return (result == -1) ? -errno : result;
230 }
231
232 SyscallReturn
233 ftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
234 {
235 int fd = process->sim_fd(xc->getSyscallArg(0));
236
237 if (fd < 0)
238 return -EBADF;
239
240 off_t length = xc->getSyscallArg(1);
241
242 int result = ftruncate(fd, length);
243 return (result == -1) ? -errno : result;
244 }
245
246 SyscallReturn
247 chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
248 {
249 string path;
250
251 if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
252 return -EFAULT;
253
254 /* XXX endianess */
255 uint32_t owner = xc->getSyscallArg(1);
256 uid_t hostOwner = owner;
257 uint32_t group = xc->getSyscallArg(2);
258 gid_t hostGroup = group;
259
260 int result = chown(path.c_str(), hostOwner, hostGroup);
261 return (result == -1) ? -errno : result;
262 }
263
264 SyscallReturn
265 fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
266 {
267 int fd = process->sim_fd(xc->getSyscallArg(0));
268
269 if (fd < 0)
270 return -EBADF;
271
272 /* XXX endianess */
273 uint32_t owner = xc->getSyscallArg(1);
274 uid_t hostOwner = owner;
275 uint32_t group = xc->getSyscallArg(2);
276 gid_t hostGroup = group;
277
278 int result = fchown(fd, hostOwner, hostGroup);
279 return (result == -1) ? -errno : result;
280 }