diff --git a/so3/arch/arm32/include/asm/syscall_number.h b/so3/arch/arm32/include/asm/syscall_number.h index 1da6a2f71..9f6552805 100644 --- a/so3/arch/arm32/include/asm/syscall_number.h +++ b/so3/arch/arm32/include/asm/syscall_number.h @@ -24,61 +24,82 @@ */ #define SYSCALL_EXIT 1 -#define SYSCALL_EXECVE 2 -#define SYSCALL_WAITPID 3 -#define SYSCALL_READ 4 -#define SYSCALL_WRITE 5 -#define SYSCALL_FORK 7 -#define SYSCALL_PTRACE 8 -#define SYSCALL_READDIR 9 -#define SYSCALL_OPEN 14 -#define SYSCALL_CLOSE 15 -#define SYSCALL_THREAD_CREATE 16 -#define SYSCALL_THREAD_JOIN 17 -#define SYSCALL_THREAD_EXIT 18 -#define SYSCALL_PIPE 19 -#define SYSCALL_IOCTL 20 -#define SYSCALL_FCNTL 21 -#define SYSCALL_DUP 22 -#define SYSCALL_DUP2 23 - -#define SYSCALL_SOCKET 26 -#define SYSCALL_BIND 27 -#define SYSCALL_LISTEN 28 -#define SYSCALL_ACCEPT 29 -#define SYSCALL_CONNECT 30 -#define SYSCALL_RECV 31 -#define SYSCALL_SEND 32 -#define SYSCALL_SENDTO 33 - -#define SYSCALL_STAT 34 -#define SYSCALL_MMAP 35 -#define SYSCALL_GETPID 37 - -#define SYSCALL_GETTIMEOFDAY 38 -#define SYSCALL_SETTIMEOFDAY 39 -#define SYSCALL_CLOCK_GETTIME 40 +#define SYSCALL_FORK 2 +#define SYSCALL_READ 3 +#define SYSCALL_WRITE 4 +#define SYSCALL_OPEN 5 +#define SYSCALL_CLOSE 6 -#define SYSCALL_THREAD_YIELD 43 +#define SYSCALL_EXECVE 11 -#define SYSCALL_SBRK 45 -#define SYSCALL_SIGACTION 46 -#define SYSCALL_KILL 47 -#define SYSCALL_SIGRETURN 48 +#define SYSCALL_LSEEK 19 +#define SYSCALL_GETPID 20 -#define SYSCALL_LSEEK 50 +#define SYSCALL_PTRACE 26 -#define SYSCALL_MUTEX_LOCK 60 -#define SYSCALL_MUTEX_UNLOCK 61 +#define SYSCALL_KILL 37 + +#define SYSCALL_DUP 41 +#define SYSCALL_PIPE 42 + +#define SYSCALL_BRK 45 -#define SYSCALL_NANOSLEEP 70 +#define SYSCALL_IOCTL 54 -#define SYSCALL_SYSINFO 99 +#define SYSCALL_DUP2 63 -#define SYSCALL_SETSOCKOPT 110 -#define SYSCALL_RECVFROM 111 +#define SYSCALL_GETTIMEOFDAY_TIME32 78 + +#define SYSCALL_WAIT4 114 + +#define SYSCALL_SIGRETURN 119 #define SYSCALL_READV 145 #define SYSCALL_WRITEV 146 +#define SYSCALL_NANOSLEEP 162 + +#define SYSCALL_RT_SIGRETURN 173 +#define SYSCALL_RT_SIGACTION 174 + +#define SYSCALL_MMAP2 192 + +#define SYSCALL_STAT64 195 + +#define SYSCALL_GETDENTS64 217 + +#define SYSCALL_CLOCK_GETTIME32 263 + +#define SYSCALL_SOCKET 281 +#define SYSCALL_BIND 282 +#define SYSCALL_CONNECT 283 +#define SYSCALL_LISTEN 284 +#define SYSCALL_ACCEPT 285 + +#define SYSCALL_SEND 289 +#define SYSCALL_SENDTO 290 + +#define SYSCALL_RECV 291 +#define SYSCALL_RECVFROM 292 + +#define SYSCALL_SETSOCKOPT 294 + +#define SYSCALL_OPENAT 322 + +#define SYSCALL_FSTATAT64 327 + +#define SYSCALL_DUP3 358 +#define SYSCALL_PIPE2 359 + +#define SYSCALL_CLOCK_GETTIME64 403 + +/* Following syscalls still need to be aligned */ +#define SYSCALL_THREAD_CREATE 16 +#define SYSCALL_THREAD_JOIN 17 +#define SYSCALL_THREAD_EXIT 18 +#define SYSCALL_THREAD_YIELD 43 + +#define SYSCALL_MUTEX_LOCK 60 +#define SYSCALL_MUTEX_UNLOCK 61 + #endif /* ARCH_ARM32_SYSCALL_NUMBER_H */ diff --git a/so3/arch/arm64/exception.S b/so3/arch/arm64/exception.S index bde52f61b..cf58242bc 100644 --- a/so3/arch/arm64/exception.S +++ b/so3/arch/arm64/exception.S @@ -557,7 +557,7 @@ el01_sync_handler: // Check if sigreturn has been called. In this case, we // clean the stack frame which has been used to manage the user handler. - cmp x8, #SYSCALL_SIGRETURN + cmp x8, #SYSCALL_RT_SIGRETURN bne __ret_from_fork // Reset the stack frame by removing the one issued from sigreturn diff --git a/so3/arch/arm64/include/asm/syscall_number.h b/so3/arch/arm64/include/asm/syscall_number.h index 2cbbea82d..be298b5f0 100644 --- a/so3/arch/arm64/include/asm/syscall_number.h +++ b/so3/arch/arm64/include/asm/syscall_number.h @@ -22,63 +22,70 @@ /* * Syscall number definition */ +#define SYSCALL_DUP 23 +#define SYSCALL_DUP3 24 -#define SYSCALL_EXIT 1 -#define SYSCALL_EXECVE 2 -#define SYSCALL_WAITPID 3 -#define SYSCALL_READ 4 -#define SYSCALL_WRITE 5 -#define SYSCALL_FORK 7 -#define SYSCALL_PTRACE 8 -#define SYSCALL_READDIR 9 -#define SYSCALL_OPEN 14 -#define SYSCALL_CLOSE 15 -#define SYSCALL_THREAD_CREATE 16 -#define SYSCALL_THREAD_JOIN 17 -#define SYSCALL_THREAD_EXIT 18 -#define SYSCALL_PIPE 19 -#define SYSCALL_IOCTL 20 -#define SYSCALL_FCNTL 21 -#define SYSCALL_DUP 22 -#define SYSCALL_DUP2 23 - -#define SYSCALL_SOCKET 26 -#define SYSCALL_BIND 27 -#define SYSCALL_LISTEN 28 -#define SYSCALL_ACCEPT 29 -#define SYSCALL_CONNECT 30 -#define SYSCALL_RECV 31 -#define SYSCALL_SEND 32 -#define SYSCALL_SENDTO 33 - -#define SYSCALL_STAT 34 -#define SYSCALL_MMAP 35 -#define SYSCALL_GETPID 37 - -#define SYSCALL_GETTIMEOFDAY 38 -#define SYSCALL_SETTIMEOFDAY 39 -#define SYSCALL_CLOCK_GETTIME 40 - -#define SYSCALL_THREAD_YIELD 43 - -#define SYSCALL_SBRK 45 -#define SYSCALL_SIGACTION 46 -#define SYSCALL_KILL 47 -#define SYSCALL_SIGRETURN 48 +#define SYSCALL_IOCTL 29 -#define SYSCALL_LSEEK 50 +#define SYSCALL_OPENAT 56 +#define SYSCALL_CLOSE 57 -#define SYSCALL_MUTEX_LOCK 60 -#define SYSCALL_MUTEX_UNLOCK 61 +#define SYSCALL_PIPE2 59 +#define SYSCALL_GETDENTS64 61 +#define SYSCALL_LSEEK 62 +#define SYSCALL_READ 63 +#define SYSCALL_WRITE 64 #define SYSCALL_READV 65 #define SYSCALL_WRITEV 66 -#define SYSCALL_NANOSLEEP 70 +#define SYSCALL_NEWFSTATAT 79 + +#define SYSCALL_EXIT 93 + +#define SYSCALL_NANOSLEEP 101 + +#define SYSCALL_CLOCK_GETTIME 113 + +#define SYSCALL_PTRACE 117 + +#define SYSCALL_KILL 129 + +#define SYSCALL_RT_SIGACTION 134 + +#define SYSCALL_RT_SIGRETURN 139 -#define SYSCALL_SYSINFO 99 +#define SYSCALL_GETTIMEOFDAY 169 -#define SYSCALL_SETSOCKOPT 110 -#define SYSCALL_RECVFROM 111 +#define SYSCALL_GETPID 172 + +#define SYSCALL_SOCKET 198 + +#define SYSCALL_BIND 200 +#define SYSCALL_LISTEN 201 +#define SYSCALL_ACCEPT 202 +#define SYSCALL_CONNECT 203 + +#define SYSCALL_SENDTO 206 +#define SYSCALL_RECVFROM 207 +#define SYSCALL_SETSOCKOPT 208 + +#define SYSCALL_BRK 214 + +#define SYSCALL_EXECVE 221 +#define SYSCALL_MMAP 222 + +#define SYSCALL_WAIT4 260 + +/* Following syscalls still need to be aligned */ +#define SYSCALL_FORK 7 // => clone + +#define SYSCALL_THREAD_CREATE 16 +#define SYSCALL_THREAD_JOIN 17 +#define SYSCALL_THREAD_EXIT 18 +#define SYSCALL_THREAD_YIELD 43 + +#define SYSCALL_MUTEX_LOCK 60 +#define SYSCALL_MUTEX_UNLOCK 61 #endif /* ARCH_ARM64_SYSCALL_NUMBER_H */ diff --git a/so3/fs/elf.c b/so3/fs/elf.c index 0489e7de5..c05309a6b 100644 --- a/so3/fs/elf.c +++ b/so3/fs/elf.c @@ -35,12 +35,12 @@ uint8_t *elf_load_buffer(const char *filename) struct stat st; /* open and read file */ - fd = sys_do_open(filename, O_RDONLY); + fd = sys_do_open(filename, O_RDONLY, 0); if (fd < 0) return NULL; - if (sys_do_stat(filename, &st)) + if (sys_do_newfstatat(AT_FDCWD, filename, &st, 0)) return NULL; if (!st.st_size) diff --git a/so3/fs/fat/fat.c b/so3/fs/fat/fat.c index 4a41b514f..551454488 100644 --- a/so3/fs/fat/fat.c +++ b/so3/fs/fat/fat.c @@ -415,8 +415,7 @@ int fat_stat(const char *path, struct stat *st) } time_fat_fat2so3(finfo.fdate, finfo.ftime, &tm); - st->st_mtim = tm.tv_sec; - strcpy(st->st_name, path); + st->st_mtime = tm.tv_sec; st->st_size = finfo.fsize; return 0; diff --git a/so3/fs/vfs.c b/so3/fs/vfs.c index 7c0ee97bb..5f7f76dff 100644 --- a/so3/fs/vfs.c +++ b/so3/fs/vfs.c @@ -33,6 +33,9 @@ #include #include +#include +#include + /* The VFS abstract subsystem manages a table of open file descriptors where indexes are known as gfd (global file descriptor). * Every process has its own file descriptor table. A local file descriptor (belonging to a process) must be linked to a global file descriptor * according to the fd type. @@ -381,7 +384,7 @@ int vfs_clone_fd(int *fd_src, int *fd_dst) /**************************** Syscall implementation ****************************/ /* Low Level read */ -static int do_read(int fd, void *buffer, int count) +static int do_read(int fd, void *buffer, size_t count) { int gfd; int ret; @@ -423,7 +426,7 @@ static int do_read(int fd, void *buffer, int count) } /* Low Level write */ -static int do_write(int fd, const void *buffer, int count) +static int do_write(int fd, const void *buffer, size_t count) { int gfd; int ret; @@ -532,7 +535,62 @@ static int do_mmap_anon(int fd, addr_t virt_addr, uint32_t page_count, off_t off return virt_addr; } -SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count) +/** + * @brief Low level stat implementation. + */ +static long do_stat(const char *path, struct stat *st) +{ + int ret; + + memset(st, 0, sizeof(*st)); + + mutex_lock(&vfs_lock); + + /* FIXME Find the correct mount point with the path */ + if (!registered_fs_ops[FS_FAT]) { + mutex_unlock(&vfs_lock); + return -ENOENT; + } + + if (!registered_fs_ops[FS_FAT]->stat) { + mutex_unlock(&vfs_lock); + return -ENOENT; + } + + ret = registered_fs_ops[FS_FAT]->stat(path, st); + + mutex_unlock(&vfs_lock); + + return ret; +} + +/** + * @brief Function to convert stat to stat64 for ARM32 compatibility. + */ +static struct stat64 stat_to_stat64(struct stat *st) +{ + return (struct stat64) { + .st_dev = st->st_dev, + .__st_ino = st->st_ino, + .st_mode = st->st_mode, + .st_nlink = st->st_nlink, + .st_uid = st->st_uid, + .st_gid = st->st_gid, + .st_rdev = st->st_rdev, + .st_size = st->st_size, + .st_blksize = st->st_blksize, + .st_blocks = st->st_blocks, + .st_atime = st->st_atime, + .st_atime_nsec = st->st_atime_nsec, + .st_mtime = st->st_mtime, + .st_mtime_nsec = st->st_mtime_nsec, + .st_ctime = st->st_ctime, + .st_ctime_nsec = st->st_ctime_nsec, + .st_ino = st->st_ino, + }; +} + +SYSCALL_DEFINE3(read, int, fd, void *, buffer, size_t, count) { return do_read(fd, buffer, count); } @@ -540,7 +598,7 @@ SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count) /** * @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes */ -SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count) +SYSCALL_DEFINE3(write, int, fd, const void *, buffer, size_t, count) { return do_write(fd, buffer, count); } @@ -548,12 +606,16 @@ SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count) /** * @brief This function opens a file. Not all file types are supported. */ -SYSCALL_DEFINE2(open, const char *, filename, int, flags) +SYSCALL_DEFINE3(open, const char *, filename, int, flags, mode_t, mode) { int fd, gfd, ret = -1; uint32_t type; struct file_operations *fops; + if (mode != 0) { + LOG_WARNING("mode parameters isn't supported\n"); + } + mutex_lock(&vfs_lock); /* @@ -612,15 +674,35 @@ SYSCALL_DEFINE2(open, const char *, filename, int, flags) return ret; } +/** + * @brief Simple openat implementation ignoring dirfd for aarch64. + */ +SYSCALL_DEFINE4(openat, int, dirfd, const char *, filename, int, flags, mode_t, mode) +{ + if (dirfd != AT_FDCWD) { + LOG_WARNING("dirfd parameters isn't supported\n"); + return -ENOSYS; + } + + return sys_do_open(filename, flags, mode); +} + /* - * @brief readdir read a directory entry which will be stored in a struct dirent entry + * @brief gedetens64 read a directory entry which will be stored in a struct dirent entry. + * This is used for readdir on userspace. * @param fd This is the file descriptor provided as (DIR *) when doing opendir in the userspace. */ -SYSCALL_DEFINE3(readdir, int, fd, char *, buf, int, len) +SYSCALL_DEFINE3(getdents64, int, fd, struct dirent *, buf, size_t, count) { struct dirent *dirent; int gfd; + /* Dirent d_name should be a flexible array, which is not the case here. + So ensure that the given dirent can actually our full dirent. */ + if (count < sizeof(struct dirent)) { + return -EINVAL; + } + mutex_lock(&vfs_lock); gfd = vfs_get_gfd(fd); @@ -715,9 +797,25 @@ SYSCALL_DEFINE1(close, int, fd) return 0; } +/** + * @brief Simple dup3 implementation ignoring flags for aarch64. + */ +SYSCALL_DEFINE3(dup3, int, oldfd, int, newfd, int, flags) +{ + if (oldfd == newfd) { + return -EINVAL; + } + + if (flags != 0) { + LOG_WARNING("Flags not supported.\n"); + return -ENOSYS; + } + + return sys_do_dup2(oldfd, newfd); +} + /** * @brief dup2 creates a synonym of oldfd on newfd - * */ SYSCALL_DEFINE2(dup2, int, oldfd, int, newfd) { @@ -780,30 +878,68 @@ SYSCALL_DEFINE1(dup, int, oldfd) #endif } -SYSCALL_DEFINE2(stat, const char *, path, struct stat *, st) +/** + * @brief On ARM32, stat64 syscall is called instead of stat. + */ +SYSCALL_DEFINE2(stat64, const char *, path, struct stat64 *, st) { - int ret; + struct stat stat; + long ret = 0; - mutex_lock(&vfs_lock); + ret = do_stat(path, &stat); - /* FIXME Find the correct mount point with the path */ - if (!registered_fs_ops[FS_FAT]) { - mutex_unlock(&vfs_lock); - return -ENOENT; + if (ret >= 0) { + *st = stat_to_stat64(&stat); } - if (!registered_fs_ops[FS_FAT]->stat) { - mutex_unlock(&vfs_lock); - return -ENOENT; + return ret; +} + +/** + * @brief On ARM32, fstatat64 syscall is called instead of fstatat and stat in some condition. + */ +SYSCALL_DEFINE4(fstatat64, int, fd, const char *, path, struct stat64 *, st, int, flags) +{ + struct stat stat; + int ret; + + if (fd != AT_FDCWD) { + LOG_WARNING("fd parameters isn't supported\n"); + return -ENOSYS; } - ret = registered_fs_ops[FS_FAT]->stat(path, st); + if (flags != 0) { + LOG_WARNING("Flags not supported\n"); + return -ENOSYS; + } - mutex_unlock(&vfs_lock); + ret = do_stat(path, &stat); + + if (ret >= 0) { + *st = stat_to_stat64(&stat); + } return ret; } +/** + * @brief On aarch64, newfstatat syscall is called for stat. + */ +SYSCALL_DEFINE4(newfstatat, int, fd, const char *, path, struct stat *, st, int, flags) +{ + if (fd != AT_FDCWD) { + LOG_WARNING("fd parameters isn't supported\n"); + return -ENOSYS; + } + + if (flags != 0) { + LOG_WARNING("Flags not supported\n"); + return -ENOSYS; + } + + return do_stat(path, st); +} + /** * An mmap() implementation in VFS. */ @@ -823,6 +959,14 @@ SYSCALL_DEFINE6(mmap, addr_t, start, size_t, length, int, prot, int, flags, int, return do_mmap(fd, start, page_count, offset); } +/** + * Works like mmap, but with the given offset been in page count. + */ +SYSCALL_DEFINE6(mmap2, addr_t, start, size_t, length, int, prot, int, flags, int, fd, off_t, pgoffset) +{ + return sys_do_mmap(start, length, prot, flags, fd, pgoffset * PAGE_SIZE); +} + SYSCALL_DEFINE3(ioctl, int, fd, unsigned long, cmd, unsigned long, args) { int rc, gfd; @@ -872,14 +1016,23 @@ SYSCALL_DEFINE3(lseek, int, fd, off_t, off, int, whence) return rc; } -/* - * Implementation of the fcntl syscall +/** + * @brief Implementation of llseek syscall for ARM32 which use it instead of lseek. */ -SYSCALL_DEFINE3(fcntl, int, fd, unsigned long, cmd, unsigned long, args) +SYSCALL_DEFINE5(_llseek, int, fd, unsigned long, offset_high, unsigned long, offset_low, off_t *, result, unsigned, whence) { - /* Not yet implemented */ + off_t offset = ((off_t) offset_high << 32) | offset_low; + off_t ret; - return 0; + ret = sys_do_lseek(fd, offset, whence); + + if (ret >= 0) { + /* New offset is returned in the 64 bits of result. */ + *result = ret; + ret = 0; + } + + return ret; } /* diff --git a/so3/include/device/timer.h b/so3/include/device/timer.h index d159e6bb1..cdca9f822 100644 --- a/so3/include/device/timer.h +++ b/so3/include/device/timer.h @@ -37,6 +37,18 @@ struct timeval { time_t tv_usec; /* microseconds */ }; +/* Time conversion units - ARM32 compatibility. */ + +struct timespec32 { + time32_t tv_sec; /* seconds */ + time32_t tv_nsec; /* nanoseconds */ +}; + +struct timeval32 { + time32_t tv_sec; /* seconds */ + time32_t tv_usec; /* microseconds */ +}; + /* All timing information below must be express in nanoseconds. The underlying hardware is responsible * to perform the necessary alignment on 64 bits. */ diff --git a/so3/include/dirent.h b/so3/include/dirent.h index c480e80b5..6c63cee25 100644 --- a/so3/include/dirent.h +++ b/so3/include/dirent.h @@ -22,7 +22,7 @@ #define DIRENT_H_ typedef uint64_t ino_t; -typedef uint32_t off_t; +typedef int64_t off_t; struct dirent { ino_t d_ino; diff --git a/so3/include/net.h b/so3/include/net.h index 52a97f27c..b527ddf8a 100644 --- a/so3/include/net.h +++ b/so3/include/net.h @@ -66,17 +66,26 @@ #define SIOCSIFHWBROADCAST 0x8937 #define SIOCGIFCOUNT 0x8938 +/* network address struct used by the userspace */ +struct usr_sockaddr_in { + u16 sin_family; + in_port_t sin_port; + struct in_addr sin_addr; + uint8_t sin_zero[8]; +}; + void net_init(void); SYSCALL_DECLARE(socket, int domain, int type, int protocol); -SYSCALL_DECLARE(connect, int sockfd, const struct sockaddr *name, socklen_t namelen); -SYSCALL_DECLARE(bind, int sockfd, const struct sockaddr *addr, socklen_t addrlen); +SYSCALL_DECLARE(connect, int sockfd, const struct usr_sockaddr_in *name, socklen_t namelen); +SYSCALL_DECLARE(bind, int sockfd, const struct usr_sockaddr_in *addr, socklen_t addrlen); SYSCALL_DECLARE(listen, int sockfd, int backlog); -SYSCALL_DECLARE(accept, int sockfd, struct sockaddr *addr, socklen_t *addrlen); +SYSCALL_DECLARE(accept, int sockfd, struct usr_sockaddr_in *addr, socklen_t *addrlen); SYSCALL_DECLARE(recv, int sockfd, void *mem, size_t len, int flags); -SYSCALL_DECLARE(recvfrom, int sockfd, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); +SYSCALL_DECLARE(recvfrom, int sockfd, void *mem, size_t len, int flags, struct usr_sockaddr_in *from, socklen_t *fromlen); SYSCALL_DECLARE(send, int sockfd, const void *dataptr, size_t size, int flags); -SYSCALL_DECLARE(sendto, int sockfd, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen); +SYSCALL_DECLARE(sendto, int sockfd, const void *dataptr, size_t size, int flags, const struct usr_sockaddr_in *to, + socklen_t tolen); SYSCALL_DECLARE(setsockopt, int sockfd, int level, int optname, const void *optval, socklen_t optlen); #endif /* NET_H */ diff --git a/so3/include/pipe.h b/so3/include/pipe.h index 961f0b4c9..2f8f24101 100644 --- a/so3/include/pipe.h +++ b/so3/include/pipe.h @@ -54,5 +54,6 @@ struct pipe_desc { typedef struct pipe_desc pipe_desc_t; SYSCALL_DECLARE(pipe, int *pipefd); +SYSCALL_DECLARE(pipe2, int *pipefd, int flags); #endif /* PIPE_H */ diff --git a/so3/include/process.h b/so3/include/process.h index 83fceefe7..5b444deab 100644 --- a/so3/include/process.h +++ b/so3/include/process.h @@ -142,7 +142,7 @@ SYSCALL_DECLARE(getpid, void); SYSCALL_DECLARE(execve, const char *filename, char **argv, char **envp); SYSCALL_DECLARE(fork, void); SYSCALL_DECLARE(exit, int exit_status); -SYSCALL_DECLARE(waitpid, int pid, uint32_t *wstatus, uint32_t options); +SYSCALL_DECLARE(wait4, int pid, uint32_t *wstatus, uint32_t options, void *rusage); pcb_t *find_proc_by_pid(uint32_t pid); @@ -153,6 +153,6 @@ void dump_proc(void); extern int __exec(const char *file); extern int __write(int fd, char *buffer, int count); -SYSCALL_DECLARE(sbrk, int increment); +SYSCALL_DECLARE(brk, long increment); #endif /* PROCESS_H */ diff --git a/so3/include/ptrace.h b/so3/include/ptrace.h index e2b828721..b77dfa09d 100644 --- a/so3/include/ptrace.h +++ b/so3/include/ptrace.h @@ -208,7 +208,7 @@ struct ptrace_peeksiginfo_args { int32_t nr; }; -SYSCALL_DECLARE(ptrace, enum __ptrace_request request, uint32_t pid, void *addr, void *data); +SYSCALL_DECLARE(ptrace, enum __ptrace_request request, int pid, void *addr, void *data); struct pcb; struct user; diff --git a/so3/include/signal.h b/so3/include/signal.h index b4f8156a8..1feb49783 100644 --- a/so3/include/signal.h +++ b/so3/include/signal.h @@ -94,8 +94,9 @@ typedef struct __sigaction { sigaction_t *sa; } __sigaction_t; -SYSCALL_DECLARE(sigaction, int signum, const sigaction_t *action, sigaction_t *old_action); +SYSCALL_DECLARE(rt_sigaction, int signum, const sigaction_t *action, sigaction_t *old_action, size_t sigsize); SYSCALL_DECLARE(kill, int pid, int sig); SYSCALL_DECLARE(sigreturn, void); +SYSCALL_DECLARE(rt_sigreturn, void); #endif /* SIGNAL_H */ diff --git a/so3/include/stat.h b/so3/include/stat.h index 6571c90a1..835b7d896 100644 --- a/so3/include/stat.h +++ b/so3/include/stat.h @@ -22,16 +22,52 @@ #include -#define FILENAME_SIZE 256 - -typedef uint32_t mode_t; - +/* Stat structure copied from Linux include/uapi/asm-generic/stat.h */ struct stat { - char st_name[FILENAME_SIZE]; /* Filename */ - unsigned long st_size; /* Size of file */ - time_t st_mtim; /* Time of last modification in sec*/ - unsigned char st_flags; /* Regular file flag (not supported on fat) */ - mode_t st_mode; /* Protection not used (not supported on fat) */ + unsigned long st_dev; /* Device. */ + unsigned long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long st_rdev; /* Device number, if device. */ + unsigned long __pad1; + long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad2; + long st_blocks; /* Number 512-byte blocks allocated. */ + long st_atime; /* Time of last access. */ + unsigned long st_atime_nsec; + long st_mtime; /* Time of last modification. */ + unsigned long st_mtime_nsec; + long st_ctime; /* Time of last status change. */ + unsigned long st_ctime_nsec; + unsigned int __unused4; + unsigned int __unused5; +}; + +/* This is for ARM32 compatibility as 64bits version of stat will be called. + Adapted from arch/arm64/include/asm/stat.h on Linux */ +struct stat64 { + u64 st_dev; /* Device. */ + unsigned char __pad0[4]; + u32 __st_ino; /* File serial number. */ + u32 st_mode; /* File mode. */ + u32 st_nlink; /* Link count. */ + u32 st_uid; /* User ID of the file's owner. */ + u32 st_gid; /* Group ID of the file's group. */ + u64 st_rdev; /* Device number, if device. */ + unsigned char __pad3[4]; + s64 st_size; /* Size of file, in bytes. */ + u32 st_blksize; /* Optimal block size for I/O. */ + u64 st_blocks; /* Number 512-byte blocks allocated. */ + u32 st_atime; /* Time of last access. */ + u32 st_atime_nsec; + u32 st_mtime; /* Time of last modification. */ + u32 st_mtime_nsec; + u32 st_ctime; /* Time of last status change. */ + u32 st_ctime_nsec; + u64 st_ino; }; #endif /* STAT_H */ diff --git a/so3/include/syscall.h b/so3/include/syscall.h index 1c1031576..711b84145 100644 --- a/so3/include/syscall.h +++ b/so3/include/syscall.h @@ -21,12 +21,6 @@ #ifndef ASM_ARM_SYSCALL_H #define ASM_ARM_SYSCALL_H -#define SYSINFO_DUMP_HEAP 0 -#define SYSINFO_DUMP_SCHED 1 -#define SYSINFO_TEST_MALLOC 2 -#define SYSINFO_PRINTK 3 -#define SYSINFO_DUMP_PROC 4 - #include #ifndef __ASSEMBLY__ @@ -120,8 +114,6 @@ typedef long (*syscall_fn_t)(syscall_args_t *); long syscall_handle(syscall_args_t *); -SYSCALL_DECLARE(sysinfo, unsigned long info_number, char *text); - #endif /* __ASSEMBLY__ */ #endif /* ASM_ARM_SYSCALL_H */ diff --git a/so3/include/timer.h b/so3/include/timer.h index bb125c666..8905046a0 100644 --- a/so3/include/timer.h +++ b/so3/include/timer.h @@ -128,7 +128,9 @@ void clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec) SYSCALL_DECLARE(nanosleep, const struct timespec *req, struct timespec *rem); -SYSCALL_DECLARE(gettimeofday, struct timespec *tv); +SYSCALL_DECLARE(gettimeofday_time32, struct timeval32 *tv, void *tz); +SYSCALL_DECLARE(gettimeofday, struct timeval *tv, void *tz); +SYSCALL_DECLARE(clock_gettime32, int clk_id, struct timespec32 *ts); SYSCALL_DECLARE(clock_gettime, int clk_id, struct timespec *ts); #ifdef CONFIG_AVZ diff --git a/so3/include/types.h b/so3/include/types.h index b128206fe..75efc09fc 100644 --- a/so3/include/types.h +++ b/so3/include/types.h @@ -116,7 +116,8 @@ typedef __u32 __bitwise __wsum; typedef unsigned __bitwise__ gfp_t; -typedef u64 time_t; +typedef long time32_t; +typedef s64 time_t; #define ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) diff --git a/so3/include/vfs.h b/so3/include/vfs.h index 89430c6c4..5c72e7208 100644 --- a/so3/include/vfs.h +++ b/so3/include/vfs.h @@ -94,6 +94,10 @@ /* mmap flags options */ #define MAP_ANONYMOUS 0x10 /* don't use a file */ +/* Special value for dirfd used to indicate openat + should use the current working directory. */ +#define AT_FDCWD (-100) + /* Return error values */ #define MAP_FAILED ((void *) -1) /* mmap fail */ @@ -104,7 +108,7 @@ #include #include -#include +typedef uint32_t mode_t; struct iovec { void *iov_base; @@ -160,18 +164,23 @@ typedef enum { /* Syscall accessible from userspace */ -SYSCALL_DECLARE(open, const char *filename, int flags); -SYSCALL_DECLARE(read, int fd, void *buffer, int count); -SYSCALL_DECLARE(write, int fd, const void *buffer, int count); -SYSCALL_DECLARE(readdir, int fd, char *buf, int len); +SYSCALL_DECLARE(openat, int dirfd, const char *filename, int flags, mode_t mode) +SYSCALL_DECLARE(open, const char *filename, int flags, mode_t mode); +SYSCALL_DECLARE(read, int fd, void *buffer, size_t count); +SYSCALL_DECLARE(write, int fd, const void *buffer, size_t count); +SYSCALL_DECLARE(getdents64, int fd, struct dirent *buf, size_t count); SYSCALL_DECLARE(close, int fd); SYSCALL_DECLARE(dup, int oldfd); SYSCALL_DECLARE(dup2, int oldfd, int newfd); -SYSCALL_DECLARE(stat, const char *path, struct stat *st); +SYSCALL_DECLARE(dup3, int oldfd, int newfd, int flags); +SYSCALL_DECLARE(stat64, const char *path, struct stat64 *st); +SYSCALL_DECLARE(fstatat64, int fd, const char *filename, struct stat64 *statbuf, int flag); +SYSCALL_DECLARE(newfstatat, int fd, const char *filename, struct stat *statbuf, int flag); SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int flags, int fd, off_t offset); +SYSCALL_DECLARE(mmap2, addr_t start, size_t length, int prot, int flags, int fd, off_t pgoffset); SYSCALL_DECLARE(ioctl, int fd, unsigned long cmd, unsigned long args); -SYSCALL_DECLARE(fcntl, int fd, unsigned long cmd, unsigned long args); SYSCALL_DECLARE(lseek, int fd, off_t off, int whence); +SYSCALL_DECLARE(_llseek, int fd, unsigned long offset_high, unsigned long offset_low, off_t *result, unsigned whence); SYSCALL_DECLARE(writev, unsigned long fd, const struct iovec *vec, unsigned long vlen); SYSCALL_DECLARE(readv, unsigned long fd, const struct iovec *vec, unsigned long vlen); diff --git a/so3/ipc/pipe.c b/so3/ipc/pipe.c index e649bdff3..8efe9c7ca 100644 --- a/so3/ipc/pipe.c +++ b/so3/ipc/pipe.c @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include #include @@ -308,3 +308,16 @@ SYSCALL_DEFINE1(pipe, int *, pipefd) return 0; } + +/** + * Simple pipe2 implementation ignoring flags for aarch64. + */ +SYSCALL_DEFINE2(pipe2, int *, pipefd, int, flags) +{ + if (flags != 0) { + LOG_WARNING("Flags not supported.\n"); + return -ENOSYS; + } + + return sys_do_pipe(pipefd); +} diff --git a/so3/ipc/signal.c b/so3/ipc/signal.c index c610b2ad9..24de966a5 100644 --- a/so3/ipc/signal.c +++ b/so3/ipc/signal.c @@ -44,6 +44,14 @@ SYSCALL_DEFINE0(sigreturn) return 0; } +/** + * rt_sigreturn isn't different from sigreturn for SO3 use case. + */ +SYSCALL_DEFINE0(rt_sigreturn) +{ + return sys_do_sigreturn(); +} + /** * Checks if signals were set and executes their handlers if so. */ @@ -103,11 +111,16 @@ void __mem(int a, char *adr, int log) { } #endif /* 0 */ -SYSCALL_DEFINE3(sigaction, int, signum, const sigaction_t *, action, sigaction_t *, old_action) +SYSCALL_DEFINE4(rt_sigaction, int, signum, const sigaction_t *, action, sigaction_t *, old_action, size_t, sigsize) { + if (sigsize != sizeof(sigset_t)) { + LOG_WARNING("Invalid sigset size\n"); + return -EINVAL; + } + if (signum < 0 || signum >= _NSIG) { LOG_ERROR("signum not valid!\n"); - return -1; + return -EINVAL; } if (old_action != NULL) diff --git a/so3/kernel/process.c b/so3/kernel/process.c index 21a21f628..13ec54092 100644 --- a/so3/kernel/process.c +++ b/so3/kernel/process.c @@ -969,7 +969,7 @@ SYSCALL_DEFINE0(getpid) } /* - * Waitpid implementation - do_waitpid() does the following operations: + * Waitpid implementation via wait4 - sys_do_wait4() does the following operations: * - Suspend the current process until the child process finished its execution * (exit()) If the pid argument is -1, waitpid() looks for a possible terminated * process and performs the operation. If no process is finished (in zombie @@ -977,8 +977,10 @@ SYSCALL_DEFINE0(getpid) * - Get the exit code from the child PCB * - Clean the PCB and page tables * - Return the pid if successful operation + * + * rusage is ignored */ -SYSCALL_DEFINE3(waitpid, int, pid, uint32_t *, wstatus, uint32_t, options) +SYSCALL_DEFINE4(wait4, int, pid, uint32_t *, wstatus, uint32_t, options, void *, rusage) { pcb_t *child; unsigned long flags; @@ -1088,7 +1090,7 @@ SYSCALL_DEFINE3(waitpid, int, pid, uint32_t *, wstatus, uint32_t, options) * @return This function will the position of the end of the heap / program *break before increment */ -SYSCALL_DEFINE1(sbrk, int, increment) +SYSCALL_DEFINE1(brk, long, increment) { pcb_t *pcb = current()->pcb; int ret_pointer; diff --git a/so3/kernel/ptrace.c b/so3/kernel/ptrace.c index 8750f6667..3a30ef729 100644 --- a/so3/kernel/ptrace.c +++ b/so3/kernel/ptrace.c @@ -64,7 +64,7 @@ void __check_ptrace_syscall(void) /* * Implementation of ptrace syscall */ -SYSCALL_DEFINE4(ptrace, enum __ptrace_request, request, uint32_t, pid, void *, addr, void *, data) +SYSCALL_DEFINE4(ptrace, enum __ptrace_request, request, int, pid, void *, addr, void *, data) { pcb_t *pcb; diff --git a/so3/kernel/syscalls.c b/so3/kernel/syscalls.c index 68e15083f..d87c60098 100644 --- a/so3/kernel/syscalls.c +++ b/so3/kernel/syscalls.c @@ -35,9 +35,10 @@ extern uint32_t __get_syscall_stack_arg(uint32_t nr); extern void test_malloc(int test_no); +#warning Not updated, a rework is needed to avoid having a big array because of #ifdef ... static const syscall_fn_t syscall_table[NR_SYSCALLS] = { [0 ... NR_SYSCALLS - 1] = NULL, - + /* #ifdef CONFIG_MMU [SYSCALL_GETPID] = __sys_getpid, [SYSCALL_GETTIMEOFDAY] = __sys_gettimeofday, @@ -93,37 +94,9 @@ static const syscall_fn_t syscall_table[NR_SYSCALLS] = { [SYSCALL_RECVFROM] = __sys_recvfrom, #endif [SYSCALL_SYSINFO] = __sys_sysinfo, +*/ }; -SYSCALL_DEFINE2(sysinfo, unsigned long, info_number, char *, text) -{ - switch (info_number) { - case SYSINFO_DUMP_HEAP: - dump_heap("Heap info asked from user.\n"); - break; - - case SYSINFO_DUMP_SCHED: - dump_sched(); - break; - -#ifdef CONFIG_MMU - case SYSINFO_DUMP_PROC: - dump_proc(); - break; -#endif - -#ifdef CONFIG_APP_TEST_MALLOC - case SYSINFO_TEST_MALLOC: - test_malloc(a->args[1]); - break; -#endif - case SYSINFO_PRINTK: - printk("%s", (char *) text); - break; - } - return 0; -} - /* * Process syscalls according to the syscall number passed in r7 on ARM and x8 on ARM64. * According to SO3 ABI, the syscall arguments are passed in r0-r5 on ARM and x0-x5 on ARM64. diff --git a/so3/kernel/thread.c b/so3/kernel/thread.c index 363ec1520..51062add5 100644 --- a/so3/kernel/thread.c +++ b/so3/kernel/thread.c @@ -255,9 +255,9 @@ void thread_exit(int *exit_status) * According to the thread which is calling thread_exit(), the behaviour may differ. * Typically, if it is the main thread of the process, we have to wait until all * running threads (belonging to the process) are completed, and we pursue with - * do_exit(). + * sys_do_exit(). * - * - If pcb->state == PROC_STATE_ZOMBIE, it means we are called from do_exit() + * - If pcb->state == PROC_STATE_ZOMBIE, it means we are called from sys_do_exit() */ pcb = current()->pcb; diff --git a/so3/kernel/timer.c b/so3/kernel/timer.c index 3c2173ca4..075b39c70 100644 --- a/so3/kernel/timer.c +++ b/so3/kernel/timer.c @@ -405,10 +405,28 @@ void timer_init(void) #endif } +SYSCALL_DEFINE2(gettimeofday_time32, struct timeval32 *, ts, void *, tz) +{ + struct timeval time64; + + long ret = sys_do_gettimeofday(&time64, NULL); + + if (ret < 0) { + return ret; + } + + ts->tv_sec = (time32_t) time64.tv_sec; + ts->tv_usec = (time32_t) time64.tv_usec; + + return 0; +} + /* * This function gets the current time and put it in the parameter tv + * + * Timezone (tz) is ignored */ -SYSCALL_DEFINE1(gettimeofday, struct timespec *, ts) +SYSCALL_DEFINE2(gettimeofday, struct timeval *, ts, void *, tz) { u64 time; @@ -419,7 +437,23 @@ SYSCALL_DEFINE1(gettimeofday, struct timespec *, ts) time = NOW(); ts->tv_sec = time / (time_t) 1000000000; - ts->tv_nsec = time; + ts->tv_usec = time / (time_t) 1000; + + return 0; +} + +SYSCALL_DEFINE2(clock_gettime32, int, clk_id, struct timespec32 *, ts) +{ + struct timespec time64; + + long ret = sys_do_clock_gettime(clk_id, &time64); + + if (ret < 0) { + return ret; + } + + ts->tv_sec = (time32_t) time64.tv_sec; + ts->tv_nsec = (time32_t) time64.tv_nsec; return 0; } diff --git a/so3/net/net.c b/so3/net/net.c index d638f0797..21effb26c 100644 --- a/so3/net/net.c +++ b/so3/net/net.c @@ -134,29 +134,21 @@ struct ifreq2 { } ifr_ifru; }; -/* network address struct used by the userspace */ -struct sockaddr_in_usr { - u16 sin_family; - in_port_t sin_port; - struct in_addr sin_addr; - uint8_t sin_zero[8]; -}; - /** * Adapt a userspace sockaddr to a lwip one. * Iwip sockaddr have a sa_len field as first byte * @param usr * @param lwip */ -struct sockaddr *user_to_lwip_sockadd(struct sockaddr_in_usr *usr, struct sockaddr_in *lwip) +struct sockaddr *user_to_lwip_sockadd(const struct usr_sockaddr_in *usr, struct sockaddr_in *lwip) { if (usr == NULL) { return NULL; } - memset(lwip, 0, sizeof(struct sockaddr)); + memset(lwip, 0, sizeof(struct sockaddr_in)); - lwip->sin_len = sizeof(struct sockaddr); + lwip->sin_len = sizeof(struct sockaddr_in); lwip->sin_family = usr->sin_family; lwip->sin_port = usr->sin_port; lwip->sin_addr = usr->sin_addr; @@ -424,7 +416,7 @@ SYSCALL_DEFINE3(socket, int, domain, int, type, int, protocol) return fd; } -SYSCALL_DEFINE3(connect, int, sockfd, const struct sockaddr *, addr, socklen_t, namelen) +SYSCALL_DEFINE3(connect, int, sockfd, const struct usr_sockaddr_in *, addr, socklen_t, namelen) { int ret; struct sockaddr_in addr_lwip; @@ -436,13 +428,13 @@ SYSCALL_DEFINE3(connect, int, sockfd, const struct sockaddr *, addr, socklen_t, return -EBADF; } - addr_ptr = user_to_lwip_sockadd((struct sockaddr_in_usr *) addr, &addr_lwip); + addr_ptr = user_to_lwip_sockadd(addr, &addr_lwip); ret = lwip_connect(lwip_fd, addr_ptr, namelen); return lwip_return(ret); } -SYSCALL_DEFINE3(bind, int, sockfd, const struct sockaddr *, addr, socklen_t, addrlen) +SYSCALL_DEFINE3(bind, int, sockfd, const struct usr_sockaddr_in *, addr, socklen_t, addrlen) { int ret; struct sockaddr_in addr_lwip; @@ -454,7 +446,7 @@ SYSCALL_DEFINE3(bind, int, sockfd, const struct sockaddr *, addr, socklen_t, add return -EBADF; } - addr_ptr = user_to_lwip_sockadd((struct sockaddr_in_usr *) addr, &addr_lwip); + addr_ptr = user_to_lwip_sockadd(addr, &addr_lwip); ret = lwip_bind(lwip_fd, addr_ptr, addrlen); return lwip_return(ret); @@ -473,7 +465,7 @@ SYSCALL_DEFINE2(listen, int, sockfd, int, backlog) return lwip_return(ret); } -SYSCALL_DEFINE3(accept, int, sockfd, struct sockaddr *, addr, socklen_t *, addrlen) +SYSCALL_DEFINE3(accept, int, sockfd, struct usr_sockaddr_in *, addr, socklen_t *, addrlen) { int fd, gfd, lwip_fd, lwip_bind_fd; struct file_operations *fops; @@ -485,7 +477,7 @@ SYSCALL_DEFINE3(accept, int, sockfd, struct sockaddr *, addr, socklen_t *, addrl return -EBADF; } - addr_ptr = user_to_lwip_sockadd((struct sockaddr_in_usr *) addr, &addr_lwip); + addr_ptr = user_to_lwip_sockadd(addr, &addr_lwip); fops = register_sock(); @@ -532,16 +524,21 @@ SYSCALL_DEFINE4(recv, int, sockfd, void *, mem, size_t, len, int, flags) return lwip_return(ret); } -SYSCALL_DEFINE6(recvfrom, int, sockfd, void *, mem, size_t, len, int, flags, struct sockaddr *, from, socklen_t *, fromlen) +SYSCALL_DEFINE6(recvfrom, int, sockfd, void *, mem, size_t, len, int, flags, struct usr_sockaddr_in *, from, socklen_t *, + fromlen) { int ret; + struct sockaddr_in from_lwip; + struct sockaddr *from_ptr; int lwip_fd = get_lwip_fd(sockfd); if (lwip_fd < 0) { return -EBADF; } - ret = lwip_recvfrom(lwip_fd, mem, len, flags, from, fromlen); + from_ptr = user_to_lwip_sockadd(from, &from_lwip); + + ret = lwip_recvfrom(lwip_fd, mem, len, flags, from_ptr, fromlen); return lwip_return(ret); } @@ -558,20 +555,21 @@ SYSCALL_DEFINE4(send, int, sockfd, const void *, dataptr, size_t, size, int, fla return lwip_return(ret); } -SYSCALL_DEFINE6(sendto, int, sockfd, const void *, dataptr, size_t, size, int, flags, const struct sockaddr *, to, socklen_t, - tolen) +SYSCALL_DEFINE6(sendto, int, sockfd, const void *, dataptr, size_t, size, int, flags, const struct usr_sockaddr_in *, to, + socklen_t, tolen) { int ret; struct sockaddr_in to_lwip; + struct sockaddr *to_ptr; int lwip_fd = get_lwip_fd(sockfd); if (lwip_fd < 0) { return -EBADF; } - user_to_lwip_sockadd((struct sockaddr_in_usr *) to, &to_lwip); + to_ptr = user_to_lwip_sockadd(to, &to_lwip); - ret = lwip_sendto(lwip_fd, dataptr, size, flags, (struct sockaddr *) &to_lwip, tolen); + ret = lwip_sendto(lwip_fd, dataptr, size, flags, to_ptr, tolen); return lwip_return(ret); }