arch-riscv: Add an implementation of set_tid_address syscall in RISCV
[gem5.git] / src / arch / riscv / linux / process.cc
1 /*
2 * Copyright (c) 2005 The Regents of The University of Michigan
3 * Copyright (c) 2007 MIPS Technologies, Inc.
4 * Copyright (c) 2016 The University of Virginia
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: Gabe Black
31 * Korey Sewell
32 * Alec Roelke
33 */
34
35 #include "arch/riscv/linux/process.hh"
36
37 #include <map>
38
39 #include "arch/riscv/isa_traits.hh"
40 #include "arch/riscv/linux/linux.hh"
41 #include "base/trace.hh"
42 #include "cpu/thread_context.hh"
43 #include "debug/SyscallVerbose.hh"
44 #include "kern/linux/linux.hh"
45 #include "sim/eventq.hh"
46 #include "sim/process.hh"
47 #include "sim/syscall_desc.hh"
48 #include "sim/syscall_emul.hh"
49 #include "sim/system.hh"
50
51 using namespace std;
52 using namespace RiscvISA;
53
54 /// Target uname() handler.
55 static SyscallReturn
56 unameFunc(SyscallDesc *desc, int callnum, Process *process,
57 ThreadContext *tc)
58 {
59 int index = 0;
60 TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
61
62 strcpy(name->sysname, "Linux");
63 strcpy(name->nodename,"sim.gem5.org");
64 strcpy(name->release, "3.0.0");
65 strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
66 strcpy(name->machine, "riscv");
67
68 name.copyOut(tc->getMemProxy());
69 return 0;
70 }
71
72 std::map<int, SyscallDesc> RiscvLinuxProcess::syscallDescs = {
73 {0, SyscallDesc("io_setup")},
74 {1, SyscallDesc("io_destroy")},
75 {2, SyscallDesc("io_submit")},
76 {3, SyscallDesc("io_cancel")},
77 {4, SyscallDesc("io_getevents")},
78 {5, SyscallDesc("setxattr")},
79 {6, SyscallDesc("lsetxattr")},
80 {7, SyscallDesc("fsetxattr")},
81 {8, SyscallDesc("getxattr")},
82 {9, SyscallDesc("lgetxattr")},
83 {10, SyscallDesc("fgetxattr")},
84 {11, SyscallDesc("listxattr")},
85 {12, SyscallDesc("llistxattr")},
86 {13, SyscallDesc("flistxattr")},
87 {14, SyscallDesc("removexattr")},
88 {15, SyscallDesc("lremovexattr")},
89 {16, SyscallDesc("fremovexattr")},
90 {17, SyscallDesc("getcwd", getcwdFunc)},
91 {18, SyscallDesc("lookup_dcookie")},
92 {19, SyscallDesc("eventfd2")},
93 {20, SyscallDesc("epoll_create1")},
94 {21, SyscallDesc("epoll_ctl")},
95 {22, SyscallDesc("epoll_pwait")},
96 {23, SyscallDesc("dup", dupFunc)},
97 {24, SyscallDesc("dup3")},
98 {25, SyscallDesc("fcntl", fcntl64Func)},
99 {26, SyscallDesc("inotify_init1")},
100 {27, SyscallDesc("inotify_add_watch")},
101 {28, SyscallDesc("inotify_rm_watch")},
102 {29, SyscallDesc("ioctl", ioctlFunc<RiscvLinux>)},
103 {30, SyscallDesc("ioprio_get")},
104 {31, SyscallDesc("ioprio_set")},
105 {32, SyscallDesc("flock")},
106 {33, SyscallDesc("mknodat")},
107 {34, SyscallDesc("mkdirat")},
108 {35, SyscallDesc("unlinkat", unlinkatFunc<RiscvLinux>)},
109 {36, SyscallDesc("symlinkat")},
110 {37, SyscallDesc("linkat")},
111 {38, SyscallDesc("renameat", renameatFunc<RiscvLinux>)},
112 {39, SyscallDesc("umount2")},
113 {40, SyscallDesc("mount")},
114 {41, SyscallDesc("pivot_root")},
115 {42, SyscallDesc("nfsservctl")},
116 {43, SyscallDesc("statfs", statfsFunc<RiscvLinux>)},
117 {44, SyscallDesc("fstatfs", fstatfsFunc<RiscvLinux>)},
118 {45, SyscallDesc("truncate", truncateFunc)},
119 {46, SyscallDesc("ftruncate", ftruncate64Func)},
120 {47, SyscallDesc("fallocate", fallocateFunc)},
121 {48, SyscallDesc("faccessat", faccessatFunc<RiscvLinux>)},
122 {49, SyscallDesc("chdir")},
123 {50, SyscallDesc("fchdir")},
124 {51, SyscallDesc("chroot")},
125 {52, SyscallDesc("fchmod", fchmodFunc<RiscvLinux>)},
126 {53, SyscallDesc("fchmodat")},
127 {54, SyscallDesc("fchownat")},
128 {55, SyscallDesc("fchown", fchownFunc)},
129 {56, SyscallDesc("openat", openatFunc<RiscvLinux>)},
130 {57, SyscallDesc("close", closeFunc)},
131 {58, SyscallDesc("vhangup")},
132 {59, SyscallDesc("pipe2")},
133 {60, SyscallDesc("quotactl")},
134 {61, SyscallDesc("getdents64")},
135 {62, SyscallDesc("lseek", lseekFunc)},
136 {63, SyscallDesc("read", readFunc)},
137 {64, SyscallDesc("write", writeFunc)},
138 {66, SyscallDesc("writev", writevFunc<RiscvLinux>)},
139 {67, SyscallDesc("pread64")},
140 {68, SyscallDesc("pwrite64", pwrite64Func<RiscvLinux>)},
141 {69, SyscallDesc("preadv")},
142 {70, SyscallDesc("pwritev")},
143 {71, SyscallDesc("sendfile")},
144 {72, SyscallDesc("pselect6")},
145 {73, SyscallDesc("ppoll")},
146 {74, SyscallDesc("signalfd64")},
147 {75, SyscallDesc("vmsplice")},
148 {76, SyscallDesc("splice")},
149 {77, SyscallDesc("tee")},
150 {78, SyscallDesc("readlinkat", readlinkatFunc<RiscvLinux>)},
151 {79, SyscallDesc("fstatat", fstatat64Func<RiscvLinux>)},
152 {80, SyscallDesc("fstat", fstat64Func<RiscvLinux>)},
153 {81, SyscallDesc("sync")},
154 {82, SyscallDesc("fsync")},
155 {83, SyscallDesc("fdatasync")},
156 {84, SyscallDesc("sync_file_range2")},
157 {85, SyscallDesc("timerfd_create")},
158 {86, SyscallDesc("timerfd_settime")},
159 {87, SyscallDesc("timerfd_gettime")},
160 {88, SyscallDesc("utimensat")},
161 {89, SyscallDesc("acct")},
162 {90, SyscallDesc("capget")},
163 {91, SyscallDesc("capset")},
164 {92, SyscallDesc("personality")},
165 {93, SyscallDesc("exit", exitFunc)},
166 {94, SyscallDesc("exit_group", exitGroupFunc)},
167 {95, SyscallDesc("waitid")},
168 {96, SyscallDesc("set_tid_address", setTidAddressFunc)},
169 {97, SyscallDesc("unshare")},
170 {98, SyscallDesc("futex", futexFunc<RiscvLinux>)},
171 {99, SyscallDesc("set_robust_list")},
172 {100, SyscallDesc("get_robust_list")},
173 {101, SyscallDesc("nanosleep")},
174 {102, SyscallDesc("getitimer")},
175 {103, SyscallDesc("setitimer")},
176 {104, SyscallDesc("kexec_load")},
177 {105, SyscallDesc("init_module")},
178 {106, SyscallDesc("delete_module")},
179 {107, SyscallDesc("timer_create")},
180 {108, SyscallDesc("timer_gettime")},
181 {109, SyscallDesc("timer_getoverrun")},
182 {110, SyscallDesc("timer_settime")},
183 {111, SyscallDesc("timer_delete")},
184 {112, SyscallDesc("clock_settime")},
185 {113, SyscallDesc("clock_gettime", clock_gettimeFunc<RiscvLinux>)},
186 {114, SyscallDesc("clock_getres", clock_getresFunc<RiscvLinux>)},
187 {115, SyscallDesc("clock_nanosleep")},
188 {116, SyscallDesc("syslog")},
189 {117, SyscallDesc("ptrace")},
190 {118, SyscallDesc("sched_setparam")},
191 {119, SyscallDesc("sched_setscheduler")},
192 {120, SyscallDesc("sched_getscheduler")},
193 {121, SyscallDesc("sched_getparam")},
194 {122, SyscallDesc("sched_setaffinity")},
195 {123, SyscallDesc("sched_getaffinity")},
196 {124, SyscallDesc("sched_yield")},
197 {125, SyscallDesc("sched_get_priority_max")},
198 {126, SyscallDesc("sched_get_priority_min")},
199 {127, SyscallDesc("scheD_rr_get_interval")},
200 {128, SyscallDesc("restart_syscall")},
201 {129, SyscallDesc("kill")},
202 {130, SyscallDesc("tkill")},
203 {131, SyscallDesc("tgkill", tgkillFunc<RiscvLinux>)},
204 {132, SyscallDesc("sigaltstack")},
205 {133, SyscallDesc("rt_sigsuspend", ignoreFunc, SyscallDesc::WarnOnce)},
206 {134, SyscallDesc("rt_sigaction", ignoreFunc, SyscallDesc::WarnOnce)},
207 {135, SyscallDesc("rt_sigprocmask", ignoreFunc, SyscallDesc::WarnOnce)},
208 {136, SyscallDesc("rt_sigpending", ignoreFunc, SyscallDesc::WarnOnce)},
209 {137, SyscallDesc("rt_sigtimedwait", ignoreFunc,SyscallDesc::WarnOnce)},
210 {138, SyscallDesc("rt_sigqueueinfo", ignoreFunc,SyscallDesc::WarnOnce)},
211 {139, SyscallDesc("rt_sigreturn", ignoreFunc, SyscallDesc::WarnOnce)},
212 {140, SyscallDesc("setpriority")},
213 {141, SyscallDesc("getpriority")},
214 {142, SyscallDesc("reboot")},
215 {143, SyscallDesc("setregid")},
216 {144, SyscallDesc("setgid")},
217 {145, SyscallDesc("setreuid")},
218 {146, SyscallDesc("setuid", setuidFunc)},
219 {147, SyscallDesc("setresuid")},
220 {148, SyscallDesc("getresuid")},
221 {149, SyscallDesc("getresgid")},
222 {150, SyscallDesc("getresgid")},
223 {151, SyscallDesc("setfsuid")},
224 {152, SyscallDesc("setfsgid")},
225 {153, SyscallDesc("times", timesFunc<RiscvLinux>)},
226 {154, SyscallDesc("setpgid", setpgidFunc)},
227 {155, SyscallDesc("getpgid")},
228 {156, SyscallDesc("getsid")},
229 {157, SyscallDesc("setsid")},
230 {158, SyscallDesc("getgroups")},
231 {159, SyscallDesc("setgroups")},
232 {160, SyscallDesc("uname", unameFunc)},
233 {161, SyscallDesc("sethostname")},
234 {162, SyscallDesc("setdomainname")},
235 {163, SyscallDesc("getrlimit", getrlimitFunc<RiscvLinux>)},
236 {164, SyscallDesc("setrlimit", ignoreFunc)},
237 {165, SyscallDesc("getrusage", getrusageFunc<RiscvLinux>)},
238 {166, SyscallDesc("umask", umaskFunc)},
239 {167, SyscallDesc("prctl")},
240 {168, SyscallDesc("getcpu")},
241 {169, SyscallDesc("gettimeofday", gettimeofdayFunc<RiscvLinux>)},
242 {170, SyscallDesc("settimeofday")},
243 {171, SyscallDesc("adjtimex")},
244 {172, SyscallDesc("getpid", getpidFunc)},
245 {173, SyscallDesc("getppid", getppidFunc)},
246 {174, SyscallDesc("getuid", getuidFunc)},
247 {175, SyscallDesc("geteuid", geteuidFunc)},
248 {176, SyscallDesc("getgid", getgidFunc)},
249 {177, SyscallDesc("getegid", getegidFunc)},
250 {178, SyscallDesc("gettid", gettidFunc)},
251 {179, SyscallDesc("sysinfo", sysinfoFunc<RiscvLinux>)},
252 {180, SyscallDesc("mq_open")},
253 {181, SyscallDesc("mq_unlink")},
254 {182, SyscallDesc("mq_timedsend")},
255 {183, SyscallDesc("mq_timedrecieve")},
256 {184, SyscallDesc("mq_notify")},
257 {185, SyscallDesc("mq_getsetattr")},
258 {186, SyscallDesc("msgget")},
259 {187, SyscallDesc("msgctl")},
260 {188, SyscallDesc("msgrcv")},
261 {189, SyscallDesc("msgsnd")},
262 {190, SyscallDesc("semget")},
263 {191, SyscallDesc("semctl")},
264 {192, SyscallDesc("semtimedop")},
265 {193, SyscallDesc("semop")},
266 {194, SyscallDesc("shmget")},
267 {195, SyscallDesc("shmctl")},
268 {196, SyscallDesc("shmat")},
269 {197, SyscallDesc("shmdt")},
270 {198, SyscallDesc("socket")},
271 {199, SyscallDesc("socketpair")},
272 {200, SyscallDesc("bind")},
273 {201, SyscallDesc("listen")},
274 {202, SyscallDesc("accept")},
275 {203, SyscallDesc("connect")},
276 {204, SyscallDesc("getsockname")},
277 {205, SyscallDesc("getpeername")},
278 {206, SyscallDesc("sendo")},
279 {207, SyscallDesc("recvfrom")},
280 {208, SyscallDesc("setsockopt")},
281 {209, SyscallDesc("getsockopt")},
282 {210, SyscallDesc("shutdown")},
283 {211, SyscallDesc("sendmsg")},
284 {212, SyscallDesc("recvmsg")},
285 {213, SyscallDesc("readahead")},
286 {214, SyscallDesc("brk", brkFunc)},
287 {215, SyscallDesc("munmap", munmapFunc)},
288 {216, SyscallDesc("mremap", mremapFunc<RiscvLinux>)},
289 {217, SyscallDesc("add_key")},
290 {218, SyscallDesc("request_key")},
291 {219, SyscallDesc("keyctl")},
292 {220, SyscallDesc("clone", cloneFunc<RiscvLinux>)},
293 {221, SyscallDesc("execve", execveFunc<RiscvLinux>)},
294 {222, SyscallDesc("mmap", mmapFunc<RiscvLinux>)},
295 {223, SyscallDesc("fadvise64")},
296 {224, SyscallDesc("swapon")},
297 {225, SyscallDesc("swapoff")},
298 {226, SyscallDesc("mprotect", ignoreFunc)},
299 {227, SyscallDesc("msync", ignoreFunc)},
300 {228, SyscallDesc("mlock", ignoreFunc)},
301 {229, SyscallDesc("munlock", ignoreFunc)},
302 {230, SyscallDesc("mlockall", ignoreFunc)},
303 {231, SyscallDesc("munlockall", ignoreFunc)},
304 {232, SyscallDesc("mincore", ignoreFunc)},
305 {233, SyscallDesc("madvise", ignoreFunc)},
306 {234, SyscallDesc("remap_file_pages")},
307 {235, SyscallDesc("mbind", ignoreFunc)},
308 {236, SyscallDesc("get_mempolicy")},
309 {237, SyscallDesc("set_mempolicy")},
310 {238, SyscallDesc("migrate_pages")},
311 {239, SyscallDesc("move_pages")},
312 {240, SyscallDesc("tgsigqueueinfo")},
313 {241, SyscallDesc("perf_event_open")},
314 {242, SyscallDesc("accept4")},
315 {243, SyscallDesc("recvmmsg")},
316 {260, SyscallDesc("wait4")},
317 {261, SyscallDesc("prlimit64", prlimitFunc<RiscvLinux>)},
318 {262, SyscallDesc("fanotify_init")},
319 {263, SyscallDesc("fanotify_mark")},
320 {264, SyscallDesc("name_to_handle_at")},
321 {265, SyscallDesc("open_by_handle_at")},
322 {266, SyscallDesc("clock_adjtime")},
323 {267, SyscallDesc("syncfs")},
324 {268, SyscallDesc("setns")},
325 {269, SyscallDesc("sendmmsg")},
326 {270, SyscallDesc("process_vm_ready")},
327 {271, SyscallDesc("process_vm_writev")},
328 {272, SyscallDesc("kcmp")},
329 {273, SyscallDesc("finit_module")},
330 {274, SyscallDesc("sched_setattr")},
331 {275, SyscallDesc("sched_getattr")},
332 {276, SyscallDesc("renameat2")},
333 {277, SyscallDesc("seccomp")},
334 {278, SyscallDesc("getrandom")},
335 {279, SyscallDesc("memfd_create")},
336 {280, SyscallDesc("bpf")},
337 {281, SyscallDesc("execveat")},
338 {282, SyscallDesc("userfaultid")},
339 {283, SyscallDesc("membarrier")},
340 {284, SyscallDesc("mlock2")},
341 {285, SyscallDesc("copy_file_range")},
342 {286, SyscallDesc("preadv2")},
343 {287, SyscallDesc("pwritev2")},
344 {1024, SyscallDesc("open", openFunc<RiscvLinux>)},
345 {1025, SyscallDesc("link")},
346 {1026, SyscallDesc("unlink", unlinkFunc)},
347 {1027, SyscallDesc("mknod")},
348 {1028, SyscallDesc("chmod", chmodFunc<RiscvLinux>)},
349 {1029, SyscallDesc("chown", chownFunc)},
350 {1030, SyscallDesc("mkdir", mkdirFunc)},
351 {1031, SyscallDesc("rmdir")},
352 {1032, SyscallDesc("lchown")},
353 {1033, SyscallDesc("access", accessFunc)},
354 {1034, SyscallDesc("rename", renameFunc)},
355 {1035, SyscallDesc("readlink", readlinkFunc)},
356 {1036, SyscallDesc("symlink")},
357 {1037, SyscallDesc("utimes", utimesFunc<RiscvLinux>)},
358 {1038, SyscallDesc("stat", stat64Func<RiscvLinux>)},
359 {1039, SyscallDesc("lstat", lstat64Func<RiscvLinux>)},
360 {1040, SyscallDesc("pipe", pipeFunc)},
361 {1041, SyscallDesc("dup2", dup2Func)},
362 {1042, SyscallDesc("epoll_create")},
363 {1043, SyscallDesc("inotifiy_init")},
364 {1044, SyscallDesc("eventfd")},
365 {1045, SyscallDesc("signalfd")},
366 {1046, SyscallDesc("sendfile")},
367 {1047, SyscallDesc("ftruncate", ftruncate64Func)},
368 {1048, SyscallDesc("truncate", truncate64Func)},
369 {1049, SyscallDesc("stat", stat64Func<RiscvLinux>)},
370 {1050, SyscallDesc("lstat", lstat64Func<RiscvLinux>)},
371 {1051, SyscallDesc("fstat", fstat64Func<RiscvLinux>)},
372 {1052, SyscallDesc("fcntl", fcntl64Func)},
373 {1053, SyscallDesc("fadvise64")},
374 {1054, SyscallDesc("newfstatat")},
375 {1055, SyscallDesc("fstatfs", fstatfsFunc<RiscvLinux>)},
376 {1056, SyscallDesc("statfs", statfsFunc<RiscvLinux>)},
377 {1057, SyscallDesc("lseek", lseekFunc)},
378 {1058, SyscallDesc("mmap", mmapFunc<RiscvLinux>)},
379 {1059, SyscallDesc("alarm")},
380 {1060, SyscallDesc("getpgrp")},
381 {1061, SyscallDesc("pause")},
382 {1062, SyscallDesc("time", timeFunc<RiscvLinux>)},
383 {1063, SyscallDesc("utime")},
384 {1064, SyscallDesc("creat")},
385 {1065, SyscallDesc("getdents")},
386 {1066, SyscallDesc("futimesat")},
387 {1067, SyscallDesc("select")},
388 {1068, SyscallDesc("poll")},
389 {1069, SyscallDesc("epoll_wait")},
390 {1070, SyscallDesc("ustat")},
391 {1071, SyscallDesc("vfork")},
392 {1072, SyscallDesc("oldwait4")},
393 {1073, SyscallDesc("recv")},
394 {1074, SyscallDesc("send")},
395 {1075, SyscallDesc("bdflush")},
396 {1076, SyscallDesc("umount")},
397 {1077, SyscallDesc("uselib")},
398 {1078, SyscallDesc("sysctl")},
399 {1079, SyscallDesc("fork")},
400 {2011, SyscallDesc("getmainvars")}
401 };
402
403 RiscvLinuxProcess::RiscvLinuxProcess(ProcessParams * params,
404 ObjectFile *objFile) : RiscvProcess(params, objFile)
405 {}
406
407 SyscallDesc*
408 RiscvLinuxProcess::getDesc(int callnum)
409 {
410 return syscallDescs.find(callnum) != syscallDescs.end() ?
411 &syscallDescs.at(callnum) : nullptr;
412 }