From e53b1b798ac5c0ea2f8196197de9622b592bf2ed Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Sun, 19 Apr 2026 15:12:28 -0300 Subject: [PATCH] Complete syscall coverage in ulibc and newlib wrappers Audit of all 141 kernel syscalls vs ulibc/newlib wrappers revealed many missing implementations. Both libraries had syscall numbers defined but no corresponding POSIX wrapper functions. ulibc additions (unistd.c): - select, fcntl, rename (was stub returning -1), umask - dup3, openat, fstatat, unlinkat - mount, umount2, umount - wait4, waitid, sigreturn, sigqueue, set_thread_area ulibc header updates: - unistd.h: declarations for all new functions - signal.h: union sigval, sigqueue, sigreturn declarations - sys/mount.h: new header with mount/umount2/umount + flags - Removed old rename() stub from stdio.c newlib additions (posix_stubs.c): - Complete syscall number table (was 32 entries, now all 141) - All missing POSIX wrappers: fcntl, rename, rmdir, mkdir, unlink, dup3, openat, fstatat, unlinkat, mount, umount2, umount, wait4, waitid, sigreturn, sigqueue, set_thread_area, pread, pwrite, truncate, ftruncate, fsync, fdatasync, sigpending, sigsuspend, readv, writev, times, flock, setitimer, getitimer, link, symlink, readlink, pipe2, clock_gettime, gettimeofday, mmap, munmap, mprotect, madvise, getrlimit, setrlimit, getrusage, uname, brk, sbrk - Added includes: sys/mman.h, sys/resource.h, sys/utsname.h, sys/uio.h, sys/times.h, sys/wait.h Fix: setitimer/getitimer signatures corrected from void* to struct itimerval* to match sys/time.h declarations. Tests: 103/103 PASS, 16/16 battery PASS, 69/69 host PASS. --- newlib/libgloss/adros/posix_stubs.c | 321 ++++++++++++++++++++++++++++ user/ulibc/include/signal.h | 7 + user/ulibc/include/sys/mount.h | 34 +++ user/ulibc/include/unistd.h | 14 ++ user/ulibc/src/stdio.c | 5 - user/ulibc/src/unistd.c | 77 ++++++- 6 files changed, 451 insertions(+), 7 deletions(-) create mode 100644 user/ulibc/include/sys/mount.h diff --git a/newlib/libgloss/adros/posix_stubs.c b/newlib/libgloss/adros/posix_stubs.c index c796b0b6..b9c052cf 100644 --- a/newlib/libgloss/adros/posix_stubs.c +++ b/newlib/libgloss/adros/posix_stubs.c @@ -23,6 +23,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -39,12 +45,23 @@ #include /* ---- AdrOS syscall numbers (must match include/syscall.h) ---- */ +#define SYS_EXIT 2 +#define SYS_GETPID 3 +#define SYS_OPEN 4 +#define SYS_READ 5 +#define SYS_CLOSE 6 #define SYS_WAITPID 7 +#define SYS_LSEEK 9 +#define SYS_FSTAT 10 +#define SYS_STAT 11 #define SYS_DUP 12 #define SYS_DUP2 13 #define SYS_PIPE 14 +#define SYS_EXECVE 15 +#define SYS_FORK 16 #define SYS_GETPPID 17 #define SYS_POLL 18 +#define SYS_KILL 19 #define SYS_SELECT 20 #define SYS_IOCTL 21 #define SYS_SETSID 22 @@ -52,24 +69,121 @@ #define SYS_GETPGRP 24 #define SYS_SIGACTION 25 #define SYS_SIGPROCMASK 26 +#define SYS_SIGRETURN 27 +#define SYS_MKDIR 28 +#define SYS_UNLINK 29 #define SYS_GETDENTS 30 #define SYS_FCNTL 31 #define SYS_CHDIR 32 #define SYS_GETCWD 33 +#define SYS_PIPE2 34 +#define SYS_DUP3 35 +#define SYS_OPENAT 36 +#define SYS_FSTATAT 37 +#define SYS_UNLINKAT 38 +#define SYS_RENAME 39 +#define SYS_RMDIR 40 +#define SYS_BRK 41 #define SYS_NANOSLEEP 42 +#define SYS_CLOCK_GETTIME 43 +#define SYS_MMAP 44 +#define SYS_MUNMAP 45 +#define SYS_SHMGET 46 +#define SYS_SHMAT 47 +#define SYS_SHMDT 48 +#define SYS_SHMCTL 49 #define SYS_CHMOD 50 #define SYS_CHOWN 51 #define SYS_GETUID 52 #define SYS_GETGID 53 +#define SYS_LINK 54 +#define SYS_SYMLINK 55 +#define SYS_READLINK 56 +#define SYS_SET_THREAD_AREA 57 +#define SYS_SOCKET 58 +#define SYS_BIND 59 +#define SYS_LISTEN 60 +#define SYS_ACCEPT 61 +#define SYS_CONNECT 62 +#define SYS_SEND 63 +#define SYS_RECV 64 +#define SYS_SENDTO 65 +#define SYS_RECVFROM 66 +#define SYS_CLONE 67 +#define SYS_GETTID 68 +#define SYS_FSYNC 69 +#define SYS_FDATASYNC 70 +#define SYS_SIGPENDING 71 +#define SYS_PREAD 72 +#define SYS_PWRITE 73 #define SYS_ACCESS 74 #define SYS_UMASK 75 #define SYS_SETUID 76 #define SYS_SETGID 77 +#define SYS_TRUNCATE 78 +#define SYS_FTRUNCATE 79 +#define SYS_SIGSUSPEND 80 +#define SYS_READV 81 +#define SYS_WRITEV 82 #define SYS_ALARM 83 +#define SYS_TIMES 84 +#define SYS_FUTEX 85 +#define SYS_SIGALTSTACK 86 +#define SYS_FLOCK 87 #define SYS_GETEUID 88 #define SYS_GETEGID 89 #define SYS_SETEUID 90 #define SYS_SETEGID 91 +#define SYS_SETITIMER 92 +#define SYS_GETITIMER 93 +#define SYS_WAITID 94 +#define SYS_SIGQUEUE 95 +#define SYS_POSIX_SPAWN 96 +#define SYS_MQ_OPEN 97 +#define SYS_MQ_CLOSE 98 +#define SYS_MQ_SEND 99 +#define SYS_MQ_RECEIVE 100 +#define SYS_MQ_UNLINK 101 +#define SYS_SEM_OPEN 102 +#define SYS_SEM_CLOSE 103 +#define SYS_SEM_WAIT 104 +#define SYS_SEM_POST 105 +#define SYS_SEM_UNLINK 106 +#define SYS_SEM_GETVALUE 107 +#define SYS_GETADDRINFO 108 +#define SYS_DLOPEN 109 +#define SYS_DLSYM 110 +#define SYS_DLCLOSE 111 +#define SYS_EPOLL_CREATE 112 +#define SYS_EPOLL_CTL 113 +#define SYS_EPOLL_WAIT 114 +#define SYS_INOTIFY_INIT 115 +#define SYS_INOTIFY_ADD_WATCH 116 +#define SYS_INOTIFY_RM_WATCH 117 +#define SYS_SENDMSG 118 +#define SYS_RECVMSG 119 +#define SYS_PIVOT_ROOT 120 +#define SYS_AIO_READ 121 +#define SYS_AIO_WRITE 122 +#define SYS_AIO_ERROR 123 +#define SYS_AIO_RETURN 124 +#define SYS_AIO_SUSPEND 125 +#define SYS_MOUNT 126 +#define SYS_GETTIMEOFDAY 127 +#define SYS_MPROTECT 128 +#define SYS_GETRLIMIT 129 +#define SYS_SETRLIMIT 130 +#define SYS_SETSOCKOPT 131 +#define SYS_GETSOCKOPT 132 +#define SYS_SHUTDOWN 133 +#define SYS_GETPEERNAME 134 +#define SYS_GETSOCKNAME 135 +#define SYS_UNAME 136 +#define SYS_GETRUSAGE 137 +#define SYS_UMOUNT2 138 +#define SYS_WAIT4 139 +#define SYS_MADVISE 140 +#define SYS_EXECVEAT 141 /* ---- Raw syscall helpers ---- */ @@ -419,6 +533,213 @@ int gethostname(char *name, size_t len) { errno = ENAMETOOLONG; return -1; } +/* ================================================================ + * Additional POSIX wrappers (previously missing) + * ================================================================ */ + +int fcntl(int fd, int cmd, ...) { + va_list ap; + va_start(ap, cmd); + int arg = va_arg(ap, int); + va_end(ap); + return _check(_sc3(SYS_FCNTL, fd, cmd, arg)); +} + +int rename(const char *oldpath, const char *newpath) { + return _check(_sc2(SYS_RENAME, (int)oldpath, (int)newpath)); +} + +int rmdir(const char *path) { + return _check(_sc1(SYS_RMDIR, (int)path)); +} + +int mkdir(const char *path, mode_t mode) { + (void)mode; + return _check(_sc1(SYS_MKDIR, (int)path)); +} + +int unlink(const char *path) { + return _check(_sc1(SYS_UNLINK, (int)path)); +} + +int dup3(int oldfd, int newfd, int flags) { + return _check(_sc3(SYS_DUP3, oldfd, newfd, flags)); +} + +int openat(int dirfd, const char *path, int flags, ...) { + return _check(_sc3(SYS_OPENAT, dirfd, (int)path, flags)); +} + +int fstatat(int dirfd, const char *path, struct stat *buf, int flags) { + return _check(_sc4(SYS_FSTATAT, dirfd, (int)path, (int)buf, flags)); +} + +int unlinkat(int dirfd, const char *path, int flags) { + return _check(_sc3(SYS_UNLINKAT, dirfd, (int)path, flags)); +} + +int mount(const char *source, const char *target, const char *fs_type, + unsigned long flags, const void *data) { + return _check(_sc5(SYS_MOUNT, (int)source, (int)target, (int)fs_type, (int)flags, (int)data)); +} + +int umount2(const char *target, int flags) { + return _check(_sc2(SYS_UMOUNT2, (int)target, flags)); +} + +int umount(const char *target) { + return umount2(target, 0); +} + +pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) { + return (pid_t)_check(_sc4(SYS_WAIT4, (int)pid, (int)status, options, (int)rusage)); +} + +int waitid(int idtype, int id, void *info, int options) { + return _check(_sc4(SYS_WAITID, idtype, id, (int)info, options)); +} + +int sigreturn(void) { + return _sc0(SYS_SIGRETURN); +} + +int sigqueue(pid_t pid, int sig, const union sigval value) { + return _check(_sc3(SYS_SIGQUEUE, (int)pid, sig, (int)value.sival_int)); +} + +int set_thread_area(void *desc) { + return _check(_sc1(SYS_SET_THREAD_AREA, (int)desc)); +} + +ssize_t pread(int fd, void *buf, size_t count, off_t offset) { + return (ssize_t)_check(_sc4(SYS_PREAD, fd, (int)buf, (int)count, (int)offset)); +} + +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) { + return (ssize_t)_check(_sc4(SYS_PWRITE, fd, (int)buf, (int)count, (int)offset)); +} + +int truncate(const char *path, off_t length) { + return _check(_sc2(SYS_TRUNCATE, (int)path, (int)length)); +} + +int ftruncate(int fd, off_t length) { + return _check(_sc2(SYS_FTRUNCATE, fd, (int)length)); +} + +int fsync(int fd) { + return _check(_sc1(SYS_FSYNC, fd)); +} + +int fdatasync(int fd) { + return _check(_sc1(SYS_FDATASYNC, fd)); +} + +int sigpending(sigset_t *set) { + return _check(_sc1(SYS_SIGPENDING, (int)set)); +} + +int sigsuspend(const sigset_t *mask) { + return _check(_sc1(SYS_SIGSUSPEND, (int)mask)); +} + +ssize_t readv(int fd, const struct iovec *iov, int iovcnt) { + return (ssize_t)_check(_sc3(SYS_READV, fd, (int)iov, iovcnt)); +} + +ssize_t writev(int fd, const struct iovec *iov, int iovcnt) { + return (ssize_t)_check(_sc3(SYS_WRITEV, fd, (int)iov, iovcnt)); +} + +clock_t times(struct tms *buf) { + return (clock_t)_sc1(SYS_TIMES, (int)buf); +} + +int flock(int fd, int operation) { + return _check(_sc2(SYS_FLOCK, fd, operation)); +} + +int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) { + return _check(_sc3(SYS_SETITIMER, which, (int)new_value, (int)old_value)); +} + +int getitimer(int which, struct itimerval *curr_value) { + return _check(_sc2(SYS_GETITIMER, which, (int)curr_value)); +} + +int link(const char *oldpath, const char *newpath) { + return _check(_sc2(SYS_LINK, (int)oldpath, (int)newpath)); +} + +int symlink(const char *target, const char *linkpath) { + return _check(_sc2(SYS_SYMLINK, (int)target, (int)linkpath)); +} + +ssize_t readlink(const char *path, char *buf, size_t bufsiz) { + return (ssize_t)_check(_sc3(SYS_READLINK, (int)path, (int)buf, (int)bufsiz)); +} + +int pipe2(int fds[2], int flags) { + return _check(_sc2(SYS_PIPE2, (int)fds, flags)); +} + +int clock_gettime(clockid_t clk_id, struct timespec *tp) { + return _check(_sc2(SYS_CLOCK_GETTIME, (int)clk_id, (int)tp)); +} + +int gettimeofday(struct timeval *tv, void *tz) { + (void)tz; + return _check(_sc2(SYS_GETTIMEOFDAY, (int)tv, 0)); +} + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { + int ret = _sc5(SYS_MMAP, (int)addr, (int)length, prot, flags, fd); + (void)offset; + if (ret < 0 && ret > -4096) { errno = -ret; return MAP_FAILED; } + return (void *)ret; +} + +int munmap(void *addr, size_t length) { + return _check(_sc2(SYS_MUNMAP, (int)addr, (int)length)); +} + +int mprotect(void *addr, size_t len, int prot) { + return _check(_sc3(SYS_MPROTECT, (int)addr, (int)len, prot)); +} + +int madvise(void *addr, size_t length, int advice) { + return _check(_sc3(SYS_MADVISE, (int)addr, (int)length, advice)); +} + +int getrlimit(int resource, struct rlimit *rlim) { + return _check(_sc2(SYS_GETRLIMIT, resource, (int)rlim)); +} + +int setrlimit(int resource, const struct rlimit *rlim) { + return _check(_sc2(SYS_SETRLIMIT, resource, (int)rlim)); +} + +int getrusage(int who, struct rusage *usage) { + return _check(_sc2(SYS_GETRUSAGE, who, (int)usage)); +} + +int uname(struct utsname *buf) { + return _check(_sc1(SYS_UNAME, (int)buf)); +} + +void *brk(void *addr) { + return (void *)_sc1(SYS_BRK, (int)addr); +} + +void *sbrk(intptr_t increment) { + void *cur = brk(0); + if (increment == 0) return cur; + void *new_end = (void *)((char *)cur + increment); + void *result = brk(new_end); + if ((uintptr_t)result < (uintptr_t)new_end) return (void *)-1; + return cur; +} + int mkfifo(const char *path, mode_t mode) { (void)path; (void)mode; errno = ENOSYS; diff --git a/user/ulibc/include/signal.h b/user/ulibc/include/signal.h index f0cd36f0..e8e14300 100644 --- a/user/ulibc/include/signal.h +++ b/user/ulibc/include/signal.h @@ -66,6 +66,11 @@ struct siginfo { typedef struct siginfo siginfo_t; +union sigval { + int sival_int; + void* sival_ptr; +}; + int kill(int pid, int sig); int raise(int sig); int sigaction(int signum, const struct sigaction* act, @@ -106,5 +111,7 @@ typedef struct { } stack_t; int sigaltstack(const stack_t* ss, stack_t* old_ss); +int sigqueue(int pid, int sig, const union sigval value); +int sigreturn(void); #endif diff --git a/user/ulibc/include/sys/mount.h b/user/ulibc/include/sys/mount.h new file mode 100644 index 00000000..aa7561f2 --- /dev/null +++ b/user/ulibc/include/sys/mount.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#ifndef ULIBC_SYS_MOUNT_H +#define ULIBC_SYS_MOUNT_H + +#include + +/* Mount flags */ +#define MS_RDONLY 1 +#define MS_NOSUID 2 +#define MS_NODEV 4 +#define MS_NOEXEC 8 +#define MS_SYNCHRONOUS 16 +#define MS_REMOUNT 32 +#define MS_NOATIME 1024 + +/* Umount flags */ +#define MNT_FORCE 1 +#define MNT_DETACH 2 +#define MNT_EXPIRE 4 + +int mount(const char* source, const char* target, const char* fs_type, + unsigned long flags, const void* data); +int umount2(const char* target, int flags); +int umount(const char* target); + +#endif diff --git a/user/ulibc/include/unistd.h b/user/ulibc/include/unistd.h index 3ca39ff1..066800eb 100644 --- a/user/ulibc/include/unistd.h +++ b/user/ulibc/include/unistd.h @@ -12,6 +12,7 @@ #include #include +#include #define SEEK_SET 0 #define SEEK_CUR 1 @@ -63,6 +64,7 @@ unsigned int alarm(unsigned int seconds); #define LOCK_UN 8 #define LOCK_NB 4 int flock(int fd, int operation); +int umask(int mask); int isatty(int fd); void* brk(void* addr); @@ -112,6 +114,18 @@ char* ttyname(int fd); int pipe2(int fds[2], int flags); int execle(const char* path, const char* arg, ...); int execveat(int dirfd, const char* path, char* const argv[], char* const envp[], int flags); +int dup3(int oldfd, int newfd, int flags); +int openat(int dirfd, const char* path, int flags, ...); +int fstatat(int dirfd, const char* path, void* buf, int flags); +int unlinkat(int dirfd, const char* path, int flags); +int mount(const char* source, const char* target, const char* fs_type, unsigned long flags, const void* data); +int umount2(const char* target, int flags); +int umount(const char* target); +int wait4(int pid, int* status, int options, void* rusage); +int waitid(int idtype, int id, void* info, int options); +int sigreturn(void); +int sigqueue(int pid, int sig, const union sigval value); +int set_thread_area(void* desc); char* getlogin(void); int getlogin_r(char* buf, size_t bufsize); int tcgetpgrp(int fd); diff --git a/user/ulibc/src/stdio.c b/user/ulibc/src/stdio.c index 257ed12a..ce6092a2 100644 --- a/user/ulibc/src/stdio.c +++ b/user/ulibc/src/stdio.c @@ -196,11 +196,6 @@ int remove(const char* path) { return unlink(path); } -int rename(const char* oldpath, const char* newpath) { - (void)oldpath; (void)newpath; - return -1; -} - int setvbuf(FILE* fp, char* buf, int mode, size_t size) { (void)buf; (void)size; /* we use internal buffer only */ if (!fp) return -1; diff --git a/user/ulibc/src/unistd.c b/user/ulibc/src/unistd.c index 6dcadb35..f0b79279 100644 --- a/user/ulibc/src/unistd.c +++ b/user/ulibc/src/unistd.c @@ -12,6 +12,9 @@ #include "errno.h" #include "termios.h" #include "stdlib.h" +#include "sys/select.h" +#include "sys/time.h" +#include "signal.h" int read(int fd, void* buf, size_t count) { return __syscall_ret(_syscall3(SYS_READ, fd, (int)buf, (int)count)); @@ -179,11 +182,11 @@ unsigned int alarm(unsigned int seconds) { return (unsigned int)_syscall1(SYS_ALARM, (int)seconds); } -int setitimer(int which, const void* new_value, void* old_value) { +int setitimer(int which, const struct itimerval* new_value, struct itimerval* old_value) { return __syscall_ret(_syscall3(SYS_SETITIMER, which, (int)new_value, (int)old_value)); } -int getitimer(int which, void* curr_value) { +int getitimer(int which, struct itimerval* curr_value) { return __syscall_ret(_syscall2(SYS_GETITIMER, which, (int)curr_value)); } @@ -312,3 +315,73 @@ void* sbrk(int increment) { if ((unsigned int)result < (unsigned int)new_end) return (void*)-1; return cur; } + +int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, + struct timeval* timeout) { + return __syscall_ret(_syscall5(SYS_SELECT, nfds, (int)readfds, (int)writefds, + (int)exceptfds, (int)timeout)); +} + +int fcntl(int fd, int cmd, ...) { + __builtin_va_list ap; + __builtin_va_start(ap, cmd); + int arg = __builtin_va_arg(ap, int); + __builtin_va_end(ap); + return __syscall_ret(_syscall3(SYS_FCNTL, fd, cmd, arg)); +} + +int rename(const char* oldpath, const char* newpath) { + return __syscall_ret(_syscall2(SYS_RENAME, (int)oldpath, (int)newpath)); +} + +int umask(int mask) { + return _syscall1(SYS_UMASK, mask); +} + +int dup3(int oldfd, int newfd, int flags) { + return __syscall_ret(_syscall3(SYS_DUP3, oldfd, newfd, flags)); +} + +int openat(int dirfd, const char* path, int flags, ...) { + return __syscall_ret(_syscall3(SYS_OPENAT, dirfd, (int)path, flags)); +} + +int fstatat(int dirfd, const char* path, void* buf, int flags) { + return __syscall_ret(_syscall4(SYS_FSTATAT, dirfd, (int)path, (int)buf, flags)); +} + +int unlinkat(int dirfd, const char* path, int flags) { + return __syscall_ret(_syscall3(SYS_UNLINKAT, dirfd, (int)path, flags)); +} + +int mount(const char* source, const char* target, const char* fs_type, unsigned long flags, const void* data) { + return __syscall_ret(_syscall5(SYS_MOUNT, (int)source, (int)target, (int)fs_type, (int)flags, (int)data)); +} + +int umount2(const char* target, int flags) { + return __syscall_ret(_syscall2(SYS_UMOUNT2, (int)target, flags)); +} + +int umount(const char* target) { + return umount2(target, 0); +} + +int wait4(int pid, int* status, int options, void* rusage) { + return __syscall_ret(_syscall4(SYS_WAIT4, pid, (int)status, options, (int)rusage)); +} + +int waitid(int idtype, int id, void* info, int options) { + return __syscall_ret(_syscall4(SYS_WAITID, idtype, id, (int)info, options)); +} + +int sigreturn(void) { + return _syscall0(SYS_SIGRETURN); +} + +int sigqueue(int pid, int sig, const union sigval value) { + return __syscall_ret(_syscall3(SYS_SIGQUEUE, pid, sig, (int)value.sival_int)); +} + +int set_thread_area(void* desc) { + return __syscall_ret(_syscall1(SYS_SET_THREAD_AREA, (int)desc)); +} -- 2.43.0