mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
475 lines
14 KiB
Diff
475 lines
14 KiB
Diff
diff --git mlibc-clean/options/ansi/generic/wchar.cpp mlibc-workdir/options/ansi/generic/wchar.cpp
|
|
index b44ebc2..9339316 100644
|
|
--- mlibc-clean/options/ansi/generic/wchar.cpp
|
|
+++ mlibc-workdir/options/ansi/generic/wchar.cpp
|
|
@@ -54,8 +54,13 @@ size_t mbrlen(const char *__restrict mbs, size_t mb_limit, mbstate_t *__restrict
|
|
|
|
mlibc::code_seq<const char> nseq{mbs, mbs + mb_limit};
|
|
mlibc::code_seq<wchar_t> wseq{&wc, &wc + 1};
|
|
- if(auto e = cc->decode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null)
|
|
- __ensure(!"decode_wtranscode() errors are not handled");
|
|
+ if(auto e = cc->decode_wtranscode(nseq, wseq, *stp); e != mlibc::charcode_error::null) {
|
|
+ if(e == mlibc::charcode_error::input_underflow)
|
|
+ return static_cast<size_t>(-1);
|
|
+ __ensure(e == mlibc::charcode_error::illegal_input);
|
|
+ errno = EILSEQ;
|
|
+ return static_cast<size_t>(-1);
|
|
+ }
|
|
return nseq.it - mbs;
|
|
}
|
|
|
|
diff --git mlibc-clean/options/glibc/generic/execinfo.cpp mlibc-workdir/options/glibc/generic/execinfo.cpp
|
|
index 1ed110d..ded9114 100644
|
|
--- mlibc-clean/options/glibc/generic/execinfo.cpp
|
|
+++ mlibc-workdir/options/glibc/generic/execinfo.cpp
|
|
@@ -4,6 +4,7 @@
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <unwind.h>
|
|
+#include <errno.h>
|
|
|
|
#include <bits/ensure.h>
|
|
#include <mlibc/debug.hpp>
|
|
@@ -52,29 +53,7 @@ _Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) {
|
|
} // namespace
|
|
|
|
int backtrace(void **buffer, int size) {
|
|
- if (size <= 0)
|
|
- return 0;
|
|
-
|
|
- if (!libgccHandle) {
|
|
- libgccHandle = dlopen("libgcc_s.so.1", RTLD_LAZY | RTLD_LOCAL);
|
|
- if (!libgccHandle || libgccHandle.value() == nullptr) {
|
|
- auto error = dlerror();
|
|
- mlibc::infoLogger() << "Failed to load libgcc_s.so.1: " << (error ? error : "") << frg::endlog;
|
|
- return 0;
|
|
- }
|
|
-
|
|
- unwindBacktrace = reinterpret_cast<UnwindBacktrace>(dlsym(libgccHandle.value(), "_Unwind_Backtrace"));
|
|
- unwindGetIP = reinterpret_cast<UnwindGetIP>(dlsym(libgccHandle.value(), "_Unwind_GetIP"));
|
|
-
|
|
- if (!unwindBacktrace || !unwindGetIP) {
|
|
- mlibc::infoLogger() << "Failed to find unwind functions in libgcc_s.so.1: " << dlerror() << frg::endlog;
|
|
- return 0;
|
|
- }
|
|
- }
|
|
-
|
|
- UnwindState state{buffer, size};
|
|
- unwindBacktrace(trace, &state);
|
|
- return state.current_frame;
|
|
+ return ENOSYS;
|
|
}
|
|
|
|
char **backtrace_symbols(void *const *, int) {
|
|
@@ -82,25 +61,5 @@ char **backtrace_symbols(void *const *, int) {
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
-void backtrace_symbols_fd(void *const *buffer, int size, int fd) {
|
|
- if (size <= 0 || fd < 0)
|
|
- return;
|
|
-
|
|
- for (int frame_num = 0; frame_num < size; frame_num++) {
|
|
- Dl_info info;
|
|
- if (dladdr(buffer[frame_num], &info) != 0) {
|
|
- if (info.dli_fname != nullptr)
|
|
- write(fd, info.dli_fname, strlen(info.dli_fname));
|
|
-
|
|
- if (info.dli_sname != nullptr)
|
|
- dprintf(fd, "(%s+0x%" PRIxPTR ") ", info.dli_sname,
|
|
- reinterpret_cast<uintptr_t>(buffer[frame_num]) - reinterpret_cast<uintptr_t>(info.dli_saddr));
|
|
- else if(info.dli_saddr)
|
|
- dprintf(fd, "(+%p) ", info.dli_saddr);
|
|
- else
|
|
- dprintf(fd, "() ");
|
|
- }
|
|
-
|
|
- dprintf(fd, "[%p]\n", buffer[frame_num]);
|
|
- }
|
|
+void backtrace_symbols_fd(void *const *, int, int) {
|
|
}
|
|
diff --git mlibc-clean/options/posix/generic/net-if.cpp mlibc-workdir/options/posix/generic/net-if.cpp
|
|
index 992aef7..e39c499 100644
|
|
--- mlibc-clean/options/posix/generic/net-if.cpp
|
|
+++ mlibc-workdir/options/posix/generic/net-if.cpp
|
|
@@ -22,11 +22,18 @@ char *if_indextoname(unsigned int index, char *name) {
|
|
}
|
|
|
|
struct if_nameindex *if_nameindex(void) {
|
|
- mlibc::infoLogger() << "mlibc: if_nameindex() is a no-op" << frg::endlog;
|
|
- errno = ENOSYS;
|
|
- return nullptr;
|
|
+ auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_if_nameindex, 0);
|
|
+ struct if_nameindex *ret = 0;
|
|
+
|
|
+ if(int e = sysdep(&ret); e) {
|
|
+ errno = e;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
+
|
|
unsigned int if_nametoindex(const char *name) {
|
|
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_if_nametoindex, 0);
|
|
unsigned int ret = 0;
|
|
diff --git mlibc-clean/options/posix/generic/netdb.cpp mlibc-workdir/options/posix/generic/netdb.cpp
|
|
index 299d9d3..d32237c 100644
|
|
--- mlibc-clean/options/posix/generic/netdb.cpp
|
|
+++ mlibc-workdir/options/posix/generic/netdb.cpp
|
|
@@ -371,8 +371,8 @@ int gethostbyaddr_r(const void *__restrict, socklen_t, int, struct hostent *__re
|
|
|
|
int gethostbyname_r(const char *__restrict, struct hostent *__restrict, char *__restrict, size_t,
|
|
struct hostent **__restrict, int *__restrict) {
|
|
- __ensure(!"Not implemented");
|
|
- __builtin_unreachable();
|
|
+ mlibc::infoLogger() << "gethostbyname_r is a stub!" << frg::endlog;
|
|
+ return -1;
|
|
}
|
|
|
|
struct protoent *getprotobyname(const char *) {
|
|
diff --git mlibc-clean/options/posix/include/mlibc/posix-sysdeps.hpp mlibc-workdir/options/posix/include/mlibc/posix-sysdeps.hpp
|
|
index 3666050..ecfc1ae 100644
|
|
--- mlibc-clean/options/posix/include/mlibc/posix-sysdeps.hpp
|
|
+++ mlibc-workdir/options/posix/include/mlibc/posix-sysdeps.hpp
|
|
@@ -230,6 +230,7 @@ int sys_vm_unmap(void *pointer, size_t size);
|
|
|
|
[[gnu::weak]] int sys_if_indextoname(unsigned int index, char *name);
|
|
[[gnu::weak]] int sys_if_nametoindex(const char *name, unsigned int *ret);
|
|
+[[gnu::weak]] int sys_if_nameindex(struct if_nameindex **);
|
|
|
|
[[gnu::weak]] int sys_ptsname(int fd, char *buffer, size_t length);
|
|
[[gnu::weak]] int sys_unlockpt(int fd);
|
|
diff --git mlibc-clean/options/rtld/generic/linker.cpp mlibc-workdir/options/rtld/generic/linker.cpp
|
|
index 07dbe11..3ece6ec 100644
|
|
--- mlibc-clean/options/rtld/generic/linker.cpp
|
|
+++ mlibc-workdir/options/rtld/generic/linker.cpp
|
|
@@ -29,7 +29,7 @@ uintptr_t libraryBase = 0x41000000;
|
|
|
|
constexpr bool verbose = false;
|
|
constexpr bool stillSlightlyVerbose = false;
|
|
-constexpr bool logBaseAddresses = false;
|
|
+constexpr bool logBaseAddresses = true;
|
|
constexpr bool logRpath = false;
|
|
constexpr bool logLdPath = false;
|
|
constexpr bool logSymbolVersions = false;
|
|
diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
|
index 939925e..5c3ca08 100644
|
|
--- mlibc-clean/sysdeps/astral/generic/generic.cpp
|
|
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
|
@@ -1,4 +1,5 @@
|
|
#include <bits/ensure.h>
|
|
+#include <net/if.h>
|
|
#include <mlibc/debug.hpp>
|
|
#include <mlibc/all-sysdeps.hpp>
|
|
#include <errno.h>
|
|
@@ -13,6 +14,16 @@
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
+#include <sys/sysmacros.h>
|
|
+
|
|
+typedef struct {
|
|
+ struct sockaddr addr;
|
|
+ struct sockaddr broadaddr;
|
|
+ struct sockaddr netmask;
|
|
+ struct sockaddr hwaddr;
|
|
+ short flags;
|
|
+ int mtu;
|
|
+} astral_net_info_t;
|
|
|
|
namespace mlibc {
|
|
int sys_setgroups(size_t size, const gid_t *list) {
|
|
@@ -31,13 +42,170 @@ namespace mlibc {
|
|
return 0;
|
|
}
|
|
|
|
+ int sys_setxattr(const char *path, const char *name,
|
|
+ const void *val, size_t size, int flags) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+ int sys_lsetxattr(const char *path, const char *name,
|
|
+ const void *val, size_t size, int flags) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_fsetxattr(int fd, const char *name, const void *val,
|
|
+ size_t size, int flags) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_getxattr(const char *path, const char *name,
|
|
+ void *val, size_t size, ssize_t *nread) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_lgetxattr(const char *path, const char *name,
|
|
+ void *val, size_t size, ssize_t *nread) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_fgetxattr(int fd, const char *name, void *val,
|
|
+ size_t size, ssize_t *nread) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_listxattr(const char *path, char *list, size_t size,
|
|
+ ssize_t *nread) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_llistxattr(const char *path, char *list, size_t size,
|
|
+ ssize_t *nread) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+ int sys_flistxattr(int fd, char *list, size_t size,
|
|
+ ssize_t *nread) {
|
|
+ return ENOTSUP;
|
|
+ }
|
|
+
|
|
+#ifndef MLIBC_BUILDING_RTLD
|
|
+ // XXX this might leak memory in case of an error.
|
|
+ int sys_getifaddrs(struct ifaddrs **out) {
|
|
+ struct ifaddrs *list = NULL;
|
|
+
|
|
+ int dirfd;
|
|
+ int error = sys_open("/dev/", O_DIRECTORY | O_RDONLY, 0, &dirfd);
|
|
+ if (error)
|
|
+ return error;
|
|
+
|
|
+
|
|
+ struct dirent dent;
|
|
+ size_t bytes_read;
|
|
+ for (;;) {
|
|
+ error = sys_read_entries(dirfd, &dent, sizeof(dent), &bytes_read);
|
|
+ if (error)
|
|
+ goto leave;
|
|
+
|
|
+ if (bytes_read == 0)
|
|
+ break;
|
|
+
|
|
+ struct stat st;
|
|
+ if (sys_stat(fsfd_target::fd_path, dirfd, dent.d_name, AT_SYMLINK_NOFOLLOW, &st))
|
|
+ continue;
|
|
+
|
|
+ // check if network device
|
|
+ if (!S_ISCHR(st.st_mode) || major(st.st_rdev) != 10)
|
|
+ continue;
|
|
+
|
|
+ int fd;
|
|
+ error = sys_openat(dirfd, dent.d_name, 0, 0, &fd);
|
|
+ if (error)
|
|
+ continue;
|
|
+
|
|
+ astral_net_info_t net_info;
|
|
+ int r;
|
|
+ error = sys_ioctl(fd, 0x1337631, &net_info, &r);
|
|
+ if (error) {
|
|
+ sys_close(fd);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ struct ifaddrs *next = (struct ifaddrs *)malloc(sizeof(struct ifaddrs));
|
|
+ __ensure(next);
|
|
+
|
|
+ next->ifa_next = list;
|
|
+
|
|
+ next->ifa_name = strdup(dent.d_name);
|
|
+ __ensure(next->ifa_name);
|
|
+
|
|
+ next->ifa_flags = net_info.flags;
|
|
+
|
|
+ next->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr));
|
|
+ __ensure(next->ifa_addr);
|
|
+ memcpy(next->ifa_addr, &net_info.addr, sizeof(struct sockaddr));
|
|
+
|
|
+ next->ifa_netmask = (struct sockaddr *)malloc(sizeof(struct sockaddr));
|
|
+ __ensure(next->ifa_netmask);
|
|
+ memcpy(next->ifa_netmask, &net_info.netmask, sizeof(struct sockaddr));
|
|
+
|
|
+ next->ifa_broadaddr = (struct sockaddr *)malloc(sizeof(struct sockaddr));
|
|
+ __ensure(next->ifa_broadaddr);
|
|
+ memcpy(next->ifa_broadaddr, &net_info.broadaddr, sizeof(struct sockaddr));
|
|
+
|
|
+ next->ifa_data = nullptr;
|
|
+
|
|
+ list = next;
|
|
+ sys_close(fd);
|
|
+ }
|
|
+
|
|
+ *out = list;
|
|
+
|
|
+ leave:
|
|
+ sys_close(dirfd);
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ // XXX extremely leaky.
|
|
+ int sys_if_nameindex(struct if_nameindex **out) {
|
|
+ struct ifaddrs *ifaddrs;
|
|
+ if (int e = sys_getifaddrs(&ifaddrs); e)
|
|
+ return e;
|
|
+
|
|
+ struct ifaddrs *it = ifaddrs;
|
|
+ int count = 0;
|
|
+ while (it) {
|
|
+ ++count;
|
|
+ it = it->ifa_next;
|
|
+ }
|
|
+
|
|
+ struct if_nameindex *arr = (struct if_nameindex *)malloc(sizeof(struct if_nameindex) * (count + 1));
|
|
+ if (!arr)
|
|
+ return ENOMEM;
|
|
+
|
|
+ int i = 0;
|
|
+ while (ifaddrs) {
|
|
+ arr[i].if_index = i + 1;
|
|
+ arr[i].if_name = strdup(ifaddrs->ifa_name);
|
|
+ __ensure(arr[i].if_name);
|
|
+
|
|
+ ++i;
|
|
+
|
|
+ ifaddrs = ifaddrs->ifa_next;
|
|
+ }
|
|
+
|
|
+ arr[count].if_index = 0;
|
|
+ arr[count].if_name = nullptr;
|
|
+
|
|
+ *out = arr;
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+#endif
|
|
+
|
|
int sys_getsockopt(int fd, int layer, int number,
|
|
void *__restrict buffer, socklen_t *__restrict size) {
|
|
(void)size;
|
|
(void)buffer;
|
|
- // TODO unstub
|
|
- mlibc::infoLogger() << "getsockopt: " << fd << " " << layer << " " << number << frg::endlog;
|
|
- return 0;
|
|
+ long ret;
|
|
+ return syscall(SYSCALL_GETSOCKOPT, &ret, fd, layer, number, (uint64_t)buffer, (uint64_t)size);
|
|
}
|
|
|
|
int sys_inet_configured(bool *ipv4, bool *ipv6) {
|
|
@@ -47,6 +215,71 @@ namespace mlibc {
|
|
return 0;
|
|
}
|
|
|
|
+ int sys_unlockpt(int fd) {
|
|
+ int r;
|
|
+ // unlockpt is a no-op kernel side, so use this to check for an invalid pty
|
|
+ return sys_ioctl(fd, 0x13376167, NULL, &r);
|
|
+ }
|
|
+
|
|
+ int sys_statfs(const char *path, struct statfs *buf) {
|
|
+ struct statvfs stvfs;
|
|
+ int ret = sys_statvfs(path, &stvfs);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ buf->f_type = 0; /* statvfs has no f_type */
|
|
+ buf->f_blocks = stvfs.f_blocks;
|
|
+ buf->f_bfree = stvfs.f_bfree;
|
|
+ buf->f_bavail = stvfs.f_bavail;
|
|
+ buf->f_files = stvfs.f_files;
|
|
+ buf->f_ffree = stvfs.f_ffree;
|
|
+ buf->f_fsid.__val[0] = (int)(stvfs.f_fsid & 0xFFFFFFFF);
|
|
+ buf->f_fsid.__val[1] = (int)(stvfs.f_fsid >> 32);
|
|
+ buf->f_namelen = stvfs.f_namemax;
|
|
+ buf->f_flags = stvfs.f_flag;
|
|
+ buf->f_bsize = stvfs.f_frsize;
|
|
+ buf->f_frsize = stvfs.f_bsize;
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_fstatfs(int fd, struct statfs *buf) {
|
|
+ struct statvfs stvfs;
|
|
+ int ret = sys_fstatvfs(fd, &stvfs);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ buf->f_type = 0; /* statvfs has no f_type */
|
|
+ buf->f_bsize = stvfs.f_bsize;
|
|
+ buf->f_bfree = stvfs.f_bfree;
|
|
+ buf->f_bavail = stvfs.f_bavail;
|
|
+ buf->f_files = stvfs.f_files;
|
|
+ buf->f_ffree = stvfs.f_ffree;
|
|
+ buf->f_fsid.__val[0] = (int)(stvfs.f_fsid & 0xFFFFFFFF);
|
|
+ buf->f_fsid.__val[1] = (int)(stvfs.f_fsid >> 32);
|
|
+ buf->f_namelen = stvfs.f_namemax;
|
|
+ buf->f_flags = stvfs.f_flag;
|
|
+ buf->f_bsize = stvfs.f_frsize;
|
|
+ buf->f_frsize = stvfs.f_bsize;
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int sys_statvfs(const char *path, struct statvfs *out) {
|
|
+ long r;
|
|
+ return syscall(SYSCALL_FSTATVFSAT, &r, AT_FDCWD, (uint64_t)path, (uint64_t)out, 0);
|
|
+ }
|
|
+
|
|
+ int sys_fstatvfs(int fd, struct statvfs *out) {
|
|
+ long r;
|
|
+ return syscall(SYSCALL_FSTATVFS, &r, fd, (uint64_t)out);
|
|
+ }
|
|
+
|
|
+ void sys_yield() {
|
|
+ long r;
|
|
+ syscall(SYSCALL_YIELD, &r);
|
|
+ }
|
|
+
|
|
int sys_readv(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_read) {
|
|
long r;
|
|
int error = syscall(SYSCALL_READV, &r, fd, (uint64_t)iovs, iovc);
|
|
@@ -489,6 +722,7 @@ namespace mlibc {
|
|
|
|
int sys_setsockopt(int fd, int layer, int number, const void *buffer, socklen_t size) {
|
|
long ret;
|
|
+ mlibc::infoLogger() << "setsockopt: fd " << fd << " layer " << layer << " number " << number << frg::endlog;
|
|
return syscall(SYSCALL_SETSOCKOPT, &ret, fd, layer, number, (uint64_t)buffer, size);
|
|
}
|
|
|
|
diff --git mlibc-clean/sysdeps/astral/include/astral/archctl.h mlibc-workdir/sysdeps/astral/include/astral/archctl.h
|
|
index 7e4f2a1..ecc2677 100644
|
|
--- mlibc-clean/sysdeps/astral/include/astral/archctl.h
|
|
+++ mlibc-workdir/sysdeps/astral/include/astral/archctl.h
|
|
@@ -5,6 +5,17 @@
|
|
#define ARCH_CTL_SET_FSBASE 1
|
|
#define ARCH_CTL_GET_GSBASE 2
|
|
#define ARCH_CTL_GET_FSBASE 3
|
|
+#define ARCH_CTL_SET_SYSTRACE 4
|
|
+#define ARCH_CTL_SET_LDT_ENTRY 5
|
|
+
|
|
+#define ARCH_CTL_SYSTRACE_OFF 0
|
|
+#define ARCH_CTL_SYSTRACE_SELF 1
|
|
+#define ARCH_CTL_SYSTRACE_ALL 2
|
|
+
|
|
+typedef struct {
|
|
+ uint64_t entry;
|
|
+ uint16_t seg;
|
|
+} archctl_ldt_request_t;
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
|
index a6c4067..7568e64 100644
|
|
--- mlibc-clean/sysdeps/astral/include/astral/syscall.h
|
|
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
|
@@ -103,6 +103,10 @@
|
|
#define SYSCALL_SYSINFO 96
|
|
#define SYSCALL_WRITEV 97
|
|
#define SYSCALL_READV 98
|
|
+#define SYSCALL_YIELD 99
|
|
+#define SYSCALL_FSTATVFS 100
|
|
+#define SYSCALL_FSTATVFSAT 101
|
|
+#define SYSCALL_GETSOCKOPT 102
|
|
|
|
#ifndef __MLIBC_ABI_ONLY
|
|
|