Modified dune syscalls and extensions structures
[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
20
21 static int lemu_debug;
22 static uth_mutex_t *lemu_logging_lock;
23 static FILE *lemu_global_logfile;
24
25 void init_lemu_logging(int log_level)
26 {
27         const char *logfile_name = "lemu.log";
28         FILE *x = fopen(logfile_name, "w");
29
30         lemu_debug = log_level;
31         lemu_logging_lock = uth_mutex_alloc();
32
33         if (x != NULL)
34                 lemu_global_logfile = x;
35         else
36                 lemu_global_logfile = stderr;
37 }
38
39 void destroy_lemu_logging(void)
40 {
41         if (lemu_logging_lock != NULL)
42                 uth_mutex_free(lemu_logging_lock);
43
44         if (lemu_global_logfile != stderr)
45                 fclose(lemu_global_logfile);
46 }
47
48
49
50
51 bool dune_sys_read(struct vm_trapframe *tf)
52 {
53         ssize_t retval = read(tf->tf_rdi, (void*) tf->tf_rsi, (size_t) tf->tf_rdx);
54         int err = errno;
55
56         if (retval == -1) {
57                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
58                           "ERROR %zd\n", err);
59                 tf->tf_rax = -err;
60         } else {
61                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
62                           "SUCCESS %zd\n", retval);
63                 tf->tf_rax = retval;
64         }
65         return true;
66 }
67
68
69 bool dune_sys_write(struct vm_trapframe *tf)
70 {
71         ssize_t retval = write((int) tf->tf_rdi, (const void *) tf->tf_rsi,
72                                (size_t) tf->tf_rdx);
73         int err = errno;
74
75         if (retval == -1) {
76                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
77                           "ERROR %zd\n", err);
78                 tf->tf_rax = -err;
79         } else {
80                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
81                           "SUCCESS %zd\n", retval);
82                 tf->tf_rax = retval;
83         }
84         return true;
85 }
86
87 bool dune_sys_gettid(struct vm_trapframe *tf)
88 {
89         tf->tf_rax = tf->tf_guest_pcoreid;
90         return true;
91 }
92
93 bool dune_sys_gettimeofday(struct vm_trapframe *tf)
94 {
95         int retval = gettimeofday((struct timeval*) tf->tf_rdi,
96                                   (struct timezone*) tf->tf_rsi);
97         int err = errno;
98
99         if (retval == -1) {
100                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, true,
101                           "ERROR %d\n", err);
102                 tf->tf_rax = -err;
103         } else {
104                 lemuprint(tf->tf_guest_pcoreid, tf->tf_rax, false,
105                           "SUCCESS %d\n", retval);
106                 tf->tf_rax = retval;
107         }
108         return true;
109 }
110
111
112
113 struct dune_sys_table_entry dune_syscall_table[DUNE_MAX_NUM_SYSCALLS] = {
114         [DUNE_SYS_READ] = {dune_sys_read, "DUNE_SYS_READ"},
115         [DUNE_SYS_WRITE] = {dune_sys_write, "DUNE_SYS_WRITE"},
116         [DUNE_SYS_OPEN] = {NULL, "DUNE_SYS_OPEN"},
117         [DUNE_SYS_CLOSE] = {NULL, "DUNE_SYS_CLOSE"},
118         [DUNE_SYS_STAT] = {NULL, "DUNE_SYS_STAT"},
119         [DUNE_SYS_FSTAT] = {NULL, "DUNE_SYS_FSTAT"},
120         [DUNE_SYS_LSTAT] = {NULL, "DUNE_SYS_LSTAT"},
121         [DUNE_SYS_POLL] = {NULL, "DUNE_SYS_POLL"},
122         [DUNE_SYS_LSEEK] = {NULL, "DUNE_SYS_LSEEK"},
123         [DUNE_SYS_MMAP] = {NULL, "DUNE_SYS_MMAP"},
124         [DUNE_SYS_MPROTECT] = {NULL, "DUNE_SYS_MPROTECT"},
125         [DUNE_SYS_MUNMAP] = {NULL, "DUNE_SYS_MUNMAP"},
126         [DUNE_SYS_BRK] = {NULL, "DUNE_SYS_BRK"},
127         [DUNE_SYS_RT_SIGACTION] = {NULL, "DUNE_SYS_RT_SIGACTION"},
128         [DUNE_SYS_RT_SIGPROCMASK] = {NULL, "DUNE_SYS_RT_SIGPROCMASK"},
129         [DUNE_SYS_RT_SIGRETURN] = {NULL, "DUNE_SYS_RT_SIGRETURN"},
130         [DUNE_SYS_IOCTL] = {NULL, "DUNE_SYS_IOCTL"},
131         [DUNE_SYS_PREAD64] = {NULL, "DUNE_SYS_PREAD64"},
132         [DUNE_SYS_PWRITE64] = {NULL, "DUNE_SYS_PWRITE64"},
133         [DUNE_SYS_READV] = {NULL, "DUNE_SYS_READV"},
134         [DUNE_SYS_WRITEV] = {NULL, "DUNE_SYS_WRITEV"},
135         [DUNE_SYS_ACCESS] = {NULL, "DUNE_SYS_ACCESS"},
136         [DUNE_SYS_PIPE] = {NULL, "DUNE_SYS_PIPE"},
137         [DUNE_SYS_SELECT] = {NULL, "DUNE_SYS_SELECT"},
138         [DUNE_SYS_SCHED_YIELD] = {NULL, "DUNE_SYS_SCHED_YIELD"},
139         [DUNE_SYS_MREMAP] = {NULL, "DUNE_SYS_MREMAP"},
140         [DUNE_SYS_MSYNC] = {NULL, "DUNE_SYS_MSYNC"},
141         [DUNE_SYS_MINCORE] = {NULL, "DUNE_SYS_MINCORE"},
142         [DUNE_SYS_MADVISE] = {NULL, "DUNE_SYS_MADVISE"},
143         [DUNE_SYS_SHMGET] = {NULL, "DUNE_SYS_SHMGET"},
144         [DUNE_SYS_SHMAT] = {NULL, "DUNE_SYS_SHMAT"},
145         [DUNE_SYS_SHMCTL] = {NULL, "DUNE_SYS_SHMCTL"},
146         [DUNE_SYS_DUP] = {NULL, "DUNE_SYS_DUP"},
147         [DUNE_SYS_DUP2] = {NULL, "DUNE_SYS_DUP2"},
148         [DUNE_SYS_PAUSE] = {NULL, "DUNE_SYS_PAUSE"},
149         [DUNE_SYS_NANOSLEEP] = {NULL, "DUNE_SYS_NANOSLEEP"},
150         [DUNE_SYS_GETITIMER] = {NULL, "DUNE_SYS_GETITIMER"},
151         [DUNE_SYS_ALARM] = {NULL, "DUNE_SYS_ALARM"},
152         [DUNE_SYS_SETITIMER] = {NULL, "DUNE_SYS_SETITIMER"},
153         [DUNE_SYS_GETPID] = {NULL, "DUNE_SYS_GETPID"},
154         [DUNE_SYS_SENDFILE] = {NULL, "DUNE_SYS_SENDFILE"},
155         [DUNE_SYS_SOCKET] = {NULL, "DUNE_SYS_SOCKET"},
156         [DUNE_SYS_CONNECT] = {NULL, "DUNE_SYS_CONNECT"},
157         [DUNE_SYS_ACCEPT] = {NULL, "DUNE_SYS_ACCEPT"},
158         [DUNE_SYS_SENDTO] = {NULL, "DUNE_SYS_SENDTO"},
159         [DUNE_SYS_RECVFROM] = {NULL, "DUNE_SYS_RECVFROM"},
160         [DUNE_SYS_SENDMSG] = {NULL, "DUNE_SYS_SENDMSG"},
161         [DUNE_SYS_RECVMSG] = {NULL, "DUNE_SYS_RECVMSG"},
162         [DUNE_SYS_SHUTDOWN] = {NULL, "DUNE_SYS_SHUTDOWN"},
163         [DUNE_SYS_BIND] = {NULL, "DUNE_SYS_BIND"},
164         [DUNE_SYS_LISTEN] = {NULL, "DUNE_SYS_LISTEN"},
165         [DUNE_SYS_GETSOCKNAME] = {NULL, "DUNE_SYS_GETSOCKNAME"},
166         [DUNE_SYS_GETPEERNAME] = {NULL, "DUNE_SYS_GETPEERNAME"},
167         [DUNE_SYS_SOCKETPAIR] = {NULL, "DUNE_SYS_SOCKETPAIR"},
168         [DUNE_SYS_SETSOCKOPT] = {NULL, "DUNE_SYS_SETSOCKOPT"},
169         [DUNE_SYS_GETSOCKOPT] = {NULL, "DUNE_SYS_GETSOCKOPT"},
170         [DUNE_SYS_CLONE] = {NULL, "DUNE_SYS_CLONE"},
171         [DUNE_SYS_FORK] = {NULL, "DUNE_SYS_FORK"},
172         [DUNE_SYS_VFORK] = {NULL, "DUNE_SYS_VFORK"},
173         [DUNE_SYS_EXECVE] = {NULL, "DUNE_SYS_EXECVE"},
174         [DUNE_SYS_EXIT] = {NULL, "DUNE_SYS_EXIT"},
175         [DUNE_SYS_WAIT4] = {NULL, "DUNE_SYS_WAIT4"},
176         [DUNE_SYS_KILL] = {NULL, "DUNE_SYS_KILL"},
177         [DUNE_SYS_UNAME] = {NULL, "DUNE_SYS_UNAME"},
178         [DUNE_SYS_SEMGET] = {NULL, "DUNE_SYS_SEMGET"},
179         [DUNE_SYS_SEMOP] = {NULL, "DUNE_SYS_SEMOP"},
180         [DUNE_SYS_SEMCTL] = {NULL, "DUNE_SYS_SEMCTL"},
181         [DUNE_SYS_SHMDT] = {NULL, "DUNE_SYS_SHMDT"},
182         [DUNE_SYS_MSGGET] = {NULL, "DUNE_SYS_MSGGET"},
183         [DUNE_SYS_MSGSND] = {NULL, "DUNE_SYS_MSGSND"},
184         [DUNE_SYS_MSGRCV] = {NULL, "DUNE_SYS_MSGRCV"},
185         [DUNE_SYS_MSGCTL] = {NULL, "DUNE_SYS_MSGCTL"},
186         [DUNE_SYS_FCNTL] = {NULL, "DUNE_SYS_FCNTL"},
187         [DUNE_SYS_FLOCK] = {NULL, "DUNE_SYS_FLOCK"},
188         [DUNE_SYS_FSYNC] = {NULL, "DUNE_SYS_FSYNC"},
189         [DUNE_SYS_FDATASYNC] = {NULL, "DUNE_SYS_FDATASYNC"},
190         [DUNE_SYS_TRUNCATE] = {NULL, "DUNE_SYS_TRUNCATE"},
191         [DUNE_SYS_FTRUNCATE] = {NULL, "DUNE_SYS_FTRUNCATE"},
192         [DUNE_SYS_GETDENTS] = {NULL, "DUNE_SYS_GETDENTS"},
193         [DUNE_SYS_GETCWD] = {NULL, "DUNE_SYS_GETCWD"},
194         [DUNE_SYS_CHDIR] = {NULL, "DUNE_SYS_CHDIR"},
195         [DUNE_SYS_FCHDIR] = {NULL, "DUNE_SYS_FCHDIR"},
196         [DUNE_SYS_RENAME] = {NULL, "DUNE_SYS_RENAME"},
197         [DUNE_SYS_MKDIR] = {NULL, "DUNE_SYS_MKDIR"},
198         [DUNE_SYS_RMDIR] = {NULL, "DUNE_SYS_RMDIR"},
199         [DUNE_SYS_CREAT] = {NULL, "DUNE_SYS_CREAT"},
200         [DUNE_SYS_LINK] = {NULL, "DUNE_SYS_LINK"},
201         [DUNE_SYS_UNLINK] = {NULL, "DUNE_SYS_UNLINK"},
202         [DUNE_SYS_SYMLINK] = {NULL, "DUNE_SYS_SYMLINK"},
203         [DUNE_SYS_READLINK] = {NULL, "DUNE_SYS_READLINK"},
204         [DUNE_SYS_CHMOD] = {NULL, "DUNE_SYS_CHMOD"},
205         [DUNE_SYS_FCHMOD] = {NULL, "DUNE_SYS_FCHMOD"},
206         [DUNE_SYS_CHOWN] = {NULL, "DUNE_SYS_CHOWN"},
207         [DUNE_SYS_FCHOWN] = {NULL, "DUNE_SYS_FCHOWN"},
208         [DUNE_SYS_LCHOWN] = {NULL, "DUNE_SYS_LCHOWN"},
209         [DUNE_SYS_UMASK] = {NULL, "DUNE_SYS_UMASK"},
210         [DUNE_SYS_GETTIMEOFDAY] = {dune_sys_gettimeofday, "DUNE_SYS_GETTIMEOFDAY"},
211         [DUNE_SYS_GETRLIMIT] = {NULL, "DUNE_SYS_GETRLIMIT"},
212         [DUNE_SYS_GETRUSAGE] = {NULL, "DUNE_SYS_GETRUSAGE"},
213         [DUNE_SYS_SYSINFO] = {NULL, "DUNE_SYS_SYSINFO"},
214         [DUNE_SYS_TIMES] = {NULL, "DUNE_SYS_TIMES"},
215         [DUNE_SYS_PTRACE] = {NULL, "DUNE_SYS_PTRACE"},
216         [DUNE_SYS_GETUID] = {NULL, "DUNE_SYS_GETUID"},
217         [DUNE_SYS_SYSLOG] = {NULL, "DUNE_SYS_SYSLOG"},
218         [DUNE_SYS_GETGID] = {NULL, "DUNE_SYS_GETGID"},
219         [DUNE_SYS_SETUID] = {NULL, "DUNE_SYS_SETUID"},
220         [DUNE_SYS_SETGID] = {NULL, "DUNE_SYS_SETGID"},
221         [DUNE_SYS_GETEUID] = {NULL, "DUNE_SYS_GETEUID"},
222         [DUNE_SYS_GETEGID] = {NULL, "DUNE_SYS_GETEGID"},
223         [DUNE_SYS_SETPGID] = {NULL, "DUNE_SYS_SETPGID"},
224         [DUNE_SYS_GETPPID] = {NULL, "DUNE_SYS_GETPPID"},
225         [DUNE_SYS_GETPGRP] = {NULL, "DUNE_SYS_GETPGRP"},
226         [DUNE_SYS_SETSID] = {NULL, "DUNE_SYS_SETSID"},
227         [DUNE_SYS_SETREUID] = {NULL, "DUNE_SYS_SETREUID"},
228         [DUNE_SYS_SETREGID] = {NULL, "DUNE_SYS_SETREGID"},
229         [DUNE_SYS_GETGROUPS] = {NULL, "DUNE_SYS_GETGROUPS"},
230         [DUNE_SYS_SETGROUPS] = {NULL, "DUNE_SYS_SETGROUPS"},
231         [DUNE_SYS_SETRESUID] = {NULL, "DUNE_SYS_SETRESUID"},
232         [DUNE_SYS_GETRESUID] = {NULL, "DUNE_SYS_GETRESUID"},
233         [DUNE_SYS_SETRESGID] = {NULL, "DUNE_SYS_SETRESGID"},
234         [DUNE_SYS_GETRESGID] = {NULL, "DUNE_SYS_GETRESGID"},
235         [DUNE_SYS_GETPGID] = {NULL, "DUNE_SYS_GETPGID"},
236         [DUNE_SYS_SETFSUID] = {NULL, "DUNE_SYS_SETFSUID"},
237         [DUNE_SYS_SETFSGID] = {NULL, "DUNE_SYS_SETFSGID"},
238         [DUNE_SYS_GETSID] = {NULL, "DUNE_SYS_GETSID"},
239         [DUNE_SYS_CAPGET] = {NULL, "DUNE_SYS_CAPGET"},
240         [DUNE_SYS_CAPSET] = {NULL, "DUNE_SYS_CAPSET"},
241         [DUNE_SYS_RT_SIGPENDING] = {NULL, "DUNE_SYS_RT_SIGPENDING"},
242         [DUNE_SYS_RT_SIGTIMEDWAIT] = {NULL, "DUNE_SYS_RT_SIGTIMEDWAIT"},
243         [DUNE_SYS_RT_SIGQUEUEINFO] = {NULL, "DUNE_SYS_RT_SIGQUEUEINFO"},
244         [DUNE_SYS_RT_SIGSUSPEND] = {NULL, "DUNE_SYS_RT_SIGSUSPEND"},
245         [DUNE_SYS_SIGALTSTACK] = {NULL, "DUNE_SYS_SIGALTSTACK"},
246         [DUNE_SYS_UTIME] = {NULL, "DUNE_SYS_UTIME"},
247         [DUNE_SYS_MKNOD] = {NULL, "DUNE_SYS_MKNOD"},
248         [DUNE_SYS_USELIB] = {NULL, "DUNE_SYS_USELIB"},
249         [DUNE_SYS_PERSONALITY] = {NULL, "DUNE_SYS_PERSONALITY"},
250         [DUNE_SYS_USTAT] = {NULL, "DUNE_SYS_USTAT"},
251         [DUNE_SYS_STATFS] = {NULL, "DUNE_SYS_STATFS"},
252         [DUNE_SYS_FSTATFS] = {NULL, "DUNE_SYS_FSTATFS"},
253         [DUNE_SYS_SYSFS] = {NULL, "DUNE_SYS_SYSFS"},
254         [DUNE_SYS_GETPRIORITY] = {NULL, "DUNE_SYS_GETPRIORITY"},
255         [DUNE_SYS_SETPRIORITY] = {NULL, "DUNE_SYS_SETPRIORITY"},
256         [DUNE_SYS_SCHED_SETPARAM] = {NULL, "DUNE_SYS_SCHED_SETPARAM"},
257         [DUNE_SYS_SCHED_GETPARAM] = {NULL, "DUNE_SYS_SCHED_GETPARAM"},
258         [DUNE_SYS_SCHED_SETSCHEDULER] = {NULL, "DUNE_SYS_SCHED_SETSCHEDULER"},
259         [DUNE_SYS_SCHED_GETSCHEDULER] = {NULL, "DUNE_SYS_SCHED_GETSCHEDULER"},
260         [DUNE_SYS_SCHED_GET_PRIORITY_MAX] = {NULL,
261                                             "DUNE_SYS_SCHED_GET_PRIORITY_MAX"},
262         [DUNE_SYS_SCHED_GET_PRIORITY_MIN] = {NULL,
263                                             "DUNE_SYS_SCHED_GET_PRIORITY_MIN"},
264         [DUNE_SYS_SCHED_RR_GET_INTERVAL] = {NULL, "DUNE_SYS_SCHED_RR_GET_INTERVAL"},
265         [DUNE_SYS_MLOCK] = {NULL, "DUNE_SYS_MLOCK"},
266         [DUNE_SYS_MUNLOCK] = {NULL, "DUNE_SYS_MUNLOCK"},
267         [DUNE_SYS_MLOCKALL] = {NULL, "DUNE_SYS_MLOCKALL"},
268         [DUNE_SYS_MUNLOCKALL] = {NULL, "DUNE_SYS_MUNLOCKALL"},
269         [DUNE_SYS_VHANGUP] = {NULL, "DUNE_SYS_VHANGUP"},
270         [DUNE_SYS_MODIFY_LDT] = {NULL, "DUNE_SYS_MODIFY_LDT"},
271         [DUNE_SYS_PIVOT_ROOT] = {NULL, "DUNE_SYS_PIVOT_ROOT"},
272         [DUNE_SYS__SYSCTL] = {NULL, "DUNE_SYS__SYSCTL"},
273         [DUNE_SYS_PRCTL] = {NULL, "DUNE_SYS_PRCTL"},
274         [DUNE_SYS_ARCH_PRCTL] = {NULL, "DUNE_SYS_ARCH_PRCTL"},
275         [DUNE_SYS_ADJTIMEX] = {NULL, "DUNE_SYS_ADJTIMEX"},
276         [DUNE_SYS_SETRLIMIT] = {NULL, "DUNE_SYS_SETRLIMIT"},
277         [DUNE_SYS_CHROOT] = {NULL, "DUNE_SYS_CHROOT"},
278         [DUNE_SYS_SYNC] = {NULL, "DUNE_SYS_SYNC"},
279         [DUNE_SYS_ACCT] = {NULL, "DUNE_SYS_ACCT"},
280         [DUNE_SYS_SETTIMEOFDAY] = {NULL, "DUNE_SYS_SETTIMEOFDAY"},
281         [DUNE_SYS_MOUNT] = {NULL, "DUNE_SYS_MOUNT"},
282         [DUNE_SYS_UMOUNT2] = {NULL, "DUNE_SYS_UMOUNT2"},
283         [DUNE_SYS_SWAPON] = {NULL, "DUNE_SYS_SWAPON"},
284         [DUNE_SYS_SWAPOFF] = {NULL, "DUNE_SYS_SWAPOFF"},
285         [DUNE_SYS_REBOOT] = {NULL, "DUNE_SYS_REBOOT"},
286         [DUNE_SYS_SETHOSTNAME] = {NULL, "DUNE_SYS_SETHOSTNAME"},
287         [DUNE_SYS_SETDOMAINNAME] = {NULL, "DUNE_SYS_SETDOMAINNAME"},
288         [DUNE_SYS_IOPL] = {NULL, "DUNE_SYS_IOPL"},
289         [DUNE_SYS_IOPERM] = {NULL, "DUNE_SYS_IOPERM"},
290         [DUNE_SYS_CREATE_MODULE] = {NULL, "DUNE_SYS_CREATE_MODULE"},
291         [DUNE_SYS_INIT_MODULE] = {NULL, "DUNE_SYS_INIT_MODULE"},
292         [DUNE_SYS_DELETE_MODULE] = {NULL, "DUNE_SYS_DELETE_MODULE"},
293         [DUNE_SYS_GET_KERNEL_SYMS] = {NULL, "DUNE_SYS_GET_KERNEL_SYMS"},
294         [DUNE_SYS_QUERY_MODULE] = {NULL, "DUNE_SYS_QUERY_MODULE"},
295         [DUNE_SYS_QUOTACTL] = {NULL, "DUNE_SYS_QUOTACTL"},
296         [DUNE_SYS_NFSSERVCTL] = {NULL, "DUNE_SYS_NFSSERVCTL"},
297         [DUNE_SYS_GETPMSG] = {NULL, "DUNE_SYS_GETPMSG"},
298         [DUNE_SYS_PUTPMSG] = {NULL, "DUNE_SYS_PUTPMSG"},
299         [DUNE_SYS_AFS_SYSCALL] = {NULL, "DUNE_SYS_AFS_SYSCALL"},
300         [DUNE_SYS_TUXCALL] = {NULL, "DUNE_SYS_TUXCALL"},
301         [DUNE_SYS_SECURITY] = {NULL, "DUNE_SYS_SECURITY"},
302         [DUNE_SYS_GETTID] = {dune_sys_gettid, "DUNE_SYS_GETTID"},
303         [DUNE_SYS_READAHEAD] = {NULL, "DUNE_SYS_READAHEAD"},
304         [DUNE_SYS_SETXATTR] = {NULL, "DUNE_SYS_SETXATTR"},
305         [DUNE_SYS_LSETXATTR] = {NULL, "DUNE_SYS_LSETXATTR"},
306         [DUNE_SYS_FSETXATTR] = {NULL, "DUNE_SYS_FSETXATTR"},
307         [DUNE_SYS_GETXATTR] = {NULL, "DUNE_SYS_GETXATTR"},
308         [DUNE_SYS_LGETXATTR] = {NULL, "DUNE_SYS_LGETXATTR"},
309         [DUNE_SYS_FGETXATTR] = {NULL, "DUNE_SYS_FGETXATTR"},
310         [DUNE_SYS_LISTXATTR] = {NULL, "DUNE_SYS_LISTXATTR"},
311         [DUNE_SYS_LLISTXATTR] = {NULL, "DUNE_SYS_LLISTXATTR"},
312         [DUNE_SYS_FLISTXATTR] = {NULL, "DUNE_SYS_FLISTXATTR"},
313         [DUNE_SYS_REMOVEXATTR] = {NULL, "DUNE_SYS_REMOVEXATTR"},
314         [DUNE_SYS_LREMOVEXATTR] = {NULL, "DUNE_SYS_LREMOVEXATTR"},
315         [DUNE_SYS_FREMOVEXATTR] = {NULL, "DUNE_SYS_FREMOVEXATTR"},
316         [DUNE_SYS_TKILL] = {NULL, "DUNE_SYS_TKILL"},
317         [DUNE_SYS_TIME] = {NULL, "DUNE_SYS_TIME"},
318         [DUNE_SYS_FUTEX] = {NULL, "DUNE_SYS_FUTEX"},
319         [DUNE_SYS_SCHED_SETAFFINITY] = {NULL, "DUNE_SYS_SCHED_SETAFFINITY"},
320         [DUNE_SYS_SCHED_GETAFFINITY] = {NULL, "DUNE_SYS_SCHED_GETAFFINITY"},
321         [DUNE_SYS_SET_THREAD_AREA] = {NULL, "DUNE_SYS_SET_THREAD_AREA"},
322         [DUNE_SYS_IO_SETUP] = {NULL, "DUNE_SYS_IO_SETUP"},
323         [DUNE_SYS_IO_DESTROY] = {NULL, "DUNE_SYS_IO_DESTROY"},
324         [DUNE_SYS_IO_GETEVENTS] = {NULL, "DUNE_SYS_IO_GETEVENTS"},
325         [DUNE_SYS_IO_SUBMIT] = {NULL, "DUNE_SYS_IO_SUBMIT"},
326         [DUNE_SYS_IO_CANCEL] = {NULL, "DUNE_SYS_IO_CANCEL"},
327         [DUNE_SYS_GET_THREAD_AREA] = {NULL, "DUNE_SYS_GET_THREAD_AREA"},
328         [DUNE_SYS_LOOKUP_DCOOKIE] = {NULL, "DUNE_SYS_LOOKUP_DCOOKIE"},
329         [DUNE_SYS_EPOLL_CREATE] = {NULL, "DUNE_SYS_EPOLL_CREATE"},
330         [DUNE_SYS_EPOLL_CTL_OLD] = {NULL, "DUNE_SYS_EPOLL_CTL_OLD"},
331         [DUNE_SYS_EPOLL_WAIT_OLD] = {NULL, "DUNE_SYS_EPOLL_WAIT_OLD"},
332         [DUNE_SYS_REMAP_FILE_PAGES] = {NULL, "DUNE_SYS_REMAP_FILE_PAGES"},
333         [DUNE_SYS_GETDENTS64] = {NULL, "DUNE_SYS_GETDENTS64"},
334         [DUNE_SYS_SET_TID_ADDRESS] = {NULL, "DUNE_SYS_SET_TID_ADDRESS"},
335         [DUNE_SYS_RESTART_SYSCALL] = {NULL, "DUNE_SYS_RESTART_SYSCALL"},
336         [DUNE_SYS_SEMTIMEDOP] = {NULL, "DUNE_SYS_SEMTIMEDOP"},
337         [DUNE_SYS_FADVISE64] = {NULL, "DUNE_SYS_FADVISE64"},
338         [DUNE_SYS_TIMER_CREATE] = {NULL, "DUNE_SYS_TIMER_CREATE"},
339         [DUNE_SYS_TIMER_SETTIME] = {NULL, "DUNE_SYS_TIMER_SETTIME"},
340         [DUNE_SYS_TIMER_GETTIME] = {NULL, "DUNE_SYS_TIMER_GETTIME"},
341         [DUNE_SYS_TIMER_GETOVERRUN] = {NULL, "DUNE_SYS_TIMER_GETOVERRUN"},
342         [DUNE_SYS_TIMER_DELETE] = {NULL, "DUNE_SYS_TIMER_DELETE"},
343         [DUNE_SYS_CLOCK_SETTIME] = {NULL, "DUNE_SYS_CLOCK_SETTIME"},
344         [DUNE_SYS_CLOCK_GETTIME] = {NULL, "DUNE_SYS_CLOCK_GETTIME"},
345         [DUNE_SYS_CLOCK_GETRES] = {NULL, "DUNE_SYS_CLOCK_GETRES"},
346         [DUNE_SYS_CLOCK_NANOSLEEP] = {NULL, "DUNE_SYS_CLOCK_NANOSLEEP"},
347         [DUNE_SYS_EXIT_GROUP] = {NULL, "DUNE_SYS_EXIT_GROUP"},
348         [DUNE_SYS_EPOLL_WAIT] = {NULL, "DUNE_SYS_EPOLL_WAIT"},
349         [DUNE_SYS_EPOLL_CTL] = {NULL, "DUNE_SYS_EPOLL_CTL"},
350         [DUNE_SYS_TGKILL] = {NULL, "DUNE_SYS_TGKILL"},
351         [DUNE_SYS_UTIMES] = {NULL, "DUNE_SYS_UTIMES"},
352         [DUNE_SYS_VSERVER] = {NULL, "DUNE_SYS_VSERVER"},
353         [DUNE_SYS_MBIND] = {NULL, "DUNE_SYS_MBIND"},
354         [DUNE_SYS_SET_MEMPOLICY] = {NULL, "DUNE_SYS_SET_MEMPOLICY"},
355         [DUNE_SYS_GET_MEMPOLICY] = {NULL, "DUNE_SYS_GET_MEMPOLICY"},
356         [DUNE_SYS_MQ_OPEN] = {NULL, "DUNE_SYS_MQ_OPEN"},
357         [DUNE_SYS_MQ_UNLINK] = {NULL, "DUNE_SYS_MQ_UNLINK"},
358         [DUNE_SYS_MQ_TIMEDSEND] = {NULL, "DUNE_SYS_MQ_TIMEDSEND"},
359         [DUNE_SYS_MQ_TIMEDRECEIVE] = {NULL, "DUNE_SYS_MQ_TIMEDRECEIVE"},
360         [DUNE_SYS_MQ_NOTIFY] = {NULL, "DUNE_SYS_MQ_NOTIFY"},
361         [DUNE_SYS_MQ_GETSETATTR] = {NULL, "DUNE_SYS_MQ_GETSETATTR"},
362         [DUNE_SYS_KEXEC_LOAD] = {NULL, "DUNE_SYS_KEXEC_LOAD"},
363         [DUNE_SYS_WAITID] = {NULL, "DUNE_SYS_WAITID"},
364         [DUNE_SYS_ADD_KEY] = {NULL, "DUNE_SYS_ADD_KEY"},
365         [DUNE_SYS_REQUEST_KEY] = {NULL, "DUNE_SYS_REQUEST_KEY"},
366         [DUNE_SYS_KEYCTL] = {NULL, "DUNE_SYS_KEYCTL"},
367         [DUNE_SYS_IOPRIO_SET] = {NULL, "DUNE_SYS_IOPRIO_SET"},
368         [DUNE_SYS_IOPRIO_GET] = {NULL, "DUNE_SYS_IOPRIO_GET"},
369         [DUNE_SYS_INOTIFY_INIT] = {NULL, "DUNE_SYS_INOTIFY_INIT"},
370         [DUNE_SYS_INOTIFY_ADD_WATCH] = {NULL, "DUNE_SYS_INOTIFY_ADD_WATCH"},
371         [DUNE_SYS_INOTIFY_RM_WATCH] = {NULL, "DUNE_SYS_INOTIFY_RM_WATCH"},
372         [DUNE_SYS_MIGRATE_PAGES] = {NULL, "DUNE_SYS_MIGRATE_PAGES"},
373         [DUNE_SYS_OPENAT] = {NULL, "DUNE_SYS_OPENAT"},
374         [DUNE_SYS_MKDIRAT] = {NULL, "DUNE_SYS_MKDIRAT"},
375         [DUNE_SYS_MKNODAT] = {NULL, "DUNE_SYS_MKNODAT"},
376         [DUNE_SYS_FCHOWNAT] = {NULL, "DUNE_SYS_FCHOWNAT"},
377         [DUNE_SYS_FUTIMESAT] = {NULL, "DUNE_SYS_FUTIMESAT"},
378         [DUNE_SYS_NEWFSTATAT] = {NULL, "DUNE_SYS_NEWFSTATAT"},
379         [DUNE_SYS_UNLINKAT] = {NULL, "DUNE_SYS_UNLINKAT"},
380         [DUNE_SYS_RENAMEAT] = {NULL, "DUNE_SYS_RENAMEAT"},
381         [DUNE_SYS_LINKAT] = {NULL, "DUNE_SYS_LINKAT"},
382         [DUNE_SYS_SYMLINKAT] = {NULL, "DUNE_SYS_SYMLINKAT"},
383         [DUNE_SYS_READLINKAT] = {NULL, "DUNE_SYS_READLINKAT"},
384         [DUNE_SYS_FCHMODAT] = {NULL, "DUNE_SYS_FCHMODAT"},
385         [DUNE_SYS_FACCESSAT] = {NULL, "DUNE_SYS_FACCESSAT"},
386         [DUNE_SYS_PSELECT6] = {NULL, "DUNE_SYS_PSELECT6"},
387         [DUNE_SYS_PPOLL] = {NULL, "DUNE_SYS_PPOLL"},
388         [DUNE_SYS_UNSHARE] = {NULL, "DUNE_SYS_UNSHARE"},
389         [DUNE_SYS_SET_ROBUST_LIST] = {NULL, "DUNE_SYS_SET_ROBUST_LIST"},
390         [DUNE_SYS_GET_ROBUST_LIST] = {NULL, "DUNE_SYS_GET_ROBUST_LIST"},
391         [DUNE_SYS_SPLICE] = {NULL, "DUNE_SYS_SPLICE"},
392         [DUNE_SYS_TEE] = {NULL, "DUNE_SYS_TEE"},
393         [DUNE_SYS_SYNC_FILE_RANGE] = {NULL, "DUNE_SYS_SYNC_FILE_RANGE"},
394         [DUNE_SYS_VMSPLICE] = {NULL, "DUNE_SYS_VMSPLICE"},
395         [DUNE_SYS_MOVE_PAGES] = {NULL, "DUNE_SYS_MOVE_PAGES"},
396         [DUNE_SYS_UTIMENSAT] = {NULL, "DUNE_SYS_UTIMENSAT"},
397         [DUNE_SYS_EPOLL_PWAIT] = {NULL, "DUNE_SYS_EPOLL_PWAIT"},
398         [DUNE_SYS_SIGNALFD] = {NULL, "DUNE_SYS_SIGNALFD"},
399         [DUNE_SYS_TIMERFD_CREATE] = {NULL, "DUNE_SYS_TIMERFD_CREATE"},
400         [DUNE_SYS_EVENTFD] = {NULL, "DUNE_SYS_EVENTFD"},
401         [DUNE_SYS_FALLOCATE] = {NULL, "DUNE_SYS_FALLOCATE"},
402         [DUNE_SYS_TIMERFD_SETTIME] = {NULL, "DUNE_SYS_TIMERFD_SETTIME"},
403         [DUNE_SYS_TIMERFD_GETTIME] = {NULL, "DUNE_SYS_TIMERFD_GETTIME"},
404         [DUNE_SYS_ACCEPT4] = {NULL, "DUNE_SYS_ACCEPT4"},
405         [DUNE_SYS_SIGNALFD4] = {NULL, "DUNE_SYS_SIGNALFD4"},
406         [DUNE_SYS_EVENTFD2] = {NULL, "DUNE_SYS_EVENTFD2"},
407         [DUNE_SYS_EPOLL_CREATE1] = {NULL, "DUNE_SYS_EPOLL_CREATE1"},
408         [DUNE_SYS_DUP3] = {NULL, "DUNE_SYS_DUP3"},
409         [DUNE_SYS_PIPE2] = {NULL, "DUNE_SYS_PIPE2"},
410         [DUNE_SYS_INOTIFY_INIT1] = {NULL, "DUNE_SYS_INOTIFY_INIT1"},
411         [DUNE_SYS_PREADV] = {NULL, "DUNE_SYS_PREADV"},
412         [DUNE_SYS_PWRITEV] = {NULL, "DUNE_SYS_PWRITEV"},
413         [DUNE_SYS_RT_TGSIGQUEUEINFO] = {NULL, "DUNE_SYS_RT_TGSIGQUEUEINFO"},
414         [DUNE_SYS_PERF_EVENT_OPEN] = {NULL, "DUNE_SYS_PERF_EVENT_OPEN"},
415         [DUNE_SYS_RECVMMSG] = {NULL, "DUNE_SYS_RECVMMSG"},
416         [DUNE_SYS_FANOTIFY_INIT] = {NULL, "DUNE_SYS_FANOTIFY_INIT"},
417         [DUNE_SYS_FANOTIFY_MARK] = {NULL, "DUNE_SYS_FANOTIFY_MARK"},
418         [DUNE_SYS_PRLIMIT64] = {NULL, "DUNE_SYS_PRLIMIT64"},
419         [DUNE_SYS_NAME_TO_HANDLE_AT] = {NULL, "DUNE_SYS_NAME_TO_HANDLE_AT"},
420         [DUNE_SYS_OPEN_BY_HANDLE_AT] = {NULL, "DUNE_SYS_OPEN_BY_HANDLE_AT"},
421         [DUNE_SYS_CLOCK_ADJTIME] = {NULL, "DUNE_SYS_CLOCK_ADJTIME"},
422         [DUNE_SYS_SYNCFS] = {NULL, "DUNE_SYS_SYNCFS"},
423         [DUNE_SYS_SENDMMSG] = {NULL, "DUNE_SYS_SENDMMSG"},
424         [DUNE_SYS_SETNS] = {NULL, "DUNE_SYS_SETNS"},
425         [DUNE_SYS_GETCPU] = {NULL, "DUNE_SYS_GETCPU"},
426         [DUNE_SYS_PROCESS_VM_READV] = {NULL, "DUNE_SYS_PROCESS_VM_READV"},
427         [DUNE_SYS_PROCESS_VM_WRITEV] = {NULL, "DUNE_SYS_PROCESS_VM_WRITEV"},
428 };
429
430 bool init_syscall_table(void)
431 {
432         int i;
433
434         for (i = 0; i < DUNE_MAX_NUM_SYSCALLS ; ++i) {
435                 if (dune_syscall_table[i].name == NULL)
436                         dune_syscall_table[i].name = "nosyscall";
437         }
438
439         if (dlopen("liblinuxemu_extend.so", RTLD_NOW) == NULL) {
440                 fprintf(stderr, "Not using any syscall extensions\n Reason: %s\n",
441                         dlerror());
442                 return false;
443         }
444
445         return true;
446 }
447
448 void lemuprint(const uint32_t tid, uint64_t syscall_number,
449                const bool isError, const char *fmt, ...)
450 {
451         va_list valist;
452         const char *prefix = "[TID %d] %s: ";
453         bool double_logging = false;
454
455         // Do not use global variable as a check to acquire lock.
456         // make sure it is not changed during our acquire/release.
457         int debug = lemu_debug;
458
459         // If we are not going to log anything anyway, just bail out.
460         if (!(debug > 0 || isError))
461                 return;
462
463         const char *syscall_name;
464
465         if (syscall_number >= DUNE_MAX_NUM_SYSCALLS)
466                 panic("lemuprint: Illegal Syscall #%d!\n", syscall_number);
467         else
468                 syscall_name = dune_syscall_table[syscall_number].name;
469
470         va_start(valist, fmt);
471
472         uth_mutex_lock(lemu_logging_lock);
473
474         // Print to stderr if debug level is sufficient
475         if (debug > 1) {
476                 fprintf(stderr, prefix, tid, syscall_name);
477                 vfprintf(stderr, fmt, valist);
478                 // Checks if we will double log to stderr
479                 if (lemu_global_logfile == stderr)
480                         double_logging = true;
481         }
482
483         // Log to the global logfile, if we defaulted the global logging to
484         // stderr then we don't want to log 2 times to stderr.
485         if (lemu_global_logfile != NULL && !double_logging) {
486                 fprintf(lemu_global_logfile, prefix, tid, syscall_name);
487                 vfprintf(lemu_global_logfile, fmt, valist);
488         }
489
490         uth_mutex_unlock(lemu_logging_lock);
491
492         va_end(valist);
493 }
494
495
496 /* TODO: have an array which classifies syscall args
497  * and "special" system calls (ones with weird return
498  * values etc.). For some cases, we don't even do a system
499  * call, and in many cases we have to rearrange arguments
500  * since Linux and Akaros don't share signatures, so this
501  * gets tricky. */
502 bool
503 linuxemu(struct guest_thread *gth, struct vm_trapframe *tf)
504 {
505         bool ret = false;
506
507         if (tf->tf_rax >= DUNE_MAX_NUM_SYSCALLS) {
508                 fprintf(stderr, "System call %d is out of range\n", tf->tf_rax);
509                 return false;
510         }
511
512
513         if (dune_syscall_table[tf->tf_rax].call == NULL) {
514                 fprintf(stderr, "System call #%d (%s) is not implemented\n",
515                         tf->tf_rax, dune_syscall_table[tf->tf_rax].name);
516                 return false;
517         }
518
519         lemuprint(tf->tf_guest_pcoreid, tf->tf_rax,
520                   false, "vmcall(%d, %p, %p, %p, %p, %p, %p);\n", tf->tf_rax,
521                   tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_r10, tf->tf_r8,
522                   tf->tf_r9);
523
524         tf->tf_rip += 3;
525
526         return (dune_syscall_table[tf->tf_rax].call)(tf);
527 }