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