AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
syscall.c
Go to the documentation of this file.
1
8
9#include "syscalls.h"
10
12LOGGER_DEFINE(syscall, syscall_log, syscall_log_level)
13
14
22struct file *fd_file(int fd)
23{
24 struct file *file = proc_fd_file(curproc, fd);
25 return file ? file_hold(file) : NULL;
26}
27
28/*
29 * User memory: a system call reads what the program passed it with
30 * copyin(), or copyinstr() for a string (upath_get() for a path), and
31 * writes its results with copyout(); data goes through an iobuf
32 * (fs/iobuf.h). A bad address makes them fail with EFAULT. Past them, the
33 * kernel only works with its own copies.
34 */
35
46int upath_get(const char *upath, char **path)
47{
48 char *buf = kmalloc(UPATH_MAX, &M_BUFFER, 0);
49
50 *path = NULL;
51
52 if (!buf)
53 return -ENOMEM;
54
55 long len = copyinstr(buf, upath, UPATH_MAX);
56
57 if (len < 0) {
58 kfree(buf);
59 return len;
60 }
61
62 *path = buf;
63 return 0;
64}
65
66/*
67 * The table says what each system call number calls. All its entries
68 * have the one type that the dispatch calls them through, syscall_t: five
69 * arguments the size of a register, and a long result. A system call is
70 * written with its own types instead, as sys_read(int fd, void *buf,
71 * size_t nbytes).
72 *
73 * SYSCALLn(name, types...) makes the table's entry for sys_<name>, which
74 * takes n arguments: a function sys_<name>_entry() of the table's type,
75 * which converts the registers to those types and calls sys_<name>(). So
76 * the compiler checks every call. Calling sys_read() itself through a
77 * pointer of another type would be undefined behaviour in C, even though
78 * x86's and aarch64's calling conventions happen to make it work.
79 */
80
81#define SYSCALL_ARGS \
82 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5
83
84#define SYSCALL0(name) \
85 static long sys_##name##_entry(SYSCALL_ARGS) \
86 { return sys_##name(); }
87#define SYSCALL1(name, t1) \
88 static long sys_##name##_entry(SYSCALL_ARGS) \
89 { return sys_##name((t1) a1); }
90#define SYSCALL2(name, t1, t2) \
91 static long sys_##name##_entry(SYSCALL_ARGS) \
92 { return sys_##name((t1) a1, (t2) a2); }
93#define SYSCALL3(name, t1, t2, t3) \
94 static long sys_##name##_entry(SYSCALL_ARGS) \
95 { return sys_##name((t1) a1, (t2) a2, (t3) a3); }
96#define SYSCALL4(name, t1, t2, t3, t4) \
97 static long sys_##name##_entry(SYSCALL_ARGS) \
98 { return sys_##name((t1) a1, (t2) a2, (t3) a3, (t4) a4); }
99#define SYSCALL5(name, t1, t2, t3, t4, t5) \
100 static long sys_##name##_entry(SYSCALL_ARGS) \
101 { return sys_##name((t1) a1, (t2) a2, (t3) a3, (t4) a4, (t5) a5); }
102
103SYSCALL1(exit, int)
104SYSCALL1(close, int)
105SYSCALL3(execve, const char *, char * const *, char * const *)
106SYSCALL0(fork)
107SYSCALL2(fstat, int, struct aquila_stat *)
108SYSCALL0(getpid)
109SYSCALL1(isatty, int)
110SYSCALL2(kill, pid_t, int)
111SYSCALL2(link, const char *, const char *)
112SYSCALL5(linkat, int, const char *, int, const char *, int)
113SYSCALL3(lseek, int, off_t, int)
114SYSCALL3(open, const char *, int, mode_t)
115SYSCALL4(openat, int, const char *, int, mode_t)
116SYSCALL3(read, int, void *, size_t)
117SYSCALL1(sbrk, ptrdiff_t)
118SYSCALL2(stat, const char *, struct aquila_stat *)
119SYSCALL4(fstatat, int, const char *, struct aquila_stat *, int)
120SYSCALL1(times, struct aquila_tms *)
121SYSCALL1(unlink, const char *)
122SYSCALL3(unlinkat, int, const char *, int)
123SYSCALL3(waitpid, int, int *, int)
124SYSCALL3(write, int, void *, size_t)
125SYSCALL3(ioctl, int, int, void *)
126SYSCALL3(sigaction, int, const struct aquila_sigaction *, struct aquila_sigaction *)
127SYSCALL2(readdir, int, struct dirent *)
128SYSCALL1(mount, struct aquila_mount_args *)
129SYSCALL2(mkdir, const char *, mode_t)
130SYSCALL1(uname, struct utsname *)
131SYSCALL1(pipe, int *)
132SYSCALL3(fcntl, int, int, uintptr_t)
133SYSCALL1(chdir, const char *)
134SYSCALL2(getcwd, char *, size_t)
135SYSCALL1(thread_create, struct aquila_thread_args *)
136SYSCALL1(thread_exit, void *)
137SYSCALL2(thread_join, int, void **)
138SYSCALL2(setpgid, pid_t, pid_t)
139SYSCALL3(mknod, const char *, uint32_t, uint32_t)
140SYSCALL4(mknodat, int, const char *, uint32_t, uint32_t)
141SYSCALL2(lstat, const char *, struct aquila_stat *)
142SYSCALL1(setuid, uid_t)
143SYSCALL2(ftruncate, int, off_t)
144SYSCALL1(setgid, gid_t)
145SYSCALL0(getuid)
146SYSCALL0(getgid)
147SYSCALL2(mmap, struct aquila_mmap_args *, void **)
148SYSCALL2(munmap, void *, size_t)
149SYSCALL3(socket, int, int, int)
150SYSCALL3(accept, int, const struct sockaddr *, socklen_t *)
151SYSCALL3(bind, int, const struct sockaddr *, socklen_t)
152SYSCALL3(connect, int, const struct sockaddr *, socklen_t)
153SYSCALL2(listen, int, int)
154SYSCALL1(send, struct aquila_socket_io_args *)
155SYSCALL1(recv, struct aquila_socket_io_args *)
156SYSCALL3(getsockname, int, struct sockaddr *, socklen_t *)
157SYSCALL3(getpeername, int, struct sockaddr *, socklen_t *)
158SYSCALL5(getsockopt, int, int, int, void *, socklen_t *)
159SYSCALL5(setsockopt, int, int, int, const void *, socklen_t)
160SYSCALL1(umask, mode_t)
161SYSCALL2(chmod, const char *, mode_t)
162SYSCALL4(fchmodat, int, const char *, mode_t, int)
163SYSCALL2(fchmod, int, mode_t)
164SYSCALL1(sysconf, int)
165SYSCALL2(access, const char *, int)
166SYSCALL4(faccessat, int, const char *, int, int)
167SYSCALL2(gettimeofday, struct timeval *, struct timezone *)
168SYSCALL3(sigmask, int, const sigset_t *, sigset_t *)
169SYSCALL1(sigsuspend, const sigset_t *)
170SYSCALL0(sigreturn)
171SYSCALL0(getppid)
172SYSCALL1(select, struct aquila_select_args *)
173SYSCALL3(poll, struct pollfd *, nfds_t, int)
174SYSCALL0(getpgrp)
175SYSCALL3(chown, const char *, uid_t, gid_t)
176SYSCALL5(fchownat, int, const char *, uid_t, gid_t, int)
177SYSCALL3(fchown, int, uid_t, gid_t)
178SYSCALL3(lchown, const char *, uid_t, gid_t)
179SYSCALL4(utimensat, int, const char *, const struct aquila_timespec *, int)
180SYSCALL1(rmdir, const char *)
181SYSCALL3(symlinkat, const char *, int, const char *)
182SYSCALL4(readlinkat, int, const char *, char *, size_t)
183SYSCALL4(renameat, int, const char *, int, const char *)
184SYSCALL2(flock, int, int)
185SYSCALL0(sync)
186SYSCALL2(shutdown, int, int)
187SYSCALL3(setitimer, int, const struct aquila_itimer *, struct aquila_itimer *)
188SYSCALL3(getrandom, void *, size_t, unsigned)
189SYSCALL0(thread_self)
190SYSCALL1(reboot, unsigned)
191SYSCALL1(fchdir, int)
192SYSCALL0(setsid)
193SYSCALL2(nanosleep, const struct aquila_timespec *, struct aquila_timespec *)
194SYSCALL2(clock_gettime, int, struct aquila_timespec *)
195SYSCALL2(sethostname, const char *, size_t)
196
198 [SYS_exit] = sys_exit_entry,
199 [SYS_close] = sys_close_entry,
200 [SYS_execve] = sys_execve_entry,
201 [SYS_fork] = sys_fork_entry,
202 [SYS_fstat] = sys_fstat_entry,
203 [SYS_getpid] = sys_getpid_entry,
204 [SYS_isatty] = sys_isatty_entry,
205 [SYS_kill] = sys_kill_entry,
206 [SYS_link] = sys_link_entry,
207 [SYS_lseek] = sys_lseek_entry,
208 [SYS_open] = sys_open_entry,
209 [SYS_read] = sys_read_entry,
210 [SYS_sbrk] = sys_sbrk_entry,
211 [SYS_stat] = sys_stat_entry,
212 [SYS_times] = sys_times_entry,
213 [SYS_unlink] = sys_unlink_entry,
214 [SYS_waitpid] = sys_waitpid_entry,
215 [SYS_write] = sys_write_entry,
216 [SYS_ioctl] = sys_ioctl_entry,
217 [SYS_sigaction] = sys_sigaction_entry,
218 [SYS_readdir] = sys_readdir_entry,
219 [SYS_mount] = sys_mount_entry,
220 [SYS_mkdir] = sys_mkdir_entry,
221 [SYS_uname] = sys_uname_entry,
222 [SYS_pipe] = sys_pipe_entry,
223 [SYS_fcntl] = sys_fcntl_entry,
224 [SYS_chdir] = sys_chdir_entry,
225 [SYS_getcwd] = sys_getcwd_entry,
226 [SYS_thread_create] = sys_thread_create_entry,
227 [SYS_thread_exit] = sys_thread_exit_entry,
228 [SYS_thread_join] = sys_thread_join_entry,
229 [SYS_setpgid] = sys_setpgid_entry,
230 [SYS_mknod] = sys_mknod_entry,
231 [SYS_lstat] = sys_lstat_entry,
232 [SYS_getuid] = sys_getuid_entry,
233 [SYS_getgid] = sys_getgid_entry,
234 [SYS_mmap] = sys_mmap_entry,
235 [SYS_munmap] = sys_munmap_entry,
236 [SYS_socket] = sys_socket_entry,
237 [SYS_accept] = sys_accept_entry,
238 [SYS_bind] = sys_bind_entry,
239 [SYS_connect] = sys_connect_entry,
240 [SYS_listen] = sys_listen_entry,
241 [SYS_send] = sys_send_entry,
242 [SYS_recv] = sys_recv_entry,
243 [SYS_umask] = sys_umask_entry,
244 [SYS_chmod] = sys_chmod_entry,
245 [SYS_sysconf] = sys_sysconf_entry,
246 [SYS_gettimeofday] = sys_gettimeofday_entry,
247 [SYS_access] = sys_access_entry,
248 [SYS_sigmask] = sys_sigmask_entry,
249 [SYS_select] = sys_select_entry,
250 [SYS_getpgrp] = sys_getpgrp_entry,
251 [SYS_chown] = sys_chown_entry,
252 [SYS_fchown] = sys_fchown_entry,
253 [SYS_lchown] = sys_lchown_entry,
254 [SYS_rmdir] = sys_rmdir_entry,
255 [SYS_setuid] = sys_setuid_entry,
256 [SYS_setgid] = sys_setgid_entry,
257 [SYS_ftruncate] = sys_ftruncate_entry,
258 [SYS_sigsuspend] = sys_sigsuspend_entry,
259 [SYS_getppid] = sys_getppid_entry,
260 [SYS_openat] = sys_openat_entry,
261 [SYS_fstatat] = sys_fstatat_entry,
262 [SYS_unlinkat] = sys_unlinkat_entry,
263 [SYS_mknodat] = sys_mknodat_entry,
264 [SYS_linkat] = sys_linkat_entry,
265 [SYS_symlinkat] = sys_symlinkat_entry,
266 [SYS_readlinkat] = sys_readlinkat_entry,
267 [SYS_renameat] = sys_renameat_entry,
268 [SYS_faccessat] = sys_faccessat_entry,
269 [SYS_fchmodat] = sys_fchmodat_entry,
270 [SYS_fchownat] = sys_fchownat_entry,
271 [SYS_utimensat] = sys_utimensat_entry,
272 [SYS_fchmod] = sys_fchmod_entry,
273 [SYS_fchdir] = sys_fchdir_entry,
274 [SYS_setsid] = sys_setsid_entry,
275 [SYS_nanosleep] = sys_nanosleep_entry,
276 [SYS_clock_gettime] = sys_clock_gettime_entry,
277 [SYS_sethostname] = sys_sethostname_entry,
278 [SYS_poll] = sys_poll_entry,
279 [SYS_flock] = sys_flock_entry,
280 [SYS_reboot] = sys_reboot_entry,
281 [SYS_sync] = sys_sync_entry,
282 [SYS_shutdown] = sys_shutdown_entry,
283 [SYS_setitimer] = sys_setitimer_entry,
284 [SYS_thread_self] = sys_thread_self_entry,
285 [SYS_getrandom] = sys_getrandom_entry,
286 [SYS_getsockname] = sys_getsockname_entry,
287 [SYS_getpeername] = sys_getpeername_entry,
288 [SYS_getsockopt] = sys_getsockopt_entry,
289 [SYS_setsockopt] = sys_setsockopt_entry,
290 [SYS_sigreturn] = sys_sigreturn_entry,
291};
292
293const size_t syscall_cnt = sizeof(syscall_table)/sizeof(syscall_table[0]);
294
295
313void syscall_dispatch(unsigned long nr, uintptr_t a1, uintptr_t a2, uintptr_t a3,
314 uintptr_t a4, uintptr_t a5)
315{
316 curthread->syscall_nr = nr;
317
318 if (nr >= syscall_cnt || !syscall_table[nr]) {
319 printk("[%d:%d] %s: undefined syscall %ld\n", curproc->pid, curthread->tid,
320 curproc->name, (int64_t) nr);
322 return;
323 }
324
325 long ret = syscall_table[nr](a1, a2, a3, a4, a5);
326
327 if (nr != SYS_sigreturn)
329
330 /* the open files the call used: let go of */
332
333 /* a restart was this call, or none */
334 curthread->restarting = 0;
335}
void arch_syscall_return(struct thread *thread, uintptr_t val)
Sets the result of a thread's system call, in the register that returns it to user mode.
Definition syscall.c:43
struct file * file_hold(struct file *file)
Holds an open file for the current system call, until it returns.
Definition file.c:82
void thread_files_release(struct thread *thread)
Lets go of the open files a thread's system call held, when the call returns or the thread is killed.
Definition file.c:99
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition printk.c:249
#define LOG_NONE
Definition printk.h:11
#define LOGGER_DEFINE(module, name, _level)
Definition printk.h:28
struct file * proc_fd_file(struct proc *proc, int fd)
Finds the open file a descriptor refers to.
Definition proc.c:560
#define curproc
Definition sched.h:13
#define curthread
Definition sched.h:12
#define NULL
Definition stddef.h:27
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
unsigned int uint32_t
Definition stddef.h:22
__PTRDIFF_TYPE__ ptrdiff_t
Definition stddef.h:10
signed long long int int64_t
Definition stddef.h:19
A file descriptor: the open file it refers to (fs/file.c, shared with the descriptors that dup() and ...
Definition proc.h:47
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
A pipe, or a FIFO's pipe.
Definition pipe.h:17
A socket.
Definition socket.h:16
#define SYSCALL2(name, t1, t2)
Definition syscall.c:90
static int syscall_log_level
Definition syscall.c:11
#define SYSCALL0(name)
Definition syscall.c:84
struct file * fd_file(int fd)
Finds the open file that a descriptor of the current process refers to, and holds it until the system...
Definition syscall.c:22
#define SYSCALL3(name, t1, t2, t3)
Definition syscall.c:93
#define SYSCALL1(name, t1)
Definition syscall.c:87
#define SYSCALL5(name, t1, t2, t3, t4, t5)
Definition syscall.c:99
int upath_get(const char *upath, char **path)
Copies a path from user memory into a new kernel buffer.
Definition syscall.c:46
#define SYSCALL4(name, t1, t2, t3, t4)
Definition syscall.c:96
const syscall_t syscall_table[]
Definition syscall.c:197
long(*) syscall_t(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t)
Definition syscall.h:8
const size_t syscall_cnt
Definition syscall.c:293
void syscall_dispatch(unsigned long nr, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5)
Runs a system call that the current thread made from user mode.
Definition syscall.c:313
#define UPATH_MAX
Definition syscalls.h:54
int thread_create(struct thread *thread, uintptr_t stack, uintptr_t entry, uintptr_t uentry, uintptr_t arg, uintptr_t attr, struct thread **new_thread)
Makes a new thread in the process of an existing one, for pthread_create().
Definition thread.c:86
int gettimeofday(struct timeval *tv, struct timezone *tz)
Reads the wall clock, in microseconds, for gettimeofday().
Definition time.c:78
int pid_t
Definition types.h:8
unsigned long sigset_t
Definition types.h:27
long int off_t
Definition types.h:10
uint32_t gid_t
Definition types.h:21
uint32_t uid_t
Definition types.h:20
uint32_t mode_t
Definition types.h:15