d44defd8573fb3d6fd9d333695038e7704834a89
[akaros.git] / user / vmm / linuxemu.c
1 /* Copyright (c) 2016 Google Inc.
2  * See LICENSE for details.
3  *
4  * Linux emulation for virtual machines. */
5
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <vmm/vmm.h>
13 #include <errno.h>
14 #include <sys/syscall.h>
15 #include <vmm/linux_syscalls.h>
16 #include <sys/time.h>
17 #include <vmm/linuxemu.h>
18 #include <dlfcn.h>
19 #include <sys/mman.h>
20 #include <futex.h>
21
22 static int lemu_debug;
23
24 static uth_mutex_t *lemu_logging_lock;
25
26 static FILE *lemu_global_logfile;
27
28 void init_lemu_logging(int log_level)
29 {
30         const char *logfile_name = "lemu.log";
31         FILE *x = fopen(logfile_name, "w");
32
33         lemu_debug = log_level;
34         lemu_logging_lock = uth_mutex_alloc();
35
36         if (x != NULL)
37                 lemu_global_logfile = x;
38         else
39                 lemu_global_logfile = stderr;
40 }
41
42 void destroy_lemu_logging(void)
43 {
44         if (lemu_logging_lock != NULL)
45                 uth_mutex_free(lemu_logging_lock);
46
47         if (lemu_global_logfile != stderr)
48                 fclose(lemu_global_logfile);
49 }
50
51
52 /////////////////////////////////////
53 // BEGIN DUNE SYSCALL IMPLEMENTATIONS
54 /////////////////////////////////////
55
56 //////////////////////////////////////////////////////
57 // Ported Syscalls (we just call the akaros version)
58 //////////////////////////////////////////////////////
59
60 bool dune_sys_ftruncate(struct vm_trapframe *tf)
61 {
62         int retval = ftruncate((int) tf->tf_rdi, (off_t) tf->tf_rsi);
63         int err = errno;
64
65         if (retval == -1) {
66                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
67                           "ERROR %d\n", err);
68                 tf->tf_rax = -err;
69         } else {
70                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
71                           "SUCCESS %d\n", retval);
72                 tf->tf_rax = retval;
73         }
74         return true;
75
76 }
77
78 bool dune_sys_fcntl(struct vm_trapframe *tf)
79 {
80         int retval = fcntl((int) tf->tf_rdi, (int) tf->tf_rsi, (int) tf->tf_rdx);
81         int err = errno;
82
83         if (retval == -1) {
84                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
85                           "ERROR %d\n", err);
86                 tf->tf_rax = -err;
87         } else {
88                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
89                           "SUCCESS %d\n", retval);
90                 tf->tf_rax = retval;
91         }
92         return true;
93 }
94
95 bool dune_sys_pread64(struct vm_trapframe *tf)
96 {
97         int fd = (int) tf->tf_rdi;
98         void *buf = (void*) tf->tf_rsi;
99         size_t count = tf->tf_rdx;
100         off_t offset = (off_t) tf->tf_r10;
101
102         ssize_t retval = pread(fd, buf, count, offset);
103         int err = errno;
104
105         if (retval == -1) {
106                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
107                           "ERROR %zd\n", err);
108                 tf->tf_rax = -err;
109         } else {
110                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
111                           "SUCCESS %zd\n", retval);
112                 tf->tf_rax = retval;
113         }
114         return true;
115 }
116
117 bool dune_sys_read(struct vm_trapframe *tf)
118 {
119         ssize_t retval = read(tf->tf_rdi, (void*) tf->tf_rsi, (size_t) tf->tf_rdx);
120         int err = errno;
121
122         if (retval == -1) {
123                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
124                           "ERROR %zd\n", err);
125                 tf->tf_rax = -err;
126         } else {
127                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
128                           "SUCCESS %zd\n", retval);
129                 tf->tf_rax = retval;
130         }
131         return true;
132 }
133
134 bool dune_sys_pwrite64(struct vm_trapframe *tf)
135 {
136         int fd = (int) tf->tf_rdi;
137         const void *buf = (const void*) tf->tf_rsi;
138         size_t length = (size_t) tf->tf_rdx;
139         off_t offset = (off_t) tf->tf_r10;
140
141         ssize_t retval = pwrite(fd, buf, length, offset);
142         int err = errno;
143
144         if (retval == -1) {
145                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
146                           "ERROR %zd\n", err);
147                 tf->tf_rax = -err;
148         } else {
149                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
150                           "SUCCESS %zd\n", retval);
151                 tf->tf_rax = retval;
152         }
153         return true;
154 }
155
156 bool dune_sys_write(struct vm_trapframe *tf)
157 {
158         ssize_t retval = write((int) tf->tf_rdi, (const void *) tf->tf_rsi,
159                                (size_t) tf->tf_rdx);
160         int err = errno;
161
162         if (retval == -1) {
163                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
164                           "ERROR %zd\n", err);
165                 tf->tf_rax = -err;
166         } else {
167                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
168                           "SUCCESS %zd\n", retval);
169                 tf->tf_rax = retval;
170         }
171         return true;
172 }
173
174 bool dune_sys_getpid(struct vm_trapframe *tf)
175 {
176         // Getpid always suceeds
177         int retval = getpid();
178
179         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n", retval);
180         tf->tf_rax = retval;
181         return true;
182 }
183
184 bool dune_sys_gettimeofday(struct vm_trapframe *tf)
185 {
186         int retval = gettimeofday((struct timeval*) tf->tf_rdi,
187                                   (struct timezone*) tf->tf_rsi);
188         int err = errno;
189
190         if (retval == -1) {
191                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
192                           "ERROR %d\n", err);
193                 tf->tf_rax = -err;
194         } else {
195                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
196                           "SUCCESS %d\n", retval);
197                 tf->tf_rax = retval;
198         }
199         return true;
200 }
201
202 bool dune_sys_dup(struct vm_trapframe *tf)
203 {
204         int retval = dup((int) tf->tf_rdi);
205         int err = errno;
206
207         if (retval == -1) {
208                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
209                           "ERROR %d\n", err);
210                 tf->tf_rax = -err;
211         } else {
212                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
213                           "SUCCESS %d\n", retval);
214                 tf->tf_rax = retval;
215         }
216         return true;
217 }
218
219 bool dune_sys_dup2(struct vm_trapframe *tf)
220 {
221         int retval = dup2((int) tf->tf_rdi, (int)tf->tf_rsi);
222         int err = errno;
223
224         if (retval == -1) {
225                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
226                           "ERROR %d\n", err);
227                 tf->tf_rax = -err;
228         } else {
229                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
230                           "SUCCESS %d\n", retval);
231                 tf->tf_rax = retval;
232         }
233         return true;
234 }
235
236 bool dune_sys_umask(struct vm_trapframe *tf)
237 {
238         //Umask always succeeds
239         int retval = umask((mode_t) tf->tf_rdi);
240
241         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n", retval);
242         tf->tf_rax = retval;
243         return true;
244 }
245
246 bool dune_sys_clock_gettime(struct vm_trapframe *tf)
247 {
248         int retval = clock_gettime(tf->tf_rdi, (struct timespec*) tf->tf_rsi);
249         int err = errno;
250
251         if (retval == -1) {
252                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
253                           "ERROR %d\n", err);
254                 tf->tf_rax = -err;
255         } else {
256                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
257                           "SUCCESS %d\n", retval);
258                 tf->tf_rax = retval;
259         }
260         return true;
261 }
262
263 bool dune_sys_munmap(struct vm_trapframe *tf)
264 {
265         int retval = munmap((void *) tf->tf_rdi, tf->tf_rsi);
266         int err = errno;
267
268         if (retval == -1) {
269                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
270                           "ERROR %d\n", err);
271                 tf->tf_rax = -err;
272         } else {
273                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
274                           "SUCCESS %d\n", retval);
275                 tf->tf_rax = retval;
276         }
277         return true;
278 }
279
280 bool dune_sys_futex(struct vm_trapframe *tf)
281 {
282         int *uaddr = (int*) tf->tf_rdi;
283         int op = (int) tf->tf_rsi;
284         int val = (int) tf->tf_rdx;
285         struct timespec *timeout = (struct timespec *) tf->tf_r10;
286         int *uaddr2 = (int*) tf->tf_r8;
287         int val3 = (int) tf->tf_r9;
288         int retval = futex(uaddr, op, val, timeout, uaddr2, val3);
289         int err = errno;
290
291         if (retval == -1) {
292                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
293                           "ERROR %d\n", err);
294                 tf->tf_rax = -err;
295         } else {
296                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
297                           "SUCCESS %d\n", retval);
298                 tf->tf_rax = retval;
299         }
300         return true;
301 }
302
303 bool dune_sys_gettid(struct vm_trapframe *tf)
304 {
305         // Gettid always succeeds
306         int retval = tf->tf_guest_pcoreid;
307
308         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n", retval);
309         tf->tf_rax = retval;
310         return true;
311 }
312
313 /////////////////////////////////////////////////////////
314 // Modified Syscalls (Partially implemented in Akaros)
315 ////////////////////////////////////////////////////////
316
317 bool dune_sys_open(struct vm_trapframe *tf)
318 {
319         // To Be Implemented
320         return false;
321 }
322
323 bool dune_sys_openat(struct vm_trapframe *tf)
324 {
325
326         // To Be Implemented
327         return false;
328 }
329
330 bool dune_sys_readlinkat(struct vm_trapframe *tf)
331 {
332         // To Be Implemented
333         return false;
334 }
335
336 bool dune_sys_unlinkat(struct vm_trapframe *tf)
337 {
338         // To Be Implemented
339         return false;
340 }
341
342 bool dune_sys_close(struct vm_trapframe *tf)
343 {
344         // To Be Implemented
345         return false;
346 }
347
348 bool dune_sys_sched_yield(struct vm_trapframe *tf)
349 {
350         // To Be Implemented
351         return false;
352 }
353
354
355 bool dune_sys_fstat(struct vm_trapframe *tf)
356 {
357         // To Be Implemented
358         return false;
359 }
360
361 bool dune_sys_stat(struct vm_trapframe *tf)
362 {
363         // To Be Implemented
364         return false;
365 }
366
367 ///////////////////////////////////////////////////
368 // Newly Implemented Syscalls
369 ///////////////////////////////////////////////////
370
371 // Fallocate syscall
372 bool dune_sys_fallocate(struct vm_trapframe *tf)
373 {
374         // To Be Implemented
375         return false;
376 }
377
378 bool dune_sys_sched_getaffinity(struct vm_trapframe *tf)
379 {
380         // To Be Implemented
381         return false;
382 }
383
384 bool dune_sys_pselect6(struct vm_trapframe *tf)
385 {
386         // To Be Implemented
387         return false;
388 }
389
390 bool dune_sys_getrandom(struct vm_trapframe *tf)
391 {
392         // To Be Implemented
393         return false;
394 }
395
396 /////////////////////////////////////////////////////////////////
397 /// We don't have a good implementation for these syscalls,
398 /// they will not work in all cases
399 /////////////////////////////////////////////////////////////////
400
401 bool dune_sys_getgroups(struct vm_trapframe *tf)
402 {
403         // To Be Implemented
404         return false;
405 }
406
407
408 bool dune_sys_geteuid(struct vm_trapframe *tf)
409 {
410         // To Be Implemented
411         return false;
412 }
413
414 bool dune_sys_getegid(struct vm_trapframe *tf)
415 {
416         // To Be Implemented
417         return false;
418 }
419
420
421 bool dune_sys_getuid(struct vm_trapframe *tf)
422 {
423         // To Be Implemented
424         return false;
425 }
426
427 bool dune_sys_getgid(struct vm_trapframe *tf)
428 {
429         // To Be Implemented
430         return false;
431 }
432
433 bool dune_sys_mincore(struct vm_trapframe *tf)
434 {
435         // To Be Implemented
436         return false;
437 }
438
439 bool dune_sys_rt_sigprocmask(struct vm_trapframe *tf)
440 {
441         // To Be Implemented
442         return false;
443 }
444
445 bool dune_sys_sigaltstack(struct vm_trapframe *tf)
446 {
447         // To Be Implemented
448         return false;
449 }
450
451 bool dune_sys_rt_sigaction(struct vm_trapframe *tf)
452 {
453         // To Be Implemented
454         return false;
455 }
456
457 bool dune_sys_epoll_create1(struct vm_trapframe *tf)
458 {
459         // To Be Implemented
460         return false;
461 }
462
463 bool dune_sys_epoll_wait(struct vm_trapframe *tf)
464 {
465         // To Be Implemented
466         return false;
467 }
468
469 // Unimplemented
470 bool dune_sys_epoll_ctl(struct vm_trapframe *tf)
471 {
472         // To Be Implemented
473         return false;
474 }
475
476 // Unimplemented
477 bool dune_sys_fstatfs(struct vm_trapframe *tf)
478 {
479         // To Be Implemented
480         return false;
481 }
482
483 // Main syscall table
484 struct dune_sys_table_entry dune_syscall_table[DUNE_MAX_NUM_SYSCALLS] = {
485         [DUNE_SYS_READ] = {dune_sys_read, "DUNE_SYS_READ"},
486         [DUNE_SYS_WRITE] = {dune_sys_write, "DUNE_SYS_WRITE"},
487         [DUNE_SYS_OPEN] = {dune_sys_open, "DUNE_SYS_OPEN"},
488         [DUNE_SYS_CLOSE] = {dune_sys_close, "DUNE_SYS_CLOSE"},
489         [DUNE_SYS_STAT] = {dune_sys_stat, "DUNE_SYS_STAT"},
490         [DUNE_SYS_FSTAT] = {dune_sys_fstat, "DUNE_SYS_FSTAT"},
491         [DUNE_SYS_LSTAT] = {NULL, "DUNE_SYS_LSTAT"},
492         [DUNE_SYS_POLL] = {NULL, "DUNE_SYS_POLL"},
493         [DUNE_SYS_LSEEK] = {NULL, "DUNE_SYS_LSEEK"},
494         [DUNE_SYS_MMAP] = {NULL, "DUNE_SYS_MMAP"},
495         [DUNE_SYS_MPROTECT] = {NULL, "DUNE_SYS_MPROTECT"},
496         [DUNE_SYS_MUNMAP] = {dune_sys_munmap, "DUNE_SYS_MUNMAP"},
497         [DUNE_SYS_BRK] = {NULL, "DUNE_SYS_BRK"},
498         [DUNE_SYS_RT_SIGACTION] = {dune_sys_rt_sigaction, "DUNE_SYS_RT_SIGACTION"},
499         [DUNE_SYS_RT_SIGPROCMASK] = {dune_sys_rt_sigprocmask,
500                                      "DUNE_SYS_RT_SIGPROCMASK"},
501         [DUNE_SYS_RT_SIGRETURN] = {NULL, "DUNE_SYS_RT_SIGRETURN"},
502         [DUNE_SYS_IOCTL] = {NULL, "DUNE_SYS_IOCTL"},
503         [DUNE_SYS_PREAD64] = {dune_sys_pread64, "DUNE_SYS_PREAD64"},
504         [DUNE_SYS_PWRITE64] = {dune_sys_pwrite64, "DUNE_SYS_PWRITE64"},
505         [DUNE_SYS_READV] = {NULL, "DUNE_SYS_READV"},
506         [DUNE_SYS_WRITEV] = {NULL, "DUNE_SYS_WRITEV"},
507         [DUNE_SYS_ACCESS] = {NULL, "DUNE_SYS_ACCESS"},
508         [DUNE_SYS_PIPE] = {NULL, "DUNE_SYS_PIPE"},
509         [DUNE_SYS_SELECT] = {NULL, "DUNE_SYS_SELECT"},
510         [DUNE_SYS_SCHED_YIELD] = {dune_sys_sched_yield, "DUNE_SYS_SCHED_YIELD"},
511         [DUNE_SYS_MREMAP] = {NULL, "DUNE_SYS_MREMAP"},
512         [DUNE_SYS_MSYNC] = {NULL, "DUNE_SYS_MSYNC"},
513         [DUNE_SYS_MINCORE] = {dune_sys_mincore, "DUNE_SYS_MINCORE"},
514         [DUNE_SYS_MADVISE] = {NULL, "DUNE_SYS_MADVISE"},
515         [DUNE_SYS_SHMGET] = {NULL, "DUNE_SYS_SHMGET"},
516         [DUNE_SYS_SHMAT] = {NULL, "DUNE_SYS_SHMAT"},
517         [DUNE_SYS_SHMCTL] = {NULL, "DUNE_SYS_SHMCTL"},
518         [DUNE_SYS_DUP] = {dune_sys_dup, "DUNE_SYS_DUP"},
519         [DUNE_SYS_DUP2] = {dune_sys_dup2, "DUNE_SYS_DUP2"},
520         [DUNE_SYS_PAUSE] = {NULL, "DUNE_SYS_PAUSE"},
521         [DUNE_SYS_NANOSLEEP] = {NULL, "DUNE_SYS_NANOSLEEP"},
522         [DUNE_SYS_GETITIMER] = {NULL, "DUNE_SYS_GETITIMER"},
523         [DUNE_SYS_ALARM] = {NULL, "DUNE_SYS_ALARM"},
524         [DUNE_SYS_SETITIMER] = {NULL, "DUNE_SYS_SETITIMER"},
525         [DUNE_SYS_GETPID] = {dune_sys_getpid, "DUNE_SYS_GETPID"},
526         [DUNE_SYS_SENDFILE] = {NULL, "DUNE_SYS_SENDFILE"},
527         [DUNE_SYS_SOCKET] = {NULL, "DUNE_SYS_SOCKET"},
528         [DUNE_SYS_CONNECT] = {NULL, "DUNE_SYS_CONNECT"},
529         [DUNE_SYS_ACCEPT] = {NULL, "DUNE_SYS_ACCEPT"},
530         [DUNE_SYS_SENDTO] = {NULL, "DUNE_SYS_SENDTO"},
531         [DUNE_SYS_RECVFROM] = {NULL, "DUNE_SYS_RECVFROM"},
532         [DUNE_SYS_SENDMSG] = {NULL, "DUNE_SYS_SENDMSG"},
533         [DUNE_SYS_RECVMSG] = {NULL, "DUNE_SYS_RECVMSG"},
534         [DUNE_SYS_SHUTDOWN] = {NULL, "DUNE_SYS_SHUTDOWN"},
535         [DUNE_SYS_BIND] = {NULL, "DUNE_SYS_BIND"},
536         [DUNE_SYS_LISTEN] = {NULL, "DUNE_SYS_LISTEN"},
537         [DUNE_SYS_GETSOCKNAME] = {NULL, "DUNE_SYS_GETSOCKNAME"},
538         [DUNE_SYS_GETPEERNAME] = {NULL, "DUNE_SYS_GETPEERNAME"},
539         [DUNE_SYS_SOCKETPAIR] = {NULL, "DUNE_SYS_SOCKETPAIR"},
540         [DUNE_SYS_SETSOCKOPT] = {NULL, "DUNE_SYS_SETSOCKOPT"},
541         [DUNE_SYS_GETSOCKOPT] = {NULL, "DUNE_SYS_GETSOCKOPT"},
542         [DUNE_SYS_CLONE] = {NULL, "DUNE_SYS_CLONE"},
543         [DUNE_SYS_FORK] = {NULL, "DUNE_SYS_FORK"},
544         [DUNE_SYS_VFORK] = {NULL, "DUNE_SYS_VFORK"},
545         [DUNE_SYS_EXECVE] = {NULL, "DUNE_SYS_EXECVE"},
546         [DUNE_SYS_EXIT] = {NULL, "DUNE_SYS_EXIT"},
547         [DUNE_SYS_WAIT4] = {NULL, "DUNE_SYS_WAIT4"},
548         [DUNE_SYS_KILL] = {NULL, "DUNE_SYS_KILL"},
549         [DUNE_SYS_UNAME] = {NULL, "DUNE_SYS_UNAME"},
550         [DUNE_SYS_SEMGET] = {NULL, "DUNE_SYS_SEMGET"},
551         [DUNE_SYS_SEMOP] = {NULL, "DUNE_SYS_SEMOP"},
552         [DUNE_SYS_SEMCTL] = {NULL, "DUNE_SYS_SEMCTL"},
553         [DUNE_SYS_SHMDT] = {NULL, "DUNE_SYS_SHMDT"},
554         [DUNE_SYS_MSGGET] = {NULL, "DUNE_SYS_MSGGET"},
555         [DUNE_SYS_MSGSND] = {NULL, "DUNE_SYS_MSGSND"},
556         [DUNE_SYS_MSGRCV] = {NULL, "DUNE_SYS_MSGRCV"},
557         [DUNE_SYS_MSGCTL] = {NULL, "DUNE_SYS_MSGCTL"},
558         [DUNE_SYS_FCNTL] = {dune_sys_fcntl, "DUNE_SYS_FCNTL"},
559         [DUNE_SYS_FLOCK] = {NULL, "DUNE_SYS_FLOCK"},
560         [DUNE_SYS_FSYNC] = {NULL, "DUNE_SYS_FSYNC"},
561         [DUNE_SYS_FDATASYNC] = {NULL, "DUNE_SYS_FDATASYNC"},
562         [DUNE_SYS_TRUNCATE] = {NULL, "DUNE_SYS_TRUNCATE"},
563         [DUNE_SYS_FTRUNCATE] = {dune_sys_ftruncate, "DUNE_SYS_FTRUNCATE"},
564         [DUNE_SYS_GETDENTS] = {NULL, "DUNE_SYS_GETDENTS"},
565         [DUNE_SYS_GETCWD] = {NULL, "DUNE_SYS_GETCWD"},
566         [DUNE_SYS_CHDIR] = {NULL, "DUNE_SYS_CHDIR"},
567         [DUNE_SYS_FCHDIR] = {NULL, "DUNE_SYS_FCHDIR"},
568         [DUNE_SYS_RENAME] = {NULL, "DUNE_SYS_RENAME"},
569         [DUNE_SYS_MKDIR] = {NULL, "DUNE_SYS_MKDIR"},
570         [DUNE_SYS_RMDIR] = {NULL, "DUNE_SYS_RMDIR"},
571         [DUNE_SYS_CREAT] = {NULL, "DUNE_SYS_CREAT"},
572         [DUNE_SYS_LINK] = {NULL, "DUNE_SYS_LINK"},
573         [DUNE_SYS_UNLINK] = {NULL, "DUNE_SYS_UNLINK"},
574         [DUNE_SYS_SYMLINK] = {NULL, "DUNE_SYS_SYMLINK"},
575         [DUNE_SYS_READLINK] = {NULL, "DUNE_SYS_READLINK"},
576         [DUNE_SYS_CHMOD] = {NULL, "DUNE_SYS_CHMOD"},
577         [DUNE_SYS_FCHMOD] = {NULL, "DUNE_SYS_FCHMOD"},
578         [DUNE_SYS_CHOWN] = {NULL, "DUNE_SYS_CHOWN"},
579         [DUNE_SYS_FCHOWN] = {NULL, "DUNE_SYS_FCHOWN"},
580         [DUNE_SYS_LCHOWN] = {NULL, "DUNE_SYS_LCHOWN"},
581         [DUNE_SYS_UMASK] = {dune_sys_umask, "DUNE_SYS_UMASK"},
582         [DUNE_SYS_GETTIMEOFDAY] = {dune_sys_gettimeofday, "DUNE_SYS_GETTIMEOFDAY"},
583         [DUNE_SYS_GETRLIMIT] = {NULL, "DUNE_SYS_GETRLIMIT"},
584         [DUNE_SYS_GETRUSAGE] = {NULL, "DUNE_SYS_GETRUSAGE"},
585         [DUNE_SYS_SYSINFO] = {NULL, "DUNE_SYS_SYSINFO"},
586         [DUNE_SYS_TIMES] = {NULL, "DUNE_SYS_TIMES"},
587         [DUNE_SYS_PTRACE] = {NULL, "DUNE_SYS_PTRACE"},
588         [DUNE_SYS_GETUID] = {dune_sys_getuid, "DUNE_SYS_GETUID"},
589         [DUNE_SYS_SYSLOG] = {NULL, "DUNE_SYS_SYSLOG"},
590         [DUNE_SYS_GETGID] = {dune_sys_getgid, "DUNE_SYS_GETGID"},
591         [DUNE_SYS_SETUID] = {NULL, "DUNE_SYS_SETUID"},
592         [DUNE_SYS_SETGID] = {NULL, "DUNE_SYS_SETGID"},
593         [DUNE_SYS_GETEUID] = {dune_sys_geteuid, "DUNE_SYS_GETEUID"},
594         [DUNE_SYS_GETEGID] = {dune_sys_getegid, "DUNE_SYS_GETEGID"},
595         [DUNE_SYS_SETPGID] = {NULL, "DUNE_SYS_SETPGID"},
596         [DUNE_SYS_GETPPID] = {NULL, "DUNE_SYS_GETPPID"},
597         [DUNE_SYS_GETPGRP] = {NULL, "DUNE_SYS_GETPGRP"},
598         [DUNE_SYS_SETSID] = {NULL, "DUNE_SYS_SETSID"},
599         [DUNE_SYS_SETREUID] = {NULL, "DUNE_SYS_SETREUID"},
600         [DUNE_SYS_SETREGID] = {NULL, "DUNE_SYS_SETREGID"},
601         [DUNE_SYS_GETGROUPS] = {dune_sys_getgroups, "DUNE_SYS_GETGROUPS"},
602         [DUNE_SYS_SETGROUPS] = {NULL, "DUNE_SYS_SETGROUPS"},
603         [DUNE_SYS_SETRESUID] = {NULL, "DUNE_SYS_SETRESUID"},
604         [DUNE_SYS_GETRESUID] = {NULL, "DUNE_SYS_GETRESUID"},
605         [DUNE_SYS_SETRESGID] = {NULL, "DUNE_SYS_SETRESGID"},
606         [DUNE_SYS_GETRESGID] = {NULL, "DUNE_SYS_GETRESGID"},
607         [DUNE_SYS_GETPGID] = {NULL, "DUNE_SYS_GETPGID"},
608         [DUNE_SYS_SETFSUID] = {NULL, "DUNE_SYS_SETFSUID"},
609         [DUNE_SYS_SETFSGID] = {NULL, "DUNE_SYS_SETFSGID"},
610         [DUNE_SYS_GETSID] = {NULL, "DUNE_SYS_GETSID"},
611         [DUNE_SYS_CAPGET] = {NULL, "DUNE_SYS_CAPGET"},
612         [DUNE_SYS_CAPSET] = {NULL, "DUNE_SYS_CAPSET"},
613         [DUNE_SYS_RT_SIGPENDING] = {NULL, "DUNE_SYS_RT_SIGPENDING"},
614         [DUNE_SYS_RT_SIGTIMEDWAIT] = {NULL, "DUNE_SYS_RT_SIGTIMEDWAIT"},
615         [DUNE_SYS_RT_SIGQUEUEINFO] = {NULL, "DUNE_SYS_RT_SIGQUEUEINFO"},
616         [DUNE_SYS_RT_SIGSUSPEND] = {NULL, "DUNE_SYS_RT_SIGSUSPEND"},
617         [DUNE_SYS_SIGALTSTACK] = {dune_sys_sigaltstack, "DUNE_SYS_SIGALTSTACK"},
618         [DUNE_SYS_UTIME] = {NULL, "DUNE_SYS_UTIME"},
619         [DUNE_SYS_MKNOD] = {NULL, "DUNE_SYS_MKNOD"},
620         [DUNE_SYS_USELIB] = {NULL, "DUNE_SYS_USELIB"},
621         [DUNE_SYS_PERSONALITY] = {NULL, "DUNE_SYS_PERSONALITY"},
622         [DUNE_SYS_USTAT] = {NULL, "DUNE_SYS_USTAT"},
623         [DUNE_SYS_STATFS] = {NULL, "DUNE_SYS_STATFS"},
624         [DUNE_SYS_FSTATFS] = {dune_sys_fstatfs, "DUNE_SYS_FSTATFS"},
625         [DUNE_SYS_SYSFS] = {NULL, "DUNE_SYS_SYSFS"},
626         [DUNE_SYS_GETPRIORITY] = {NULL, "DUNE_SYS_GETPRIORITY"},
627         [DUNE_SYS_SETPRIORITY] = {NULL, "DUNE_SYS_SETPRIORITY"},
628         [DUNE_SYS_SCHED_SETPARAM] = {NULL, "DUNE_SYS_SCHED_SETPARAM"},
629         [DUNE_SYS_SCHED_GETPARAM] = {NULL, "DUNE_SYS_SCHED_GETPARAM"},
630         [DUNE_SYS_SCHED_SETSCHEDULER] = {NULL, "DUNE_SYS_SCHED_SETSCHEDULER"},
631         [DUNE_SYS_SCHED_GETSCHEDULER] = {NULL, "DUNE_SYS_SCHED_GETSCHEDULER"},
632         [DUNE_SYS_SCHED_GET_PRIORITY_MAX] = {NULL,
633                                             "DUNE_SYS_SCHED_GET_PRIORITY_MAX"},
634         [DUNE_SYS_SCHED_GET_PRIORITY_MIN] = {NULL,
635                                             "DUNE_SYS_SCHED_GET_PRIORITY_MIN"},
636         [DUNE_SYS_SCHED_RR_GET_INTERVAL] = {NULL, "DUNE_SYS_SCHED_RR_GET_INTERVAL"},
637         [DUNE_SYS_MLOCK] = {NULL, "DUNE_SYS_MLOCK"},
638         [DUNE_SYS_MUNLOCK] = {NULL, "DUNE_SYS_MUNLOCK"},
639         [DUNE_SYS_MLOCKALL] = {NULL, "DUNE_SYS_MLOCKALL"},
640         [DUNE_SYS_MUNLOCKALL] = {NULL, "DUNE_SYS_MUNLOCKALL"},
641         [DUNE_SYS_VHANGUP] = {NULL, "DUNE_SYS_VHANGUP"},
642         [DUNE_SYS_MODIFY_LDT] = {NULL, "DUNE_SYS_MODIFY_LDT"},
643         [DUNE_SYS_PIVOT_ROOT] = {NULL, "DUNE_SYS_PIVOT_ROOT"},
644         [DUNE_SYS__SYSCTL] = {NULL, "DUNE_SYS__SYSCTL"},
645         [DUNE_SYS_PRCTL] = {NULL, "DUNE_SYS_PRCTL"},
646         [DUNE_SYS_ARCH_PRCTL] = {NULL, "DUNE_SYS_ARCH_PRCTL"},
647         [DUNE_SYS_ADJTIMEX] = {NULL, "DUNE_SYS_ADJTIMEX"},
648         [DUNE_SYS_SETRLIMIT] = {NULL, "DUNE_SYS_SETRLIMIT"},
649         [DUNE_SYS_CHROOT] = {NULL, "DUNE_SYS_CHROOT"},
650         [DUNE_SYS_SYNC] = {NULL, "DUNE_SYS_SYNC"},
651         [DUNE_SYS_ACCT] = {NULL, "DUNE_SYS_ACCT"},
652         [DUNE_SYS_SETTIMEOFDAY] = {NULL, "DUNE_SYS_SETTIMEOFDAY"},
653         [DUNE_SYS_MOUNT] = {NULL, "DUNE_SYS_MOUNT"},
654         [DUNE_SYS_UMOUNT2] = {NULL, "DUNE_SYS_UMOUNT2"},
655         [DUNE_SYS_SWAPON] = {NULL, "DUNE_SYS_SWAPON"},
656         [DUNE_SYS_SWAPOFF] = {NULL, "DUNE_SYS_SWAPOFF"},
657         [DUNE_SYS_REBOOT] = {NULL, "DUNE_SYS_REBOOT"},
658         [DUNE_SYS_SETHOSTNAME] = {NULL, "DUNE_SYS_SETHOSTNAME"},
659         [DUNE_SYS_SETDOMAINNAME] = {NULL, "DUNE_SYS_SETDOMAINNAME"},
660         [DUNE_SYS_IOPL] = {NULL, "DUNE_SYS_IOPL"},
661         [DUNE_SYS_IOPERM] = {NULL, "DUNE_SYS_IOPERM"},
662         [DUNE_SYS_CREATE_MODULE] = {NULL, "DUNE_SYS_CREATE_MODULE"},
663         [DUNE_SYS_INIT_MODULE] = {NULL, "DUNE_SYS_INIT_MODULE"},
664         [DUNE_SYS_DELETE_MODULE] = {NULL, "DUNE_SYS_DELETE_MODULE"},
665         [DUNE_SYS_GET_KERNEL_SYMS] = {NULL, "DUNE_SYS_GET_KERNEL_SYMS"},
666         [DUNE_SYS_QUERY_MODULE] = {NULL, "DUNE_SYS_QUERY_MODULE"},
667         [DUNE_SYS_QUOTACTL] = {NULL, "DUNE_SYS_QUOTACTL"},
668         [DUNE_SYS_NFSSERVCTL] = {NULL, "DUNE_SYS_NFSSERVCTL"},
669         [DUNE_SYS_GETPMSG] = {NULL, "DUNE_SYS_GETPMSG"},
670         [DUNE_SYS_PUTPMSG] = {NULL, "DUNE_SYS_PUTPMSG"},
671         [DUNE_SYS_AFS_SYSCALL] = {NULL, "DUNE_SYS_AFS_SYSCALL"},
672         [DUNE_SYS_TUXCALL] = {NULL, "DUNE_SYS_TUXCALL"},
673         [DUNE_SYS_SECURITY] = {NULL, "DUNE_SYS_SECURITY"},
674         [DUNE_SYS_GETTID] = {dune_sys_gettid, "DUNE_SYS_GETTID"},
675         [DUNE_SYS_READAHEAD] = {NULL, "DUNE_SYS_READAHEAD"},
676         [DUNE_SYS_SETXATTR] = {NULL, "DUNE_SYS_SETXATTR"},
677         [DUNE_SYS_LSETXATTR] = {NULL, "DUNE_SYS_LSETXATTR"},
678         [DUNE_SYS_FSETXATTR] = {NULL, "DUNE_SYS_FSETXATTR"},
679         [DUNE_SYS_GETXATTR] = {NULL, "DUNE_SYS_GETXATTR"},
680         [DUNE_SYS_LGETXATTR] = {NULL, "DUNE_SYS_LGETXATTR"},
681         [DUNE_SYS_FGETXATTR] = {NULL, "DUNE_SYS_FGETXATTR"},
682         [DUNE_SYS_LISTXATTR] = {NULL, "DUNE_SYS_LISTXATTR"},
683         [DUNE_SYS_LLISTXATTR] = {NULL, "DUNE_SYS_LLISTXATTR"},
684         [DUNE_SYS_FLISTXATTR] = {NULL, "DUNE_SYS_FLISTXATTR"},
685         [DUNE_SYS_REMOVEXATTR] = {NULL, "DUNE_SYS_REMOVEXATTR"},
686         [DUNE_SYS_LREMOVEXATTR] = {NULL, "DUNE_SYS_LREMOVEXATTR"},
687         [DUNE_SYS_FREMOVEXATTR] = {NULL, "DUNE_SYS_FREMOVEXATTR"},
688         [DUNE_SYS_TKILL] = {NULL, "DUNE_SYS_TKILL"},
689         [DUNE_SYS_TIME] = {NULL, "DUNE_SYS_TIME"},
690         [DUNE_SYS_FUTEX] = {dune_sys_futex, "DUNE_SYS_FUTEX"},
691         [DUNE_SYS_SCHED_SETAFFINITY] = {NULL, "DUNE_SYS_SCHED_SETAFFINITY"},
692         [DUNE_SYS_SCHED_GETAFFINITY] = {dune_sys_sched_getaffinity,
693                                         "DUNE_SYS_SCHED_GETAFFINITY"},
694         [DUNE_SYS_SET_THREAD_AREA] = {NULL, "DUNE_SYS_SET_THREAD_AREA"},
695         [DUNE_SYS_IO_SETUP] = {NULL, "DUNE_SYS_IO_SETUP"},
696         [DUNE_SYS_IO_DESTROY] = {NULL, "DUNE_SYS_IO_DESTROY"},
697         [DUNE_SYS_IO_GETEVENTS] = {NULL, "DUNE_SYS_IO_GETEVENTS"},
698         [DUNE_SYS_IO_SUBMIT] = {NULL, "DUNE_SYS_IO_SUBMIT"},
699         [DUNE_SYS_IO_CANCEL] = {NULL, "DUNE_SYS_IO_CANCEL"},
700         [DUNE_SYS_GET_THREAD_AREA] = {NULL, "DUNE_SYS_GET_THREAD_AREA"},
701         [DUNE_SYS_LOOKUP_DCOOKIE] = {NULL, "DUNE_SYS_LOOKUP_DCOOKIE"},
702         [DUNE_SYS_EPOLL_CREATE] = {NULL, "DUNE_SYS_EPOLL_CREATE"},
703         [DUNE_SYS_EPOLL_CTL_OLD] = {NULL, "DUNE_SYS_EPOLL_CTL_OLD"},
704         [DUNE_SYS_EPOLL_WAIT_OLD] = {NULL, "DUNE_SYS_EPOLL_WAIT_OLD"},
705         [DUNE_SYS_REMAP_FILE_PAGES] = {NULL, "DUNE_SYS_REMAP_FILE_PAGES"},
706         [DUNE_SYS_GETDENTS64] = {NULL, "DUNE_SYS_GETDENTS64"},
707         [DUNE_SYS_SET_TID_ADDRESS] = {NULL, "DUNE_SYS_SET_TID_ADDRESS"},
708         [DUNE_SYS_RESTART_SYSCALL] = {NULL, "DUNE_SYS_RESTART_SYSCALL"},
709         [DUNE_SYS_SEMTIMEDOP] = {NULL, "DUNE_SYS_SEMTIMEDOP"},
710         [DUNE_SYS_FADVISE64] = {NULL, "DUNE_SYS_FADVISE64"},
711         [DUNE_SYS_TIMER_CREATE] = {NULL, "DUNE_SYS_TIMER_CREATE"},
712         [DUNE_SYS_TIMER_SETTIME] = {NULL, "DUNE_SYS_TIMER_SETTIME"},
713         [DUNE_SYS_TIMER_GETTIME] = {NULL, "DUNE_SYS_TIMER_GETTIME"},
714         [DUNE_SYS_TIMER_GETOVERRUN] = {NULL, "DUNE_SYS_TIMER_GETOVERRUN"},
715         [DUNE_SYS_TIMER_DELETE] = {NULL, "DUNE_SYS_TIMER_DELETE"},
716         [DUNE_SYS_CLOCK_SETTIME] = {NULL, "DUNE_SYS_CLOCK_SETTIME"},
717         [DUNE_SYS_CLOCK_GETTIME] = {dune_sys_clock_gettime,
718                                     "DUNE_SYS_CLOCK_GETTIME"},
719         [DUNE_SYS_CLOCK_GETRES] = {NULL, "DUNE_SYS_CLOCK_GETRES"},
720         [DUNE_SYS_CLOCK_NANOSLEEP] = {NULL, "DUNE_SYS_CLOCK_NANOSLEEP"},
721         [DUNE_SYS_EXIT_GROUP] = {NULL, "DUNE_SYS_EXIT_GROUP"},
722         [DUNE_SYS_EPOLL_WAIT] = {dune_sys_epoll_wait, "DUNE_SYS_EPOLL_WAIT"},
723         [DUNE_SYS_EPOLL_CTL] = {dune_sys_epoll_ctl, "DUNE_SYS_EPOLL_CTL"},
724         [DUNE_SYS_TGKILL] = {NULL, "DUNE_SYS_TGKILL"},
725         [DUNE_SYS_UTIMES] = {NULL, "DUNE_SYS_UTIMES"},
726         [DUNE_SYS_VSERVER] = {NULL, "DUNE_SYS_VSERVER"},
727         [DUNE_SYS_MBIND] = {NULL, "DUNE_SYS_MBIND"},
728         [DUNE_SYS_SET_MEMPOLICY] = {NULL, "DUNE_SYS_SET_MEMPOLICY"},
729         [DUNE_SYS_GET_MEMPOLICY] = {NULL, "DUNE_SYS_GET_MEMPOLICY"},
730         [DUNE_SYS_MQ_OPEN] = {NULL, "DUNE_SYS_MQ_OPEN"},
731         [DUNE_SYS_MQ_UNLINK] = {NULL, "DUNE_SYS_MQ_UNLINK"},
732         [DUNE_SYS_MQ_TIMEDSEND] = {NULL, "DUNE_SYS_MQ_TIMEDSEND"},
733         [DUNE_SYS_MQ_TIMEDRECEIVE] = {NULL, "DUNE_SYS_MQ_TIMEDRECEIVE"},
734         [DUNE_SYS_MQ_NOTIFY] = {NULL, "DUNE_SYS_MQ_NOTIFY"},
735         [DUNE_SYS_MQ_GETSETATTR] = {NULL, "DUNE_SYS_MQ_GETSETATTR"},
736         [DUNE_SYS_KEXEC_LOAD] = {NULL, "DUNE_SYS_KEXEC_LOAD"},
737         [DUNE_SYS_WAITID] = {NULL, "DUNE_SYS_WAITID"},
738         [DUNE_SYS_ADD_KEY] = {NULL, "DUNE_SYS_ADD_KEY"},
739         [DUNE_SYS_REQUEST_KEY] = {NULL, "DUNE_SYS_REQUEST_KEY"},
740         [DUNE_SYS_KEYCTL] = {NULL, "DUNE_SYS_KEYCTL"},
741         [DUNE_SYS_IOPRIO_SET] = {NULL, "DUNE_SYS_IOPRIO_SET"},
742         [DUNE_SYS_IOPRIO_GET] = {NULL, "DUNE_SYS_IOPRIO_GET"},
743         [DUNE_SYS_INOTIFY_INIT] = {NULL, "DUNE_SYS_INOTIFY_INIT"},
744         [DUNE_SYS_INOTIFY_ADD_WATCH] = {NULL, "DUNE_SYS_INOTIFY_ADD_WATCH"},
745         [DUNE_SYS_INOTIFY_RM_WATCH] = {NULL, "DUNE_SYS_INOTIFY_RM_WATCH"},
746         [DUNE_SYS_MIGRATE_PAGES] = {NULL, "DUNE_SYS_MIGRATE_PAGES"},
747         [DUNE_SYS_OPENAT] = {dune_sys_openat, "DUNE_SYS_OPENAT"},
748         [DUNE_SYS_MKDIRAT] = {NULL, "DUNE_SYS_MKDIRAT"},
749         [DUNE_SYS_MKNODAT] = {NULL, "DUNE_SYS_MKNODAT"},
750         [DUNE_SYS_FCHOWNAT] = {NULL, "DUNE_SYS_FCHOWNAT"},
751         [DUNE_SYS_FUTIMESAT] = {NULL, "DUNE_SYS_FUTIMESAT"},
752         [DUNE_SYS_NEWFSTATAT] = {NULL, "DUNE_SYS_NEWFSTATAT"},
753         [DUNE_SYS_UNLINKAT] = {dune_sys_unlinkat, "DUNE_SYS_UNLINKAT"},
754         [DUNE_SYS_RENAMEAT] = {NULL, "DUNE_SYS_RENAMEAT"},
755         [DUNE_SYS_LINKAT] = {NULL, "DUNE_SYS_LINKAT"},
756         [DUNE_SYS_SYMLINKAT] = {NULL, "DUNE_SYS_SYMLINKAT"},
757         [DUNE_SYS_READLINKAT] = {dune_sys_readlinkat, "DUNE_SYS_READLINKAT"},
758         [DUNE_SYS_FCHMODAT] = {NULL, "DUNE_SYS_FCHMODAT"},
759         [DUNE_SYS_FACCESSAT] = {NULL, "DUNE_SYS_FACCESSAT"},
760         [DUNE_SYS_PSELECT6] = {dune_sys_pselect6, "DUNE_SYS_PSELECT6"},
761         [DUNE_SYS_PPOLL] = {NULL, "DUNE_SYS_PPOLL"},
762         [DUNE_SYS_UNSHARE] = {NULL, "DUNE_SYS_UNSHARE"},
763         [DUNE_SYS_SET_ROBUST_LIST] = {NULL, "DUNE_SYS_SET_ROBUST_LIST"},
764         [DUNE_SYS_GET_ROBUST_LIST] = {NULL, "DUNE_SYS_GET_ROBUST_LIST"},
765         [DUNE_SYS_SPLICE] = {NULL, "DUNE_SYS_SPLICE"},
766         [DUNE_SYS_TEE] = {NULL, "DUNE_SYS_TEE"},
767         [DUNE_SYS_SYNC_FILE_RANGE] = {NULL, "DUNE_SYS_SYNC_FILE_RANGE"},
768         [DUNE_SYS_VMSPLICE] = {NULL, "DUNE_SYS_VMSPLICE"},
769         [DUNE_SYS_MOVE_PAGES] = {NULL, "DUNE_SYS_MOVE_PAGES"},
770         [DUNE_SYS_UTIMENSAT] = {NULL, "DUNE_SYS_UTIMENSAT"},
771         [DUNE_SYS_EPOLL_PWAIT] = {NULL, "DUNE_SYS_EPOLL_PWAIT"},
772         [DUNE_SYS_SIGNALFD] = {NULL, "DUNE_SYS_SIGNALFD"},
773         [DUNE_SYS_TIMERFD_CREATE] = {NULL, "DUNE_SYS_TIMERFD_CREATE"},
774         [DUNE_SYS_EVENTFD] = {NULL, "DUNE_SYS_EVENTFD"},
775         [DUNE_SYS_FALLOCATE] = {dune_sys_fallocate, "DUNE_SYS_FALLOCATE"},
776         [DUNE_SYS_TIMERFD_SETTIME] = {NULL, "DUNE_SYS_TIMERFD_SETTIME"},
777         [DUNE_SYS_TIMERFD_GETTIME] = {NULL, "DUNE_SYS_TIMERFD_GETTIME"},
778         [DUNE_SYS_ACCEPT4] = {NULL, "DUNE_SYS_ACCEPT4"},
779         [DUNE_SYS_SIGNALFD4] = {NULL, "DUNE_SYS_SIGNALFD4"},
780         [DUNE_SYS_EVENTFD2] = {NULL, "DUNE_SYS_EVENTFD2"},
781         [DUNE_SYS_EPOLL_CREATE1] = {dune_sys_epoll_create1,
782                                     "DUNE_SYS_EPOLL_CREATE1"},
783         [DUNE_SYS_DUP3] = {NULL, "DUNE_SYS_DUP3"},
784         [DUNE_SYS_PIPE2] = {NULL, "DUNE_SYS_PIPE2"},
785         [DUNE_SYS_INOTIFY_INIT1] = {NULL, "DUNE_SYS_INOTIFY_INIT1"},
786         [DUNE_SYS_PREADV] = {NULL, "DUNE_SYS_PREADV"},
787         [DUNE_SYS_PWRITEV] = {NULL, "DUNE_SYS_PWRITEV"},
788         [DUNE_SYS_RT_TGSIGQUEUEINFO] = {NULL, "DUNE_SYS_RT_TGSIGQUEUEINFO"},
789         [DUNE_SYS_PERF_EVENT_OPEN] = {NULL, "DUNE_SYS_PERF_EVENT_OPEN"},
790         [DUNE_SYS_RECVMMSG] = {NULL, "DUNE_SYS_RECVMMSG"},
791         [DUNE_SYS_FANOTIFY_INIT] = {NULL, "DUNE_SYS_FANOTIFY_INIT"},
792         [DUNE_SYS_FANOTIFY_MARK] = {NULL, "DUNE_SYS_FANOTIFY_MARK"},
793         [DUNE_SYS_PRLIMIT64] = {NULL, "DUNE_SYS_PRLIMIT64"},
794         [DUNE_SYS_NAME_TO_HANDLE_AT] = {NULL, "DUNE_SYS_NAME_TO_HANDLE_AT"},
795         [DUNE_SYS_OPEN_BY_HANDLE_AT] = {NULL, "DUNE_SYS_OPEN_BY_HANDLE_AT"},
796         [DUNE_SYS_CLOCK_ADJTIME] = {NULL, "DUNE_SYS_CLOCK_ADJTIME"},
797         [DUNE_SYS_SYNCFS] = {NULL, "DUNE_SYS_SYNCFS"},
798         [DUNE_SYS_SENDMMSG] = {NULL, "DUNE_SYS_SENDMMSG"},
799         [DUNE_SYS_SETNS] = {NULL, "DUNE_SYS_SETNS"},
800         [DUNE_SYS_GETCPU] = {NULL, "DUNE_SYS_GETCPU"},
801         [DUNE_SYS_PROCESS_VM_READV] = {NULL, "DUNE_SYS_PROCESS_VM_READV"},
802         [DUNE_SYS_PROCESS_VM_WRITEV] = {NULL, "DUNE_SYS_PROCESS_VM_WRITEV"},
803         [DUNE_SYS_KCMP] = {NULL, "DUNE_KCMP"},
804         [DUNE_SYS_FINIT_MODULE] = {NULL, "DUNE_SYS_FINIT_MODULE"},
805         [DUNE_SYS_SCHED_SETATTR] = {NULL, "DUNE_SYS_SCHED_SETATTR"},
806         [DUNE_SYS_SCHED_GETATTR] = {NULL, "DUNE_SYS_SCHED_GETATTR"},
807         [DUNE_SYS_RENAMEAT2] = {NULL, "DUNE_SYS_RENAMEAT2"},
808         [DUNE_SYS_SECCOMP] = {NULL, "DUNE_SYS_SECCOMP"},
809         [DUNE_SYS_GETRANDOM] = {dune_sys_getrandom, "DUNE_SYS_GETRANDOM"},
810         [DUNE_SYS_MEMFD_CREATE] = {NULL, "DUNE_SYS_MEMFD_CREATE"},
811         [DUNE_SYS_KEXEC_FILE_LOAD] = {NULL, "DUNE_SYS_KEXEC_FILE_LOAD"},
812         [DUNE_SYS_BPF] = {NULL, "DUNE_SYS_BPF"},
813         [DUNE_STUB_EXECVEAT] = {NULL, "DUNE_STUB_EXECVEAT"},
814         [DUNE_USERFAULTFD] = {NULL, "DUNE_USERFAULTFD"},
815         [DUNE_MEMBARRIER] = {NULL, "DUNE_MEMBARRIER"},
816         [DUNE_MLOCK2] = {NULL, "DUNE_MLOCK2"},
817         [DUNE_COPY_FILE_RANGE] = {NULL, "DUNE_COPY_FILE_RANGE"},
818         [DUNE_PREADV2] = {NULL, "DUNE_PREADV2"},
819         [DUNE_PWRITEV2] = {NULL, "DUNE_PWRITEV2"},
820
821 };
822
823 bool init_syscall_table(void)
824 {
825         int i;
826
827         for (i = 0; i < DUNE_MAX_NUM_SYSCALLS ; ++i) {
828                 if (dune_syscall_table[i].name == NULL)
829                         dune_syscall_table[i].name = "nosyscall";
830         }
831
832         if (dlopen("liblinuxemu_extend.so", RTLD_NOW) == NULL) {
833                 fprintf(stderr, "Not using any syscall extensions\n Reason: %s\n",
834                         dlerror());
835                 return false;
836         }
837
838         return true;
839 }
840
841 void lemuprint(const uint32_t tid, uint64_t syscall_number,
842                const bool isError, const char *fmt, ...)
843 {
844         va_list valist;
845         const char *prefix = "[TID %d] %s: ";
846         bool double_logging = false;
847
848         // Do not use global variable as a check to acquire lock.
849         // make sure it is not changed during our acquire/release.
850         int debug = lemu_debug;
851
852         // If we are not going to log anything anyway, just bail out.
853         if (!(debug > 0 || isError))
854                 return;
855
856         const char *syscall_name;
857
858         if (syscall_number >= DUNE_MAX_NUM_SYSCALLS)
859                 panic("lemuprint: Illegal Syscall #%d!\n", syscall_number);
860         else
861                 syscall_name = dune_syscall_table[syscall_number].name;
862
863         va_start(valist, fmt);
864
865         uth_mutex_lock(lemu_logging_lock);
866
867         // Print to stderr if debug level is sufficient
868         if (debug > 1) {
869                 fprintf(stderr, prefix, tid, syscall_name);
870                 vfprintf(stderr, fmt, valist);
871                 // Checks if we will double log to stderr
872                 if (lemu_global_logfile == stderr)
873                         double_logging = true;
874         }
875
876         // Log to the global logfile, if we defaulted the global logging to
877         // stderr then we don't want to log 2 times to stderr.
878         if (lemu_global_logfile != NULL && !double_logging) {
879                 fprintf(lemu_global_logfile, prefix, tid, syscall_name);
880                 vfprintf(lemu_global_logfile, fmt, valist);
881         }
882
883         uth_mutex_unlock(lemu_logging_lock);
884
885         va_end(valist);
886 }
887
888
889 /* TODO: have an array which classifies syscall args
890  * and "special" system calls (ones with weird return
891  * values etc.). For some cases, we don't even do a system
892  * call, and in many cases we have to rearrange arguments
893  * since Linux and Akaros don't share signatures, so this
894  * gets tricky. */
895 bool
896 linuxemu(struct guest_thread *gth, struct vm_trapframe *tf)
897 {
898         bool ret = false;
899
900         if (tf->tf_rax >= DUNE_MAX_NUM_SYSCALLS) {
901                 fprintf(stderr, "System call %d is out of range\n", tf->tf_rax);
902                 return false;
903         }
904
905
906         if (dune_syscall_table[tf->tf_rax].call == NULL) {
907                 fprintf(stderr, "System call #%d (%s) is not implemented\n",
908                         tf->tf_rax, dune_syscall_table[tf->tf_rax].name);
909                 return false;
910         }
911
912         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax,
913                   false, "vmcall(%d, %p, %p, %p, %p, %p, %p);\n", tf->tf_rax,
914                   tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_r10, tf->tf_r8,
915                   tf->tf_r9);
916
917         tf->tf_rip += 3;
918
919         return (dune_syscall_table[tf->tf_rax].call)(tf);
920 }