parlib: have 2LS libraries #include parlib/stdio.h
[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 <parlib/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 #include <sys/epoll.h>
22
23 // This is the maximum fd number we allow opened in dune
24 #define DUNE_NR_FILE_DESC 100
25
26 // Some defines used in linux syscalls
27 #define FALLOC_FL_KEEP_SIZE 1
28 #define FALLOC_FL_PUNCH_HOLE 2
29 #define GRND_NONBLOCK 0x0001
30 #define GRND_RANDOM 0x0002
31
32 static int lemu_debug;
33
34 static uth_mutex_t *lemu_logging_lock;
35 static uth_mutex_t *fd_table_lock;
36
37 static FILE *lemu_global_logfile;
38
39 //Records the open fds of files opened with linuxemu
40 // TODO: Make this a dynamic array in the future
41 char *openfd_filenames[DUNE_NR_FILE_DESC];
42
43 void init_lemu_logging(int log_level)
44 {
45         const char *logfile_name = "lemu.log";
46         FILE *x = fopen(logfile_name, "w");
47
48         lemu_debug = log_level;
49         lemu_logging_lock = uth_mutex_alloc();
50
51         if (x != NULL)
52                 lemu_global_logfile = x;
53         else
54                 lemu_global_logfile = stderr;
55 }
56
57 void destroy_lemu_logging(void)
58 {
59         if (lemu_logging_lock != NULL)
60                 uth_mutex_free(lemu_logging_lock);
61
62         if (lemu_global_logfile != stderr)
63                 fclose(lemu_global_logfile);
64 }
65
66 /////////////////////////////////////
67 // BEGIN SYSCALL HELPERS
68 /////////////////////////////////////
69
70 // Checks if path is an absolute path
71 // Symlinks are not resolved, we just check if we refer to the root directory
72 bool is_absolute_path(const char *path)
73 {
74         if (!path || strlen(path) == 0)
75                 return false;
76         return (strncmp(path, "/", 1) == 0);
77 }
78
79
80 // This resolves relative paths in syscalls like openat and unlinkat, based on
81 // our currently opened fds in dune
82 //
83 // This function will allocate memory for the string absolute_path, it is the
84 // caller's responsibility to free this memory when it is done
85 //
86 // If path is an absolute path already, we ignore fd and retrun a copy of path
87 // in absolute_path
88 bool get_absolute_path_from_fd(int fd, const char *path, char **absolute_path)
89 {
90         if (!path) {
91                 fprintf(stderr, "get_absolute_path_from_fd: suffix is null.\n");
92                 return false;
93         }
94
95         if (fd >= DUNE_NR_FILE_DESC) {
96                 fprintf(stderr, "get_absolute_path_from_fd: fd too large.\n");
97                 return false;
98         }
99
100         int len1 = strlen(path);
101
102         if (len1 == 0) {
103                 fprintf(stderr,
104                         "get_absolute_path_from_fd: suffix is empty.\n");
105                 return false;
106         }
107
108         if (is_absolute_path(path)) {
109                 *absolute_path = calloc(sizeof(char), len1 + 1);
110                 if (!(*absolute_path)) {
111                         fprintf(stderr,
112                                 "get_absolute_path_from_fd: couldn't allocate memory.\n");
113                         return false;
114                 }
115                 strcpy(*absolute_path, path);
116                 return true;
117         }
118
119         uth_mutex_lock(fd_table_lock);
120         if (!openfd_filenames[fd]) {
121                 uth_mutex_unlock(fd_table_lock);
122                 fprintf(stderr,
123                         "get_absolute_path_from_fd: no file open at fd.\n");
124                 return false;
125         }
126
127         int len2 = strlen(openfd_filenames[fd]);
128
129         if (len2 == 0) {
130                 uth_mutex_unlock(fd_table_lock);
131                 fprintf(stderr,
132                         "get_absolute_path_from_fd: prefix has length 0, fd was probably not open.\n");
133                 return false;
134         }
135
136         // Add space for an extra slash and a null terminator
137         int total_len = len1 + len2 + 2;
138
139         *absolute_path = calloc(sizeof(char), total_len);
140
141         if (!(*absolute_path)) {
142                 uth_mutex_unlock(fd_table_lock);
143                 fprintf(stderr,
144                         "get_absolute_path_from_fd: couldn't allocate memory.\n");
145                 return false;
146         }
147
148         strcat(*absolute_path, openfd_filenames[fd]);
149         uth_mutex_unlock(fd_table_lock);
150
151         // Add a slash if we don't have one
152         if ((*absolute_path)[len2 - 1] != '/')
153                 strcat(*absolute_path, "/");
154
155         strcat(*absolute_path, path);
156
157         fprintf(stderr, "Constructed full path \"%s\"\n", *absolute_path);
158         return true;
159 }
160
161
162 //Akaros open flags are different than linux
163 //This function converts them
164 int convert_open_flags_ltoa(int flags)
165 {
166         int lower3bits = flags & 0x7;
167         int otherstuff = flags & ~(0x7);
168
169         switch (lower3bits) {
170         case 0:
171                 otherstuff |= O_RDONLY;
172                 break;
173         case 1:
174                 otherstuff |= O_WRONLY;
175                 break;
176         case 2:
177                 otherstuff |= O_RDWR;
178                 break;
179         default:
180                 // TODO(ganshun): We panic here for now if they are trying
181                 // behavior we do not expect
182                 panic("linuxemu, convert_open_flags_ltoa: unknown open flags provided\n");
183                 break;
184         }
185         return otherstuff;
186 }
187
188 int convert_open_flags_atol(int flags)
189 {
190         int lower3bits = flags & 0x7;
191         int otherstuff = flags & ~(0x7);
192
193         switch (lower3bits) {
194         case O_RDONLY:
195                 otherstuff |= 0;
196                 break;
197         case O_WRONLY:
198                 otherstuff |= 1;
199                 break;
200         case O_RDWR:
201                 otherstuff |= 2;
202                 break;
203         default:
204                 // TODO(ganshun): We panic here for now if they are trying
205                 // behavior we do not expect
206                 panic("linuxemu, convert_open_flags_atol: unknown open flags provided\n");
207                 break;
208         }
209         return otherstuff;
210 }
211
212 // Updates the fd mapping for a specific fd. Allows the fd mapping to
213 // be freed (in the case of a close). Calls to the function may leave
214 // values in the fd table as NULL
215 bool update_fd_map(int fd, const char *path)
216 {
217         int len = 0;
218
219         if (fd >= DUNE_NR_FILE_DESC)
220                 return false;
221
222         if (path)
223                 len = strlen(path);
224
225         uth_mutex_lock(fd_table_lock);
226
227         // If there was a file here before, free the string
228         // Potential optimization would be to only free when
229         // we need to grow the size of the string.
230         if (openfd_filenames[fd]) {
231                 free(openfd_filenames[fd]);
232                 openfd_filenames[fd] = NULL;
233         }
234         // If we have a new file to put here, allocate memory
235         // and copy it in.
236         if (len) {
237                 openfd_filenames[fd] = (char*) calloc(sizeof(char), len + 1);
238                 if (!openfd_filenames[fd]) {
239                         uth_mutex_unlock(fd_table_lock);
240                         panic("update_fd_map could not allocate memory\n");
241                         return false;
242                 }
243                 strcpy(openfd_filenames[fd], path);
244         }
245
246         uth_mutex_unlock(fd_table_lock);
247         return true;
248 }
249
250 void convert_stat_akaros_to_linux(struct stat *si_akaros,
251                                   struct linux_stat_amd64 *si)
252 {
253         si->st_dev =  (uint64_t) si_akaros->st_dev;
254         si->st_ino = (uint64_t) si_akaros->st_ino;
255         si->st_mode = (uint32_t) si_akaros->st_mode;
256         si->st_nlink = (uint64_t) si_akaros->st_nlink;
257         si->st_uid = (uint32_t) si_akaros->st_uid;
258         si->st_gid = (uint32_t) si_akaros->st_gid;
259         si->st_rdev = (uint64_t) si_akaros->st_rdev;
260         si->st_size = (int64_t) si_akaros->st_size;
261         si->st_blksize = (int64_t) si_akaros->st_blksize;
262         si->st_blocks = (int64_t) si_akaros->st_blocks;
263
264         //For now the akaros timespec works out... this might change
265         //akaros timespec must be 2x int64_t for this to be valid
266         si->st_atim = si_akaros->st_atim;
267         si->st_mtim = si_akaros->st_mtim;
268         si->st_ctim = si_akaros->st_ctim;
269 }
270
271 /////////////////////////////////////
272 // BEGIN DUNE SYSCALL IMPLEMENTATIONS
273 /////////////////////////////////////
274
275 //////////////////////////////////////////////////////
276 // Ported Syscalls (we just call the akaros version)
277 //////////////////////////////////////////////////////
278
279 bool dune_sys_ftruncate(struct vm_trapframe *tf)
280 {
281         int retval = ftruncate((int) tf->tf_rdi, (off_t) tf->tf_rsi);
282         int err = errno;
283
284         if (retval == -1) {
285                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
286                           "ERROR %d\n", err);
287                 tf->tf_rax = -err;
288         } else {
289                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
290                           "SUCCESS %d\n", retval);
291                 tf->tf_rax = retval;
292         }
293         return true;
294
295 }
296
297 bool dune_sys_fcntl(struct vm_trapframe *tf)
298 {
299         int retval = fcntl((int) tf->tf_rdi, (int) tf->tf_rsi, (int) tf->tf_rdx);
300         int err = errno;
301
302         if (retval == -1) {
303                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
304                           "ERROR %d\n", err);
305                 tf->tf_rax = -err;
306         } else {
307                 // TODO(ganshun): fix fcntl SETFL, ak flags are different.
308                 if (tf->tf_rsi == 3)
309                         retval = convert_open_flags_atol(retval);
310                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
311                           "SUCCESS %d\n", retval);
312                 tf->tf_rax = retval;
313         }
314         return true;
315 }
316
317 bool dune_sys_pread64(struct vm_trapframe *tf)
318 {
319         int fd = (int) tf->tf_rdi;
320         void *buf = (void*) tf->tf_rsi;
321         size_t count = tf->tf_rdx;
322         off_t offset = (off_t) tf->tf_r10;
323
324         ssize_t retval = pread(fd, buf, count, offset);
325         int err = errno;
326
327         if (retval == -1) {
328                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
329                           "ERROR %zd\n", err);
330                 tf->tf_rax = -err;
331         } else {
332                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
333                           "SUCCESS %zd\n", retval);
334                 tf->tf_rax = retval;
335         }
336         return true;
337 }
338
339 bool dune_sys_read(struct vm_trapframe *tf)
340 {
341         ssize_t retval = read(tf->tf_rdi, (void*) tf->tf_rsi,
342                               (size_t) tf->tf_rdx);
343         int err = errno;
344
345         if (retval == -1) {
346                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
347                           "ERROR %zd\n", err);
348                 tf->tf_rax = -err;
349         } else {
350                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
351                           "SUCCESS %zd\n", retval);
352                 tf->tf_rax = retval;
353         }
354         return true;
355 }
356
357 bool dune_sys_pwrite64(struct vm_trapframe *tf)
358 {
359         int fd = (int) tf->tf_rdi;
360         const void *buf = (const void*) tf->tf_rsi;
361         size_t length = (size_t) tf->tf_rdx;
362         off_t offset = (off_t) tf->tf_r10;
363
364         ssize_t retval = pwrite(fd, buf, length, offset);
365         int err = errno;
366
367         if (retval == -1) {
368                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
369                           "ERROR %zd\n", err);
370                 tf->tf_rax = -err;
371         } else {
372                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
373                           "SUCCESS %zd\n", retval);
374                 tf->tf_rax = retval;
375         }
376         return true;
377 }
378
379 bool dune_sys_write(struct vm_trapframe *tf)
380 {
381         ssize_t retval = write((int) tf->tf_rdi, (const void *) tf->tf_rsi,
382                                (size_t) tf->tf_rdx);
383         int err = errno;
384
385         if (retval == -1) {
386                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
387                           "ERROR %zd\n", err);
388                 tf->tf_rax = -err;
389         } else {
390                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
391                           "SUCCESS %zd\n", retval);
392                 tf->tf_rax = retval;
393         }
394         return true;
395 }
396
397 bool dune_sys_getpid(struct vm_trapframe *tf)
398 {
399         // Getpid always suceeds
400         int retval = getpid();
401
402         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n",
403                   retval);
404         tf->tf_rax = retval;
405         return true;
406 }
407
408 bool dune_sys_gettimeofday(struct vm_trapframe *tf)
409 {
410         int retval = gettimeofday((struct timeval*) tf->tf_rdi,
411                                   (struct timezone*) tf->tf_rsi);
412         int err = errno;
413
414         if (retval == -1) {
415                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
416                           "ERROR %d\n", err);
417                 tf->tf_rax = -err;
418         } else {
419                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
420                           "SUCCESS %d\n", retval);
421                 tf->tf_rax = retval;
422         }
423         return true;
424 }
425
426 bool dune_sys_dup(struct vm_trapframe *tf)
427 {
428         int retval = dup((int) tf->tf_rdi);
429         int err = errno;
430
431         if (retval == -1) {
432                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
433                           "ERROR %d\n", err);
434                 tf->tf_rax = -err;
435         } else {
436                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
437                           "SUCCESS %d\n", retval);
438                 tf->tf_rax = retval;
439         }
440         return true;
441 }
442
443 bool dune_sys_dup2(struct vm_trapframe *tf)
444 {
445         int retval = dup2((int) tf->tf_rdi, (int)tf->tf_rsi);
446         int err = errno;
447
448         if (retval == -1) {
449                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
450                           "ERROR %d\n", err);
451                 tf->tf_rax = -err;
452         } else {
453                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
454                           "SUCCESS %d\n", retval);
455                 tf->tf_rax = retval;
456         }
457         return true;
458 }
459
460 bool dune_sys_umask(struct vm_trapframe *tf)
461 {
462         //Umask always succeeds
463         int retval = umask((mode_t) tf->tf_rdi);
464
465         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n",
466                   retval);
467         tf->tf_rax = retval;
468         return true;
469 }
470
471 bool dune_sys_clock_gettime(struct vm_trapframe *tf)
472 {
473         int retval = clock_gettime(tf->tf_rdi, (struct timespec*) tf->tf_rsi);
474         int err = errno;
475
476         if (retval == -1) {
477                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
478                           "ERROR %d\n", err);
479                 tf->tf_rax = -err;
480         } else {
481                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
482                           "SUCCESS %d\n", retval);
483                 tf->tf_rax = retval;
484         }
485         return true;
486 }
487
488 bool dune_sys_munmap(struct vm_trapframe *tf)
489 {
490         int retval = munmap((void *) tf->tf_rdi, tf->tf_rsi);
491         int err = errno;
492
493         if (retval == -1) {
494                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
495                           "ERROR %d\n", err);
496                 tf->tf_rax = -err;
497         } else {
498                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
499                           "SUCCESS %d\n", retval);
500                 tf->tf_rax = retval;
501         }
502         return true;
503 }
504
505 bool dune_sys_futex(struct vm_trapframe *tf)
506 {
507         int *uaddr = (int*) tf->tf_rdi;
508         int op = (int) tf->tf_rsi;
509         int val = (int) tf->tf_rdx;
510         struct timespec *timeout = (struct timespec *) tf->tf_r10;
511         int *uaddr2 = (int*) tf->tf_r8;
512         int val3 = (int) tf->tf_r9;
513         int retval = futex(uaddr, op, val, timeout, uaddr2, val3);
514         int err = errno;
515
516         if (retval == -1) {
517                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
518                           "ERROR %d\n", err);
519                 tf->tf_rax = -err;
520         } else {
521                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
522                           "SUCCESS %d\n", retval);
523                 tf->tf_rax = retval;
524         }
525         return true;
526 }
527
528 bool dune_sys_gettid(struct vm_trapframe *tf)
529 {
530         // Gettid always succeeds
531         int retval = tf->tf_guest_pcoreid;
532
533         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false, "SUCCESS %d\n",
534                   retval);
535         tf->tf_rax = retval;
536         return true;
537 }
538
539 /////////////////////////////////////////////////////////
540 // Modified Syscalls (Partially implemented in Akaros)
541 ////////////////////////////////////////////////////////
542
543 bool dune_sys_open(struct vm_trapframe *tf)
544 {
545         const char *file = (const char *) tf->tf_rdi;
546         int flags = tf->tf_rsi;
547         int mode = tf->tf_rdx;
548
549         flags = convert_open_flags_ltoa(flags);
550         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
551                   "Trying to open \"%s\"\n", file);
552
553         int retval  = open(file, flags, mode);
554         int err = errno;
555
556         if (retval == -1) {
557                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
558                           "ERROR %d\n", err);
559                 tf->tf_rax = -err;
560                 return true;
561         }
562
563         if (!update_fd_map(retval, file))
564                 panic("[TID %d] %s: ERROR in updating fd_mapping\n",
565                       tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name);
566
567         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
568                   "SUCCESS %d\n", retval);
569         tf->tf_rax = retval;
570         return true;
571 }
572
573 bool dune_sys_openat(struct vm_trapframe *tf)
574 {
575
576         int fd = (int) tf->tf_rdi;
577         const char *s = (const char *) tf->tf_rsi;
578         int flags = (int) tf->tf_rdx;
579         char *s_absolute = NULL;
580         int retval;
581         int err;
582
583         // TODO: we panic here on failure, but there are probably instances
584         // where we'd want to recover and return EBADF or ENOTDIR
585         if (!get_absolute_path_from_fd(fd, s, &s_absolute)) {
586                 panic("[TID %d] %s: ERROR in getting absolute path fd was %d, suffix was %s\n",
587                       tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name,
588                       fd, s);
589         }
590
591         flags = convert_open_flags_ltoa(flags);
592         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
593                   "trying to open absolute path %s with translated flags %p\n",
594                   s, flags);
595         retval = open(s_absolute, flags);
596         err = errno;
597
598         if (retval == -1) {
599                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
600                           "ERROR %d\n", err);
601                 tf->tf_rax = -err;
602                 free(s_absolute);
603                 return true;
604         }
605
606         if (!update_fd_map(retval, s_absolute)) {
607                 panic("[TID %d] %s: ERROR in updating fd_mapping\n",
608                       tf->tf_guest_pcoreid,
609                       dune_syscall_table[tf->tf_rax].name);
610         }
611
612         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
613                   "SUCCESS %d\n", retval);
614         free(s_absolute);
615         tf->tf_rax = retval;
616         return true;
617 }
618
619 bool dune_sys_readlinkat(struct vm_trapframe *tf)
620 {
621         int fd = (int) tf->tf_rdi;
622         const char *s = (const char*) tf->tf_rsi;
623         char *buf = (char *) tf->tf_rdx;
624         size_t bufsize = (size_t) tf->tf_r10;
625         ssize_t retval;
626         int err;
627         char *s_absolute = NULL;
628
629
630         if (!get_absolute_path_from_fd(fd, s, &s_absolute)) {
631                 panic("[TID %d] %s: ERROR in getting absolute path fd was %d, suffix was %s\n",
632                       tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name,
633                       fd, s);
634         }
635
636         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
637                   "trying to readlink %s\n", s_absolute);
638         retval = readlink(s_absolute, buf, bufsize);
639         err = errno;
640         free(s_absolute);
641
642         if (retval == -1) {
643                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
644                           "ERROR %d\n", err);
645                 tf->tf_rax = -err;
646         } else {
647                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
648                           "SUCCESS %zd\n", retval);
649                 tf->tf_rax = retval;
650         }
651         return true;
652 }
653
654 bool dune_sys_unlinkat(struct vm_trapframe *tf)
655 {
656         int fd = (int) tf->tf_rdi;
657         const char *s = (const char*) tf->tf_rsi;
658         int flags = (int) tf->tf_rdx;
659         char *s_absolute = NULL;
660         int retval, err;
661
662         if (!get_absolute_path_from_fd(fd, s, &s_absolute)) {
663                 panic("[TID %d] %s: ERROR in getting absolute path fd was %d, suffix was %s\n",
664                       tf->tf_guest_pcoreid, dune_syscall_table[tf->tf_rax].name,
665                       fd, s);
666         }
667
668         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
669                   "trying to unlink %s\n", s_absolute);
670         retval = unlink(s_absolute);
671         err = errno;
672         free(s_absolute);
673
674         if (retval == -1) {
675                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
676                           "ERROR %d\n", err);
677                 tf->tf_rax = -err;
678         } else {
679                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
680                           "SUCCESS %d\n", retval);
681                 tf->tf_rax = retval;
682         }
683         return true;
684 }
685
686 bool dune_sys_close(struct vm_trapframe *tf)
687 {
688         int fd = tf->tf_rdi;
689         int retval, err;
690
691         retval = close(fd);
692         err = errno;
693
694         if (retval == -1) {
695                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
696                           "ERROR %d\n", err);
697                 tf->tf_rax = -err;
698                 return true;
699         }
700
701         if (!update_fd_map(fd, NULL)) {
702                 panic("[TID %d] %s: ERROR in updating fd_mapping\n",
703                       tf->tf_guest_pcoreid,
704                       dune_syscall_table[tf->tf_rax].name);
705         }
706
707         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
708                   "SUCCESS %d\n", retval);
709         tf->tf_rax = retval;
710         return true;
711 }
712
713 bool dune_sys_sched_yield(struct vm_trapframe *tf)
714 {
715         tf->tf_rax = 0;
716         uthread_sched_yield();
717         return true;
718 }
719
720
721 bool dune_sys_fstat(struct vm_trapframe *tf)
722 {
723         struct stat si_akaros_val;
724         int fd = tf->tf_rdi;
725         struct linux_stat_amd64 *si = (struct linux_stat_amd64*) tf->tf_rsi;
726
727         // TODO(ganshun): Check if mmaped
728         if (!si) {
729                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
730                           "ERROR %d\n", EFAULT);
731                 tf->tf_rax = -EFAULT;
732                 return true;
733         }
734
735         struct stat *si_akaros = &si_akaros_val;
736
737         // Make sure we zero out the data on the stack
738         memset((void*) si_akaros, 0, sizeof(struct stat));
739
740         int retval = fstat(fd, si_akaros);
741         int err = errno;
742
743         if (retval == -1) {
744                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
745                           "ERROR %d\n", err);
746                 tf->tf_rax = -err;
747         } else {
748                 convert_stat_akaros_to_linux(si_akaros, si);
749                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
750                           "SUCCESS %d\n", retval);
751                 tf->tf_rax = retval;
752         }
753         return true;
754 }
755
756 bool dune_sys_stat(struct vm_trapframe *tf)
757 {
758         struct stat si_akaros_val;
759         const char *path = (const char*) tf->tf_rdi;
760         struct linux_stat_amd64 *si = (struct linux_stat_amd64*) tf->tf_rsi;
761
762         // TODO(ganshun): Check if mmaped
763         if (!si) {
764                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
765                           "ERROR %d\n", EFAULT);
766                 tf->tf_rax = -EFAULT;
767                 return true;
768         }
769
770         struct stat *si_akaros = &si_akaros_val;
771
772         // Make sure we zero out the data on the stack
773         memset((void*) si_akaros, 0, sizeof(struct stat));
774
775         int retval = stat(path, si_akaros);
776         int err = errno;
777
778         if (retval == -1) {
779                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
780                           "ERROR %d\n", err);
781                 tf->tf_rax = -err;
782         } else {
783                 convert_stat_akaros_to_linux(si_akaros, si);
784                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
785                           "SUCCESS %d\n", retval);
786                 tf->tf_rax = retval;
787         }
788         return true;
789 }
790
791 ///////////////////////////////////////////////////
792 // Newly Implemented Syscalls
793 ///////////////////////////////////////////////////
794
795 // Dune implementation of fallocate, it just writes zeros for now
796 int dune_fallocate(int fd, int mode, off_t offset, off_t len)
797 {
798         if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)))
799                 return posix_fallocate(fd, offset, len);
800
801         if (offset < 0 || len <= 0) {
802                 errno = EINVAL;
803                 return -1;
804         }
805         struct stat st;
806         int ret = fstat(fd, &st);
807
808         if (ret == -1) {
809                 errno == EBADF;
810                 return -1;
811         }
812         if (offset + len >= st.st_size) {
813                 // Panic here as we cannot support changing the size of the file
814                 // right now.
815                 panic("dune_fallocate: would write over the size of the file!");
816         }
817         if (S_ISFIFO(st.st_mode)) {
818                 errno = ESPIPE;
819                 return -1;
820         }
821         if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) {
822                 errno = ENODEV;
823                 return -1;
824         }
825
826         // TODO(ganshun): For punch hole, we just write zeros to the file for
827         // now
828         if ((mode & FALLOC_FL_PUNCH_HOLE) && (mode & FALLOC_FL_KEEP_SIZE)) {
829                 const size_t buffer_size = 0x100000;
830                 int pos;
831                 ssize_t amt = 0;
832                 size_t tot = 0;
833                 size_t size;
834                 char *buf = calloc(sizeof(char), buffer_size);
835
836                 if (!buf)
837                         panic("dune_fallocate: could not allocate a buffer\n");
838
839                 for (pos = offset; pos < offset + len; pos += amt) {
840                         size = len + offset - pos;
841                         if (size > buffer_size)
842                                 size = buffer_size;
843                         amt = write(fd, buf, size);
844                         if (amt == -1) {
845                                 free(buf);
846                                 errno = EIO;
847                                 return -1;
848                         }
849                         tot += amt;
850                         fprintf(stderr, "%d bytes written so far\n", tot);
851                 }
852                 free(buf);
853                 return tot;
854         }
855
856         // Unsupported otherwise
857         errno = ENOSYS;
858         return -1;
859 }
860
861 // Fallocate syscall
862 bool dune_sys_fallocate(struct vm_trapframe *tf)
863 {
864         int fd = (int) tf->tf_rdi;
865         int mode = (int) tf->tf_rsi;
866         off_t offset = (off_t) tf->tf_rdx;
867         off_t len = (off_t) tf->tf_r10;
868
869         int retval = dune_fallocate(fd, mode, offset, len);
870         int err = errno;
871
872         if (retval == -1) {
873                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
874                           "ERROR %d\n", err);
875                 tf->tf_rax = -err;
876         } else {
877                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
878                           "SUCCESS %d\n", retval);
879                 tf->tf_rax = retval;
880         }
881         return true;
882 }
883
884 // Currently unsupported
885 bool dune_sys_sched_getaffinity(struct vm_trapframe *tf)
886 {
887         tf->tf_rax = -ENOSYS;
888         return true;
889 }
890
891 // We do not implement pselect; however, some applications may try to
892 // use it as a portable way to sleep. If that is the case, then we
893 // allow it
894 bool dune_sys_pselect6(struct vm_trapframe *tf)
895 {
896         int nfds = (int) tf->tf_rdi;
897         fd_set *readfds = (fd_set *) tf->tf_rsi;
898         fd_set *writefds = (fd_set *) tf->tf_rdx;
899         fd_set *exceptfds = (fd_set *) tf->tf_r10;
900         const struct timespec *timeout = (const struct timespec *) tf->tf_r8;
901         const sigset_t *sigmask = (const sigset_t *) tf->tf_r9;
902
903         // Check if process wants to sleep
904         if (nfds == 0 && readfds == NULL && writefds == NULL &&
905             exceptfds == NULL && timeout != NULL) {
906                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
907                           "Sleeping for %ld seconds, %ld nanoseconds\n",
908                           timeout->tv_sec, timeout->tv_nsec);
909                 nanosleep(timeout, NULL);
910                 tf->tf_rax = 0;
911                 return true;
912         }
913
914         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
915                   "unimplemented, will now fail...\n");
916         return false;
917 }
918
919 bool dune_sys_getrandom(struct vm_trapframe *tf)
920 {
921         const char *random_source = "/dev/urandom";
922         void *buf = (void*) tf->tf_rdi;
923         size_t len = (size_t) tf->tf_rsi;
924         unsigned int flags = (unsigned int) tf->tf_rdx;
925
926         if (!buf) {
927                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
928                           "buffer inaccessable\n");
929                 tf->tf_rax = -EFAULT;
930                 return true;
931         }
932         if (flags & GRND_RANDOM || flags & GRND_NONBLOCK) {
933                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
934                           "unsupported flags specified\n");
935                 tf->tf_rax = -EINVAL;
936                 return true;
937         }
938
939         int fd = open(random_source, O_RDONLY);
940         int err = errno;
941
942         if (fd == -1) {
943                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
944                           "ERROR opening random source %s, errno=%d\n",
945                           random_source, err);
946                 return false;
947         }
948
949         ssize_t retval = read(fd, buf, len);
950
951         err = errno;
952         close(fd);
953         if (retval == -1) {
954                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
955                           "ERROR reading from random source %s, errno=%d\n",
956                           random_source, err);
957                 tf->tf_rax = -err;
958         } else {
959                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
960                           "SUCCESS %zd\n", retval);
961                 tf->tf_rax = retval;
962         }
963         return true;
964 }
965
966 /////////////////////////////////////////////////////////////////
967 /// We don't have a good implementation for these syscalls,
968 /// they will not work in all cases
969 /////////////////////////////////////////////////////////////////
970
971 bool dune_sys_getgroups(struct vm_trapframe *tf)
972 {
973         tf->tf_rax = 0;
974         return true;
975 }
976
977
978 bool dune_sys_geteuid(struct vm_trapframe *tf)
979 {
980         tf->tf_rax = 0;
981         return true;
982 }
983
984 bool dune_sys_getegid(struct vm_trapframe *tf)
985 {
986         tf->tf_rax = 0;
987         return true;
988 }
989
990
991 bool dune_sys_getuid(struct vm_trapframe *tf)
992 {
993         tf->tf_rax = 0;
994         return true;
995 }
996
997
998 bool dune_sys_getgid(struct vm_trapframe *tf)
999 {
1000         tf->tf_rax = 0;
1001         return true;
1002 }
1003
1004 // TODO(ganshun): implement mincore
1005 bool dune_sys_mincore(struct vm_trapframe *tf)
1006 {
1007         tf->tf_rax = -ENOMEM;
1008         return true;
1009 }
1010
1011 bool dune_sys_rt_sigprocmask(struct vm_trapframe *tf)
1012 {
1013         int retval = sigprocmask(tf->tf_rdi, (const sigset_t*) tf->tf_rsi,
1014                                  (sigset_t*) tf->tf_rdx);
1015         int err = errno;
1016
1017         if (retval == -1) {
1018                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
1019                           "ERROR %d\n", err);
1020                 tf->tf_rax = -err;
1021         } else {
1022                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
1023                           "SUCCESS %d\n", retval);
1024                 tf->tf_rax = retval;
1025         }
1026         return true;
1027 }
1028
1029 // TODO(ganshun): sigaltstack needs to implemented for the guest
1030 bool dune_sys_sigaltstack(struct vm_trapframe *tf)
1031 {
1032         tf->tf_rax = 0;
1033         return true;
1034 }
1035
1036
1037 // TODO(ganshun): more signal code, we need to be careful with this one,
1038 // we should not register guest signal handlers in akaros
1039 bool dune_sys_rt_sigaction(struct vm_trapframe *tf)
1040 {
1041         tf->tf_rax = 0;
1042         return true;
1043 }
1044
1045 //TODO(ganshun): we do not support epoll currently except for create and wait
1046 bool dune_sys_epoll_create1(struct vm_trapframe *tf)
1047 {
1048         int flags = 0;
1049         // TODO(ganshun): epoll_create is not fully supported for all flags
1050         // so we ignore the flags variable in the trapframe since it is not used.
1051         int retval = epoll_create1(flags);
1052         int err = errno;
1053
1054         if (retval == -1) {
1055                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
1056                           "ERROR %d\n", err);
1057                 tf->tf_rax = -err;
1058         } else {
1059                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
1060                           "SUCCESS %d\n", retval);
1061                 tf->tf_rax = retval;
1062         }
1063         return true;
1064 }
1065
1066 bool dune_sys_epoll_wait(struct vm_trapframe *tf)
1067 {
1068         int epfd = (int) tf->tf_rdi;
1069         struct epoll_event *events = (struct epoll_event*) tf->tf_rsi;
1070         int maxevents = (int) tf->tf_rdx;
1071         int timeout = (int) tf->tf_r10;
1072         int retval = epoll_wait(epfd, events, maxevents, timeout);
1073         int err = errno;
1074
1075         if (retval == -1) {
1076                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
1077                           "ERROR %d\n", err);
1078                 tf->tf_rax = -err;
1079         } else {
1080                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
1081                           "SUCCESS %d\n", retval);
1082                 tf->tf_rax = retval;
1083         }
1084         return true;
1085 }
1086
1087 // Unimplemented
1088 bool dune_sys_epoll_ctl(struct vm_trapframe *tf)
1089 {
1090         tf->tf_rax = -ENOSYS;
1091         return true;
1092 }
1093
1094 // Unimplemented
1095 bool dune_sys_fstatfs(struct vm_trapframe *tf)
1096 {
1097         tf->tf_rax = -ENOSYS;
1098         return true;
1099 }
1100
1101 // Main syscall table
1102 struct dune_sys_table_entry dune_syscall_table[DUNE_MAX_NUM_SYSCALLS] = {
1103         [DUNE_SYS_READ] = {dune_sys_read, "DUNE_SYS_READ"},
1104         [DUNE_SYS_WRITE] = {dune_sys_write, "DUNE_SYS_WRITE"},
1105         [DUNE_SYS_OPEN] = {dune_sys_open, "DUNE_SYS_OPEN"},
1106         [DUNE_SYS_CLOSE] = {dune_sys_close, "DUNE_SYS_CLOSE"},
1107         [DUNE_SYS_STAT] = {dune_sys_stat, "DUNE_SYS_STAT"},
1108         [DUNE_SYS_FSTAT] = {dune_sys_fstat, "DUNE_SYS_FSTAT"},
1109         [DUNE_SYS_LSTAT] = {NULL, "DUNE_SYS_LSTAT"},
1110         [DUNE_SYS_POLL] = {NULL, "DUNE_SYS_POLL"},
1111         [DUNE_SYS_LSEEK] = {NULL, "DUNE_SYS_LSEEK"},
1112         [DUNE_SYS_MMAP] = {NULL, "DUNE_SYS_MMAP"},
1113         [DUNE_SYS_MPROTECT] = {NULL, "DUNE_SYS_MPROTECT"},
1114         [DUNE_SYS_MUNMAP] = {dune_sys_munmap, "DUNE_SYS_MUNMAP"},
1115         [DUNE_SYS_BRK] = {NULL, "DUNE_SYS_BRK"},
1116         [DUNE_SYS_RT_SIGACTION] = {dune_sys_rt_sigaction, "DUNE_SYS_RT_SIGACTION"},
1117         [DUNE_SYS_RT_SIGPROCMASK] = {dune_sys_rt_sigprocmask,
1118                                      "DUNE_SYS_RT_SIGPROCMASK"},
1119         [DUNE_SYS_RT_SIGRETURN] = {NULL, "DUNE_SYS_RT_SIGRETURN"},
1120         [DUNE_SYS_IOCTL] = {NULL, "DUNE_SYS_IOCTL"},
1121         [DUNE_SYS_PREAD64] = {dune_sys_pread64, "DUNE_SYS_PREAD64"},
1122         [DUNE_SYS_PWRITE64] = {dune_sys_pwrite64, "DUNE_SYS_PWRITE64"},
1123         [DUNE_SYS_READV] = {NULL, "DUNE_SYS_READV"},
1124         [DUNE_SYS_WRITEV] = {NULL, "DUNE_SYS_WRITEV"},
1125         [DUNE_SYS_ACCESS] = {NULL, "DUNE_SYS_ACCESS"},
1126         [DUNE_SYS_PIPE] = {NULL, "DUNE_SYS_PIPE"},
1127         [DUNE_SYS_SELECT] = {NULL, "DUNE_SYS_SELECT"},
1128         [DUNE_SYS_SCHED_YIELD] = {dune_sys_sched_yield, "DUNE_SYS_SCHED_YIELD"},
1129         [DUNE_SYS_MREMAP] = {NULL, "DUNE_SYS_MREMAP"},
1130         [DUNE_SYS_MSYNC] = {NULL, "DUNE_SYS_MSYNC"},
1131         [DUNE_SYS_MINCORE] = {dune_sys_mincore, "DUNE_SYS_MINCORE"},
1132         [DUNE_SYS_MADVISE] = {NULL, "DUNE_SYS_MADVISE"},
1133         [DUNE_SYS_SHMGET] = {NULL, "DUNE_SYS_SHMGET"},
1134         [DUNE_SYS_SHMAT] = {NULL, "DUNE_SYS_SHMAT"},
1135         [DUNE_SYS_SHMCTL] = {NULL, "DUNE_SYS_SHMCTL"},
1136         [DUNE_SYS_DUP] = {dune_sys_dup, "DUNE_SYS_DUP"},
1137         [DUNE_SYS_DUP2] = {dune_sys_dup2, "DUNE_SYS_DUP2"},
1138         [DUNE_SYS_PAUSE] = {NULL, "DUNE_SYS_PAUSE"},
1139         [DUNE_SYS_NANOSLEEP] = {NULL, "DUNE_SYS_NANOSLEEP"},
1140         [DUNE_SYS_GETITIMER] = {NULL, "DUNE_SYS_GETITIMER"},
1141         [DUNE_SYS_ALARM] = {NULL, "DUNE_SYS_ALARM"},
1142         [DUNE_SYS_SETITIMER] = {NULL, "DUNE_SYS_SETITIMER"},
1143         [DUNE_SYS_GETPID] = {dune_sys_getpid, "DUNE_SYS_GETPID"},
1144         [DUNE_SYS_SENDFILE] = {NULL, "DUNE_SYS_SENDFILE"},
1145         [DUNE_SYS_SOCKET] = {NULL, "DUNE_SYS_SOCKET"},
1146         [DUNE_SYS_CONNECT] = {NULL, "DUNE_SYS_CONNECT"},
1147         [DUNE_SYS_ACCEPT] = {NULL, "DUNE_SYS_ACCEPT"},
1148         [DUNE_SYS_SENDTO] = {NULL, "DUNE_SYS_SENDTO"},
1149         [DUNE_SYS_RECVFROM] = {NULL, "DUNE_SYS_RECVFROM"},
1150         [DUNE_SYS_SENDMSG] = {NULL, "DUNE_SYS_SENDMSG"},
1151         [DUNE_SYS_RECVMSG] = {NULL, "DUNE_SYS_RECVMSG"},
1152         [DUNE_SYS_SHUTDOWN] = {NULL, "DUNE_SYS_SHUTDOWN"},
1153         [DUNE_SYS_BIND] = {NULL, "DUNE_SYS_BIND"},
1154         [DUNE_SYS_LISTEN] = {NULL, "DUNE_SYS_LISTEN"},
1155         [DUNE_SYS_GETSOCKNAME] = {NULL, "DUNE_SYS_GETSOCKNAME"},
1156         [DUNE_SYS_GETPEERNAME] = {NULL, "DUNE_SYS_GETPEERNAME"},
1157         [DUNE_SYS_SOCKETPAIR] = {NULL, "DUNE_SYS_SOCKETPAIR"},
1158         [DUNE_SYS_SETSOCKOPT] = {NULL, "DUNE_SYS_SETSOCKOPT"},
1159         [DUNE_SYS_GETSOCKOPT] = {NULL, "DUNE_SYS_GETSOCKOPT"},
1160         [DUNE_SYS_CLONE] = {NULL, "DUNE_SYS_CLONE"},
1161         [DUNE_SYS_FORK] = {NULL, "DUNE_SYS_FORK"},
1162         [DUNE_SYS_VFORK] = {NULL, "DUNE_SYS_VFORK"},
1163         [DUNE_SYS_EXECVE] = {NULL, "DUNE_SYS_EXECVE"},
1164         [DUNE_SYS_EXIT] = {NULL, "DUNE_SYS_EXIT"},
1165         [DUNE_SYS_WAIT4] = {NULL, "DUNE_SYS_WAIT4"},
1166         [DUNE_SYS_KILL] = {NULL, "DUNE_SYS_KILL"},
1167         [DUNE_SYS_UNAME] = {NULL, "DUNE_SYS_UNAME"},
1168         [DUNE_SYS_SEMGET] = {NULL, "DUNE_SYS_SEMGET"},
1169         [DUNE_SYS_SEMOP] = {NULL, "DUNE_SYS_SEMOP"},
1170         [DUNE_SYS_SEMCTL] = {NULL, "DUNE_SYS_SEMCTL"},
1171         [DUNE_SYS_SHMDT] = {NULL, "DUNE_SYS_SHMDT"},
1172         [DUNE_SYS_MSGGET] = {NULL, "DUNE_SYS_MSGGET"},
1173         [DUNE_SYS_MSGSND] = {NULL, "DUNE_SYS_MSGSND"},
1174         [DUNE_SYS_MSGRCV] = {NULL, "DUNE_SYS_MSGRCV"},
1175         [DUNE_SYS_MSGCTL] = {NULL, "DUNE_SYS_MSGCTL"},
1176         [DUNE_SYS_FCNTL] = {dune_sys_fcntl, "DUNE_SYS_FCNTL"},
1177         [DUNE_SYS_FLOCK] = {NULL, "DUNE_SYS_FLOCK"},
1178         [DUNE_SYS_FSYNC] = {NULL, "DUNE_SYS_FSYNC"},
1179         [DUNE_SYS_FDATASYNC] = {NULL, "DUNE_SYS_FDATASYNC"},
1180         [DUNE_SYS_TRUNCATE] = {NULL, "DUNE_SYS_TRUNCATE"},
1181         [DUNE_SYS_FTRUNCATE] = {dune_sys_ftruncate, "DUNE_SYS_FTRUNCATE"},
1182         [DUNE_SYS_GETDENTS] = {NULL, "DUNE_SYS_GETDENTS"},
1183         [DUNE_SYS_GETCWD] = {NULL, "DUNE_SYS_GETCWD"},
1184         [DUNE_SYS_CHDIR] = {NULL, "DUNE_SYS_CHDIR"},
1185         [DUNE_SYS_FCHDIR] = {NULL, "DUNE_SYS_FCHDIR"},
1186         [DUNE_SYS_RENAME] = {NULL, "DUNE_SYS_RENAME"},
1187         [DUNE_SYS_MKDIR] = {NULL, "DUNE_SYS_MKDIR"},
1188         [DUNE_SYS_RMDIR] = {NULL, "DUNE_SYS_RMDIR"},
1189         [DUNE_SYS_CREAT] = {NULL, "DUNE_SYS_CREAT"},
1190         [DUNE_SYS_LINK] = {NULL, "DUNE_SYS_LINK"},
1191         [DUNE_SYS_UNLINK] = {NULL, "DUNE_SYS_UNLINK"},
1192         [DUNE_SYS_SYMLINK] = {NULL, "DUNE_SYS_SYMLINK"},
1193         [DUNE_SYS_READLINK] = {NULL, "DUNE_SYS_READLINK"},
1194         [DUNE_SYS_CHMOD] = {NULL, "DUNE_SYS_CHMOD"},
1195         [DUNE_SYS_FCHMOD] = {NULL, "DUNE_SYS_FCHMOD"},
1196         [DUNE_SYS_CHOWN] = {NULL, "DUNE_SYS_CHOWN"},
1197         [DUNE_SYS_FCHOWN] = {NULL, "DUNE_SYS_FCHOWN"},
1198         [DUNE_SYS_LCHOWN] = {NULL, "DUNE_SYS_LCHOWN"},
1199         [DUNE_SYS_UMASK] = {dune_sys_umask, "DUNE_SYS_UMASK"},
1200         [DUNE_SYS_GETTIMEOFDAY] = {dune_sys_gettimeofday, "DUNE_SYS_GETTIMEOFDAY"},
1201         [DUNE_SYS_GETRLIMIT] = {NULL, "DUNE_SYS_GETRLIMIT"},
1202         [DUNE_SYS_GETRUSAGE] = {NULL, "DUNE_SYS_GETRUSAGE"},
1203         [DUNE_SYS_SYSINFO] = {NULL, "DUNE_SYS_SYSINFO"},
1204         [DUNE_SYS_TIMES] = {NULL, "DUNE_SYS_TIMES"},
1205         [DUNE_SYS_PTRACE] = {NULL, "DUNE_SYS_PTRACE"},
1206         [DUNE_SYS_GETUID] = {dune_sys_getuid, "DUNE_SYS_GETUID"},
1207         [DUNE_SYS_SYSLOG] = {NULL, "DUNE_SYS_SYSLOG"},
1208         [DUNE_SYS_GETGID] = {dune_sys_getgid, "DUNE_SYS_GETGID"},
1209         [DUNE_SYS_SETUID] = {NULL, "DUNE_SYS_SETUID"},
1210         [DUNE_SYS_SETGID] = {NULL, "DUNE_SYS_SETGID"},
1211         [DUNE_SYS_GETEUID] = {dune_sys_geteuid, "DUNE_SYS_GETEUID"},
1212         [DUNE_SYS_GETEGID] = {dune_sys_getegid, "DUNE_SYS_GETEGID"},
1213         [DUNE_SYS_SETPGID] = {NULL, "DUNE_SYS_SETPGID"},
1214         [DUNE_SYS_GETPPID] = {NULL, "DUNE_SYS_GETPPID"},
1215         [DUNE_SYS_GETPGRP] = {NULL, "DUNE_SYS_GETPGRP"},
1216         [DUNE_SYS_SETSID] = {NULL, "DUNE_SYS_SETSID"},
1217         [DUNE_SYS_SETREUID] = {NULL, "DUNE_SYS_SETREUID"},
1218         [DUNE_SYS_SETREGID] = {NULL, "DUNE_SYS_SETREGID"},
1219         [DUNE_SYS_GETGROUPS] = {dune_sys_getgroups, "DUNE_SYS_GETGROUPS"},
1220         [DUNE_SYS_SETGROUPS] = {NULL, "DUNE_SYS_SETGROUPS"},
1221         [DUNE_SYS_SETRESUID] = {NULL, "DUNE_SYS_SETRESUID"},
1222         [DUNE_SYS_GETRESUID] = {NULL, "DUNE_SYS_GETRESUID"},
1223         [DUNE_SYS_SETRESGID] = {NULL, "DUNE_SYS_SETRESGID"},
1224         [DUNE_SYS_GETRESGID] = {NULL, "DUNE_SYS_GETRESGID"},
1225         [DUNE_SYS_GETPGID] = {NULL, "DUNE_SYS_GETPGID"},
1226         [DUNE_SYS_SETFSUID] = {NULL, "DUNE_SYS_SETFSUID"},
1227         [DUNE_SYS_SETFSGID] = {NULL, "DUNE_SYS_SETFSGID"},
1228         [DUNE_SYS_GETSID] = {NULL, "DUNE_SYS_GETSID"},
1229         [DUNE_SYS_CAPGET] = {NULL, "DUNE_SYS_CAPGET"},
1230         [DUNE_SYS_CAPSET] = {NULL, "DUNE_SYS_CAPSET"},
1231         [DUNE_SYS_RT_SIGPENDING] = {NULL, "DUNE_SYS_RT_SIGPENDING"},
1232         [DUNE_SYS_RT_SIGTIMEDWAIT] = {NULL, "DUNE_SYS_RT_SIGTIMEDWAIT"},
1233         [DUNE_SYS_RT_SIGQUEUEINFO] = {NULL, "DUNE_SYS_RT_SIGQUEUEINFO"},
1234         [DUNE_SYS_RT_SIGSUSPEND] = {NULL, "DUNE_SYS_RT_SIGSUSPEND"},
1235         [DUNE_SYS_SIGALTSTACK] = {dune_sys_sigaltstack, "DUNE_SYS_SIGALTSTACK"},
1236         [DUNE_SYS_UTIME] = {NULL, "DUNE_SYS_UTIME"},
1237         [DUNE_SYS_MKNOD] = {NULL, "DUNE_SYS_MKNOD"},
1238         [DUNE_SYS_USELIB] = {NULL, "DUNE_SYS_USELIB"},
1239         [DUNE_SYS_PERSONALITY] = {NULL, "DUNE_SYS_PERSONALITY"},
1240         [DUNE_SYS_USTAT] = {NULL, "DUNE_SYS_USTAT"},
1241         [DUNE_SYS_STATFS] = {NULL, "DUNE_SYS_STATFS"},
1242         [DUNE_SYS_FSTATFS] = {dune_sys_fstatfs, "DUNE_SYS_FSTATFS"},
1243         [DUNE_SYS_SYSFS] = {NULL, "DUNE_SYS_SYSFS"},
1244         [DUNE_SYS_GETPRIORITY] = {NULL, "DUNE_SYS_GETPRIORITY"},
1245         [DUNE_SYS_SETPRIORITY] = {NULL, "DUNE_SYS_SETPRIORITY"},
1246         [DUNE_SYS_SCHED_SETPARAM] = {NULL, "DUNE_SYS_SCHED_SETPARAM"},
1247         [DUNE_SYS_SCHED_GETPARAM] = {NULL, "DUNE_SYS_SCHED_GETPARAM"},
1248         [DUNE_SYS_SCHED_SETSCHEDULER] = {NULL, "DUNE_SYS_SCHED_SETSCHEDULER"},
1249         [DUNE_SYS_SCHED_GETSCHEDULER] = {NULL, "DUNE_SYS_SCHED_GETSCHEDULER"},
1250         [DUNE_SYS_SCHED_GET_PRIORITY_MAX] = {NULL,
1251                                             "DUNE_SYS_SCHED_GET_PRIORITY_MAX"},
1252         [DUNE_SYS_SCHED_GET_PRIORITY_MIN] = {NULL,
1253                                             "DUNE_SYS_SCHED_GET_PRIORITY_MIN"},
1254         [DUNE_SYS_SCHED_RR_GET_INTERVAL] = {NULL, "DUNE_SYS_SCHED_RR_GET_INTERVAL"},
1255         [DUNE_SYS_MLOCK] = {NULL, "DUNE_SYS_MLOCK"},
1256         [DUNE_SYS_MUNLOCK] = {NULL, "DUNE_SYS_MUNLOCK"},
1257         [DUNE_SYS_MLOCKALL] = {NULL, "DUNE_SYS_MLOCKALL"},
1258         [DUNE_SYS_MUNLOCKALL] = {NULL, "DUNE_SYS_MUNLOCKALL"},
1259         [DUNE_SYS_VHANGUP] = {NULL, "DUNE_SYS_VHANGUP"},
1260         [DUNE_SYS_MODIFY_LDT] = {NULL, "DUNE_SYS_MODIFY_LDT"},
1261         [DUNE_SYS_PIVOT_ROOT] = {NULL, "DUNE_SYS_PIVOT_ROOT"},
1262         [DUNE_SYS__SYSCTL] = {NULL, "DUNE_SYS__SYSCTL"},
1263         [DUNE_SYS_PRCTL] = {NULL, "DUNE_SYS_PRCTL"},
1264         [DUNE_SYS_ARCH_PRCTL] = {NULL, "DUNE_SYS_ARCH_PRCTL"},
1265         [DUNE_SYS_ADJTIMEX] = {NULL, "DUNE_SYS_ADJTIMEX"},
1266         [DUNE_SYS_SETRLIMIT] = {NULL, "DUNE_SYS_SETRLIMIT"},
1267         [DUNE_SYS_CHROOT] = {NULL, "DUNE_SYS_CHROOT"},
1268         [DUNE_SYS_SYNC] = {NULL, "DUNE_SYS_SYNC"},
1269         [DUNE_SYS_ACCT] = {NULL, "DUNE_SYS_ACCT"},
1270         [DUNE_SYS_SETTIMEOFDAY] = {NULL, "DUNE_SYS_SETTIMEOFDAY"},
1271         [DUNE_SYS_MOUNT] = {NULL, "DUNE_SYS_MOUNT"},
1272         [DUNE_SYS_UMOUNT2] = {NULL, "DUNE_SYS_UMOUNT2"},
1273         [DUNE_SYS_SWAPON] = {NULL, "DUNE_SYS_SWAPON"},
1274         [DUNE_SYS_SWAPOFF] = {NULL, "DUNE_SYS_SWAPOFF"},
1275         [DUNE_SYS_REBOOT] = {NULL, "DUNE_SYS_REBOOT"},
1276         [DUNE_SYS_SETHOSTNAME] = {NULL, "DUNE_SYS_SETHOSTNAME"},
1277         [DUNE_SYS_SETDOMAINNAME] = {NULL, "DUNE_SYS_SETDOMAINNAME"},
1278         [DUNE_SYS_IOPL] = {NULL, "DUNE_SYS_IOPL"},
1279         [DUNE_SYS_IOPERM] = {NULL, "DUNE_SYS_IOPERM"},
1280         [DUNE_SYS_CREATE_MODULE] = {NULL, "DUNE_SYS_CREATE_MODULE"},
1281         [DUNE_SYS_INIT_MODULE] = {NULL, "DUNE_SYS_INIT_MODULE"},
1282         [DUNE_SYS_DELETE_MODULE] = {NULL, "DUNE_SYS_DELETE_MODULE"},
1283         [DUNE_SYS_GET_KERNEL_SYMS] = {NULL, "DUNE_SYS_GET_KERNEL_SYMS"},
1284         [DUNE_SYS_QUERY_MODULE] = {NULL, "DUNE_SYS_QUERY_MODULE"},
1285         [DUNE_SYS_QUOTACTL] = {NULL, "DUNE_SYS_QUOTACTL"},
1286         [DUNE_SYS_NFSSERVCTL] = {NULL, "DUNE_SYS_NFSSERVCTL"},
1287         [DUNE_SYS_GETPMSG] = {NULL, "DUNE_SYS_GETPMSG"},
1288         [DUNE_SYS_PUTPMSG] = {NULL, "DUNE_SYS_PUTPMSG"},
1289         [DUNE_SYS_AFS_SYSCALL] = {NULL, "DUNE_SYS_AFS_SYSCALL"},
1290         [DUNE_SYS_TUXCALL] = {NULL, "DUNE_SYS_TUXCALL"},
1291         [DUNE_SYS_SECURITY] = {NULL, "DUNE_SYS_SECURITY"},
1292         [DUNE_SYS_GETTID] = {dune_sys_gettid, "DUNE_SYS_GETTID"},
1293         [DUNE_SYS_READAHEAD] = {NULL, "DUNE_SYS_READAHEAD"},
1294         [DUNE_SYS_SETXATTR] = {NULL, "DUNE_SYS_SETXATTR"},
1295         [DUNE_SYS_LSETXATTR] = {NULL, "DUNE_SYS_LSETXATTR"},
1296         [DUNE_SYS_FSETXATTR] = {NULL, "DUNE_SYS_FSETXATTR"},
1297         [DUNE_SYS_GETXATTR] = {NULL, "DUNE_SYS_GETXATTR"},
1298         [DUNE_SYS_LGETXATTR] = {NULL, "DUNE_SYS_LGETXATTR"},
1299         [DUNE_SYS_FGETXATTR] = {NULL, "DUNE_SYS_FGETXATTR"},
1300         [DUNE_SYS_LISTXATTR] = {NULL, "DUNE_SYS_LISTXATTR"},
1301         [DUNE_SYS_LLISTXATTR] = {NULL, "DUNE_SYS_LLISTXATTR"},
1302         [DUNE_SYS_FLISTXATTR] = {NULL, "DUNE_SYS_FLISTXATTR"},
1303         [DUNE_SYS_REMOVEXATTR] = {NULL, "DUNE_SYS_REMOVEXATTR"},
1304         [DUNE_SYS_LREMOVEXATTR] = {NULL, "DUNE_SYS_LREMOVEXATTR"},
1305         [DUNE_SYS_FREMOVEXATTR] = {NULL, "DUNE_SYS_FREMOVEXATTR"},
1306         [DUNE_SYS_TKILL] = {NULL, "DUNE_SYS_TKILL"},
1307         [DUNE_SYS_TIME] = {NULL, "DUNE_SYS_TIME"},
1308         [DUNE_SYS_FUTEX] = {dune_sys_futex, "DUNE_SYS_FUTEX"},
1309         [DUNE_SYS_SCHED_SETAFFINITY] = {NULL, "DUNE_SYS_SCHED_SETAFFINITY"},
1310         [DUNE_SYS_SCHED_GETAFFINITY] = {dune_sys_sched_getaffinity,
1311                                         "DUNE_SYS_SCHED_GETAFFINITY"},
1312         [DUNE_SYS_SET_THREAD_AREA] = {NULL, "DUNE_SYS_SET_THREAD_AREA"},
1313         [DUNE_SYS_IO_SETUP] = {NULL, "DUNE_SYS_IO_SETUP"},
1314         [DUNE_SYS_IO_DESTROY] = {NULL, "DUNE_SYS_IO_DESTROY"},
1315         [DUNE_SYS_IO_GETEVENTS] = {NULL, "DUNE_SYS_IO_GETEVENTS"},
1316         [DUNE_SYS_IO_SUBMIT] = {NULL, "DUNE_SYS_IO_SUBMIT"},
1317         [DUNE_SYS_IO_CANCEL] = {NULL, "DUNE_SYS_IO_CANCEL"},
1318         [DUNE_SYS_GET_THREAD_AREA] = {NULL, "DUNE_SYS_GET_THREAD_AREA"},
1319         [DUNE_SYS_LOOKUP_DCOOKIE] = {NULL, "DUNE_SYS_LOOKUP_DCOOKIE"},
1320         [DUNE_SYS_EPOLL_CREATE] = {NULL, "DUNE_SYS_EPOLL_CREATE"},
1321         [DUNE_SYS_EPOLL_CTL_OLD] = {NULL, "DUNE_SYS_EPOLL_CTL_OLD"},
1322         [DUNE_SYS_EPOLL_WAIT_OLD] = {NULL, "DUNE_SYS_EPOLL_WAIT_OLD"},
1323         [DUNE_SYS_REMAP_FILE_PAGES] = {NULL, "DUNE_SYS_REMAP_FILE_PAGES"},
1324         [DUNE_SYS_GETDENTS64] = {NULL, "DUNE_SYS_GETDENTS64"},
1325         [DUNE_SYS_SET_TID_ADDRESS] = {NULL, "DUNE_SYS_SET_TID_ADDRESS"},
1326         [DUNE_SYS_RESTART_SYSCALL] = {NULL, "DUNE_SYS_RESTART_SYSCALL"},
1327         [DUNE_SYS_SEMTIMEDOP] = {NULL, "DUNE_SYS_SEMTIMEDOP"},
1328         [DUNE_SYS_FADVISE64] = {NULL, "DUNE_SYS_FADVISE64"},
1329         [DUNE_SYS_TIMER_CREATE] = {NULL, "DUNE_SYS_TIMER_CREATE"},
1330         [DUNE_SYS_TIMER_SETTIME] = {NULL, "DUNE_SYS_TIMER_SETTIME"},
1331         [DUNE_SYS_TIMER_GETTIME] = {NULL, "DUNE_SYS_TIMER_GETTIME"},
1332         [DUNE_SYS_TIMER_GETOVERRUN] = {NULL, "DUNE_SYS_TIMER_GETOVERRUN"},
1333         [DUNE_SYS_TIMER_DELETE] = {NULL, "DUNE_SYS_TIMER_DELETE"},
1334         [DUNE_SYS_CLOCK_SETTIME] = {NULL, "DUNE_SYS_CLOCK_SETTIME"},
1335         [DUNE_SYS_CLOCK_GETTIME] = {dune_sys_clock_gettime,
1336                                     "DUNE_SYS_CLOCK_GETTIME"},
1337         [DUNE_SYS_CLOCK_GETRES] = {NULL, "DUNE_SYS_CLOCK_GETRES"},
1338         [DUNE_SYS_CLOCK_NANOSLEEP] = {NULL, "DUNE_SYS_CLOCK_NANOSLEEP"},
1339         [DUNE_SYS_EXIT_GROUP] = {NULL, "DUNE_SYS_EXIT_GROUP"},
1340         [DUNE_SYS_EPOLL_WAIT] = {dune_sys_epoll_wait, "DUNE_SYS_EPOLL_WAIT"},
1341         [DUNE_SYS_EPOLL_CTL] = {dune_sys_epoll_ctl, "DUNE_SYS_EPOLL_CTL"},
1342         [DUNE_SYS_TGKILL] = {NULL, "DUNE_SYS_TGKILL"},
1343         [DUNE_SYS_UTIMES] = {NULL, "DUNE_SYS_UTIMES"},
1344         [DUNE_SYS_VSERVER] = {NULL, "DUNE_SYS_VSERVER"},
1345         [DUNE_SYS_MBIND] = {NULL, "DUNE_SYS_MBIND"},
1346         [DUNE_SYS_SET_MEMPOLICY] = {NULL, "DUNE_SYS_SET_MEMPOLICY"},
1347         [DUNE_SYS_GET_MEMPOLICY] = {NULL, "DUNE_SYS_GET_MEMPOLICY"},
1348         [DUNE_SYS_MQ_OPEN] = {NULL, "DUNE_SYS_MQ_OPEN"},
1349         [DUNE_SYS_MQ_UNLINK] = {NULL, "DUNE_SYS_MQ_UNLINK"},
1350         [DUNE_SYS_MQ_TIMEDSEND] = {NULL, "DUNE_SYS_MQ_TIMEDSEND"},
1351         [DUNE_SYS_MQ_TIMEDRECEIVE] = {NULL, "DUNE_SYS_MQ_TIMEDRECEIVE"},
1352         [DUNE_SYS_MQ_NOTIFY] = {NULL, "DUNE_SYS_MQ_NOTIFY"},
1353         [DUNE_SYS_MQ_GETSETATTR] = {NULL, "DUNE_SYS_MQ_GETSETATTR"},
1354         [DUNE_SYS_KEXEC_LOAD] = {NULL, "DUNE_SYS_KEXEC_LOAD"},
1355         [DUNE_SYS_WAITID] = {NULL, "DUNE_SYS_WAITID"},
1356         [DUNE_SYS_ADD_KEY] = {NULL, "DUNE_SYS_ADD_KEY"},
1357         [DUNE_SYS_REQUEST_KEY] = {NULL, "DUNE_SYS_REQUEST_KEY"},
1358         [DUNE_SYS_KEYCTL] = {NULL, "DUNE_SYS_KEYCTL"},
1359         [DUNE_SYS_IOPRIO_SET] = {NULL, "DUNE_SYS_IOPRIO_SET"},
1360         [DUNE_SYS_IOPRIO_GET] = {NULL, "DUNE_SYS_IOPRIO_GET"},
1361         [DUNE_SYS_INOTIFY_INIT] = {NULL, "DUNE_SYS_INOTIFY_INIT"},
1362         [DUNE_SYS_INOTIFY_ADD_WATCH] = {NULL, "DUNE_SYS_INOTIFY_ADD_WATCH"},
1363         [DUNE_SYS_INOTIFY_RM_WATCH] = {NULL, "DUNE_SYS_INOTIFY_RM_WATCH"},
1364         [DUNE_SYS_MIGRATE_PAGES] = {NULL, "DUNE_SYS_MIGRATE_PAGES"},
1365         [DUNE_SYS_OPENAT] = {dune_sys_openat, "DUNE_SYS_OPENAT"},
1366         [DUNE_SYS_MKDIRAT] = {NULL, "DUNE_SYS_MKDIRAT"},
1367         [DUNE_SYS_MKNODAT] = {NULL, "DUNE_SYS_MKNODAT"},
1368         [DUNE_SYS_FCHOWNAT] = {NULL, "DUNE_SYS_FCHOWNAT"},
1369         [DUNE_SYS_FUTIMESAT] = {NULL, "DUNE_SYS_FUTIMESAT"},
1370         [DUNE_SYS_NEWFSTATAT] = {NULL, "DUNE_SYS_NEWFSTATAT"},
1371         [DUNE_SYS_UNLINKAT] = {dune_sys_unlinkat, "DUNE_SYS_UNLINKAT"},
1372         [DUNE_SYS_RENAMEAT] = {NULL, "DUNE_SYS_RENAMEAT"},
1373         [DUNE_SYS_LINKAT] = {NULL, "DUNE_SYS_LINKAT"},
1374         [DUNE_SYS_SYMLINKAT] = {NULL, "DUNE_SYS_SYMLINKAT"},
1375         [DUNE_SYS_READLINKAT] = {dune_sys_readlinkat, "DUNE_SYS_READLINKAT"},
1376         [DUNE_SYS_FCHMODAT] = {NULL, "DUNE_SYS_FCHMODAT"},
1377         [DUNE_SYS_FACCESSAT] = {NULL, "DUNE_SYS_FACCESSAT"},
1378         [DUNE_SYS_PSELECT6] = {dune_sys_pselect6, "DUNE_SYS_PSELECT6"},
1379         [DUNE_SYS_PPOLL] = {NULL, "DUNE_SYS_PPOLL"},
1380         [DUNE_SYS_UNSHARE] = {NULL, "DUNE_SYS_UNSHARE"},
1381         [DUNE_SYS_SET_ROBUST_LIST] = {NULL, "DUNE_SYS_SET_ROBUST_LIST"},
1382         [DUNE_SYS_GET_ROBUST_LIST] = {NULL, "DUNE_SYS_GET_ROBUST_LIST"},
1383         [DUNE_SYS_SPLICE] = {NULL, "DUNE_SYS_SPLICE"},
1384         [DUNE_SYS_TEE] = {NULL, "DUNE_SYS_TEE"},
1385         [DUNE_SYS_SYNC_FILE_RANGE] = {NULL, "DUNE_SYS_SYNC_FILE_RANGE"},
1386         [DUNE_SYS_VMSPLICE] = {NULL, "DUNE_SYS_VMSPLICE"},
1387         [DUNE_SYS_MOVE_PAGES] = {NULL, "DUNE_SYS_MOVE_PAGES"},
1388         [DUNE_SYS_UTIMENSAT] = {NULL, "DUNE_SYS_UTIMENSAT"},
1389         [DUNE_SYS_EPOLL_PWAIT] = {NULL, "DUNE_SYS_EPOLL_PWAIT"},
1390         [DUNE_SYS_SIGNALFD] = {NULL, "DUNE_SYS_SIGNALFD"},
1391         [DUNE_SYS_TIMERFD_CREATE] = {NULL, "DUNE_SYS_TIMERFD_CREATE"},
1392         [DUNE_SYS_EVENTFD] = {NULL, "DUNE_SYS_EVENTFD"},
1393         [DUNE_SYS_FALLOCATE] = {dune_sys_fallocate, "DUNE_SYS_FALLOCATE"},
1394         [DUNE_SYS_TIMERFD_SETTIME] = {NULL, "DUNE_SYS_TIMERFD_SETTIME"},
1395         [DUNE_SYS_TIMERFD_GETTIME] = {NULL, "DUNE_SYS_TIMERFD_GETTIME"},
1396         [DUNE_SYS_ACCEPT4] = {NULL, "DUNE_SYS_ACCEPT4"},
1397         [DUNE_SYS_SIGNALFD4] = {NULL, "DUNE_SYS_SIGNALFD4"},
1398         [DUNE_SYS_EVENTFD2] = {NULL, "DUNE_SYS_EVENTFD2"},
1399         [DUNE_SYS_EPOLL_CREATE1] = {dune_sys_epoll_create1,
1400                                     "DUNE_SYS_EPOLL_CREATE1"},
1401         [DUNE_SYS_DUP3] = {NULL, "DUNE_SYS_DUP3"},
1402         [DUNE_SYS_PIPE2] = {NULL, "DUNE_SYS_PIPE2"},
1403         [DUNE_SYS_INOTIFY_INIT1] = {NULL, "DUNE_SYS_INOTIFY_INIT1"},
1404         [DUNE_SYS_PREADV] = {NULL, "DUNE_SYS_PREADV"},
1405         [DUNE_SYS_PWRITEV] = {NULL, "DUNE_SYS_PWRITEV"},
1406         [DUNE_SYS_RT_TGSIGQUEUEINFO] = {NULL, "DUNE_SYS_RT_TGSIGQUEUEINFO"},
1407         [DUNE_SYS_PERF_EVENT_OPEN] = {NULL, "DUNE_SYS_PERF_EVENT_OPEN"},
1408         [DUNE_SYS_RECVMMSG] = {NULL, "DUNE_SYS_RECVMMSG"},
1409         [DUNE_SYS_FANOTIFY_INIT] = {NULL, "DUNE_SYS_FANOTIFY_INIT"},
1410         [DUNE_SYS_FANOTIFY_MARK] = {NULL, "DUNE_SYS_FANOTIFY_MARK"},
1411         [DUNE_SYS_PRLIMIT64] = {NULL, "DUNE_SYS_PRLIMIT64"},
1412         [DUNE_SYS_NAME_TO_HANDLE_AT] = {NULL, "DUNE_SYS_NAME_TO_HANDLE_AT"},
1413         [DUNE_SYS_OPEN_BY_HANDLE_AT] = {NULL, "DUNE_SYS_OPEN_BY_HANDLE_AT"},
1414         [DUNE_SYS_CLOCK_ADJTIME] = {NULL, "DUNE_SYS_CLOCK_ADJTIME"},
1415         [DUNE_SYS_SYNCFS] = {NULL, "DUNE_SYS_SYNCFS"},
1416         [DUNE_SYS_SENDMMSG] = {NULL, "DUNE_SYS_SENDMMSG"},
1417         [DUNE_SYS_SETNS] = {NULL, "DUNE_SYS_SETNS"},
1418         [DUNE_SYS_GETCPU] = {NULL, "DUNE_SYS_GETCPU"},
1419         [DUNE_SYS_PROCESS_VM_READV] = {NULL, "DUNE_SYS_PROCESS_VM_READV"},
1420         [DUNE_SYS_PROCESS_VM_WRITEV] = {NULL, "DUNE_SYS_PROCESS_VM_WRITEV"},
1421         [DUNE_SYS_KCMP] = {NULL, "DUNE_KCMP"},
1422         [DUNE_SYS_FINIT_MODULE] = {NULL, "DUNE_SYS_FINIT_MODULE"},
1423         [DUNE_SYS_SCHED_SETATTR] = {NULL, "DUNE_SYS_SCHED_SETATTR"},
1424         [DUNE_SYS_SCHED_GETATTR] = {NULL, "DUNE_SYS_SCHED_GETATTR"},
1425         [DUNE_SYS_RENAMEAT2] = {NULL, "DUNE_SYS_RENAMEAT2"},
1426         [DUNE_SYS_SECCOMP] = {NULL, "DUNE_SYS_SECCOMP"},
1427         [DUNE_SYS_GETRANDOM] = {dune_sys_getrandom, "DUNE_SYS_GETRANDOM"},
1428         [DUNE_SYS_MEMFD_CREATE] = {NULL, "DUNE_SYS_MEMFD_CREATE"},
1429         [DUNE_SYS_KEXEC_FILE_LOAD] = {NULL, "DUNE_SYS_KEXEC_FILE_LOAD"},
1430         [DUNE_SYS_BPF] = {NULL, "DUNE_SYS_BPF"},
1431         [DUNE_STUB_EXECVEAT] = {NULL, "DUNE_STUB_EXECVEAT"},
1432         [DUNE_USERFAULTFD] = {NULL, "DUNE_USERFAULTFD"},
1433         [DUNE_MEMBARRIER] = {NULL, "DUNE_MEMBARRIER"},
1434         [DUNE_MLOCK2] = {NULL, "DUNE_MLOCK2"},
1435         [DUNE_COPY_FILE_RANGE] = {NULL, "DUNE_COPY_FILE_RANGE"},
1436         [DUNE_PREADV2] = {NULL, "DUNE_PREADV2"},
1437         [DUNE_PWRITEV2] = {NULL, "DUNE_PWRITEV2"},
1438
1439 };
1440
1441 bool init_linuxemu(void)
1442 {
1443         fd_table_lock = uth_mutex_alloc();
1444         int i;
1445
1446         for (i = 0; i < DUNE_MAX_NUM_SYSCALLS ; ++i) {
1447                 if (dune_syscall_table[i].name == NULL)
1448                         dune_syscall_table[i].name = "nosyscall";
1449         }
1450
1451         if (dlopen("liblinuxemu_extend.so", RTLD_NOW) == NULL) {
1452                 fprintf(stderr,
1453                         "Not using any syscall extensions\n Reason: %s\n",
1454                         dlerror());
1455                 return false;
1456         }
1457
1458         return true;
1459 }
1460
1461 void lemuprint(const uint32_t tid, uint64_t syscall_number,
1462                const bool isError, const char *fmt, ...)
1463 {
1464         va_list valist;
1465         const char *prefix = "[TID %d] %s: ";
1466         bool double_logging = false;
1467
1468         // Do not use global variable as a check to acquire lock.
1469         // make sure it is not changed during our acquire/release.
1470         int debug = lemu_debug;
1471
1472         // If we are not going to log anything anyway, just bail out.
1473         if (!(debug > 0 || isError))
1474                 return;
1475
1476         const char *syscall_name;
1477
1478         if (syscall_number >= DUNE_MAX_NUM_SYSCALLS)
1479                 panic("lemuprint: Illegal Syscall #%d!\n", syscall_number);
1480         else
1481                 syscall_name = dune_syscall_table[syscall_number].name;
1482
1483         va_start(valist, fmt);
1484
1485         uth_mutex_lock(lemu_logging_lock);
1486
1487         // Print to stderr if debug level is sufficient
1488         if (debug > 1) {
1489                 fprintf(stderr, prefix, tid, syscall_name);
1490                 vfprintf(stderr, fmt, valist);
1491                 // Checks if we will double log to stderr
1492                 if (lemu_global_logfile == stderr)
1493                         double_logging = true;
1494         }
1495
1496         // Log to the global logfile, if we defaulted the global logging to
1497         // stderr then we don't want to log 2 times to stderr.
1498         if (lemu_global_logfile != NULL && !double_logging) {
1499                 fprintf(lemu_global_logfile, prefix, tid, syscall_name);
1500                 vfprintf(lemu_global_logfile, fmt, valist);
1501         }
1502
1503         uth_mutex_unlock(lemu_logging_lock);
1504
1505         va_end(valist);
1506 }
1507
1508
1509 /* TODO: have an array which classifies syscall args
1510  * and "special" system calls (ones with weird return
1511  * values etc.). For some cases, we don't even do a system
1512  * call, and in many cases we have to rearrange arguments
1513  * since Linux and Akaros don't share signatures, so this
1514  * gets tricky. */
1515 bool linuxemu(struct guest_thread *gth, struct vm_trapframe *tf)
1516 {
1517         bool ret = false;
1518
1519         if (tf->tf_rax >= DUNE_MAX_NUM_SYSCALLS) {
1520                 fprintf(stderr, "System call %d is out of range\n", tf->tf_rax);
1521                 return false;
1522         }
1523
1524
1525         if (dune_syscall_table[tf->tf_rax].call == NULL) {
1526                 fprintf(stderr, "System call #%d (%s) is not implemented\n",
1527                         tf->tf_rax, dune_syscall_table[tf->tf_rax].name);
1528                 return false;
1529         }
1530
1531         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax,
1532                   false, "vmcall(%d, %p, %p, %p, %p, %p, %p);\n", tf->tf_rax,
1533                   tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_r10, tf->tf_r8,
1534                   tf->tf_r9);
1535
1536         tf->tf_rip += 3;
1537
1538         return (dune_syscall_table[tf->tf_rax].call)(tf);
1539 }