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