diff options
Diffstat (limited to 'lib/mlibc/sysdeps/lemon')
55 files changed, 1273 insertions, 0 deletions
diff --git a/lib/mlibc/sysdeps/lemon/crt-x86_64/crt0.S b/lib/mlibc/sysdeps/lemon/crt-x86_64/crt0.S new file mode 100755 index 0000000..62298e3 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/generic/entry.cpp b/lib/mlibc/sysdeps/lemon/generic/entry.cpp new file mode 100644 index 0000000..f4cf144 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/entry.cpp @@ -0,0 +1,33 @@ +#include <stdint.h> +#include <stdlib.h> +#include <bits/ensure.h> +#include <mlibc/elf/startup.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/lemon/generic/filesystem.cpp b/lib/mlibc/sysdeps/lemon/generic/filesystem.cpp new file mode 100755 index 0000000..4a7d780 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/filesystem.cpp @@ -0,0 +1,406 @@ +#include <lemon/syscall.h> + +#include <asm/ioctls.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <dirent.h> +#include <limits.h> +#include <fcntl.h> +#include <string.h> + +#include <bits/ensure.h> +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/debug.hpp> + +namespace mlibc{ + +typedef struct { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + uid_t st_gid; + dev_t st_rdev; + off_t st_size; + int64_t st_blksize; + int64_t st_blocks; +} lemon_stat_t; + +int sys_write(int fd, const void* buffer, size_t count, ssize_t* written){ + long ret = syscall(SYS_WRITE, fd, (uintptr_t)buffer, count); + + if(ret < 0) + return -ret; + + *written = ret; + return 0; +} + +int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read) { + long ret = syscall(SYS_READ, fd, (uintptr_t)buf, count); + + if(ret < 0){ + *bytes_read = 0; + return -ret; + } + + *bytes_read = ret; + return 0; +} + +int sys_pwrite(int fd, const void* buffer, size_t count, off_t off, ssize_t* written){ + int ret = syscall(SYS_PWRITE, fd, (uintptr_t)buffer, count, 0, off); + + + if(ret < 0){ + return -ret; + } + + *written = ret; + return 0; +} + +int sys_pread(int fd, void *buf, size_t count, off_t off, ssize_t *bytes_read) { + int ret = syscall(SYS_PREAD, fd, (uintptr_t)buf, count, 0, off); + + if(ret < 0){ + return -ret; + } + + *bytes_read = ret; + return 0; +} + +int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) { + long ret = syscall(SYS_LSEEK, fd, offset, whence); + + if(ret < 0){ + return -ret; + } + + *new_offset = ret; + return 0; +} + + +int sys_open(const char* filename, int flags, mode_t mode, int* fd){ + long ret = syscall(SYS_OPEN, (uintptr_t)filename, flags); + + if(ret < 0) + return -ret; + + *fd = ret; + + return 0; +} + +int sys_close(int fd){ + syscall(SYS_CLOSE, fd); + return 0; +} + +int sys_access(const char* filename, int mode){ + int fd; + if(int e = sys_open(filename, O_RDONLY, 0, &fd)){ + return e; + } + + sys_close(fd); + return 0; +} + +int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, struct stat *statbuf){ + long ret = 0; + + lemon_stat_t lemonStat; + switch(fsfdt){ + case fsfd_target::fd: + ret = syscall(SYS_FSTAT, &lemonStat, fd); + break; + case fsfd_target::path: + ret = syscall(SYS_STAT, &lemonStat, path); + break; + default: + mlibc::infoLogger() << "mlibc warning: sys_stat: unsupported fsfd target" << frg::endlog; + return EINVAL; + } + + statbuf->st_dev = lemonStat.st_dev; + statbuf->st_ino = lemonStat.st_ino; + statbuf->st_mode = lemonStat.st_mode; + statbuf->st_nlink = lemonStat.st_nlink; + statbuf->st_uid = lemonStat.st_uid; + statbuf->st_gid = lemonStat.st_gid; + statbuf->st_rdev = lemonStat.st_rdev; + statbuf->st_size = lemonStat.st_size; + statbuf->st_blksize = lemonStat.st_blksize; + statbuf->st_blocks = lemonStat.st_blocks; + + return -ret; +} + +int sys_ioctl(int fd, unsigned long request, void *arg, int *result){ + long ret = syscall(SYS_IOCTL, fd, request, arg, result); + + if(ret < 0) + return -ret; + + return 0; +} + +#ifndef MLIBC_BUILDING_RTDL + +int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events){ + long ret = syscall(SYS_POLL, fds, count, timeout); + + if(ret < 0){ + return -ret; + } + + *num_events = ret; + + return 0; +} + +int sys_mkdir(const char* path, mode_t){ + long ret = syscall(SYS_MKDIR, path); + + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_rmdir(const char* path){ + long ret = syscall(SYS_RMDIR, path); + + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_link(const char* srcpath, const char* destpath){ + long ret = syscall(SYS_LINK, srcpath, destpath); + + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_unlinkat(int fd, const char *path, int flags) { + long ret = syscall(SYS_UNLINK, fd, path, flags); + + if(ret < 0) { + return -ret; + } + + return 0; +} + +typedef struct lemon_dirent { + uint32_t inode; // Inode number + uint32_t type; + char name[NAME_MAX]; // Filename +} lemon_dirent_t; + +int sys_read_entries(int handle, void *buffer, size_t max_size, size_t *bytes_read){ + lemon_dirent_t lemonDirent; + long ret = syscall(SYS_READDIR_NEXT, handle, &lemonDirent); + + if(!ret){ + *bytes_read = 0; + return 0; + } else if(ret > 0){ + dirent* dir = (dirent*)buffer; + strcpy(dir->d_name, lemonDirent.name); + dir->d_ino = lemonDirent.inode; + dir->d_off = 0; + dir->d_reclen = sizeof(dirent); + dir->d_type = lemonDirent.type; + + *bytes_read = sizeof(dirent); + return 0; + } else { + return -ret; + } +} + +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){ + return -syscall(SYS_RENAME, path, new_path); +} + +int sys_readlink(const char *path, void *buffer, size_t max_size, ssize_t *length){ + long ret = syscall(SYS_READLINK, path, buffer, max_size); + if(ret < 0){ + return -ret; + } + + *length = ret; + return 0; +} + +int sys_dup(int fd, int flags, int* newfd){ + int ret = syscall(SYS_DUP, fd, flags, -1); + if(ret < 0){ + return -ret; + } + + *newfd = ret; + return 0; +} + +int sys_dup2(int fd, int flags, int newfd){ + int ret = syscall(SYS_DUP, fd, flags, newfd); + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_fcntl(int fd, int request, va_list args, int* result){ + if(request == F_DUPFD){ + return sys_dup(fd, 0, result); + } else if (request == F_DUPFD_CLOEXEC) { + return sys_dup(fd, O_CLOEXEC, result); + } else if(request == F_GETFD){ + *result = 0; + return 0; + } else if(request == F_SETFD){ + if(va_arg(args, int) & FD_CLOEXEC) { + return sys_ioctl(fd, FIOCLEX, NULL, result); + } else { + return sys_ioctl(fd, FIONCLEX, NULL, result); + } + } else if(request == F_GETFL){ + int ret = syscall(SYS_GET_FILE_STATUS_FLAGS, fd); + if(ret < 0){ + return -ret; + } + + *result = ret; + return 0; + } else if(request == F_SETFL){ + int ret = syscall(SYS_SET_FILE_STATUS_FLAGS, fd, va_arg(args, int)); + return -ret; + } else { + infoLogger() << "mlibc: sys_fcntl unsupported request (" << request << ")" << frg::endlog; + return EINVAL; + } +} + +int sys_pselect(int nfds, fd_set* readfds, fd_set* writefds, + fd_set *exceptfds, const struct timespec* timeout, const sigset_t* sigmask, int *num_events){ + int ret = syscall(SYS_SELECT, nfds, readfds, writefds, exceptfds, timeout); + if(ret < 0){ + return -ret; + } + + *num_events = ret; + return 0; +} + +int sys_chmod(const char *pathname, mode_t mode){ + int ret = syscall(SYS_CHMOD, pathname, mode); + + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_pipe(int *fds, int flags){ + return -syscall(SYS_PIPE, fds, flags); +} + +int sys_epoll_create(int flags, int *fd) { + int ret = syscall(SYS_EPOLL_CREATE, flags); + + if(ret < 0){ + return -ret; + } + + *fd = ret; + + return 0; +} + +int sys_epoll_ctl(int epfd, int mode, int fd, struct epoll_event *ev) { + int ret = syscall(SYS_EPOLL_CTL, epfd, mode, fd, ev); + + if(ret < 0) { + return -ret; + } + + return 0; +} + +int sys_epoll_pwait(int epfd, struct epoll_event *ev, int n, + int timeout, const sigset_t *sigmask, int *raised) { + int ret = syscall(SYS_EPOLL_WAIT, epfd, ev, n, timeout, sigmask); + + if(ret < 0) { + return -ret; + } + + *raised = ret; + + return 0; +} + +int sys_ttyname(int tty, char *buf, size_t size) { + char path[PATH_MAX] = {"/dev/pts/"}; + + struct stat stat; + if(int e = sys_stat(fsfd_target::fd, tty, nullptr, 0, &stat)) { + return e; + } + + if(!S_ISCHR(stat.st_mode)) { + return ENOTTY; // Not a char device, isn't a tty + } + + if(sys_isatty(tty)) { + return ENOTTY; + } + + // Look for tty in /dev/pts + int ptDir = open("/dev/pts", O_DIRECTORY); + __ensure(ptDir >= 0); + + struct dirent dirent; + size_t direntBytesRead; + while(!sys_read_entries(ptDir, &dirent, sizeof(dirent), &direntBytesRead) && direntBytesRead) { + // Compare the inodes + if(dirent.d_ino == stat.st_ino) { + __ensure(strlen(path) + strlen(dirent.d_name) < PATH_MAX); + strcat(path, dirent.d_name); + + strncpy(buf, path, size); + return 0; + } + } + + // Could not find corresponding TTY in /dev/pts + return ENODEV; +} + +int sys_fchdir(int fd) { + return syscall(SYS_FCHDIR, fd); +} +#endif + +} diff --git a/lib/mlibc/sysdeps/lemon/generic/lemon.cpp b/lib/mlibc/sysdeps/lemon/generic/lemon.cpp new file mode 100644 index 0000000..8f15ff1 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/lemon.cpp @@ -0,0 +1,199 @@ +#include <lemon/syscall.h> +#include <stddef.h> +#include <bits/ensure.h> +#include <abi-bits/pid_t.h> +#include <mlibc/debug.hpp> +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/thread-entry.hpp> +#include <errno.h> +#include <sys/resource.h> + +namespace mlibc{ + +int sys_futex_tid(){ + return syscall(SYS_GETTID); +} + +int sys_futex_wait(int *pointer, int expected, const struct timespec *time){ + return syscall(SYS_FUTEX_WAIT, pointer, expected); +} + +int sys_futex_wake(int *pointer) { + return syscall(SYS_FUTEX_WAKE, pointer); +} + +int sys_tcb_set(void* pointer){ + syscall(SYS_SET_FS_BASE, (uintptr_t)pointer); + return 0; +} + +int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void **window) { + __ensure(flags & MAP_ANONYMOUS); + + return syscall(SYS_MMAP, (uintptr_t)window, (size + 0xFFF) & ~static_cast<size_t>(0xFFF), (uintptr_t)hint, flags); +} + +int sys_vm_unmap(void* address, size_t size) { + __ensure(!(size & 0xFFF)); + + long ret = syscall(SYS_MUNMAP, (uintptr_t)address, (size + 0xFFF) & ~static_cast<size_t>(0xFFF)); + + return ret; +} + +int sys_anon_allocate(size_t size, void **pointer) { + return sys_vm_map(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0, pointer); +} + +int sys_anon_free(void *pointer, size_t size) { + return sys_vm_unmap(pointer, size); +} + +void sys_libc_panic(){ + sys_libc_log("libc panic!"); + __builtin_trap(); + for(;;); +} + +void sys_libc_log(const char* msg){ + syscall(0, (uintptr_t)msg); +} + +#ifndef MLIBC_BUILDING_RTDL + +void sys_exit(int status){ + syscall(SYS_EXIT, status); + + __builtin_unreachable(); +} + +pid_t sys_getpid(){ + uint64_t _pid; + syscall(SYS_GETPID, (uintptr_t)&_pid); + + pid_t pid = _pid; + return pid; +} + +pid_t sys_getppid(){ + return syscall(SYS_GETPPID); +} + +int sys_clock_get(int clock, time_t *secs, long *nanos) { + syscall(SYS_UPTIME, nanos); + + *secs = (*nanos) / 1000000000; + *nanos = (*nanos) - (*secs) * 1000000000; + + return 0; +} + +int sys_getcwd(char *buffer, size_t size){ + return syscall(SYS_GET_CWD, buffer, size); +} + +int sys_chdir(const char *path){ + syscall(SYS_CHDIR, path); + return 0; +} + +int sys_sleep(time_t* sec, long* nanosec){ + syscall(SYS_NANO_SLEEP, (*sec) * 1000000000 + (*nanosec)); + return 0; +} + +uid_t sys_getuid(){ + return syscall(SYS_GETUID); +} + +uid_t sys_geteuid(){ + return syscall(SYS_GETEUID); +} + +int sys_setuid(uid_t uid){ + return -syscall(SYS_SETUID, uid); +} + +int sys_seteuid(uid_t euid){ + return -syscall(SYS_SETEUID, euid); +} + +gid_t sys_getgid(){ + return syscall(SYS_GETGID); +} + +gid_t sys_getegid(){ + return syscall(SYS_GETEGID); +} + +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(){ + syscall(SYS_YIELD); +} + +int sys_clone(void *tcb, pid_t *tid_out, void *stack){ + pid_t tid = syscall(SYS_SPAWN_THREAD, __mlibc_start_thread, stack); + + if(tid < 0){ + errno = tid; + return -1; + } + + *tid_out = tid; + + return 0; +} + +void sys_thread_exit(){ + syscall(SYS_EXIT_THREAD); + + __builtin_unreachable(); +} + +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; + } + + pid_t ret = syscall(SYS_WAIT_PID, pid, status, flags); + + if(ret < 0){ + return -ret; + } + + *ret_pid = ret; + + return 0; +} + +int sys_fork(pid_t *child){ + long pid = syscall(SYS_FORK, 0); + if(pid < 0){ + errno = pid; + return -1; + } + + *child = pid; + return 0; +} + +int sys_execve(const char *path, char *const argv[], char *const envp[]){ + return -syscall(SYS_EXECVE, path, argv, envp); +} + +int sys_getentropy(void *buffer, size_t length){ + return -syscall(SYS_GETENTROPY, buffer, length); +} +#endif + +} diff --git a/lib/mlibc/sysdeps/lemon/generic/pty.cpp b/lib/mlibc/sysdeps/lemon/generic/pty.cpp new file mode 100644 index 0000000..794f74f --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/pty.cpp @@ -0,0 +1,63 @@ +#include <asm/ioctls.h> +#include <sys/ioctl.h> + +#include <errno.h> + +#include <bits/ensure.h> +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/debug.hpp> + +#include <stdio.h> + +namespace mlibc { + +int sys_isatty(int fd) { + struct winsize ws; + long ret = sys_ioctl(fd, TIOCGWINSZ, &ws, 0); + + if(!ret) return 0; + + return ENOTTY; +} + +int sys_tcgetattr(int fd, struct termios *attr) { + if(int e = sys_isatty(fd)) + return e; + + int ret; + sys_ioctl(fd, TCGETS, attr, &ret); + + if(ret) + return -ret; + + return 0; +} + +int sys_tcsetattr(int fd, int optional_action, const struct termios *attr) { + if(int e = sys_isatty(fd)) + return e; + + if(optional_action){ + mlibc::infoLogger() << "mlibc warning: sys_tcsetattr ignores optional_action" << frg::endlog; + } + + int ret; + sys_ioctl(fd, TCSETS, const_cast<struct termios*>(attr), &ret); + + if(ret) + return -ret; + + return 0; +} + +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; +} + +} diff --git a/lib/mlibc/sysdeps/lemon/generic/signals.cpp b/lib/mlibc/sysdeps/lemon/generic/signals.cpp new file mode 100644 index 0000000..46b4714 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/signals.cpp @@ -0,0 +1,38 @@ +#include <lemon/syscall.h> + +#include <sys/types.h> + +#include <mlibc/ansi-sysdeps.hpp> + +namespace mlibc{ + +int sys_sigprocmask(int how, const sigset_t *__restrict set, + sigset_t *__restrict retrieve){ + int ret = syscall(SYS_SIGPROCMASK, how, set, retrieve); + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_sigaction(int signal, const struct sigaction *__restrict action, + struct sigaction *__restrict oldAction) { + int ret = syscall(SYS_SIGNAL_ACTION, signal, action, oldAction); + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_kill(int pid, int signal){ + int ret = syscall(SYS_KILL, pid, signal); + if(ret < 0){ + return -ret; + } + + return 0; +} + +}
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/generic/sockets.cpp b/lib/mlibc/sysdeps/lemon/generic/sockets.cpp new file mode 100755 index 0000000..7244218 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/sockets.cpp @@ -0,0 +1,132 @@ +#include <lemon/syscall.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> + +#include <mlibc/all-sysdeps.hpp> + +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 domain, int type, int protocol, int *fd){ + long ret = syscall(SYS_SOCKET, domain, type, protocol); + + if(ret < 0){ + return -ret; + } + + *fd = ret; + + return 0; +} + +int sys_bind(int sockfd, const struct sockaddr *addr_ptr, socklen_t addrlen){ + return syscall(SYS_BIND, sockfd, addr_ptr, addrlen); +} + +int sys_connect(int sockfd, const struct sockaddr *addr_ptr, socklen_t addrlen){ + return syscall(SYS_CONNECT, sockfd, addr_ptr, addrlen); +} + +int sys_accept(int fd, int *newfd, struct sockaddr *addr_ptr, socklen_t *addr_length, int flags){ + long ret = syscall(SYS_ACCEPT, fd); + + if(ret < 0){ + return -ret; + } + + *newfd = ret; + + 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_listen(int fd, int backlog){ + return syscall(SYS_LISTEN, fd, backlog); +} + +int sys_msg_recv(int sockfd, struct msghdr *hdr, int flags, ssize_t *length){ + long ret = syscall(SYS_RECVMSG, sockfd, hdr, flags); + + if(ret < 0){ + return -ret; + } + + *length = ret; + + return 0; +} + +int sys_msg_send(int sockfd, const struct msghdr *hdr, int flags, ssize_t *length){ + long ret = syscall(SYS_SENDMSG, sockfd, hdr, flags); + + if(ret < 0){ + return -ret; + } + + *length = ret; + + return 0; +} + +int sys_setsockopt(int fd, int layer, int number, const void *buffer, socklen_t size){ + long ret = syscall(SYS_SET_SOCKET_OPTIONS, fd, layer, number, buffer, size); + + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_getsockopt(int fd, int layer, int number, void *__restrict buffer, socklen_t *__restrict size){ + long ret = syscall(SYS_GET_SOCKET_OPTIONS, fd, layer, number, buffer, size); + + if(ret < 0){ + return -ret; + } + + return 0; +} + +int sys_socketpair(int domain, int type_and_flags, int proto, int *fds){ + return -syscall(SYS_SOCKETPAIR, domain, type_and_flags, proto, fds); +} + +int sys_sockname(int fd, struct sockaddr *addr_ptr, socklen_t max_addr_length, + socklen_t *actual_length) { + return -syscall(SYS_SOCKNAME, fd, addr_ptr, max_addr_length); +} + +int sys_peername(int fd, struct sockaddr *addr_ptr, socklen_t max_addr_length, + socklen_t *actual_length) { + return -syscall(SYS_PEERNAME, fd, addr_ptr, max_addr_length); +} + +} diff --git a/lib/mlibc/sysdeps/lemon/generic/thread.cpp b/lib/mlibc/sysdeps/lemon/generic/thread.cpp new file mode 100644 index 0000000..42cd758 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/thread.cpp @@ -0,0 +1,53 @@ +#include <mlibc/thread-entry.hpp> +#include <mlibc/all-sysdeps.hpp> +#include <mlibc/tcb.hpp> +#include <bits/ensure.h> +#include <sys/mman.h> +#include <stdint.h> +#include <stddef.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 = 0x200000; + +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/lemon/generic/thread_entry.S b/lib/mlibc/sysdeps/lemon/generic/thread_entry.S new file mode 100644 index 0000000..51e703b --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/generic/thread_entry.S @@ -0,0 +1,11 @@ + +.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/lemon/include/abi-bits/access.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/access.h new file mode 120000 index 0000000..171f75f --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/access.h @@ -0,0 +1 @@ +../../../../abis/mlibc/access.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/auxv.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/auxv.h new file mode 120000 index 0000000..0f14415 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/auxv.h @@ -0,0 +1 @@ +../../../../abis/lemon/auxv.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/blkcnt_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/blkcnt_t.h new file mode 120000 index 0000000..e9d9f1b --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/blksize_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/blksize_t.h new file mode 120000 index 0000000..c6dfb6e --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/clockid_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/clockid_t.h new file mode 120000 index 0000000..71f37bb --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/dev_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/dev_t.h new file mode 120000 index 0000000..0c1143b --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/epoll.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/epoll.h new file mode 120000 index 0000000..9efc3a0 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/epoll.h @@ -0,0 +1 @@ +../../../../abis/mlibc/epoll.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/errno.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/errno.h new file mode 120000 index 0000000..589859f --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/errno.h @@ -0,0 +1 @@ +../../../../abis/mlibc/errno.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/fcntl.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/fcntl.h new file mode 120000 index 0000000..ea5323a --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/fcntl.h @@ -0,0 +1 @@ +../../../../abis/mlibc/fcntl.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/fsblkcnt_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/fsblkcnt_t.h new file mode 120000 index 0000000..898dfb2 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/fsfilcnt_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/fsfilcnt_t.h new file mode 120000 index 0000000..791755c --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/gid_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/gid_t.h new file mode 120000 index 0000000..6a77218 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/in.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/in.h new file mode 120000 index 0000000..b58c683 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/in.h @@ -0,0 +1 @@ +../../../../abis/mlibc/in.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/ino_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/ino_t.h new file mode 120000 index 0000000..10d644e --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/inotify.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/inotify.h new file mode 120000 index 0000000..3f19ef6 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/inotify.h @@ -0,0 +1 @@ +../../../../abis/mlibc/inotify.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/ioctls.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/ioctls.h new file mode 120000 index 0000000..595106b --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/ioctls.h @@ -0,0 +1 @@ +../../../../abis/linux/ioctls.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/limits.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/limits.h new file mode 120000 index 0000000..1aa5894 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/limits.h @@ -0,0 +1 @@ +../../../../abis/mlibc/limits.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/mode_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/mode_t.h new file mode 120000 index 0000000..29d7733 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/mqueue.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/mqueue.h new file mode 120000 index 0000000..fa87b07 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/mqueue.h @@ -0,0 +1 @@ +../../../../abis/linux/mqueue.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/msg.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/msg.h new file mode 120000 index 0000000..f402b49 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/msg.h @@ -0,0 +1 @@ +../../../../abis/linux/msg.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/nlink_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/nlink_t.h new file mode 120000 index 0000000..7618c27 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/packet.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/packet.h new file mode 120000 index 0000000..47067e2 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/packet.h @@ -0,0 +1 @@ +../../../../abis/mlibc/packet.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/pid_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/pid_t.h new file mode 120000 index 0000000..3fd26a7 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/poll.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/poll.h new file mode 120000 index 0000000..ab989c7 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/poll.h @@ -0,0 +1 @@ +../../../../abis/mlibc/poll.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/ptrace.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/ptrace.h new file mode 120000 index 0000000..f391fb7 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/ptrace.h @@ -0,0 +1 @@ +../../../../abis/mlibc/ptrace.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/reboot.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/reboot.h new file mode 120000 index 0000000..77013a4 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/reboot.h @@ -0,0 +1 @@ +../../../../abis/linux/reboot.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/resource.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/resource.h new file mode 120000 index 0000000..3e59c75 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/resource.h @@ -0,0 +1 @@ +../../../../abis/mlibc/resource.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/seek-whence.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/seek-whence.h new file mode 120000 index 0000000..df7bccf --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/seek-whence.h @@ -0,0 +1 @@ +../../../../abis/linux/seek-whence.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/shm.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/shm.h new file mode 120000 index 0000000..067d8c4 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/shm.h @@ -0,0 +1 @@ +../../../../abis/linux/shm.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/signal.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/signal.h new file mode 120000 index 0000000..4dcb0b7 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/signal.h @@ -0,0 +1 @@ +../../../../abis/linux/signal.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/socket.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/socket.h new file mode 120000 index 0000000..f1dc016 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/socket.h @@ -0,0 +1 @@ +../../../../abis/linux/socket.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/socklen_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/socklen_t.h new file mode 120000 index 0000000..41f3b11 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/stat.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/stat.h new file mode 120000 index 0000000..82642c3 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/stat.h @@ -0,0 +1 @@ +../../../../abis/mlibc/stat.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/statfs.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/statfs.h new file mode 120000 index 0000000..e3d202f --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/statfs.h @@ -0,0 +1 @@ +../../../../abis/linux/statfs.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/statvfs.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/statvfs.h new file mode 120000 index 0000000..1fc80c2 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/statvfs.h @@ -0,0 +1 @@ +../../../../abis/linux/statvfs.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/suseconds_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/suseconds_t.h new file mode 120000 index 0000000..9ed6597 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/termios.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/termios.h new file mode 120000 index 0000000..ee8f0b0 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/termios.h @@ -0,0 +1 @@ +../../../../abis/linux/termios.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/time.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/time.h new file mode 120000 index 0000000..97f3d52 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/time.h @@ -0,0 +1 @@ +../../../../abis/mlibc/time.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/uid_t.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/uid_t.h new file mode 120000 index 0000000..1113eba --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/utsname.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/utsname.h new file mode 120000 index 0000000..17b993f --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/utsname.h @@ -0,0 +1 @@ +../../../../abis/mlibc/utsname.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/vm-flags.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/vm-flags.h new file mode 120000 index 0000000..f1a985e --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/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/lemon/include/abi-bits/wait.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/wait.h new file mode 120000 index 0000000..feb2840 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/wait.h @@ -0,0 +1 @@ +../../../../abis/linux/wait.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/abi-bits/xattr.h b/lib/mlibc/sysdeps/lemon/include/abi-bits/xattr.h new file mode 120000 index 0000000..66412d7 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/abi-bits/xattr.h @@ -0,0 +1 @@ +../../../../abis/linux/xattr.h
\ No newline at end of file diff --git a/lib/mlibc/sysdeps/lemon/include/lemon/syscall.h b/lib/mlibc/sysdeps/lemon/include/lemon/syscall.h new file mode 100755 index 0000000..98db45d --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/lemon/syscall.h @@ -0,0 +1,194 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +#include <stdint.h> + +#define SYS_EXIT 1 +#define SYS_EXEC 2 +#define SYS_READ 3 +#define SYS_WRITE 4 +#define SYS_OPEN 5 +#define SYS_CLOSE 6 +#define SYS_SLEEP 7 +#define SYS_CREATE 8 +#define SYS_LINK 9 +#define SYS_UNLINK 10 +#define SYS_EXECVE 11 +#define SYS_CHDIR 12 +#define SYS_TIME 13 +#define SYS_MAP_FB 14 +#define SYS_GETTID 15 +#define SYS_CHMOD 16 +#define SYS_FSTAT 17 +#define SYS_STAT 18 +#define SYS_LSEEK 19 +#define SYS_GETPID 20 +#define SYS_MOUNT 21 +#define SYS_MKDIR 22 +#define SYS_RMDIR 23 +#define SYS_RENAME 24 +#define SYS_YIELD 25 +#define SYS_READDIR_NEXT 26 +#define SYS_SEND_MESSAGE 28 +#define SYS_RECEIVE_MESSAGE 29 +#define SYS_UPTIME 30 +#define SYS_GET_VIDEO_MODE 31 +#define SYS_UNAME 32 +#define SYS_READDIR 33 +#define SYS_SET_FS_BASE 34 +#define SYS_MMAP 35 +#define SYS_GET_CWD 37 +#define SYS_WAIT_PID 38 +#define SYS_NANO_SLEEP 39 +#define SYS_PREAD 40 +#define SYS_PWRITE 41 +#define SYS_IOCTL 42 +#define SYS_INFO 43 +#define SYS_MUNMAP 44 +#define SYS_CREATE_SHARED_MEMORY 45 +#define SYS_MAP_SHARED_MEMORY 46 +#define SYS_UNMAP_SHARED_MEMORY 47 +#define SYS_DESTROY_SHARED_MEMORY 48 +#define SYS_SOCKET 49 +#define SYS_BIND 50 +#define SYS_LISTEN 51 +#define SYS_ACCEPT 52 +#define SYS_CONNECT 53 +#define SYS_SEND 54 +#define SYS_SENDTO 55 +#define SYS_RECEIVE 56 +#define SYS_RECEIVEFROM 57 +#define SYS_GETUID 58 +#define SYS_SETUID 59 +#define SYS_POLL 60 +#define SYS_SENDMSG 61 +#define SYS_RECVMSG 62 +#define SYS_GETEUID 63 +#define SYS_SETEUID 64 +#define SYS_GET_PROCESS_INFO 65 +#define SYS_GET_NEXT_PROCESS_INFO 66 +#define SYS_READLINK 67 +#define SYS_SPAWN_THREAD 68 +#define SYS_EXIT_THREAD 69 +#define SYS_FUTEX_WAKE 70 +#define SYS_FUTEX_WAIT 71 +#define SYS_DUP 72 +#define SYS_GET_FILE_STATUS_FLAGS 73 +#define SYS_SET_FILE_STATUS_FLAGS 74 +#define SYS_SELECT 75 +#define SYS_CREATE_SERVICE 76 +#define SYS_CREATE_INTERFACE 77 +#define SYS_INTERFACE_ACCEPT 78 +#define SYS_INTERFACE_CONNECT 79 +#define SYS_ENDPOINT_QUEUE 80 +#define SYS_ENDPOINT_DEQUEUE 81 +#define SYS_ENDPOINT_CALL 82 +#define SYS_ENDPOINT_INFO 83 +#define SYS_KERNELOBJECT_WAIT_ONE 84 +#define SYS_KERNELOBJECT_WAIT 85 +#define SYS_KERNELOBJECT_DESTROY 86 +#define SYS_SET_SOCKET_OPTIONS 87 +#define SYS_GET_SOCKET_OPTIONS 88 +#define SYS_DEVICE_MANAGEMENT 89 +#define SYS_INTERRUPT_THREAD 90 +#define SYS_LOAD_KERNEL_MODULE 91 +#define SYS_UNLOAD_KERNEL_MODULE 92 +#define SYS_FORK 93 +#define SYS_GETGID 94 +#define SYS_GETEGID 95 +#define SYS_GETPPID 96 +#define SYS_PIPE 97 +#define SYS_GETENTROPY 98 +#define SYS_SOCKETPAIR 99 +#define SYS_PEERNAME 100 +#define SYS_SOCKNAME 101 +#define SYS_SIGNAL_ACTION 102 +#define SYS_SIGPROCMASK 103 +#define SYS_KILL 104 +#define SYS_SIGNAL_RETURN 105 +#define SYS_ALARM 106 +#define SYS_GET_RESOURCE_LIMIT 107 +#define SYS_EPOLL_CREATE 108 +#define SYS_EPOLL_CTL 109 +#define SYS_EPOLL_WAIT 110 +#define SYS_FCHDIR 111 + +#ifdef __cplusplus +extern "C"{ +#endif + +__attribute__((__always_inline__)) +static inline long syscalln0(uint64_t call) { + volatile long ret; + asm volatile("int $0x69" : "=a"(ret) : "a"(call)); + return ret; +} + +__attribute__((__always_inline__)) +static long syscalln1(uint64_t call, uint64_t arg0) { + volatile long ret; + asm volatile("int $0x69" : "=a"(ret) : "a"(call), "D"(arg0) : "memory"); + return ret; +} + +__attribute__((__always_inline__)) +static long syscalln2(uint64_t call, uint64_t arg0, uint64_t arg1) { + volatile long ret; + asm volatile("int $0x69" : "=a"(ret) : "a"(call), "D"(arg0), "S"(arg1) : "memory"); + return ret; +} + +__attribute__((__always_inline__)) +static long syscalln3(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2) { + volatile long ret; + asm volatile("int $0x69" : "=a"(ret) : "a"(call), "D"(arg0), "S"(arg1), "d"(arg2) : "memory"); + return ret; +} + +__attribute__((__always_inline__)) +static long syscalln4(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3) { + volatile long ret; + register uint64_t arg3r asm("r10") = arg3; // put arg3 in r10 + asm volatile("int $0x69" : "=a"(ret) : "a"(call), "D"(arg0), "S"(arg1), "d"(arg2), "r"(arg3r) : "memory"); + return ret; +} + +__attribute__((__always_inline__)) +static long syscalln5(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) { + volatile long ret; + register uint64_t arg3r asm("r10") = arg3; // put arg3 in r10 + register uint64_t arg4r asm("r9") = arg4; // put arg4 in r9 + asm volatile("int $0x69" : "=a"(ret) : "a"(call), "D"(arg0), "S"(arg1), "d"(arg2), "r"(arg3r), "r"(arg4r) : "memory"); + return ret; +} + +__attribute__((__always_inline__)) +static long syscalln6(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) { + volatile long ret; + register uint64_t arg3r asm("r10") = arg3; // put arg3 in r10 + register uint64_t arg4r asm("r9") = arg4; // put arg4 in r9 + register uint64_t arg5r asm("r8") = arg5; // put arg5 in r8 + asm volatile("int $0x69" : "=a"(ret) : "a"(call), "D"(arg0), "S"(arg1), "d"(arg2), "r"(arg3r), "r"(arg4r), "r"(arg5r) : "memory"); + return ret; +} + +#ifdef __cplusplus +} + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call) { return syscalln0(call); } + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call, uint64_t arg0) { return syscalln1(call, arg0); } + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call, uint64_t arg0, uint64_t arg1) { return syscalln2(call, arg0, arg1); } + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2) { return syscalln3(call, arg0, arg1, arg2); } + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3) { return syscalln4(call, arg0, arg1, arg2, arg3); } + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) { return syscalln5(call, arg0, arg1, arg2, arg3, arg4); } + __attribute__((__always_inline__)) static inline long _syscall(uint64_t call, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) { return syscalln6(call, arg0, arg1, arg2, arg3, arg4, arg5); } + + template<typename... T> + __attribute__((__always_inline__)) static inline long syscall(uint64_t call, T... args){ + return _syscall(call, (uint64_t)(args)...); + } +#else + #define GET_SYSCALL(a0, a1, a2, a3, a4, a5, a6, name, ...) name + #define syscall(...) GET_SYSCALL(__VA_ARGS__, syscalln6, syscalln5, syscalln4, syscalln3, syscalln2, syscalln1, syscalln0)(__VA_ARGS__) +#endif + +#endif diff --git a/lib/mlibc/sysdeps/lemon/include/mlibc/thread-entry.hpp b/lib/mlibc/sysdeps/lemon/include/mlibc/thread-entry.hpp new file mode 100644 index 0000000..2dd88a6 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/include/mlibc/thread-entry.hpp @@ -0,0 +1,10 @@ +#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 { + void *prepare_stack(void *entry, void *user_arg, void *tcb); +} diff --git a/lib/mlibc/sysdeps/lemon/meson.build b/lib/mlibc/sysdeps/lemon/meson.build new file mode 100644 index 0000000..8704b71 --- /dev/null +++ b/lib/mlibc/sysdeps/lemon/meson.build @@ -0,0 +1,81 @@ + +rtdl_sources += files( + 'generic/filesystem.cpp', + 'generic/lemon.cpp', +) + +libc_sources += files( + 'generic/entry.cpp', + 'generic/filesystem.cpp', + 'generic/lemon.cpp', + 'generic/pty.cpp', + 'generic/signals.cpp', + 'generic/sockets.cpp', + 'generic/thread_entry.S', + 'generic/thread.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/lemon/syscall.h', + subdir: 'lemon' + ) +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 + |