diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:00 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:32 -0500 |
commit | bd5969fc876a10b18613302db7087ef3c40f18e1 (patch) | |
tree | 7c2b8619afe902abf99570df2873fbdf40a4d1a1 /lib/mlibc/sysdeps/aero | |
parent | a95b38b1b92b172e6cc4e8e56a88a30cc65907b0 (diff) |
lib: Add mlibc
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/sysdeps/aero')
56 files changed, 1650 insertions, 0 deletions
diff --git a/lib/mlibc/sysdeps/aero/crt-x86_64/crt0.S b/lib/mlibc/sysdeps/aero/crt-x86_64/crt0.S new file mode 100644 index 0000000..62298e3 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/crt-x86_64/crt0.S @@ -0,0 +1,10 @@ +.section .text + +.global _start +_start: + mov $main, %rdi + call __mlibc_entry + +.size _start, . - _start +.section .note.GNU-stack,"",%progbits + diff --git a/lib/mlibc/sysdeps/aero/generic/aero.cpp b/lib/mlibc/sysdeps/aero/generic/aero.cpp new file mode 100644 index 0000000..e6bd277 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/aero.cpp @@ -0,0 +1,360 @@ +#include <abi-bits/pid_t.h> +#include <aero/syscall.h> +#include <bits/ensure.h> +#include <errno.h> +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/debug.hpp> +#include <mlibc/thread-entry.hpp> +#include <stddef.h> + +#include <frg/vector.hpp> +#include <mlibc/allocator.hpp> + +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 + +struct Slice { + void *ptr; + uint64_t len; +}; + +/// Helper function to construct a slice vector from the provided argument +/// array. A slice basically consists of a pointer to the data and the length of +/// it. +/// +/// ## Examples +/// ```cc +/// auto slice = create_slice({ "hello", "world" }); +/// ``` +/// +/// The `slice` will look like the following: +/// +/// ```cc +/// vector<Slice>( +/// Slice { .ptr: hello_ptr, .size: hello_size }, +/// Slice { .ptr: world_ptr, .size: world_size } +/// ) +/// ``` +static frg::vector<Slice, MemoryAllocator> create_slice(char *const arg[]) { + if (arg == nullptr) { + return frg::vector<Slice, MemoryAllocator>{getAllocator()}; + } + + // Find out the length of arg: + size_t len = 0; + + while (arg[len] != nullptr) { + len += 1; + } + + frg::vector<Slice, MemoryAllocator> params{getAllocator()}; + params.resize(len); + + // Construct the slice vector: + for (size_t i = 0; i < len; ++i) { + params[i].ptr = (void *)arg[i]; + params[i].len = strlen(arg[i]); + } + + return params; +} + +namespace mlibc { +int sys_uname(struct utsname *buf) { + auto result = syscall(SYS_UNAME, buf); + + if (result < 0) { + return -result; + } + + return result; +} + +int sys_futex_wait(int *pointer, int expected, const struct timespec *time) { + // auto result = syscall(SYS_FUTEX_WAIT, pointer, expected, time); + // + // if (result < 0) { + // return -result; + // } + // + return 0; +} + +int sys_futex_wake(int *pointer) { + // auto result = syscall(SYS_FUTEX_WAKE, pointer); + // + // if (result < 0) { + // return -result; + // } + // + return 0; +} + +int sys_tcb_set(void *pointer) { + auto result = syscall(SYS_ARCH_PRCTL, ARCH_SET_FS, (uint64_t)pointer); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, + off_t offset, void **window) { + auto result = syscall(SYS_MMAP, hint, size, prot, flags, fd, offset); + + if (result < 0) { + return -result; + } + + *window = (void *)result; + return 0; +} + +int sys_vm_unmap(void *address, size_t size) { + return syscall(SYS_MUNMAP, address, size); +} + +int sys_vm_protect(void *pointer, size_t size, int prot) { + auto res = syscall(SYS_MPROTECT, pointer, size, prot); + if (res < 0) + return -res; + + return 0; +} + +int sys_anon_allocate(size_t size, void **pointer) { + return sys_vm_map(nullptr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0, pointer); +} + +int sys_anon_free(void *pointer, size_t size) { + return sys_vm_unmap(pointer, size); +} + +void sys_libc_panic() { + mlibc::infoLogger() << "libc_panic: panicked at 'unknown'" << frg::endlog; + __ensure(!syscall(SYS_BACKTRACE)); + + sys_exit(1); +} + +void sys_libc_log(const char *msg) { syscall(SYS_LOG, msg, strlen(msg)); } + +void sys_exit(int status) { + syscall(SYS_EXIT, status); + + __builtin_unreachable(); +} + +#ifndef MLIBC_BUILDING_RTDL + +pid_t sys_getpid() { + auto result = syscall(SYS_GETPID); + __ensure(result >= 0); + + return result; +} + +pid_t sys_getppid() { + auto result = syscall(SYS_GETPPID); + __ensure(result != 0); + + return result; +} + +int sys_kill(int pid, int sig) { + auto result = syscall(SYS_KILL, pid, sig); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_clock_get(int clock, time_t *secs, long *nanos) { + struct timespec ts; + auto result = syscall(SYS_GETTIME, clock, &ts); + + if (result < 0) { + return -result; + } + + *secs = ts.tv_sec; + *nanos = ts.tv_nsec; + + return 0; +} + +int sys_getcwd(char *buffer, size_t size) { + auto result = syscall(SYS_GETCWD, buffer, size); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_chdir(const char *path) { + auto result = syscall(SYS_CHDIR, path, strlen(path)); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_gethostname(char *buffer, size_t bufsize) { + auto result = syscall(SYS_GETHOSTNAME, buffer, bufsize); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_sleep(time_t *sec, long *nanosec) { + struct timespec ts = {.tv_sec = *sec, .tv_nsec = *nanosec}; + + auto result = syscall(SYS_SLEEP, &ts); + + if (result < 0) { + return -result; + } + + return 0; +} + +pid_t sys_getpgid(pid_t pid, pid_t *pgid) { + auto ret = syscall(SYS_GETPGID, pid); + if(int e = sc_error(ret); e) + return e; + *pgid = ret; + return 0; +} + +int sys_setpgid(pid_t pid, pid_t pgid) { + auto ret = syscall(SYS_SETPGID, pid, pgid); + if(int e = sc_error(ret); e) + return e; + return 0; +} + +uid_t sys_getuid() { + mlibc::infoLogger() << "mlibc: sys_setuid is a stub" << frg::endlog; + return 0; +} + +uid_t sys_geteuid() { + mlibc::infoLogger() << "mlibc: sys_seteuid is a stub" << frg::endlog; + return 0; +} + +int sys_setsid(pid_t *sid) { + auto ret = syscall(SYS_SETSID); + if(int e = sc_error(ret); e) + return e; + *sid = ret; + return 0; +} + +int sys_seteuid(uid_t euid) UNIMPLEMENTED("sys_seteuid") + + gid_t sys_getgid() { + mlibc::infoLogger() << "mlibc: sys_setgid is a stub" << frg::endlog; + return 0; +} + +gid_t sys_getegid() { + mlibc::infoLogger() << "mlibc: sys_getegid is a stub" << frg::endlog; + return 0; +} + +int sys_setgid(gid_t gid) { + mlibc::infoLogger() << "mlibc: sys_setgid is a stub" << frg::endlog; + return 0; +} + +int sys_setegid(gid_t egid) { + mlibc::infoLogger() << "mlibc: sys_setegid is a stub" << frg::endlog; + return 0; +} + +void sys_yield() { + mlibc::infoLogger() << "mlibc: sys_yield is a stub" << frg::endlog; + __ensure(!syscall(SYS_BACKTRACE)); +} + +int sys_clone(void *tcb, pid_t *tid_out, void *stack) { + auto result = syscall(SYS_CLONE, (uintptr_t)__mlibc_start_thread, stack); + + if (result < 0) { + return -result; + } + + *tid_out = (pid_t)result; + return 0; +} + +void sys_thread_exit() UNIMPLEMENTED("sys_thread_exit") + + int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, + pid_t *ret_pid) { + if (ru) { + mlibc::infoLogger() + << "mlibc: struct rusage in sys_waitpid is unsupported" + << frg::endlog; + return ENOSYS; + } + + auto result = syscall(SYS_WAITPID, pid, status, flags); + + if (result < 0) { + return -result; + } + + *ret_pid = result; + return 0; +} + +int sys_fork(pid_t *child) { + auto result = syscall(SYS_FORK); + + if (result < 0) { + return -result; + } + + *child = result; + return 0; +} + +int sys_execve(const char *path, char *const argv[], char *const envp[]) { + auto envv_slice = create_slice(envp); + auto argv_slice = create_slice(argv); + + auto path_ptr = (uintptr_t)path; + auto path_len = strlen(path); + + auto result = + syscall(SYS_EXEC, path_ptr, path_len, argv_slice.data(), + argv_slice.size(), envv_slice.data(), envv_slice.size()); + + if (result < 0) { + return -result; + } + + __builtin_unreachable(); +} + +// int sys_getentropy(void *buffer, size_t length) +// UNIMPLEMENTED("sys_getentropy") + +#endif +} // namespace mlibc diff --git a/lib/mlibc/sysdeps/aero/generic/entry.cpp b/lib/mlibc/sysdeps/aero/generic/entry.cpp new file mode 100644 index 0000000..77d6ed5 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/entry.cpp @@ -0,0 +1,36 @@ +#include <bits/ensure.h> +#include <mlibc/elf/startup.h> +#include <stdint.h> +#include <stdlib.h> + +// defined by the POSIX library +void __mlibc_initLocale(); + +extern "C" uintptr_t *__dlapi_entrystack(); + +extern char **environ; +static mlibc::exec_stack_data __mlibc_stack_data; + +struct LibraryGuard { + LibraryGuard(); +}; + +static LibraryGuard guard; + +LibraryGuard::LibraryGuard() { + __mlibc_initLocale(); + + // Parse the exec() stack. + mlibc::parse_exec_stack(__dlapi_entrystack(), &__mlibc_stack_data); + mlibc::set_startup_data(__mlibc_stack_data.argc, __mlibc_stack_data.argv, + __mlibc_stack_data.envp); +} + +extern "C" void __mlibc_entry(int (*main_fn)(int argc, char *argv[], + char *env[])) { + // TODO: call __dlapi_enter, otherwise static builds will break (see Linux + // sysdeps) + auto result = + main_fn(__mlibc_stack_data.argc, __mlibc_stack_data.argv, environ); + exit(result); +} diff --git a/lib/mlibc/sysdeps/aero/generic/filesystem.cpp b/lib/mlibc/sysdeps/aero/generic/filesystem.cpp new file mode 100644 index 0000000..049f4c0 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/filesystem.cpp @@ -0,0 +1,472 @@ +#include "mlibc/fsfd_target.hpp" +#include <aero/syscall.h> + +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> + +#include <unistd.h> + +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/debug.hpp> + +namespace mlibc { +int sys_write(int fd, const void *buffer, size_t count, ssize_t *written) { + auto result = syscall(SYS_WRITE, fd, buffer, count); + + if (result < 0) { + return -result; + } + + *written = result; + return 0; +} + +int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read) { + auto result = syscall(SYS_READ, fd, buf, count); + + if (result < 0) { + *bytes_read = 0; + return -result; + } + + *bytes_read = result; + return 0; +} + +// clang-format off +int sys_pwrite(int fd, const void *buffer, size_t count, off_t off, + ssize_t *written) UNIMPLEMENTED("sys_pwrite") + +// clang-format off +int sys_pread(int fd, void *buf, size_t count, + off_t off, ssize_t *bytes_read) UNIMPLEMENTED("sys_pread") + +int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) { + auto result = syscall(SYS_SEEK, fd, offset, whence); + + if (result < 0) { + return -result; + } + + *new_offset = result; + return 0; +} + +int sys_open(const char *filename, int flags, mode_t mode, int *fd) { + auto result = syscall(SYS_OPEN, 0, filename, strlen(filename), flags); + + if (result < 0) { + return -result; + } + + *fd = result; + return 0; +} + +int sys_close(int fd) { + auto result = syscall(SYS_CLOSE, fd); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_access(const char *filename, int mode) { + auto result = + syscall(SYS_ACCESS, AT_FDCWD, filename, strlen(filename), mode, 0); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, + struct stat *statbuf) { + switch (fsfdt) { + case fsfd_target::path: + fd = AT_FDCWD; + break; + case fsfd_target::fd: + flags |= AT_EMPTY_PATH; + + case fsfd_target::fd_path: + break; + + default: + __ensure(!"Invalid fsfd_target"); + __builtin_unreachable(); + } + + auto ret = syscall(SYS_FSTAT, fd, path, strlen(path), flags, statbuf); + if(int e = sc_error(ret); e) + return e; + return 0; +} + +int sys_ioctl(int fd, unsigned long request, void *arg, int *result) { + auto sys_res = syscall(SYS_IOCTL, fd, request, arg); + + if (sys_res < 0) { + return -sys_res; + } + + if (result) + *result = sys_res; + return 0; +} + +int sys_isatty(int fd) { + // NOTE: The easiest way to check if a file descriptor is a TTY is to + // do an ioctl of TIOCGWINSZ on it and see if it succeeds :^) + struct winsize ws; + int result; + + if (!sys_ioctl(fd, TIOCGWINSZ, &ws, &result)) { + return 0; + } + + return ENOTTY; +} + +int sys_tcgetattr(int fd, struct termios *attr) { + int result; + + if (int e = sys_ioctl(fd, TCGETS, (void *)attr, &result); e) + return e; + + return 0; +} + +int sys_tcsetattr(int fd, int optional_action, const struct termios *attr) { + int req; + + switch (optional_action) { + case TCSANOW: req = TCSETS; break; + case TCSADRAIN: req = TCSETSW; break; + case TCSAFLUSH: req = TCSETSF; break; + default: return EINVAL; + } + + if (int e = sys_ioctl(fd, req, (void *)attr, NULL); e) + return e; + + return 0; +} + +int sys_mkdir(const char *path, mode_t) { + auto result = syscall(SYS_MKDIR, path, strlen(path)); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_link(const char *srcpath, const char *destpath) { + auto result = + syscall(SYS_LINK, srcpath, strlen(srcpath), destpath, strlen(destpath)); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_rmdir(const char *path) { + return sys_unlinkat(AT_FDCWD, path, AT_REMOVEDIR); +} + +int sys_unlinkat(int fd, const char *path, int flags) { + auto ret = syscall(SYS_UNLINK, fd, path, strlen(path), flags); + if (int e = sc_error(ret); e) + return e; + return 0; +} + +struct aero_dir_entry { + size_t inode; + size_t offset; + size_t reclen; + size_t filetyp; + char name[]; +} __attribute__((__packed__)); + +int sys_read_entries(int handle, void *buffer, size_t max_size, + size_t *bytes_read) { + auto result = syscall(SYS_GETDENTS, handle, buffer, max_size); + + // Check if we got an error. + if (result < 0) { + *bytes_read = 0; + return -result; + } + + // Nothing to read. + if (result == 0) { + *bytes_read = 0; + return 0; + } + + auto entry = (struct aero_dir_entry *)buffer; + + struct dirent dirent = { + .d_ino = static_cast<ino_t>(entry->inode), + .d_off = static_cast<off_t>(entry->offset), + .d_reclen = static_cast<unsigned short>(entry->reclen), + .d_type = static_cast<unsigned char>(entry->filetyp), + }; + + // The reclen is the size of the dirent struct, plus the size of the name. + auto name_size = entry->reclen - sizeof(struct aero_dir_entry); + __ensure(name_size < 255); + + memcpy(&dirent.d_name, entry->name, name_size); + *bytes_read = entry->reclen; + + memcpy(buffer, &dirent, sizeof(struct dirent)); + return 0; +} + +int sys_open_dir(const char *path, int *handle) { + return sys_open(path, O_DIRECTORY, 0, handle); +} + +int sys_rename(const char *path, const char *new_path) { + auto result = + syscall(SYS_RENAME, path, strlen(path), new_path, strlen(new_path)); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_readlink(const char *path, void *buffer, size_t max_size, + ssize_t *length) { + auto result = syscall(SYS_READ_LINK, path, strlen(path), buffer, max_size); + + if (result < 0) { + return -result; + } + + *length = result; + return 0; +} + +int sys_dup(int fd, int flags, int *newfd) { + auto result = syscall(SYS_DUP, fd, flags); + + if (result < 0) { + return -result; + } + + *newfd = result; + return 0; +} + +int sys_dup2(int fd, int flags, int newfd) { + auto result = syscall(SYS_DUP2, fd, newfd, flags); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_fcntl(int fd, int request, va_list args, int *result_value) { + auto result = syscall(SYS_FCNTL, fd, request, va_arg(args, uint64_t)); + + if (result < 0) { + return -result; + } + + *result_value = result; + return 0; +} + +// int sys_chmod(const char *pathname, mode_t mode) UNIMPLEMENTED("sys_chmod") + +int sys_pipe(int *fds, int flags) { + auto result = syscall(SYS_PIPE, fds, flags); + + if (result < 0) { + return -result; + } + + return 0; +} + +// epoll API syscalls: +int sys_epoll_create(int flags, int *fd) { + auto result = syscall(SYS_EPOLL_CREATE, flags); + + if (result < 0) { + return -result; + } + + *fd = result; + return 0; +} + +int sys_epoll_ctl(int epfd, int mode, int fd, struct epoll_event *ev) { + auto result = syscall(SYS_EPOLL_CTL, epfd, mode, fd, ev); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_epoll_pwait(int epfd, struct epoll_event *ev, int n, int timeout, + const sigset_t *sigmask, int *raised) { + auto result = syscall(SYS_EPOLL_PWAIT, epfd, ev, n, timeout, sigmask); + + if (result < 0) { + return -result; + } + + *raised = result; + return 0; +} + +int sys_eventfd_create(unsigned int initval, int flags, int *fd) { + auto result = syscall(SYS_EVENT_FD, initval, flags); + + if (result < 0) { + return -result; + } + + *fd = result; + return 0; +} + +int sys_ppoll(struct pollfd *fds, int nfds, const struct timespec *timeout, + const sigset_t *sigmask, int *num_events) { + auto result = syscall(SYS_POLL, fds, nfds, timeout, sigmask); + + if (result < 0) { + return -result; + } + + *num_events = result; + return 0; +} + +int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events) { + struct timespec ts; + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + + return sys_ppoll(fds, count, &ts, NULL, num_events); +} + +#ifndef MLIBC_BUILDING_RTDL +#include <stdio.h> +int sys_ptsname(int fd, char *buffer, size_t length) { + int index; + if (int e = sys_ioctl(fd, TIOCGPTN, &index, NULL); e) + return e; + if ((size_t)snprintf(buffer, length, "/dev/pts/%d", index) >= length) { + return ERANGE; + } + return 0; +} + +int sys_pselect(int num_fds, fd_set *read_set, fd_set *write_set, + fd_set *except_set, const struct timespec *timeout, + const sigset_t *sigmask, int *num_events) { + int fd = epoll_create1(0); + if (fd == -1) + return -1; + + for (int k = 0; k < FD_SETSIZE; k++) { + struct epoll_event ev; + memset(&ev, 0, sizeof(struct epoll_event)); + + if (read_set && FD_ISSET(k, read_set)) + ev.events |= EPOLLIN; + if (write_set && FD_ISSET(k, write_set)) + ev.events |= EPOLLOUT; + if (except_set && FD_ISSET(k, except_set)) + ev.events |= EPOLLPRI; + + if (!ev.events) + continue; + + ev.data.u32 = k; + if (epoll_ctl(fd, EPOLL_CTL_ADD, k, &ev)) + return -1; + } + + struct epoll_event evnts[16]; + int n = epoll_pwait( + fd, evnts, 16, + timeout ? (timeout->tv_sec * 1000 + timeout->tv_nsec / 100) : -1, + sigmask); + + if (n == -1) + return -1; + + fd_set res_read_set; + fd_set res_write_set; + fd_set res_except_set; + FD_ZERO(&res_read_set); + FD_ZERO(&res_write_set); + FD_ZERO(&res_except_set); + + int m = 0; + + for (int i = 0; i < n; i++) { + int k = evnts[i].data.u32; + + if (read_set && FD_ISSET(k, read_set) && + evnts[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) { + FD_SET(k, &res_read_set); + m++; + } + + if (write_set && FD_ISSET(k, write_set) && + evnts[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) { + FD_SET(k, &res_write_set); + m++; + } + + if (except_set && FD_ISSET(k, except_set) && + evnts[i].events & EPOLLPRI) { + FD_SET(k, &res_except_set); + m++; + } + } + + if (close(fd)) + __ensure("mlibc::pselect: close() failed on epoll file"); + + if (read_set) + memcpy(read_set, &res_read_set, sizeof(fd_set)); + + if (write_set) + memcpy(write_set, &res_write_set, sizeof(fd_set)); + + if (except_set) + memcpy(except_set, &res_except_set, sizeof(fd_set)); + + *num_events = m; + return 0; +} +#endif // #ifndef MLIBC_BUILDING_RTDL +} // namespace mlibc diff --git a/lib/mlibc/sysdeps/aero/generic/signals.S b/lib/mlibc/sysdeps/aero/generic/signals.S new file mode 100644 index 0000000..62dee9b --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/signals.S @@ -0,0 +1,9 @@ +.section .text +.global __mlibc_signal_restore + +__mlibc_signal_restore: + mov $39, %rax + syscall + ud2 +.section .note.GNU-stack,"",%progbits + diff --git a/lib/mlibc/sysdeps/aero/generic/signals.cpp b/lib/mlibc/sysdeps/aero/generic/signals.cpp new file mode 100644 index 0000000..a6f69ff --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/signals.cpp @@ -0,0 +1,53 @@ +#include <mlibc/ansi-sysdeps.hpp> +#include <mlibc/debug.hpp> + +#include <aero/syscall.h> +#include <sys/types.h> + +#define LOG_SIGACTION_INSTALL 0 + +extern "C" void __mlibc_signal_restore(); // defined in `signals.S` + +namespace mlibc { +int sys_sigaction(int how, const struct sigaction *__restrict action, + struct sigaction *__restrict old_action) { +#if LOG_SIGACTION_INSTALL + mlibc::infoLogger() << "sys_sigaction: signal " << how << frg::endlog; + mlibc::infoLogger() << "sys_sigaction: size: " << sizeof(*action) + << frg::endlog; + + if (action != NULL) { + mlibc::infoLogger() << "sys_sigaction: handler " + << (int64_t)action->sa_handler << frg::endlog; + mlibc::infoLogger() << "sys_sigaction: action " + << (int64_t)action->sa_sigaction << frg::endlog; + mlibc::infoLogger() << "sys_sigaction: flags " + << (int64_t)action->sa_flags << frg::endlog; + } + + mlibc::infoLogger() << frg::endlog; +#endif + + auto sigreturn = (sc_word_t)__mlibc_signal_restore; + + auto res = syscall(SYS_SIGACTION, how, (sc_word_t)action, sigreturn, + (sc_word_t)old_action); + + if (res < 0) { + return -res; + } + + return 0; +} + +int sys_sigprocmask(int how, const sigset_t *__restrict set, + sigset_t *__restrict retrieve) { + auto result = syscall(SYS_SIGPROCMASK, how, set, retrieve); + + if (result < 0) { + return -result; + } + + return 0; +} +} // namespace mlibc
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/generic/sockets.cpp b/lib/mlibc/sysdeps/aero/generic/sockets.cpp new file mode 100644 index 0000000..0cce3c0 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/sockets.cpp @@ -0,0 +1,250 @@ +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/thread-entry.hpp> +#include <mlibc/debug.hpp> +#include <abi-bits/in.h> +#include <abi-bits/errno.h> + +#include <aero/syscall.h> + +#include <unistd.h> +#include <stdint.h> +#include <net/if.h> +#include <sys/ioctl.h> + +namespace { + +int fcntl_helper(int fd, int request, int *result, ...) { + va_list args; + va_start(args, result); + if(!mlibc::sys_fcntl) { + return ENOSYS; + } + int ret = mlibc::sys_fcntl(fd, request, args, result); + va_end(args); + return ret; +} + +} + +namespace mlibc { +int sys_socket(int family, int type, int protocol, int *fd) { + auto result = syscall(SYS_SOCKET, family, type, protocol); + + if (result < 0) { + return -result; + } + + *fd = result; + return 0; +} + +int sys_bind(int fd, const struct sockaddr *addr_ptr, socklen_t addr_length) { + auto result = syscall(SYS_BIND, fd, addr_ptr, (sc_word_t)addr_length); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_connect(int fd, const struct sockaddr *addr_ptr, + socklen_t addr_length) { + auto result = syscall(SYS_CONNECT, fd, addr_ptr, (sc_word_t)addr_length); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_listen(int fd, int backlog) { + auto result = syscall(SYS_LISTEN, fd, backlog); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_accept(int sockfd, int *newfd, struct sockaddr *addr_ptr, + socklen_t *addr_length, int flags) { + auto result = syscall(SYS_ACCEPT, sockfd, addr_ptr, addr_length); + + if (result < 0) { + return -result; + } + + *newfd = result; + + if(flags & SOCK_NONBLOCK) { + int fcntl_ret = 0; + fcntl_helper(*newfd, F_GETFL, &fcntl_ret); + fcntl_helper(*newfd, F_SETFL, &fcntl_ret, fcntl_ret | O_NONBLOCK); + } + + if(flags & SOCK_CLOEXEC) { + int fcntl_ret = 0; + fcntl_helper(*newfd, F_GETFD, &fcntl_ret); + fcntl_helper(*newfd, F_SETFD, &fcntl_ret, fcntl_ret | FD_CLOEXEC); + } + + return 0; +} + +int sys_msg_send(int fd, const struct msghdr *hdr, int flags, ssize_t *length) { + auto result = syscall(SYS_SOCK_SEND, fd, hdr, flags); + if (result < 0) + return -result; + + *length = result; + return 0; +} + +int sys_msg_recv(int sockfd, struct msghdr *msg_hdr, int flags, + ssize_t *length) { + auto result = syscall(SYS_SOCK_RECV, sockfd, msg_hdr, flags); + + if (result < 0) { + return -result; + } + + *length = result; + return 0; +} + +int sys_socketpair(int domain, int type_and_flags, int proto, int *fds) { + auto result = syscall(SYS_SOCKET_PAIR, domain, type_and_flags, proto, fds); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_getsockopt(int fd, int layer, int number, void *__restrict buffer, + socklen_t *__restrict size) { + (void)fd; + (void)size; + if (layer == SOL_SOCKET && number == SO_PEERCRED) { + mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET " + "and SO_PEERCRED is unimplemented\e[39m" + << frg::endlog; + *(int *)buffer = 0; + return 0; + } else if (layer == SOL_SOCKET && number == SO_SNDBUF) { + mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET " + "and SO_SNDBUF is unimplemented\e[39m" + << frg::endlog; + *(int *)buffer = 4096; + return 0; + } else if (layer == SOL_SOCKET && number == SO_TYPE) { + mlibc::infoLogger() + << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_TYPE is " + "unimplemented, hardcoding SOCK_STREAM\e[39m" + << frg::endlog; + *(int *)buffer = SOCK_STREAM; + return 0; + } else if (layer == SOL_SOCKET && number == SO_ERROR) { + mlibc::infoLogger() + << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_ERROR is " + "unimplemented, hardcoding 0\e[39m" + << frg::endlog; + *(int *)buffer = 0; + return 0; + } else if (layer == SOL_SOCKET && number == SO_KEEPALIVE) { + mlibc::infoLogger() + << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and " + "SO_KEEPALIVE is unimplemented, hardcoding 0\e[39m" + << frg::endlog; + *(int *)buffer = 0; + return 0; + } else { + mlibc::panicLogger() + << "\e[31mmlibc: Unexpected getsockopt() call, layer: " << layer + << " number: " << number << "\e[39m" << frg::endlog; + __builtin_unreachable(); + } + + return 0; +} + +int sys_setsockopt(int fd, int layer, int number, const void *buffer, + socklen_t size) { + (void)fd; + (void)buffer; + (void)size; + + if (layer == SOL_SOCKET && number == SO_PASSCRED) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt(SO_PASSCRED) is not " + "implemented correctly\e[39m" + << frg::endlog; + return 0; + } else if (layer == SOL_SOCKET && number == SO_ATTACH_FILTER) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt(SO_ATTACH_FILTER) is " + "not implemented correctly\e[39m" + << frg::endlog; + return 0; + } else if (layer == SOL_SOCKET && number == SO_RCVBUFFORCE) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt(SO_RCVBUFFORCE) is not " + "implemented correctly\e[39m" + << frg::endlog; + return 0; + } else if (layer == SOL_SOCKET && number == SO_SNDBUF) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_SOCKET " + "and SO_SNDBUF is unimplemented\e[39m" + << frg::endlog; + return 0; + } else if (layer == SOL_SOCKET && number == SO_KEEPALIVE) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_SOCKET " + "and SO_KEEPALIVE is unimplemented\e[39m" + << frg::endlog; + return 0; + } else if (layer == SOL_SOCKET && number == SO_REUSEADDR) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_SOCKET " + "and SO_REUSEADDR is unimplemented\e[39m" + << frg::endlog; + return 0; + } else if (layer == AF_NETLINK && number == SO_ACCEPTCONN) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with AF_NETLINK " + "and SO_ACCEPTCONN is unimplemented\e[39m" + << frg::endlog; + return 0; + } else { + mlibc::infoLogger() + << "\e[31mmlibc: Unexpected setsockopt() call, layer: " << layer + << " number: " << number << "\e[39m" << frg::endlog; + return 0; + } +} + +int sys_shutdown(int sockfd, int how) { + auto ret = syscall(SYS_SOCK_SHUTDOWN, sockfd, how); + if(int e = sc_error(ret); e) + return e; + return 0; +} + +int sys_if_nametoindex(const char *name, unsigned int *ret) { + int fd = 0; + int r = sys_socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, AF_UNSPEC, &fd); + + if (r) + return r; + + struct ifreq ifr; + strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); + + r = sys_ioctl(fd, SIOCGIFINDEX, &ifr, NULL); + close(fd); + + if (r) + return r; + + *ret = ifr.ifr_ifindex; + return 0; +} +} // namespace mlibc diff --git a/lib/mlibc/sysdeps/aero/generic/thread.cpp b/lib/mlibc/sysdeps/aero/generic/thread.cpp new file mode 100644 index 0000000..bc9a449 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/thread.cpp @@ -0,0 +1,55 @@ +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/thread-entry.hpp> + +#include <bits/ensure.h> +#include <mlibc/tcb.hpp> + +#include <sys/mman.h> + +#include <stddef.h> +#include <stdint.h> + +extern "C" void __mlibc_enter_thread(void *entry, void *user_arg, Tcb *tcb) { + // Wait until our parent sets up the TID: + while (!__atomic_load_n(&tcb->tid, __ATOMIC_RELAXED)) + mlibc::sys_futex_wait(&tcb->tid, 0, nullptr); + + if (mlibc::sys_tcb_set(tcb)) + __ensure(!"sys_tcb_set() failed"); + + tcb->invokeThreadFunc(entry, user_arg); + + auto self = reinterpret_cast<Tcb *>(tcb); + + __atomic_store_n(&self->didExit, 1, __ATOMIC_RELEASE); + mlibc::sys_futex_wake(&self->didExit); + + mlibc::sys_thread_exit(); +} + +namespace mlibc { + +static constexpr size_t default_stacksize = 0x1000000; + +int sys_prepare_stack(void **stack, void *entry, void *user_arg, void *tcb, + size_t *stack_size, size_t *guard_size, void **stack_base) { + if (!*stack_size) + *stack_size = default_stacksize; + *guard_size = 0; + + if (*stack) { + *stack_base = *stack; + } else { + *stack_base = mmap(nullptr, *stack_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + } + + uintptr_t *sp = reinterpret_cast<uintptr_t *>(reinterpret_cast<uintptr_t>(*stack_base) + *stack_size); + + *--sp = reinterpret_cast<uintptr_t>(tcb); + *--sp = reinterpret_cast<uintptr_t>(user_arg); + *--sp = reinterpret_cast<uintptr_t>(entry); + *stack = reinterpret_cast<void *>(sp); + return 0; +} +} // namespace mlibc diff --git a/lib/mlibc/sysdeps/aero/generic/thread_entry.S b/lib/mlibc/sysdeps/aero/generic/thread_entry.S new file mode 100644 index 0000000..498fda3 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/thread_entry.S @@ -0,0 +1,10 @@ +.section .text +.global __mlibc_start_thread + +__mlibc_start_thread: + pop %rdi + pop %rsi + pop %rdx + call __mlibc_enter_thread +.section .note.GNU-stack,"",%progbits + diff --git a/lib/mlibc/sysdeps/aero/generic/time.cpp b/lib/mlibc/sysdeps/aero/generic/time.cpp new file mode 100644 index 0000000..c995148 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/generic/time.cpp @@ -0,0 +1,25 @@ +#include <mlibc/all-sysdeps.hpp> +#include <aero/syscall.h> + +namespace mlibc { +int sys_setitimer(int which, const struct itimerval *new_value, + struct itimerval *old_value) { + auto result = syscall(SYS_SETITIMER, which, new_value, old_value); + + if (result < 0) { + return -result; + } + + return 0; +} + +int sys_getitimer(int which, struct itimerval *curr_value) { + auto result = syscall(SYS_GETITIMER, which, curr_value); + + if (result < 0) { + return -result; + } + + return 0; +} +} // namespace mlibc
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/access.h b/lib/mlibc/sysdeps/aero/include/abi-bits/access.h new file mode 120000 index 0000000..171f75f --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/access.h @@ -0,0 +1 @@ +../../../../abis/mlibc/access.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/auxv.h b/lib/mlibc/sysdeps/aero/include/abi-bits/auxv.h new file mode 120000 index 0000000..86157e8 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/auxv.h @@ -0,0 +1 @@ +../../../../abis/aero/auxv.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/blkcnt_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/blkcnt_t.h new file mode 120000 index 0000000..e9d9f1b --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/blkcnt_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/blkcnt_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/blksize_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/blksize_t.h new file mode 120000 index 0000000..c6dfb6e --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/blksize_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/blksize_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/clockid_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/clockid_t.h new file mode 120000 index 0000000..71f37bb --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/clockid_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/clockid_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/dev_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/dev_t.h new file mode 120000 index 0000000..0c1143b --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/dev_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/dev_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/epoll.h b/lib/mlibc/sysdeps/aero/include/abi-bits/epoll.h new file mode 120000 index 0000000..9efc3a0 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/epoll.h @@ -0,0 +1 @@ +../../../../abis/mlibc/epoll.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/errno.h b/lib/mlibc/sysdeps/aero/include/abi-bits/errno.h new file mode 120000 index 0000000..589859f --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/errno.h @@ -0,0 +1 @@ +../../../../abis/mlibc/errno.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/fcntl.h b/lib/mlibc/sysdeps/aero/include/abi-bits/fcntl.h new file mode 120000 index 0000000..ea5323a --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/fcntl.h @@ -0,0 +1 @@ +../../../../abis/mlibc/fcntl.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/fsblkcnt_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/fsblkcnt_t.h new file mode 120000 index 0000000..898dfb2 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/fsblkcnt_t.h @@ -0,0 +1 @@ +../../../../abis/linux/fsblkcnt_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/fsfilcnt_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/fsfilcnt_t.h new file mode 120000 index 0000000..791755c --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/fsfilcnt_t.h @@ -0,0 +1 @@ +../../../../abis/linux/fsfilcnt_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/gid_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/gid_t.h new file mode 120000 index 0000000..6a77218 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/gid_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/gid_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/in.h b/lib/mlibc/sysdeps/aero/include/abi-bits/in.h new file mode 120000 index 0000000..b58c683 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/in.h @@ -0,0 +1 @@ +../../../../abis/mlibc/in.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/ino_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/ino_t.h new file mode 120000 index 0000000..10d644e --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/ino_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/ino_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/inotify.h b/lib/mlibc/sysdeps/aero/include/abi-bits/inotify.h new file mode 120000 index 0000000..3f19ef6 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/inotify.h @@ -0,0 +1 @@ +../../../../abis/mlibc/inotify.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/ioctls.h b/lib/mlibc/sysdeps/aero/include/abi-bits/ioctls.h new file mode 120000 index 0000000..595106b --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/ioctls.h @@ -0,0 +1 @@ +../../../../abis/linux/ioctls.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/limits.h b/lib/mlibc/sysdeps/aero/include/abi-bits/limits.h new file mode 120000 index 0000000..1aa5894 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/limits.h @@ -0,0 +1 @@ +../../../../abis/mlibc/limits.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/mode_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/mode_t.h new file mode 120000 index 0000000..29d7733 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/mode_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/mode_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/mqueue.h b/lib/mlibc/sysdeps/aero/include/abi-bits/mqueue.h new file mode 120000 index 0000000..fa87b07 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/mqueue.h @@ -0,0 +1 @@ +../../../../abis/linux/mqueue.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/msg.h b/lib/mlibc/sysdeps/aero/include/abi-bits/msg.h new file mode 120000 index 0000000..f402b49 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/msg.h @@ -0,0 +1 @@ +../../../../abis/linux/msg.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/nlink_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/nlink_t.h new file mode 120000 index 0000000..7618c27 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/nlink_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/nlink_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/packet.h b/lib/mlibc/sysdeps/aero/include/abi-bits/packet.h new file mode 120000 index 0000000..47067e2 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/packet.h @@ -0,0 +1 @@ +../../../../abis/mlibc/packet.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/pid_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/pid_t.h new file mode 120000 index 0000000..3fd26a7 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/pid_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/pid_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/poll.h b/lib/mlibc/sysdeps/aero/include/abi-bits/poll.h new file mode 120000 index 0000000..ab989c7 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/poll.h @@ -0,0 +1 @@ +../../../../abis/mlibc/poll.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/ptrace.h b/lib/mlibc/sysdeps/aero/include/abi-bits/ptrace.h new file mode 120000 index 0000000..f391fb7 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/ptrace.h @@ -0,0 +1 @@ +../../../../abis/mlibc/ptrace.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/reboot.h b/lib/mlibc/sysdeps/aero/include/abi-bits/reboot.h new file mode 120000 index 0000000..77013a4 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/reboot.h @@ -0,0 +1 @@ +../../../../abis/linux/reboot.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/resource.h b/lib/mlibc/sysdeps/aero/include/abi-bits/resource.h new file mode 120000 index 0000000..3e59c75 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/resource.h @@ -0,0 +1 @@ +../../../../abis/mlibc/resource.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/seek-whence.h b/lib/mlibc/sysdeps/aero/include/abi-bits/seek-whence.h new file mode 120000 index 0000000..3bd41ef --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/seek-whence.h @@ -0,0 +1 @@ +../../../../abis/mlibc/seek-whence.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/shm.h b/lib/mlibc/sysdeps/aero/include/abi-bits/shm.h new file mode 120000 index 0000000..067d8c4 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/shm.h @@ -0,0 +1 @@ +../../../../abis/linux/shm.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/signal.h b/lib/mlibc/sysdeps/aero/include/abi-bits/signal.h new file mode 120000 index 0000000..4dcb0b7 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/signal.h @@ -0,0 +1 @@ +../../../../abis/linux/signal.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/socket.h b/lib/mlibc/sysdeps/aero/include/abi-bits/socket.h new file mode 120000 index 0000000..0e1d6be --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/socket.h @@ -0,0 +1 @@ +../../../../abis/mlibc/socket.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/socklen_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/socklen_t.h new file mode 120000 index 0000000..41f3b11 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/socklen_t.h @@ -0,0 +1 @@ +../../../../abis/linux/socklen_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/stat.h b/lib/mlibc/sysdeps/aero/include/abi-bits/stat.h new file mode 120000 index 0000000..82642c3 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/stat.h @@ -0,0 +1 @@ +../../../../abis/mlibc/stat.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/statfs.h b/lib/mlibc/sysdeps/aero/include/abi-bits/statfs.h new file mode 120000 index 0000000..e3d202f --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/statfs.h @@ -0,0 +1 @@ +../../../../abis/linux/statfs.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/statvfs.h b/lib/mlibc/sysdeps/aero/include/abi-bits/statvfs.h new file mode 120000 index 0000000..1fc80c2 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/statvfs.h @@ -0,0 +1 @@ +../../../../abis/linux/statvfs.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/suseconds_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/suseconds_t.h new file mode 120000 index 0000000..9ed6597 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/suseconds_t.h @@ -0,0 +1 @@ +../../../../abis/linux/suseconds_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/termios.h b/lib/mlibc/sysdeps/aero/include/abi-bits/termios.h new file mode 120000 index 0000000..ee8f0b0 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/termios.h @@ -0,0 +1 @@ +../../../../abis/linux/termios.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/time.h b/lib/mlibc/sysdeps/aero/include/abi-bits/time.h new file mode 120000 index 0000000..97f3d52 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/time.h @@ -0,0 +1 @@ +../../../../abis/mlibc/time.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/uid_t.h b/lib/mlibc/sysdeps/aero/include/abi-bits/uid_t.h new file mode 120000 index 0000000..1113eba --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/uid_t.h @@ -0,0 +1 @@ +../../../../abis/mlibc/uid_t.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/utsname.h b/lib/mlibc/sysdeps/aero/include/abi-bits/utsname.h new file mode 120000 index 0000000..b285754 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/utsname.h @@ -0,0 +1 @@ +../../../../abis/linux/utsname.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/vm-flags.h b/lib/mlibc/sysdeps/aero/include/abi-bits/vm-flags.h new file mode 120000 index 0000000..f1a985e --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/vm-flags.h @@ -0,0 +1 @@ +../../../../abis/mlibc/vm-flags.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/wait.h b/lib/mlibc/sysdeps/aero/include/abi-bits/wait.h new file mode 120000 index 0000000..feb2840 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/wait.h @@ -0,0 +1 @@ +../../../../abis/linux/wait.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/abi-bits/xattr.h b/lib/mlibc/sysdeps/aero/include/abi-bits/xattr.h new file mode 120000 index 0000000..66412d7 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/abi-bits/xattr.h @@ -0,0 +1 @@ +../../../../abis/linux/xattr.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/aero/include/aero/syscall.h b/lib/mlibc/sysdeps/aero/include/aero/syscall.h new file mode 100644 index 0000000..3f36e4d --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/aero/syscall.h @@ -0,0 +1,231 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +#include <bits/ensure.h> +#include <stdint.h> + +#define SYS_READ 0 +#define SYS_WRITE 1 +#define SYS_OPEN 2 +#define SYS_CLOSE 3 +#define SYS_SHUTDOWN 4 +#define SYS_EXIT 5 +#define SYS_FORK 6 +#define SYS_REBOOT 7 +#define SYS_MMAP 8 +#define SYS_MUNMAP 9 +#define SYS_ARCH_PRCTL 10 +#define SYS_GETDENTS 11 +#define SYS_GETCWD 12 +#define SYS_CHDIR 13 +#define SYS_MKDIR 14 +#define SYS_MKDIR_AT 15 +#define SYS_RMDIR 16 +#define SYS_EXEC 17 +#define SYS_LOG 18 +#define SYS_UNAME 19 +#define SYS_WAITPID 20 +#define SYS_IOCTL 21 +#define SYS_GETPID 22 +#define SYS_SOCKET 23 +#define SYS_CONNECT 24 +#define SYS_BIND 25 +#define SYS_LISTEN 26 +#define SYS_ACCEPT 27 +#define SYS_SEEK 28 +#define SYS_GETTID 29 +#define SYS_GETTIME 30 +#define SYS_SLEEP 31 +#define SYS_ACCESS 32 +#define SYS_PIPE 33 +#define SYS_UNLINK 34 +#define SYS_GETHOSTNAME 35 +#define SYS_SETHOSTNAME 36 +#define SYS_INFO 37 +#define SYS_CLONE 38 +#define SYS_SIGRETURN 39 +#define SYS_SIGACTION 40 +#define SYS_SIGPROCMASK 41 +#define SYS_DUP 42 +#define SYS_FCNTL 43 +#define SYS_DUP2 44 +#define SYS_IPC_SEND 45 +#define SYS_IPC_RECV 46 +#define SYS_DISCOVER_ROOT 47 +#define SYS_BECOME_ROOT 48 +#define SYS_STAT 49 +#define SYS_FSTAT 50 +#define SYS_READ_LINK 51 +#define SYS_EPOLL_CREATE 52 +#define SYS_EPOLL_PWAIT 53 +#define SYS_EPOLL_CTL 54 +#define SYS_EVENT_FD 55 +#define SYS_KILL 56 +#define SYS_FUTEX_WAIT 57 +#define SYS_FUTEX_WAKE 58 +#define SYS_LINK 59 +#define SYS_BACKTRACE 60 +#define SYS_POLL 61 +#define SYS_EXIT_THREAD 62 +#define SYS_SOCK_RECV 63 +#define SYS_SETITIMER 64 +#define SYS_GETITIMER 65 +#define SYS_GETPPID 66 +#define SYS_SOCKET_PAIR 67 +#define SYS_RENAME 68 +#define SYS_MPROTECT 69 +#define SYS_SOCK_SEND 70 +#define SYS_TRACE 71 +#define SYS_SETPGID 72 +#define SYS_SETSID 73 +#define SYS_GETPGID 74 +#define SYS_SOCK_SHUTDOWN 75 + +// Invalid syscall used to trigger a log error in the kernel (as a hint) +// so, that we can implement the syscall in the kernel. +#define UNIMPLEMENTED(FUNCTION_NAME) \ + { \ + sys_libc_log("Unimplemented syscall: " FUNCTION_NAME); \ + sys_exit(1); \ + __builtin_unreachable(); \ + } + +extern "C" { +using sc_word_t = long; + +static sc_word_t syscall0(int sc) { + sc_word_t ret; + asm volatile("syscall" : "=a"(ret) : "a"(sc) : "rcx", "r11", "memory"); + return ret; +} + +static sc_word_t syscall1(int sc, sc_word_t arg1) { + sc_word_t ret; + asm volatile("syscall" + : "=a"(ret) + : "a"(sc), "D"(arg1) + : "rcx", "r11", "memory"); + return ret; +} + +static sc_word_t syscall2(int sc, sc_word_t arg1, sc_word_t arg2) { + sc_word_t ret; + asm volatile("syscall" + : "=a"(ret) + : "a"(sc), "D"(arg1), "S"(arg2) + : "rcx", "r11", "memory"); + return ret; +} + +static sc_word_t syscall3(int sc, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3) { + sc_word_t ret; + asm volatile("syscall" + : "=a"(ret) + : "a"(sc), "D"(arg1), "S"(arg2), "d"(arg3) + : "rcx", "r11", "memory"); + return ret; +} + +static sc_word_t syscall4(int sc, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3, sc_word_t arg4) { + sc_word_t ret; + + register sc_word_t arg4_reg asm("r10") = arg4; + + asm volatile("syscall" + : "=a"(ret) + : "a"(sc), "D"(arg1), "S"(arg2), "d"(arg3), "r"(arg4_reg) + : "rcx", "r11", "memory"); + return ret; +} + +static sc_word_t syscall5(int sc, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3, sc_word_t arg4, sc_word_t arg5) { + sc_word_t ret; + + register sc_word_t arg4_reg asm("r10") = arg4; + register sc_word_t arg5_reg asm("r8") = arg5; + + asm volatile("syscall" + : "=a"(ret) + : "a"(sc), "D"(arg1), "S"(arg2), "d"(arg3), "r"(arg4_reg), + "r"(arg5_reg) + : "rcx", "r11", "memory"); + return ret; +} + +static sc_word_t syscall6(int sc, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3, sc_word_t arg4, sc_word_t arg5, + sc_word_t arg6) { + sc_word_t ret; + + register sc_word_t arg4_reg asm("r10") = arg4; + register sc_word_t arg5_reg asm("r8") = arg5; + register sc_word_t arg6_reg asm("r9") = arg6; + + asm volatile("syscall" + : "=a"(ret) + : "a"(sc), "D"(arg1), "S"(arg2), "d"(arg3), "r"(arg4_reg), + "r"(arg5_reg), "r"(arg6_reg) + : "rcx", "r11", "memory"); + return ret; +} +} // extern "C" + +// Cast to the argument type of the extern "C" functions. +__attribute__((__always_inline__)) inline sc_word_t sc_cast(long x) { return x; } +__attribute__((__always_inline__)) inline sc_word_t sc_cast(const void *x) { + return reinterpret_cast<sc_word_t>(x); +} + +// C++ wrappers for the extern "C" functions. +__attribute__((__always_inline__)) static inline long _syscall(int call) { + return syscall0(call); +} + +__attribute__((__always_inline__)) static inline long _syscall(int call, + sc_word_t arg0) { + return syscall1(call, arg0); +} + +__attribute__((__always_inline__)) static inline long +_syscall(int call, sc_word_t arg0, sc_word_t arg1) { + return syscall2(call, arg0, arg1); +} + +__attribute__((__always_inline__)) static inline long +_syscall(int call, sc_word_t arg0, sc_word_t arg1, sc_word_t arg2) { + return syscall3(call, arg0, arg1, arg2); +} + +__attribute__((__always_inline__)) static inline long +_syscall(int call, sc_word_t arg0, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3) { + return syscall4(call, arg0, arg1, arg2, arg3); +} + +__attribute__((__always_inline__)) static inline long +_syscall(int call, sc_word_t arg0, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3, sc_word_t arg4) { + return syscall5(call, arg0, arg1, arg2, arg3, arg4); +} + +__attribute__((__always_inline__)) static inline long +_syscall(int call, sc_word_t arg0, sc_word_t arg1, sc_word_t arg2, + sc_word_t arg3, sc_word_t arg4, sc_word_t arg5) { + return syscall6(call, arg0, arg1, arg2, arg3, arg4, arg5); +} + +template <typename... T> +__attribute__((__always_inline__)) static inline long syscall(sc_word_t call, + T... args) { + return _syscall(call, sc_cast(args)...); +} + +inline int sc_error(long ret) { + if (ret < 0) + return -ret; + return 0; +} +#endif // SYSCALL_H diff --git a/lib/mlibc/sysdeps/aero/include/mlibc/thread-entry.hpp b/lib/mlibc/sysdeps/aero/include/mlibc/thread-entry.hpp new file mode 100644 index 0000000..a241479 --- /dev/null +++ b/lib/mlibc/sysdeps/aero/include/mlibc/thread-entry.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <mlibc/tcb.hpp> + +extern "C" void __mlibc_start_thread(void); +extern "C" void __mlibc_enter_thread(void *entry, void *user_arg, Tcb *tcb); + +namespace mlibc { +int prepare_stack(void **stack, void *entry, void *user_arg, void *tcb, size_t *stack_size, + size_t *guard_size); +} // namespace mlibc diff --git a/lib/mlibc/sysdeps/aero/meson.build b/lib/mlibc/sysdeps/aero/meson.build new file mode 100644 index 0000000..20cf6cf --- /dev/null +++ b/lib/mlibc/sysdeps/aero/meson.build @@ -0,0 +1,85 @@ +rtdl_dso_sources += files( + 'generic/aero.cpp', + 'generic/filesystem.cpp', +) + +libc_sources += files( + 'generic/aero.cpp', + 'generic/entry.cpp', + 'generic/thread_entry.S', + 'generic/thread.cpp', + 'generic/filesystem.cpp', + 'generic/sockets.cpp', + 'generic/signals.cpp', + 'generic/time.cpp', +) + +if not no_headers + install_headers( + 'include/abi-bits/auxv.h', + 'include/abi-bits/seek-whence.h', + 'include/abi-bits/vm-flags.h', + 'include/abi-bits/errno.h', + 'include/abi-bits/fcntl.h', + 'include/abi-bits/in.h', + 'include/abi-bits/resource.h', + 'include/abi-bits/signal.h', + 'include/abi-bits/stat.h', + 'include/abi-bits/socket.h', + 'include/abi-bits/termios.h', + 'include/abi-bits/time.h', + 'include/abi-bits/blkcnt_t.h', + 'include/abi-bits/blksize_t.h', + 'include/abi-bits/dev_t.h', + 'include/abi-bits/gid_t.h', + 'include/abi-bits/ino_t.h', + 'include/abi-bits/mode_t.h', + 'include/abi-bits/nlink_t.h', + 'include/abi-bits/pid_t.h', + 'include/abi-bits/uid_t.h', + 'include/abi-bits/access.h', + 'include/abi-bits/wait.h', + 'include/abi-bits/limits.h', + 'include/abi-bits/utsname.h', + 'include/abi-bits/ptrace.h', + 'include/abi-bits/poll.h', + 'include/abi-bits/epoll.h', + 'include/abi-bits/packet.h', + 'include/abi-bits/inotify.h', + 'include/abi-bits/clockid_t.h', + 'include/abi-bits/shm.h', + 'include/abi-bits/mqueue.h', + 'include/abi-bits/suseconds_t.h', + 'include/abi-bits/fsfilcnt_t.h', + 'include/abi-bits/fsblkcnt_t.h', + 'include/abi-bits/socklen_t.h', + 'include/abi-bits/statfs.h', + 'include/abi-bits/statvfs.h', + 'include/abi-bits/ioctls.h', + 'include/abi-bits/xattr.h', + 'include/abi-bits/msg.h', + subdir: 'abi-bits', + follow_symlinks: true + ) + install_headers( + 'include/aero/syscall.h', + subdir: 'aero' + ) +endif + +if not headers_only + crt = custom_target('crt0', + build_by_default: true, + command: c_compiler.cmd_array() + ['-c', '-o', '@OUTPUT@', '@INPUT@'], + input: 'crt-x86_64/crt0.S', + output: 'crt0.o', + install: true, + install_dir: get_option('libdir') + ) +endif + +if host_machine.cpu_family() == 'x86_64' + libc_sources += files('generic/signals.S') +else + error('Unknown architecture') +endif |