1 /*
2  * Copyright (c) 2022-2024, Netflix, Inc.
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include "host_syscall.h"
8 #include "syscall_nr.h"
9 #include <stand.h>
10 
11 /*
12  * Various trivial wrappers for Linux system calls. Please keep sorted
13  * alphabetically.
14  */
15 
16 int
host_close(int fd)17 host_close(int fd)
18 {
19 	return host_syscall(SYS_close, fd);
20 }
21 
22 int
host_dup(int fd)23 host_dup(int fd)
24 {
25 	return host_syscall(SYS_dup, fd);
26 }
27 
28 int
host_exit(int code)29 host_exit(int code)
30 {
31 	return host_syscall(SYS_exit, code);
32 }
33 
34 /* Same system call with different names on different Linux architectures due to history */
35 int
host_fstat(int fd,struct host_kstat * sb)36 host_fstat(int fd, struct host_kstat *sb)
37 {
38 #ifdef SYS_newfstat
39 	return host_syscall(SYS_newfstat, fd, (uintptr_t)sb);
40 #else
41 	return host_syscall(SYS_fstat, fd, (uintptr_t)sb);
42 #endif
43 }
44 
45 int
host_getdents64(int fd,void * dirp,int count)46 host_getdents64(int fd, void *dirp, int count)
47 {
48 	return host_syscall(SYS_getdents64, fd, (uintptr_t)dirp, count);
49 }
50 
51 int
host_getpid(void)52 host_getpid(void)
53 {
54 	return host_syscall(SYS_getpid);
55 }
56 
57 int
host_gettimeofday(struct host_timeval * a,void * b)58 host_gettimeofday(struct host_timeval *a, void *b)
59 {
60 	return host_syscall(SYS_gettimeofday, (uintptr_t)a, (uintptr_t)b);
61 }
62 
63 int
host_ioctl(int fd,unsigned long request,unsigned long arg)64 host_ioctl(int fd, unsigned long request, unsigned long arg)
65 {
66 	return host_syscall(SYS_ioctl, fd, request, arg);
67 }
68 
69 ssize_t
host_llseek(int fd,int32_t offset_high,int32_t offset_lo,uint64_t * result,int whence)70 host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence)
71 {
72 #ifdef SYS_llseek
73 	return host_syscall(SYS_llseek, fd, offset_high, offset_lo, (uintptr_t)result, whence);
74 #else
75 	int64_t rv = host_syscall(SYS_lseek, fd,
76 	    (int64_t)((uint64_t)offset_high << 32 | (uint32_t)offset_lo), whence);
77 	if (rv > 0)
78 		*result = (uint64_t)rv;
79 	return (rv);
80 #endif
81 }
82 
83 int
host_kexec_load(unsigned long entry,unsigned long nsegs,struct host_kexec_segment * segs,unsigned long flags)84 host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags)
85 {
86 	return host_syscall(SYS_kexec_load, entry, nsegs, segs, flags);
87 }
88 
89 int
host_mkdir(const char * path,host_mode_t mode)90 host_mkdir(const char *path, host_mode_t mode)
91 {
92 	return host_syscall(SYS_mkdirat, HOST_AT_FDCWD, (uintptr_t)path, mode);
93 }
94 
95 void *
host_mmap(void * addr,size_t len,int prot,int flags,int fd,off_t off)96 host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
97 {
98 	return (void *)host_syscall(SYS_mmap, (uintptr_t)addr, len, prot, flags, fd, off);
99 }
100 
101 int
host_mount(const char * src,const char * target,const char * type,unsigned long flags,void * data)102 host_mount(const char *src, const char *target, const char *type, unsigned long flags,
103     void *data)
104 {
105 	return host_syscall(SYS_mount, src, target, type, flags, data);
106 }
107 
108 int
host_munmap(void * addr,size_t len)109 host_munmap(void *addr, size_t len)
110 {
111 	return host_syscall(SYS_munmap, (uintptr_t)addr, len);
112 }
113 
114 int
host_open(const char * path,int flags,int mode)115 host_open(const char *path, int flags, int mode)
116 {
117 	return host_syscall(SYS_openat, HOST_AT_FDCWD, (uintptr_t)path, flags, mode);
118 	/* XXX original overrode errors */
119 }
120 
121 ssize_t
host_read(int fd,void * buf,size_t nbyte)122 host_read(int fd, void *buf, size_t nbyte)
123 {
124 	return host_syscall(SYS_read, fd, (uintptr_t)buf, nbyte);
125 	/* XXX original overrode errors */
126 }
127 
128 int
host_reboot(int magic1,int magic2,int cmd,uintptr_t arg)129 host_reboot(int magic1, int magic2, int cmd, uintptr_t arg)
130 {
131 	return host_syscall(SYS_reboot, magic1, magic2, cmd, arg);
132 }
133 
134 int
host_select(int nfds,long * readfds,long * writefds,long * exceptfds,struct host_timeval * timeout)135 host_select(int nfds, long *readfds, long *writefds, long *exceptfds,
136     struct host_timeval *timeout)
137 {
138 	struct timespec ts = { .tv_sec = timeout->tv_sec, .tv_nsec = timeout->tv_usec * 1000 };
139 
140 	/*
141 	 * Note, final arg is a sigset_argpack since most arch can only have 6
142 	 * syscall args. Since we're not masking signals, though, we can just
143 	 * pass a NULL.
144 	 */
145 	return host_syscall(SYS_pselect6, nfds, (uintptr_t)readfds, (uintptr_t)writefds,
146 	    (uintptr_t)exceptfds, (uintptr_t)&ts, (uintptr_t)NULL);
147 }
148 
149 int
host_stat(const char * path,struct host_kstat * sb)150 host_stat(const char *path, struct host_kstat *sb)
151 {
152 	return host_syscall(SYS_newfstatat, HOST_AT_FDCWD, (uintptr_t)path, (uintptr_t)sb, 0);
153 }
154 
155 int
host_symlink(const char * path1,const char * path2)156 host_symlink(const char *path1, const char *path2)
157 {
158 	return host_syscall(SYS_symlinkat, HOST_AT_FDCWD, path1, path2);
159 }
160 
161 int
host_uname(struct old_utsname * uts)162 host_uname(struct old_utsname *uts)
163 {
164 	return host_syscall(SYS_uname, (uintptr_t)uts);
165 }
166 
167 ssize_t
host_write(int fd,const void * buf,size_t nbyte)168 host_write(int fd, const void *buf, size_t nbyte)
169 {
170 	return host_syscall(SYS_write, fd, (uintptr_t)buf, nbyte);
171 }
172