arch,sim: Replace setuidFunc with ignoreFunc.
[gem5.git] / src / arch / power / linux / process.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * Copyright (c) 2007-2008 The Florida State University
4 * Copyright (c) 2009 The University of Edinburgh
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met: redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution;
14 * neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Authors: Korey Sewell
31 * Stephen Hines
32 * Timothy M. Jones
33 */
34
35 #include "arch/power/linux/process.hh"
36
37 #include "arch/power/isa_traits.hh"
38 #include "arch/power/linux/linux.hh"
39 #include "base/loader/object_file.hh"
40 #include "base/trace.hh"
41 #include "cpu/thread_context.hh"
42 #include "kern/linux/linux.hh"
43 #include "sim/process.hh"
44 #include "sim/syscall_desc.hh"
45 #include "sim/syscall_emul.hh"
46 #include "sim/system.hh"
47
48 using namespace std;
49 using namespace PowerISA;
50
51 namespace
52 {
53
54 class PowerLinuxObjectFileLoader : public Process::Loader
55 {
56 public:
57 Process *
58 load(ProcessParams *params, ObjectFile *obj_file) override
59 {
60 if (obj_file->getArch() != ObjectFile::Power)
61 return nullptr;
62
63 auto opsys = obj_file->getOpSys();
64
65 if (opsys == ObjectFile::UnknownOpSys) {
66 warn("Unknown operating system; assuming Linux.");
67 opsys = ObjectFile::Linux;
68 }
69
70 if (opsys != ObjectFile::Linux)
71 return nullptr;
72
73 return new PowerLinuxProcess(params, obj_file);
74 }
75 };
76
77 PowerLinuxObjectFileLoader loader;
78
79 } // anonymous namespace
80
81 /// Target uname() handler.
82 static SyscallReturn
83 unameFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
84 {
85 int index = 0;
86 auto process = tc->getProcessPtr();
87 TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
88
89 strcpy(name->sysname, "Linux");
90 strcpy(name->nodename, "sim.gem5.org");
91 strcpy(name->release, process->release.c_str());
92 strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
93 strcpy(name->machine, "power");
94
95 name.copyOut(tc->getVirtProxy());
96 return 0;
97 }
98
99 SyscallDescABI<DefaultSyscallABI> PowerLinuxProcess::syscallDescs[] = {
100 /* 0 */ { "syscall" },
101 /* 1 */ { "exit", exitFunc },
102 /* 2 */ { "fork" },
103 /* 3 */ { "read", readFunc<PowerLinux> },
104 /* 4 */ { "write", writeFunc<PowerLinux> },
105 /* 5 */ { "open", openFunc<PowerLinux> },
106 /* 6 */ { "close", closeFunc },
107 /* 7 */ { "waitpid" }, //???
108 /* 8 */ { "creat" },
109 /* 9 */ { "link" },
110 /* 10 */ { "unlink", unlinkFunc },
111 /* 11 */ { "execve" },
112 /* 12 */ { "chdir" },
113 /* 13 */ { "time", timeFunc<PowerLinux> },
114 /* 14 */ { "mknod" },
115 /* 15 */ { "chmod", chmodFunc<PowerLinux> },
116 /* 16 */ { "lchown", chownFunc },
117 /* 17 */ { "break", brkFunc }, //???
118 /* 18 */ { "unused#18" }, //???
119 /* 19 */ { "lseek", lseekFunc },
120 /* 20 */ { "getpid", getpidFunc },
121 /* 21 */ { "mount" },
122 /* 22 */ { "umount" },
123 /* 23 */ { "setuid", ignoreFunc },
124 /* 24 */ { "getuid", getuidFunc },
125 /* 25 */ { "stime" },
126 /* 26 */ { "ptrace" },
127 /* 27 */ { "alarm" },
128 /* 28 */ { "unused#28" },
129 /* 29 */ { "pause" },
130 /* 30 */ { "utime" },
131 /* 31 */ { "stty" },
132 /* 32 */ { "gtty" },
133 /* 33 */ { "access" },
134 /* 34 */ { "nice" },
135 /* 35 */ { "ftime" },
136 /* 36 */ { "sync" },
137 /* 37 */ { "kill", ignoreFunc },
138 /* 38 */ { "rename", renameFunc },
139 /* 39 */ { "mkdir" },
140 /* 40 */ { "rmdir" },
141 /* 41 */ { "dup", dupFunc },
142 /* 42 */ { "pipe" },
143 /* 43 */ { "times", timesFunc<PowerLinux> },
144 /* 44 */ { "prof" },
145 /* 45 */ { "brk", brkFunc },
146 /* 46 */ { "setgid" },
147 /* 47 */ { "getgid", getgidFunc },
148 /* 48 */ { "signal", ignoreFunc },
149 /* 49 */ { "geteuid", geteuidFunc },
150 /* 50 */ { "getegid", getegidFunc },
151 /* 51 */ { "acct" },
152 /* 52 */ { "umount2" },
153 /* 53 */ { "lock" },
154 /* 54 */ { "ioctl", ioctlFunc<PowerLinux> },
155 /* 55 */ { "fcntl", fcntlFunc },
156 /* 56 */ { "mpx" },
157 /* 57 */ { "setpgid" },
158 /* 58 */ { "ulimit" },
159 /* 59 */ { "unused#59" },
160 /* 60 */ { "umask", umaskFunc },
161 /* 61 */ { "chroot" },
162 /* 62 */ { "ustat" },
163 /* 63 */ { "dup2" },
164 /* 64 */ { "getppid", getpagesizeFunc },
165 /* 65 */ { "getpgrp" },
166 /* 66 */ { "setsid" },
167 /* 67 */ { "sigaction" },
168 /* 68 */ { "sgetmask" },
169 /* 69 */ { "ssetmask" },
170 /* 70 */ { "setreuid" },
171 /* 71 */ { "setregid" },
172 /* 72 */ { "sigsuspend" },
173 /* 73 */ { "sigpending" },
174 /* 74 */ { "sethostname", ignoreFunc },
175 /* 75 */ { "setrlimit", ignoreFunc },
176 /* 76 */ { "getrlimit" },
177 /* 77 */ { "getrusage", ignoreFunc },
178 /* 78 */ { "gettimeofday" },
179 /* 79 */ { "settimeofday" },
180 /* 80 */ { "getgroups" },
181 /* 81 */ { "setgroups" },
182 /* 82 */ { "reserved#82" },
183 /* 83 */ { "symlink" },
184 /* 84 */ { "unused#84" },
185 /* 85 */ { "readlink" },
186 /* 86 */ { "uselib" },
187 /* 87 */ { "swapon", gethostnameFunc },
188 /* 88 */ { "reboot" },
189 /* 89 */ { "readdir" },
190 /* 90 */ { "mmap", mmapFunc<PowerLinux> },
191 /* 91 */ { "munmap",munmapFunc },
192 /* 92 */ { "truncate", truncateFunc },
193 /* 93 */ { "ftruncate", ftruncateFunc },
194 /* 94 */ { "fchmod" },
195 /* 95 */ { "fchown" },
196 /* 96 */ { "getpriority" },
197 /* 97 */ { "setpriority" },
198 /* 98 */ { "profil" },
199 /* 99 */ { "statfs" },
200 /* 100 */ { "fstatfs" },
201 /* 101 */ { "ioperm" },
202 /* 102 */ { "socketcall" },
203 /* 103 */ { "syslog" },
204 /* 104 */ { "setitimer" },
205 /* 105 */ { "getitimer" },
206 /* 106 */ { "stat", statFunc<PowerLinux> },
207 /* 107 */ { "lstat" },
208 /* 108 */ { "fstat", fstatFunc<PowerLinux> },
209 /* 109 */ { "unused#109" },
210 /* 110 */ { "iopl" },
211 /* 111 */ { "vhangup" },
212 /* 112 */ { "idle", ignoreFunc },
213 /* 113 */ { "vm86" },
214 /* 114 */ { "wait4" },
215 /* 115 */ { "swapoff" },
216 /* 116 */ { "sysinfo" },
217 /* 117 */ { "ipc" },
218 /* 118 */ { "fsync" },
219 /* 119 */ { "sigreturn" },
220 /* 120 */ { "clone" },
221 /* 121 */ { "setdomainname" },
222 /* 122 */ { "uname", unameFunc },
223 /* 123 */ { "modify_ldt" },
224 /* 124 */ { "adjtimex" },
225 /* 125 */ { "mprotect", ignoreFunc },
226 /* 126 */ { "sigprocmask" },
227 /* 127 */ { "create_module" },
228 /* 128 */ { "init_module" },
229 /* 129 */ { "delete_module" },
230 /* 130 */ { "get_kernel_syms" },
231 /* 131 */ { "quotactl" },
232 /* 132 */ { "getpgid" },
233 /* 133 */ { "fchdir" },
234 /* 134 */ { "bdflush" },
235 /* 135 */ { "sysfs" },
236 /* 136 */ { "personality" },
237 /* 137 */ { "afs_syscall" },
238 /* 138 */ { "setfsuid" },
239 /* 139 */ { "setfsgid" },
240 /* 140 */ { "llseek", _llseekFunc },
241 /* 141 */ { "getdents" },
242 /* 142 */ { "newselect" },
243 /* 143 */ { "flock" },
244 /* 144 */ { "msync" },
245 /* 145 */ { "readv" },
246 /* 146 */ { "writev", writevFunc<PowerLinux> },
247 /* 147 */ { "getsid" },
248 /* 148 */ { "fdatasync" },
249 /* 149 */ { "sysctl" },
250 /* 150 */ { "mlock" },
251 /* 151 */ { "munlock" },
252 /* 152 */ { "mlockall" },
253 /* 153 */ { "munlockall" },
254 /* 154 */ { "sched_setparam" },
255 /* 155 */ { "sched_getparam" },
256 /* 156 */ { "sched_setscheduler" },
257 /* 157 */ { "sched_getscheduler" },
258 /* 158 */ { "sched_yield" },
259 /* 159 */ { "sched_get_priority_max" },
260 /* 160 */ { "sched_get_priority_min" },
261 /* 161 */ { "sched_rr_get_interval" },
262 /* 162 */ { "nanosleep" },
263 /* 163 */ { "mremap" },
264 /* 164 */ { "setresuid" },
265 /* 165 */ { "getresuid" },
266 /* 166 */ { "vm862" },
267 /* 167 */ { "query_module" },
268 /* 168 */ { "poll" },
269 /* 169 */ { "nfsservctl" },
270 /* 170 */ { "setresgid" },
271 /* 171 */ { "getresgid" },
272 /* 172 */ { "prctl" },
273 /* 173 */ { "rt_sigaction", ignoreFunc },
274 /* 174 */ { "rt_sigprocmask" },
275 /* 175 */ { "unknown#175" },
276 /* 176 */ { "rt_sigpending" },
277 /* 177 */ { "rt_sigtimedwait" },
278 /* 178 */ { "rt_sigqueueinfo", ignoreFunc },
279 /* 179 */ { "rt_sigsuspend" },
280 /* 180 */ { "pread64" },
281 /* 181 */ { "pwrite64" },
282 /* 182 */ { "chown" },
283 /* 183 */ { "getcwd" },
284 /* 184 */ { "capget" },
285 /* 185 */ { "capset" },
286 /* 186 */ { "sigaltstack" },
287 /* 187 */ { "sendfile" },
288 /* 188 */ { "getpmsg" },
289 /* 189 */ { "putpmsg" },
290 /* 190 */ { "ugetrlimit", ignoreFunc },
291 /* 191 */ { "getrlimit" },
292 /* 192 */ { "mmap2", mmapFunc<PowerLinux> },
293 /* 193 */ { "truncate64" },
294 /* 194 */ { "ftruncate64", ftruncate64Func },
295 /* 195 */ { "stat64", stat64Func<PowerLinux> },
296 /* 196 */ { "lstat64", lstat64Func<PowerLinux> },
297 /* 197 */ { "fstat64", fstat64Func<PowerLinux> },
298 /* 198 */ { "lchown" },
299 /* 199 */ { "getuid", getuidFunc },
300 /* 200 */ { "getgid", getgidFunc },
301 /* 201 */ { "geteuid", geteuidFunc },
302 /* 202 */ { "getegid", getegidFunc },
303 /* 203 */ { "setreuid" },
304 /* 204 */ { "fcntl64", fcntl64Func },
305 /* 205 */ { "getgroups" },
306 /* 206 */ { "setgroups" },
307 /* 207 */ { "fchown" },
308 /* 208 */ { "setresuid" },
309 /* 209 */ { "getresuid" },
310 /* 210 */ { "setresgid" },
311 /* 211 */ { "getresgid" },
312 /* 212 */ { "chown" },
313 /* 213 */ { "setuid" },
314 /* 214 */ { "setgid" },
315 /* 215 */ { "setfsuid" },
316 /* 216 */ { "setfsgid" },
317 /* 217 */ { "getdents64" },
318 /* 218 */ { "pivot_root" },
319 /* 219 */ { "mincore" },
320 /* 220 */ { "madvise" },
321 /* 221 */ { "unknown#221" },
322 /* 222 */ { "tux" },
323 /* 223 */ { "unknown#223" },
324 /* 224 */ { "gettid" },
325 /* 225 */ { "readahead" },
326 /* 226 */ { "setxattr" },
327 /* 227 */ { "lsetxattr" },
328 /* 228 */ { "fsetxattr" },
329 /* 229 */ { "getxattr" },
330 /* 230 */ { "lgetxattr" },
331 /* 231 */ { "fgetxattr" },
332 /* 232 */ { "listxattr" },
333 /* 233 */ { "llistxattr" },
334 /* 234 */ { "exit_group", exitGroupFunc },
335 /* 235 */ { "removexattr" },
336 /* 236 */ { "lremovexattr" },
337 /* 237 */ { "fremovexattr" },
338 /* 238 */ { "tkill" },
339 /* 239 */ { "sendfile64" },
340 /* 240 */ { "futex" },
341 /* 241 */ { "sched_setaffinity" },
342 /* 242 */ { "sched_getaffinity" },
343 /* 243 */ { "io_setup" },
344 /* 244 */ { "io_destory" },
345 /* 245 */ { "io_getevents" },
346 /* 246 */ { "io_submit" },
347 /* 247 */ { "io_cancel" },
348 /* 248 */ { "unknown#248" },
349 /* 249 */ { "lookup_dcookie" },
350 /* 250 */ { "epoll_create" },
351 /* 251 */ { "epoll_ctl" },
352 /* 252 */ { "epoll_wait" },
353 /* 253 */ { "remap_file_pages" },
354 /* 254 */ { "set_thread_area" },
355 /* 255 */ { "get_thread_area" },
356 /* 256 */ { "set_tid_address" },
357 /* 257 */ { "timer_create" },
358 /* 258 */ { "timer_settime" },
359 /* 259 */ { "timer_gettime" },
360 /* 260 */ { "timer_getoverrun" },
361 /* 261 */ { "timer_delete" },
362 /* 262 */ { "clock_settime" },
363 /* 263 */ { "clock_gettime" },
364 /* 264 */ { "clock_getres" },
365 /* 265 */ { "clock_nanosleep" },
366 /* 266 */ { "statfs64" },
367 /* 267 */ { "fstatfs64" },
368 /* 268 */ { "tgkill" },
369 /* 269 */ { "utimes" },
370 /* 270 */ { "arm_fadvise64_64" },
371 /* 271 */ { "pciconfig_iobase" },
372 /* 272 */ { "pciconfig_read" },
373 /* 273 */ { "pciconfig_write" },
374 /* 274 */ { "mq_open" },
375 /* 275 */ { "mq_unlink" },
376 /* 276 */ { "mq_timedsend" },
377 /* 277 */ { "mq_timedreceive" },
378 /* 278 */ { "mq_notify" },
379 /* 279 */ { "mq_getsetattr" },
380 /* 280 */ { "waitid" },
381 /* 281 */ { "socket" },
382 /* 282 */ { "bind" },
383 /* 283 */ { "connect" },
384 /* 284 */ { "listen" },
385 /* 285 */ { "accept" },
386 /* 286 */ { "getsockname" },
387 /* 287 */ { "getpeername" },
388 /* 288 */ { "socketpair" },
389 /* 289 */ { "send" },
390 /* 290 */ { "sendto" },
391 /* 291 */ { "recv" },
392 /* 292 */ { "recvfrom" },
393 /* 293 */ { "shutdown" },
394 /* 294 */ { "setsockopt" },
395 /* 295 */ { "getsockopt" },
396 /* 296 */ { "sendmsg" },
397 /* 297 */ { "rcvmsg" },
398 /* 298 */ { "semop" },
399 /* 299 */ { "semget" },
400 /* 300 */ { "semctl" },
401 /* 301 */ { "msgsend" },
402 /* 302 */ { "msgrcv" },
403 /* 303 */ { "msgget" },
404 /* 304 */ { "msgctl" },
405 /* 305 */ { "shmat" },
406 /* 306 */ { "shmdt" },
407 /* 307 */ { "shmget" },
408 /* 308 */ { "shmctl" },
409 /* 309 */ { "add_key" },
410 /* 310 */ { "request_key" },
411 /* 311 */ { "keyctl" },
412 /* 312 */ { "semtimedop" },
413 /* 313 */ { "vserver" },
414 /* 314 */ { "ioprio_set" },
415 /* 315 */ { "ioprio_get" },
416 /* 316 */ { "inotify_init" },
417 /* 317 */ { "inotify_add_watch" },
418 /* 318 */ { "inotify_rm_watch" },
419 /* 319 */ { "mbind" },
420 /* 320 */ { "get_mempolicy" },
421 /* 321 */ { "set_mempolicy" },
422 /* 322 */ { "openat" },
423 /* 323 */ { "mkdirat" },
424 /* 324 */ { "mknodat" },
425 /* 325 */ { "fchownat" },
426 /* 326 */ { "futimesat" },
427 /* 327 */ { "fstatat64" },
428 /* 328 */ { "unlinkat" },
429 /* 329 */ { "renameat" },
430 /* 330 */ { "linkat" },
431 /* 331 */ { "symlinkat" },
432 /* 332 */ { "readlinkat" },
433 /* 333 */ { "fchmodat" },
434 /* 334 */ { "faccessat" },
435 /* 335 */ { "pselect6" },
436 /* 336 */ { "ppoll" },
437 /* 337 */ { "unshare" },
438 /* 338 */ { "set_robust_list" },
439 /* 339 */ { "get_robust_list" },
440 /* 340 */ { "splice" },
441 /* 341 */ { "arm_sync_file_range" },
442 /* 342 */ { "tee" },
443 /* 343 */ { "vmsplice" },
444 /* 344 */ { "move_pages" },
445 /* 345 */ { "getcpu" },
446 /* 346 */ { "epoll_pwait" },
447 };
448
449 PowerLinuxProcess::PowerLinuxProcess(ProcessParams * params,
450 ObjectFile *objFile)
451 : PowerProcess(params, objFile),
452 Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
453 {
454 }
455
456 SyscallDesc*
457 PowerLinuxProcess::getDesc(int callnum)
458 {
459 if (callnum < 0 || callnum > Num_Syscall_Descs)
460 return NULL;
461
462 return &syscallDescs[callnum];
463 }
464
465 void
466 PowerLinuxProcess::initState()
467 {
468 PowerProcess::initState();
469 }
470
471 void
472 PowerLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
473 {
474 doSyscall(tc->readIntReg(0), tc, fault);
475 }
476
477 RegVal
478 PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
479 {
480 // Linux apparently allows more parameter than the ABI says it should.
481 // This limit may need to be increased even further.
482 assert(i < 6);
483 return tc->readIntReg(ArgumentReg0 + i++);
484 }