mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
1052 lines
29 KiB
Diff
1052 lines
29 KiB
Diff
diff --git mlibc-clean/abis/linux/in.h mlibc-workdir/abis/linux/in.h
|
|
index eb7be7b..eb83b56 100644
|
|
--- mlibc-clean/abis/linux/in.h
|
|
+++ mlibc-workdir/abis/linux/in.h
|
|
@@ -109,6 +109,9 @@ struct group_source_req {
|
|
|
|
#define IPPORT_RESERVED 1024
|
|
|
|
+#define IP_MULTICAST_TTL 33
|
|
+#define IPV6_MULTICAST_HOPS 18
|
|
+
|
|
#define IPPROTO_IP 0
|
|
#define IPPROTO_HOPOPTS 0
|
|
#define IPPROTO_ICMP 1
|
|
diff --git mlibc-clean/meson.build mlibc-workdir/meson.build
|
|
index 471604e..3c5bea0 100644
|
|
--- mlibc-clean/meson.build
|
|
+++ mlibc-workdir/meson.build
|
|
@@ -248,6 +248,12 @@ elif host_machine.system() == 'dripos'
|
|
rtld_include_dirs += include_directories('sysdeps/dripos/include')
|
|
libc_include_dirs += include_directories('sysdeps/dripos/include')
|
|
subdir('sysdeps/dripos')
|
|
+elif host_machine.system() == 'astral'
|
|
+ rtld_include_dirs += include_directories('sysdeps/astral/include')
|
|
+ libc_include_dirs += include_directories('sysdeps/astral/include')
|
|
+ internal_conf.set10('MLIBC_MAP_DSO_SEGMENTS', true)
|
|
+ internal_conf.set10('MLIBC_MAP_FILE_WINDOWS', true)
|
|
+ subdir('sysdeps/astral')
|
|
else
|
|
error('No sysdeps defined for OS: ' + host_machine.system())
|
|
endif
|
|
diff --git mlibc-clean/options/ansi/generic/string-stubs.cpp mlibc-workdir/options/ansi/generic/string-stubs.cpp
|
|
index 8defd0e..d6cb65b 100644
|
|
--- mlibc-clean/options/ansi/generic/string-stubs.cpp
|
|
+++ mlibc-workdir/options/ansi/generic/string-stubs.cpp
|
|
@@ -406,7 +406,6 @@ char *strerror(int e) {
|
|
case ENOPROTOOPT: s = "Protocol not available (ENOPROTOOPT)"; break;
|
|
case ENOTEMPTY: s = "Directory not empty (ENOTEMPTY)"; break;
|
|
case ENOTRECOVERABLE: s = "Sate not recoverable (ENOTRECOVERABLE)"; break;
|
|
- case ENOTSUP: s = "Operation not supported (ENOTSUP)"; break;
|
|
case ENOTTY: s = "Inappropriate ioctl for device (ENOTTY)"; break;
|
|
case EOVERFLOW: s = "Value too large for defined datatype (EOVERFLOW)"; break;
|
|
#if EOPNOTSUPP != ENOTSUP
|
|
diff --git mlibc-clean/options/glibc/generic/execinfo.cpp mlibc-workdir/options/glibc/generic/execinfo.cpp
|
|
index 3474615..e034881 100644
|
|
--- mlibc-clean/options/glibc/generic/execinfo.cpp
|
|
+++ mlibc-workdir/options/glibc/generic/execinfo.cpp
|
|
@@ -1,9 +1,10 @@
|
|
#include <execinfo.h>
|
|
#include <bits/ensure.h>
|
|
+#include <mlibc/debug.hpp>
|
|
|
|
int backtrace(void **, int) {
|
|
- __ensure(!"Not implemented");
|
|
- __builtin_unreachable();
|
|
+ mlibc::infoLogger() << "libc: backtrace() is not implemented!\n" << frg::endlog;
|
|
+ return 0;
|
|
}
|
|
|
|
char **backtrace_symbols(void *const *, int) {
|
|
diff --git mlibc-clean/options/linux/include/bits/linux/linux_stat.h mlibc-workdir/options/linux/include/bits/linux/linux_stat.h
|
|
index 59009c9..170d4a1 100644
|
|
--- mlibc-clean/options/linux/include/bits/linux/linux_stat.h
|
|
+++ mlibc-workdir/options/linux/include/bits/linux/linux_stat.h
|
|
@@ -9,7 +9,7 @@ extern "C" {
|
|
|
|
#ifndef __MLIBC_ABI_ONLY
|
|
|
|
-int statx(int, const char *, int, unsigned int, struct statx *);
|
|
+//int statx(int, const char *, int, unsigned int, struct statx *);
|
|
|
|
#endif /* !__MLIBC_ABI_ONLY */
|
|
|
|
diff --git mlibc-clean/options/posix/generic/dlfcn-stubs.cpp mlibc-workdir/options/posix/generic/dlfcn-stubs.cpp
|
|
index fc34a3b..b1a95a9 100644
|
|
--- mlibc-clean/options/posix/generic/dlfcn-stubs.cpp
|
|
+++ mlibc-workdir/options/posix/generic/dlfcn-stubs.cpp
|
|
@@ -1,4 +1,4 @@
|
|
-
|
|
+#define _GNU_SOURCE
|
|
#include <bits/ensure.h>
|
|
#include <dlfcn.h>
|
|
|
|
diff --git mlibc-clean/options/posix/generic/unistd-stubs.cpp mlibc-workdir/options/posix/generic/unistd-stubs.cpp
|
|
index 3279cc6..71837aa 100644
|
|
--- mlibc-clean/options/posix/generic/unistd-stubs.cpp
|
|
+++ mlibc-workdir/options/posix/generic/unistd-stubs.cpp
|
|
@@ -1222,6 +1222,7 @@ void encrypt(char[64], int) {
|
|
}
|
|
#endif
|
|
|
|
+#if 0
|
|
#if __MLIBC_BSD_OPTION
|
|
void *sbrk(intptr_t increment) {
|
|
if(increment) {
|
|
@@ -1238,3 +1239,4 @@ void *sbrk(intptr_t increment) {
|
|
return out;
|
|
}
|
|
#endif
|
|
+#endif
|
|
diff --git mlibc-clean/options/rtld/generic/main.cpp mlibc-workdir/options/rtld/generic/main.cpp
|
|
index 360ed37..62e5d39 100644
|
|
--- mlibc-clean/options/rtld/generic/main.cpp
|
|
+++ mlibc-workdir/options/rtld/generic/main.cpp
|
|
@@ -17,6 +17,8 @@
|
|
#include "elf.hpp"
|
|
#include "linker.hpp"
|
|
|
|
+#define _GNU_SOURCE
|
|
+
|
|
#if __MLIBC_POSIX_OPTION
|
|
#include <dlfcn.h>
|
|
#endif
|
|
diff --git mlibc-workdir/sysdeps/astral/crt-x86_64/crt0.S mlibc-workdir/sysdeps/astral/crt-x86_64/crt0.S
|
|
new file mode 100644
|
|
index 0000000..0a0a4a0
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/crt-x86_64/crt0.S
|
|
@@ -0,0 +1,7 @@
|
|
+
|
|
+.section .text
|
|
+.global _start
|
|
+_start:
|
|
+ mov $main, %rdi
|
|
+ call __mlibc_entry
|
|
+
|
|
diff --git mlibc-workdir/sysdeps/astral/generic/astral.cpp mlibc-workdir/sysdeps/astral/generic/astral.cpp
|
|
new file mode 100644
|
|
index 0000000..f1edacc
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/generic/astral.cpp
|
|
@@ -0,0 +1,17 @@
|
|
+#include <astral/archctl.h>
|
|
+#include <errno.h>
|
|
+
|
|
+#define ARCH_CTL_GSBASE 0
|
|
+#define ARCH_CTL_FSBASE 1
|
|
+
|
|
+#ifndef MLIBC_BUILDING_RTLD
|
|
+
|
|
+int syscall_archctl(int func, void *arg) {
|
|
+ long ret;
|
|
+ long error = syscall(SYSCALL_ARCHCTL, &ret, func, (uint64_t)arg);
|
|
+ if (error)
|
|
+ errno = error;
|
|
+ return error ? -1 : ret;
|
|
+}
|
|
+
|
|
+#endif
|
|
diff --git mlibc-workdir/sysdeps/astral/generic/entry.cpp mlibc-workdir/sysdeps/astral/generic/entry.cpp
|
|
new file mode 100644
|
|
index 0000000..e5b087a
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/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[])) {
|
|
+ auto result = main_fn(__mlibc_stack_data.argc, __mlibc_stack_data.argv, environ);
|
|
+ exit(result);
|
|
+}
|
|
+
|
|
diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
|
new file mode 100644
|
|
index 0000000..40e434f
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
|
@@ -0,0 +1,599 @@
|
|
+#include <bits/ensure.h>
|
|
+#include <mlibc/debug.hpp>
|
|
+#include <mlibc/all-sysdeps.hpp>
|
|
+#include <errno.h>
|
|
+#include <astral/syscall.h>
|
|
+#include <astral/archctl.h>
|
|
+#include <string.h>
|
|
+#include <stdlib.h>
|
|
+#include <asm/ioctls.h>
|
|
+#include <poll.h>
|
|
+#include <sys/select.h>
|
|
+
|
|
+#ifndef MLIBC_BUILDING_RTLD
|
|
+// (s)brk is emulated in the libc rather than being
|
|
+// an actual system call.
|
|
+#define SBRK_BUFFER_SIZE (1024 * 1024 * 16)
|
|
+static void *sbrkbuffer;
|
|
+static off_t sbrkoffset;
|
|
+
|
|
+extern "C" void *sbrk(intptr_t increment) {
|
|
+ // allocate the buffer if its the first time sbrk is called
|
|
+ if (sbrkbuffer == NULL) {
|
|
+ int e = mlibc::sys_vm_map(NULL, SBRK_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0, &sbrkbuffer);
|
|
+ if (e) {
|
|
+ errno = e;
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (increment == 0)
|
|
+ return sbrkbuffer;
|
|
+
|
|
+ off_t newoffset = sbrkoffset + increment;
|
|
+ if (newoffset < 0) {
|
|
+ // offset goes below what we allocated, this is bad
|
|
+ errno = EINVAL;
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (newoffset >= SBRK_BUFFER_SIZE) {
|
|
+ // new offset goes past what was allocated
|
|
+ errno = ENOMEM;
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ void *ret = (void *)((uintptr_t)sbrkbuffer + increment);
|
|
+ sbrkoffset = newoffset;
|
|
+ return ret;
|
|
+}
|
|
+#endif
|
|
+
|
|
+namespace mlibc {
|
|
+
|
|
+ int sys_setuid(uid_t id) {
|
|
+ // TODO UNSTUB
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_setgid(gid_t id) {
|
|
+ // TODO UNSTUB
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ uid_t sys_getuid() {
|
|
+ // TODO UNSTUB
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ gid_t sys_getgid() {
|
|
+ // TODO UNSTUB
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ uid_t sys_geteuid() {
|
|
+ // TODO UNSTUB
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ gid_t sys_getegid() {
|
|
+ // TODO UNSTUB
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ pid_t sys_getppid() {
|
|
+ // TODO UNSTUB
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ int sys_getpgid(pid_t pid, pid_t *pgid) {
|
|
+ // TODO UNSTUB
|
|
+ *pgid = 1;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ #define ASTRALHOSTNAME "astral"
|
|
+
|
|
+ int sys_gethostname(char *buffer, size_t bufsize) {
|
|
+ // TODO unstub
|
|
+ memcpy(buffer, ASTRALHOSTNAME, strlen(ASTRALHOSTNAME));
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_uname(struct utsname *buf) {
|
|
+ // TODO unstub
|
|
+ memcpy(buf->sysname, "Astral", 7);
|
|
+ memcpy(buf->nodename, ASTRALHOSTNAME, strlen(ASTRALHOSTNAME)+1);
|
|
+ memcpy(buf->version, "rw-0.0.1", 9);
|
|
+ memcpy(buf->release, "Astral", 13);
|
|
+ memcpy(buf->machine, "x86_64", 7);
|
|
+ memcpy(buf->domainname, ASTRALHOSTNAME, strlen(ASTRALHOSTNAME)+1);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_fsync(int fd) {
|
|
+ // TODO as the VFS does not do caching as of yet, this system call is stubbed and should be implemented once caching is done
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) {
|
|
+ // TODO unstub
|
|
+ return ENOSYS;
|
|
+ }
|
|
+
|
|
+ int sys_sigprocmask(int how, const sigset_t *__restrict set,
|
|
+ sigset_t *__restrict retrieve) {
|
|
+ mlibc::infoLogger() << "mlibc: sigprocmask is a stub" << frg::endlog;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_sigaction(int, const struct sigaction *__restrict,
|
|
+ struct sigaction *__restrict) {
|
|
+ mlibc::infoLogger() << "mlibc: sigaction is a stub" << frg::endlog;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_futex_tid() {
|
|
+ long ret;
|
|
+ syscall(SYSCALL_GETTID, &ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ #ifndef MLIBC_BUILDING_RTLD
|
|
+
|
|
+ [[noreturn]] void sys_thread_exit() {
|
|
+ syscall(SYSCALL_THREADEXIT, nullptr);
|
|
+ }
|
|
+
|
|
+ extern "C" void __mlibc_thread_entry();
|
|
+
|
|
+ int sys_clone(void *tcb, pid_t *pid_out, void *stack) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_NEWTHREAD, &ret, (uintptr_t)__mlibc_thread_entry, (uintptr_t)stack);
|
|
+ *pid_out = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ #endif
|
|
+
|
|
+ int sys_listen(int fd, int backlog) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_LISTEN, &ret, fd, backlog);
|
|
+ }
|
|
+
|
|
+ int sys_accept(int fd, int *newfd, struct sockaddr *addr_ptr, socklen_t *addr_length, int flags) {
|
|
+ long ret;
|
|
+ long error = syscall(SYSCALL_ACCEPT, &ret, fd, (uint64_t)addr_ptr, (uint64_t)addr_length, flags);
|
|
+ *newfd = ret;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_connect(int fd, const struct sockaddr *addr_ptr, socklen_t addr_length) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_CONNECT, &ret, fd, (uint64_t)addr_ptr, addr_length);
|
|
+ }
|
|
+
|
|
+ int sys_msg_recv(int fd, struct msghdr *hdr, int flags, ssize_t *length) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_RECVMSG, &ret, fd, (uint64_t)hdr, flags);
|
|
+ *length = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_setsockopt(int fd, int layer, int number, const void *buffer, socklen_t size) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_SETSOCKOPT, &ret, fd, layer, number, (uint64_t)buffer, size);
|
|
+ }
|
|
+
|
|
+ int sys_msg_send(int fd, const struct msghdr *hdr, int flags, ssize_t *length) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_SENDMSG, &ret, fd, (uint64_t)hdr, flags);
|
|
+ *length = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_bind(int fd, const struct sockaddr *addr_ptr, socklen_t addr_length) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_BIND, &ret, fd, (uint64_t)addr_ptr, addr_length);
|
|
+ }
|
|
+
|
|
+ int sys_socket(int family, int type, int protocol, int *fd) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_SOCKET, &ret, family, type, protocol);
|
|
+ *fd = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_RENAMEAT, &ret, olddirfd, (uint64_t)old_path, newdirfd, (uint64_t)new_path);
|
|
+ }
|
|
+
|
|
+ int sys_rename(const char *path, const char *new_path) {
|
|
+ return sys_renameat(AT_FDCWD, path, AT_FDCWD, new_path);
|
|
+ }
|
|
+
|
|
+ int sys_utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_UTIMENSAT, &ret, dirfd, (uint64_t)pathname, (uint64_t)times, flags);
|
|
+ }
|
|
+
|
|
+ int sys_fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FCHOWNAT, &ret, dirfd, (uint64_t)pathname, owner, group, flags);
|
|
+ }
|
|
+
|
|
+ int sys_mount(const char *source, const char *target, const char *fstype, unsigned long flags, const void *data) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_MOUNT, &ret, (uint64_t)source, (uint64_t)target, (uint64_t)fstype, flags, (uint64_t)data);
|
|
+ }
|
|
+
|
|
+ int sys_ftruncate(int fd, size_t size) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FTRUNCATE, &ret, fd, size);
|
|
+ }
|
|
+
|
|
+ int sys_sleep(time_t *secs, long *nanos) {
|
|
+ struct timespec ts;
|
|
+ ts.tv_sec = *secs;
|
|
+ ts.tv_nsec = *nanos;
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_NANOSLEEP, &ret, (uintptr_t)&ts, (uintptr_t)&ts);
|
|
+ *secs = ts.tv_sec;
|
|
+ *nanos = ts.tv_nsec;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_tcgetattr(int fd, struct termios *attr){
|
|
+ int res;
|
|
+ return sys_ioctl(fd, TCGETS, (void *)attr, &res);
|
|
+ }
|
|
+
|
|
+ int sys_tcsetattr(int fd, int act, const struct termios *attr){
|
|
+ int res;
|
|
+ return sys_ioctl(fd, TCSETS, (void *)attr, &res);
|
|
+ }
|
|
+
|
|
+ int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events) {
|
|
+ long ret;
|
|
+ long error = syscall(SYSCALL_POLL, &ret, (uint64_t)fds, count, timeout);
|
|
+ *num_events = ret;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+// XXX emulate with ppoll
|
|
+#ifndef MLIBC_BUILDING_RTLD
|
|
+ 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) {
|
|
+ pollfd *fds = (pollfd *)malloc(num_fds * sizeof(pollfd));
|
|
+
|
|
+ if(fds == NULL)
|
|
+ return ENOMEM;
|
|
+
|
|
+ for (int fd = 0; fd < num_fds; ++fd) {
|
|
+ short events;
|
|
+ if (read_set && FD_ISSET(fd, read_set)) {
|
|
+ events |= POLLIN;
|
|
+ }
|
|
+
|
|
+ if (write_set && FD_ISSET(fd, write_set)) {
|
|
+ events |= POLLOUT;
|
|
+ }
|
|
+
|
|
+ if (except_set && FD_ISSET(fd, except_set)) {
|
|
+ events |= POLLPRI;
|
|
+ }
|
|
+
|
|
+ if (events) {
|
|
+ fds[fd].fd = fd;
|
|
+ fds[fd].events = events;
|
|
+ fds[fd].revents = 0;
|
|
+ } else {
|
|
+ fds[fd].fd = -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ int time = timeout == NULL ? -1 : timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
|
|
+
|
|
+ int err = sys_poll(fds, num_fds, time, num_events);
|
|
+
|
|
+ if (err) {
|
|
+ free(fds);
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ for (int fd = 0; fd < num_fds; ++fd) {
|
|
+ if (read_set && (fds[fd].revents & POLLIN) == 0)
|
|
+ FD_CLR(fd, read_set);
|
|
+
|
|
+ if (write_set && (fds[fd].revents & POLLOUT) == 0)
|
|
+ FD_CLR(fd, write_set);
|
|
+
|
|
+ if (except_set && (fds[fd].revents & POLLPRI) == 0)
|
|
+ FD_CLR(fd, except_set);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ int sys_umask(mode_t mode, mode_t *old) {
|
|
+ long ret;
|
|
+ long error = syscall(SYSCALL_UMASK, &ret, mode);
|
|
+ *old = ret;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_fchmod(int fd, mode_t mode) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FCHMOD, &ret, fd, mode);
|
|
+ }
|
|
+
|
|
+ int sys_fchmodat(int fd, const char *pathname, mode_t mode, int flags) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FCHMODAT, &ret, fd, (uint64_t)pathname, mode, flags);
|
|
+ }
|
|
+
|
|
+ int sys_chmod(const char *pathname, mode_t mode) {
|
|
+ return sys_fchmodat(AT_FDCWD, pathname, mode, 0);
|
|
+ }
|
|
+
|
|
+ int sys_readlinkat(int dirfd, const char *path, void *buffer, size_t max_size, ssize_t *length) {
|
|
+ long ret;
|
|
+ long error = syscall(SYSCALL_READLINKAT, &ret, dirfd, (uint64_t)path, (uint64_t)buffer, max_size);
|
|
+ *length = ret;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_readlink(const char *path, void *buffer, size_t max_size, ssize_t *length) {
|
|
+ return sys_readlinkat(AT_FDCWD, path, buffer, max_size, length);
|
|
+ }
|
|
+
|
|
+ static int dolink(int oldfd, const char *oldpath, int newfd, const char *newpath, int flags, int type) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_LINKAT, &ret, oldfd, (uint64_t)oldpath, newfd, (uint64_t)newpath, flags, type);
|
|
+ }
|
|
+
|
|
+ int sys_linkat(int olddirfd, const char *old_path, int newdirfd, const char *new_path, int flags) {
|
|
+ return dolink(olddirfd, old_path, newdirfd, new_path, flags, 0);
|
|
+ }
|
|
+
|
|
+ int sys_link(const char *old_path, const char *new_path) {
|
|
+ return sys_linkat(AT_FDCWD, old_path, AT_FDCWD, new_path, 0);
|
|
+ }
|
|
+
|
|
+ int sys_symlinkat(const char *target_path, int dirfd, const char *link_path) {
|
|
+ return dolink(AT_FDCWD, target_path, dirfd, link_path, 0, 1);
|
|
+ }
|
|
+
|
|
+ int sys_symlink(const char *target_path, const char *link_path) {
|
|
+ return sys_symlinkat(target_path, AT_FDCWD, link_path);
|
|
+ }
|
|
+
|
|
+ int sys_mkdirat(int dirfd, const char *path, mode_t mode) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_MKDIRAT, &ret, dirfd, (uint64_t)path, mode);
|
|
+ }
|
|
+
|
|
+ int sys_mkdir(const char *path, mode_t mode) {
|
|
+ return sys_mkdirat(AT_FDCWD, path, mode);
|
|
+ }
|
|
+
|
|
+ int sys_ioctl(int fd, unsigned long request, void *arg, int *result) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_IOCTL, &ret, fd, request, (uint64_t)arg);
|
|
+ *result = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_unlinkat(int fd, const char *path, int flags) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_UNLINKAT, &ret, fd, (uint64_t)path, flags);
|
|
+ }
|
|
+
|
|
+ int sys_faccessat(int dirfd, const char *pathname, int mode, int flags){
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FACCESSAT, &ret, dirfd, (uint64_t)pathname, mode, flags);
|
|
+ }
|
|
+
|
|
+ int sys_access(const char *path, int mode){
|
|
+ return sys_faccessat(AT_FDCWD, path, mode, 0);
|
|
+ }
|
|
+
|
|
+ int sys_pipe(int *fds, int flags) {
|
|
+ long ret = 0;
|
|
+ long err = syscall(SYSCALL_PIPE2, &ret, flags);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ fds[0] = ret & 0xffffffff;
|
|
+ fds[1] = (ret >> 32) & 0xffffffff;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_chdir(const char *path) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_CHDIR, &ret, (uint64_t)path);
|
|
+ }
|
|
+
|
|
+ int sys_fcntl(int fd, int request, va_list args, int *result) {
|
|
+ long arg = va_arg(args, uint64_t);
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_FCNTL, &ret, fd, request, arg);
|
|
+ *result = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_dup(int fd, int flags, int *newfd) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_DUP, &ret, fd);
|
|
+ *newfd = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_dup2(int fd, int flags, int newfd) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_DUP2, &ret, fd, newfd);
|
|
+ }
|
|
+
|
|
+ int sys_read_entries(int handle, void *buffer, size_t max_size, size_t *bytes_read) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_GETDENTS, &ret, handle, (uint64_t)buffer, max_size);
|
|
+ if (err)
|
|
+ return err;
|
|
+ *bytes_read = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_WAITPID, &ret, pid, (uint64_t)status, flags);
|
|
+ *ret_pid = ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_execve(const char *path, char *const argv[], char *const envp[]) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_EXECVE, &ret, (uint64_t)path, (uint64_t)argv, (uint64_t)envp);
|
|
+ }
|
|
+
|
|
+ int sys_fork(pid_t *pid) {
|
|
+ long ret = 0;
|
|
+ long error = syscall(SYSCALL_FORK, &ret);
|
|
+ *pid = ret;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, struct stat *statbuf) {
|
|
+ long ret;
|
|
+ switch (fsfdt) {
|
|
+ case fsfd_target::path:
|
|
+ return syscall(SYSCALL_FSTATAT, &ret, AT_FDCWD, (uint64_t)path, (uint64_t)statbuf, flags);
|
|
+ case fsfd_target::fd:
|
|
+ return syscall(SYSCALL_FSTAT, &ret, fd, (uint64_t)statbuf);
|
|
+ case fsfd_target::fd_path:
|
|
+ return syscall(SYSCALL_FSTATAT, &ret, fd, (uint64_t)path, (uint64_t)statbuf, flags);
|
|
+ default:
|
|
+ mlibc::infoLogger() << "mlibc: stat: Unknown fsfd_target: " << (int)fsfdt << frg::endlog;
|
|
+ return ENOSYS;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pid_t sys_getpid() {
|
|
+ long ret;
|
|
+ syscall(SYSCALL_GETPID, &ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ void sys_libc_log(const char *message) {
|
|
+ long ret;
|
|
+ syscall(SYSCALL_PRINT, &ret, (uint64_t)message);
|
|
+ }
|
|
+
|
|
+ [[noreturn]] void sys_libc_panic() {
|
|
+ sys_libc_log("mlibc: panic");
|
|
+ sys_exit(1);
|
|
+ }
|
|
+
|
|
+ [[noreturn]] void sys_exit(int status) {
|
|
+ syscall(SYSCALL_EXIT, NULL, status);
|
|
+ __builtin_unreachable();
|
|
+ }
|
|
+
|
|
+ int sys_tcb_set(void *pointer) {
|
|
+ long r;
|
|
+ return syscall(SYSCALL_ARCHCTL, &r, ARCH_CTL_FSBASE, (uint64_t)pointer);
|
|
+ }
|
|
+
|
|
+ #define FUTEX_WAIT 0
|
|
+ #define FUTEX_WAKE 1
|
|
+
|
|
+ int sys_futex_wait(int *pointer, int expected, const struct timespec *time) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FUTEX, &ret, (uint64_t)pointer, FUTEX_WAIT, expected, (uint64_t)time);
|
|
+ }
|
|
+
|
|
+ int sys_futex_wake(int *pointer) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_FUTEX, &ret, (uint64_t)pointer, FUTEX_WAKE, INT_MAX, NULL);
|
|
+ }
|
|
+
|
|
+ int sys_anon_allocate(size_t size, void **pointer) {
|
|
+ size += 4096 - (size % 4096);
|
|
+ return sys_vm_map(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0, pointer);
|
|
+ }
|
|
+ int sys_anon_free(void *pointer, size_t size) {
|
|
+ size += 4096 - (size % 4096);
|
|
+ return sys_vm_unmap(pointer, size);
|
|
+ }
|
|
+
|
|
+ int sys_openat(int dirfd, const char *path, int flags, mode_t mode, int *fd) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_OPENAT, &ret, dirfd, (uint64_t)path, flags, mode);
|
|
+ if (err)
|
|
+ return err;
|
|
+ *fd = ret;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_open(const char *pathname, int flags, mode_t mode, int *fd) {
|
|
+ return sys_openat(AT_FDCWD, pathname, flags, mode, fd);
|
|
+ };
|
|
+
|
|
+ int sys_open_dir(const char *path, int *handle) {
|
|
+ return sys_open(path, O_DIRECTORY, 0, handle);
|
|
+ }
|
|
+
|
|
+ int sys_read(int fd, void *buff, size_t count, ssize_t *bytes_read) {
|
|
+ long readc;
|
|
+ long error = syscall(SYSCALL_READ, &readc, fd, (uint64_t)buff, count);
|
|
+ *bytes_read = readc;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_write(int fd, const void *buff, size_t count, ssize_t *bytes_written) {
|
|
+ long writec;
|
|
+ long error = syscall(SYSCALL_WRITE, &writec, fd, (uint64_t)buff, count);
|
|
+ *bytes_written = writec;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) {
|
|
+ long ret = 0;
|
|
+ long error = syscall(SYSCALL_SEEK, &ret, fd, offset, whence);
|
|
+ *new_offset = ret;
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ int sys_close(int fd) {
|
|
+ long r;
|
|
+ return syscall(SYSCALL_CLOSE, &r, fd);
|
|
+ }
|
|
+
|
|
+ int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void **window) {
|
|
+ long ret;
|
|
+ long err = syscall(SYSCALL_MMAP, &ret, (uint64_t)hint, size, prot, flags, fd, offset);
|
|
+ *window = (void *)ret;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ int sys_vm_unmap(void *pointer, size_t size) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_MUNMAP, &ret, (uintptr_t)pointer, size);
|
|
+ }
|
|
+
|
|
+ int sys_isatty(int fd) {
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_ISATTY, &ret, fd);
|
|
+ }
|
|
+
|
|
+ int sys_clock_get(int clock, time_t *secs, long *nanos) {
|
|
+ struct timespec ts;
|
|
+ long ret;
|
|
+ int err = syscall(SYSCALL_CLOCKGET, &ret, clock, (uint64_t)&ts);
|
|
+ *secs = ts.tv_sec;
|
|
+ *nanos = ts.tv_nsec;
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+} // namespace mlibc
|
|
+
|
|
diff --git mlibc-workdir/sysdeps/astral/include/astral/archctl.h mlibc-workdir/sysdeps/astral/include/astral/archctl.h
|
|
new file mode 100644
|
|
index 0000000..990eca0
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/include/astral/archctl.h
|
|
@@ -0,0 +1,11 @@
|
|
+#ifndef _ASTRAL_SYSCALL_ARCHCTL_INCLUDE
|
|
+#define _ASTRAL_SYSCALL_ARCHCTL_INCLUDE
|
|
+
|
|
+#include <astral/syscall.h>
|
|
+
|
|
+#define ARCH_CTL_GSBASE 0
|
|
+#define ARCH_CTL_FSBASE 1
|
|
+
|
|
+int arch_ctl(int func, void *arg);
|
|
+
|
|
+#endif
|
|
diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
|
new file mode 100644
|
|
index 0000000..c57a0fa
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
|
@@ -0,0 +1,76 @@
|
|
+#ifndef _SYSCALL_H_INCLUDE
|
|
+#define _SYSCALL_H_INCLUDE
|
|
+
|
|
+#define SYSCALL_PRINT 0
|
|
+#define SYSCALL_MMAP 1
|
|
+#define SYSCALL_OPENAT 2
|
|
+#define SYSCALL_READ 3
|
|
+#define SYSCALL_SEEK 4
|
|
+#define SYSCALL_CLOSE 5
|
|
+#define SYSCALL_ARCHCTL 6
|
|
+#define SYSCALL_WRITE 7
|
|
+#define SYSCALL_GETPID 8
|
|
+#define SYSCALL_FSTAT 9
|
|
+#define SYSCALL_FSTATAT 10
|
|
+#define SYSCALL_FORK 11
|
|
+#define SYSCALL_EXECVE 12
|
|
+#define SYSCALL_EXIT 13
|
|
+#define SYSCALL_WAITPID 14
|
|
+#define SYSCALL_MUNMAP 15
|
|
+#define SYSCALL_GETDENTS 16
|
|
+#define SYSCALL_DUP 17
|
|
+#define SYSCALL_DUP2 18
|
|
+#define SYSCALL_DUP3 19
|
|
+#define SYSCALL_FCNTL 20
|
|
+#define SYSCALL_CHDIR 21
|
|
+#define SYSCALL_PIPE2 22
|
|
+#define SYSCALL_ISATTY 23
|
|
+#define SYSCALL_FACCESSAT 24
|
|
+#define SYSCALL_UNLINKAT 25
|
|
+#define SYSCALL_IOCTL 26
|
|
+#define SYSCALL_MKDIRAT 27
|
|
+#define SYSCALL_CLOCKGET 28
|
|
+#define SYSCALL_LINKAT 29
|
|
+#define SYSCALL_READLINKAT 30
|
|
+#define SYSCALL_FCHMOD 31
|
|
+#define SYSCALL_FCHMODAT 32
|
|
+#define SYSCALL_UMASK 33
|
|
+#define SYSCALL_POLL 34
|
|
+#define SYSCALL_NANOSLEEP 35
|
|
+#define SYSCALL_FTRUNCATE 36
|
|
+#define SYSCALL_MOUNT 37
|
|
+#define SYSCALL_FCHOWNAT 38
|
|
+#define SYSCALL_UTIMENSAT 39
|
|
+#define SYSCALL_RENAMEAT 40
|
|
+#define SYSCALL_SOCKET 41
|
|
+#define SYSCALL_BIND 42
|
|
+#define SYSCALL_SENDMSG 43
|
|
+#define SYSCALL_SETSOCKOPT 44
|
|
+#define SYSCALL_RECVMSG 45
|
|
+#define SYSCALL_LISTEN 46
|
|
+#define SYSCALL_CONNECT 47
|
|
+#define SYSCALL_ACCEPT 48
|
|
+#define SYSCALL_NEWTHREAD 49
|
|
+#define SYSCALL_THREADEXIT 50
|
|
+#define SYSCALL_FUTEX 51
|
|
+#define SYSCALL_GETTID 52
|
|
+
|
|
+#include <stddef.h>
|
|
+#include <stdint.h>
|
|
+
|
|
+static long syscall(long func, long* ret, uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0, uint64_t p4 = 0, uint64_t p5 = 0, uint64_t p6 = 0) {
|
|
+ volatile long err;
|
|
+
|
|
+ register uint64_t r4 asm("r10") = p4;
|
|
+ register uint64_t r5 asm("r8") = p5;
|
|
+ register uint64_t r6 asm("r9") = p6;
|
|
+
|
|
+ asm volatile("syscall"
|
|
+ : "=a"(*ret), "=d"(err)
|
|
+ : "a"(func), "D"(p1), "S"(p2), "d"(p3), "r"(r4),
|
|
+ "r"(r5), "r"(r6)
|
|
+ : "memory", "rcx", "r11");
|
|
+ return err;
|
|
+}
|
|
+
|
|
+#endif
|
|
diff --git mlibc-workdir/sysdeps/astral/meson.build mlibc-workdir/sysdeps/astral/meson.build
|
|
new file mode 100644
|
|
index 0000000..31d913e
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/meson.build
|
|
@@ -0,0 +1,75 @@
|
|
+
|
|
+rtld_sources += files(
|
|
+ 'generic/generic.cpp',
|
|
+ 'generic/astral.cpp',
|
|
+)
|
|
+
|
|
+libc_sources += files(
|
|
+ 'generic/entry.cpp',
|
|
+ 'generic/astral.cpp',
|
|
+ 'generic/generic.cpp',
|
|
+ 'threading/x86_64-thread.cpp',
|
|
+ 'threading/x86_64-thread-entry.S',
|
|
+)
|
|
+
|
|
+if not no_headers
|
|
+ install_headers(
|
|
+ 'include/abi-bits/access.h',
|
|
+ '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/stat.h',
|
|
+ 'include/abi-bits/statx.h',
|
|
+ 'include/abi-bits/signal.h',
|
|
+ 'include/abi-bits/reboot.h',
|
|
+ 'include/abi-bits/resource.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/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',
|
|
+ 'include/abi-bits/vt.h',
|
|
+ subdir: 'abi-bits'
|
|
+ )
|
|
+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
|
|
diff --git mlibc-workdir/sysdeps/astral/threading/x86_64-thread-entry.S mlibc-workdir/sysdeps/astral/threading/x86_64-thread-entry.S
|
|
new file mode 100644
|
|
index 0000000..4cb3ae0
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/threading/x86_64-thread-entry.S
|
|
@@ -0,0 +1,7 @@
|
|
+ .section .text
|
|
+.global __mlibc_thread_entry
|
|
+__mlibc_thread_entry:
|
|
+ pop %rdi
|
|
+ pop %rsi
|
|
+ pop %rdx
|
|
+ call __mlibc_thread_trampoline
|
|
diff --git mlibc-workdir/sysdeps/astral/threading/x86_64-thread.cpp mlibc-workdir/sysdeps/astral/threading/x86_64-thread.cpp
|
|
new file mode 100644
|
|
index 0000000..3b893f0
|
|
--- /dev/null
|
|
+++ mlibc-workdir/sysdeps/astral/threading/x86_64-thread.cpp
|
|
@@ -0,0 +1,59 @@
|
|
+#include <sys/mman.h>
|
|
+#include <mlibc/debug.hpp>
|
|
+#include <errno.h>
|
|
+#include <mlibc/all-sysdeps.hpp>
|
|
+#include <bits/ensure.h>
|
|
+#include <mlibc/tcb.hpp>
|
|
+
|
|
+extern "C" void __mlibc_thread_trampoline(void *(*fn)(void *), Tcb *tcb, void *arg) {
|
|
+ if (mlibc::sys_tcb_set(tcb)) {
|
|
+ __ensure(!"failed to set tcb for new thread");
|
|
+ }
|
|
+
|
|
+ while (__atomic_load_n(&tcb->tid, __ATOMIC_RELAXED) == 0) {
|
|
+ mlibc::sys_futex_wait(&tcb->tid, 0, nullptr);
|
|
+ }
|
|
+
|
|
+ tcb->invokeThreadFunc(reinterpret_cast<void *>(fn), arg);
|
|
+
|
|
+ __atomic_store_n(&tcb->didExit, 1, __ATOMIC_RELEASE);
|
|
+ mlibc::sys_futex_wake(&tcb->didExit);
|
|
+
|
|
+ mlibc::sys_thread_exit();
|
|
+}
|
|
+
|
|
+#define DEFAULT_STACK 0x400000
|
|
+
|
|
+namespace mlibc {
|
|
+ int sys_prepare_stack(void **stack, void *entry, void *arg, void *tcb, size_t *stack_size, size_t *guard_size, void **stack_base) {
|
|
+ // TODO guard
|
|
+
|
|
+ mlibc::infoLogger() << "mlibc: sys_prepare_stack() does not setup a guard!" << frg::endlog;
|
|
+
|
|
+ *guard_size = 0;
|
|
+
|
|
+ *stack_size = *stack_size ? *stack_size : DEFAULT_STACK;
|
|
+
|
|
+ if (!*stack) {
|
|
+ *stack_base = mmap(NULL, *stack_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
|
+ if (*stack_base == MAP_FAILED) {
|
|
+ return errno;
|
|
+ }
|
|
+ } else {
|
|
+ *stack_base = *stack;
|
|
+ }
|
|
+
|
|
+ *stack = (void *)((char *)*stack_base + *stack_size);
|
|
+
|
|
+ void **stack_it = (void **)*stack;
|
|
+
|
|
+ *--stack_it = arg;
|
|
+ *--stack_it = tcb;
|
|
+ *--stack_it = entry;
|
|
+
|
|
+ *stack = (void *)stack_it;
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+}
|