Files
Astral/patches/mlibc/jinx-working-patch.patch
T
2026-08-11 14:21:18 -03:00

1116 lines
30 KiB
Diff

diff --git mlibc-clean/options/glibc/generic/stdio_ext.cpp mlibc-workdir/options/glibc/generic/stdio_ext.cpp
index ccb3725..3dfa27a 100644
--- mlibc-clean/options/glibc/generic/stdio_ext.cpp
+++ mlibc-workdir/options/glibc/generic/stdio_ext.cpp
@@ -71,14 +71,38 @@ size_t __freadahead(FILE *file_base) {
return file_base->__valid_limit - file_base->__offset;
}
-const char *__freadptr(FILE *, size_t *) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
+const char *__freadptr(FILE *file_base, size_t *size) {
+ if(file_base->__io_mode != 0) {
+ mlibc::infoLogger() << "mlibc: __freadptr() called but file is not open for reading" << frg::endlog;
+ *size = 0;
+ return nullptr;
+ }
+
+ if(file_base->__unget_ptr != file_base->__buffer_ptr) {
+ *size = file_base->__buffer_ptr - file_base->__unget_ptr;
+ return file_base->__unget_ptr;
+ }
+
+ if(file_base->__offset == file_base->__valid_limit) {
+ *size = 0;
+ return nullptr;
+ }
+
+ *size = file_base->__valid_limit - file_base->__offset;
+ return file_base->__buffer_ptr + file_base->__offset;
}
-void __freadptrinc(FILE *, size_t) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
+void __freadptrinc(FILE *file_base, size_t increment) {
+ size_t unget_size = file_base->__buffer_ptr ? file_base->__buffer_ptr - file_base->__unget_ptr : 0;
+ if(increment <= unget_size) {
+ file_base->__unget_ptr += increment;
+ return;
+ }
+
+ increment -= unget_size;
+ file_base->__unget_ptr = file_base->__buffer_ptr;
+ __ensure(file_base->__offset + increment <= file_base->__valid_limit);
+ file_base->__offset += increment;
}
void __fseterr(FILE *file_base) {
@@ -87,4 +111,3 @@ void __fseterr(FILE *file_base) {
// set the error indicator for the stream
file->__status_bits |= __MLIBC_ERROR_BIT;
}
-
diff --git mlibc-clean/options/internal/generic/global-config.cpp mlibc-workdir/options/internal/generic/global-config.cpp
index 3b7b862..3d86e7a 100644
--- mlibc-clean/options/internal/generic/global-config.cpp
+++ mlibc-workdir/options/internal/generic/global-config.cpp
@@ -1,9 +1,15 @@
#include <stdlib.h>
-#include <string.h>
+#include <mlibc/allocator.hpp>
#include <mlibc/global-config.hpp>
namespace mlibc {
+namespace {
+
+constinit mlibc::lazy_eternal<GlobalConfig> globalConfigInstance;
+
+} // namespace
+
struct GlobalConfigGuard {
GlobalConfigGuard();
};
@@ -12,7 +18,7 @@ GlobalConfigGuard guard;
GlobalConfigGuard::GlobalConfigGuard() {
// Force the config to be created during initialization of libc.so.
- mlibc::globalConfig();
+ globalConfigInstance.get();
}
static bool envEnabled(const char *env) {
@@ -29,4 +35,8 @@ GlobalConfig::GlobalConfig() {
debugMonetaryLengths = envEnabled("MLIBC_DEBUG_MONETARY_LENGTHS");
}
+const GlobalConfig &globalConfig() {
+ return globalConfigInstance.get();
+}
+
} // namespace mlibc
diff --git mlibc-clean/options/internal/include/mlibc/allocator.hpp mlibc-workdir/options/internal/include/mlibc/allocator.hpp
index 852620a..7f1aa89 100644
--- mlibc-clean/options/internal/include/mlibc/allocator.hpp
+++ mlibc-workdir/options/internal/include/mlibc/allocator.hpp
@@ -3,6 +3,7 @@
#include <mlibc/lock.hpp>
#include <bits/ensure.h>
+#include <frg/manual_box.hpp>
#include <frg/slab.hpp>
#include <internal-config.h>
@@ -13,6 +14,8 @@ public:
uintptr_t map(size_t length);
void unmap(uintptr_t address, size_t length);
+
+ static constexpr size_t num_buckets = 14;
};
typedef frg::slab_pool<VirtualAllocator, FutexLock> MemoryPool;
@@ -35,4 +38,34 @@ MemoryAllocator &getAllocator();
#endif // !MLIBC_DEBUG_ALLOCATOR
+namespace mlibc {
+
+template <typename T>
+struct lazy_eternal {
+ constexpr lazy_eternal() = default;
+
+ template <typename Self>
+ auto &get(this Self &&self) {
+ if (__atomic_load_n(&self.initialized_, __ATOMIC_ACQUIRE))
+ return *self.box_.get();
+
+ {
+ frg::unique_lock lock{self.lock_};
+ if (!__atomic_load_n(&self.initialized_, __ATOMIC_RELAXED)) {
+ self.box_.initialize();
+ __atomic_store_n(&self.initialized_, 1, __ATOMIC_RELEASE);
+ }
+ }
+
+ return *self.box_.get();
+ }
+
+private:
+ mutable uint32_t initialized_ = 0;
+ mutable FutexLock lock_;
+ mutable frg::manual_box<T> box_;
+};
+
+} // namespace mlibc
+
#endif // MLIBC_FRIGG_ALLOC
diff --git mlibc-clean/options/internal/include/mlibc/global-config.hpp mlibc-workdir/options/internal/include/mlibc/global-config.hpp
index 0235c54..3fad411 100644
--- mlibc-clean/options/internal/include/mlibc/global-config.hpp
+++ mlibc-workdir/options/internal/include/mlibc/global-config.hpp
@@ -14,11 +14,8 @@ struct GlobalConfig {
bool debugMonetaryLengths;
};
-inline const GlobalConfig &globalConfig() {
- static GlobalConfig cached;
- return cached;
-}
+const GlobalConfig &globalConfig();
-}
+} // namespace mlibc
#endif // MLIBC_GLOBAL_CONFIG
diff --git mlibc-clean/options/internal/include/mlibc/lock.hpp mlibc-workdir/options/internal/include/mlibc/lock.hpp
index f447741..ab44667 100644
--- mlibc-clean/options/internal/include/mlibc/lock.hpp
+++ mlibc-workdir/options/internal/include/mlibc/lock.hpp
@@ -14,7 +14,7 @@
template<bool Recursive>
struct alignas(4) FutexLockImpl {
- FutexLockImpl() : _state{0}, _recursion{0} { }
+ constexpr FutexLockImpl() : _state{0}, _recursion{0} { }
FutexLockImpl(const FutexLockImpl &) = delete;
diff --git mlibc-clean/options/internal/include/mlibc/sysdep-signatures.hpp mlibc-workdir/options/internal/include/mlibc/sysdep-signatures.hpp
index d639e43..694021a 100644
--- mlibc-clean/options/internal/include/mlibc/sysdep-signatures.hpp
+++ mlibc-workdir/options/internal/include/mlibc/sysdep-signatures.hpp
@@ -23,6 +23,10 @@
#include <mlibc/sysdep-tags.hpp>
+#if __MLIBC_POSIX_OPTION
+#include <net/if.h>
+#endif
+
namespace mlibc {
template<typename Tag>
@@ -156,6 +160,7 @@ SYSDEP_FUNC(Linkat, int olddirfd, const char *old_path, int newdirfd, const char
SYSDEP_FUNC(Symlink, const char *target_path, const char *link_path);
SYSDEP_FUNC(Symlinkat, const char *target_path, int dirfd, const char *link_path);
SYSDEP_FUNC(Renameat, int olddirfd, const char *old_path, int newdirfd, const char *new_path);
+SYSDEP_FUNC(Renameat2, int olddirfd, const char *old_path, int newdirfd, const char *new_path, unsigned int flags);
SYSDEP_FUNC(Fcntl, int fd, int request, va_list args, int *result);
SYSDEP_FUNC(Ttyname, int fd, char *buf, size_t size);
SYSDEP_FUNC(Fadvise, int fd, off_t offset, off_t length, int advice);
@@ -235,6 +240,7 @@ SYSDEP_FUNC(SetRegid, gid_t rgid, gid_t egid);
SYSDEP_FUNC(GetLoginR, char *name, size_t name_len);
SYSDEP_FUNC(IfIndextoname, unsigned int index, char *name);
SYSDEP_FUNC(IfNametoindex, const char *name, unsigned int *ret);
+SYSDEP_FUNC(IfNameindex, struct if_nameindex **ret);
SYSDEP_FUNC(Ptsname, int fd, char *buffer, size_t length);
SYSDEP_FUNC(Unlockpt, int fd);
SYSDEP_FUNC(ThreadSetname, void *tcb, const char *name);
diff --git mlibc-clean/options/internal/include/mlibc/sysdep-tags.hpp mlibc-workdir/options/internal/include/mlibc/sysdep-tags.hpp
index 17cf422..01941c1 100644
--- mlibc-clean/options/internal/include/mlibc/sysdep-tags.hpp
+++ mlibc-workdir/options/internal/include/mlibc/sysdep-tags.hpp
@@ -316,6 +316,8 @@ struct Symlink {};
struct Symlinkat {};
// int sys_renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path);
struct Renameat {};
+// int sys_renameat2(int olddirfd, const char *old_path, int newdirfd, const char *new_path, unsigned int flags);
+struct Renameat2 {};
// int sys_fcntl(int fd, int request, va_list args, int *result);
struct Fcntl {};
// int sys_ttyname(int fd, char *buf, size_t size);
@@ -476,6 +478,8 @@ struct GetLoginR {};
struct IfIndextoname {};
// int sys_if_nametoindex(const char *name, unsigned int *ret);
struct IfNametoindex {};
+// int sys_if_nameindex(struct if_nameindex **ret);
+struct IfNameindex {};
// int sys_ptsname(int fd, char *buffer, size_t length);
struct Ptsname {};
// int sys_unlockpt(int fd);
diff --git mlibc-clean/options/linux/generic/malloc.cpp mlibc-workdir/options/linux/generic/malloc.cpp
index 065de6c..10c7395 100644
--- mlibc-clean/options/linux/generic/malloc.cpp
+++ mlibc-workdir/options/linux/generic/malloc.cpp
@@ -1,7 +1,13 @@
-#include <bits/ensure.h>
+#include <errno.h>
#include <malloc.h>
+#include <stdlib.h>
-void *memalign(size_t, size_t) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
+void *memalign(size_t alignment, size_t size) {
+ void *ptr;
+ int ret = posix_memalign(&ptr, alignment, size);
+ if(ret) {
+ errno = ret;
+ return nullptr;
+ }
+ return ptr;
}
diff --git mlibc-clean/options/posix/generic/net-if.cpp mlibc-workdir/options/posix/generic/net-if.cpp
index ed0c463..8df2580 100644
--- mlibc-clean/options/posix/generic/net-if.cpp
+++ mlibc-workdir/options/posix/generic/net-if.cpp
@@ -6,8 +6,13 @@
#include <mlibc/all-sysdeps.hpp>
#include <mlibc/debug.hpp>
-void if_freenameindex(struct if_nameindex *) {
- mlibc::infoLogger() << "mlibc: if_freenameindex is a no-op" << frg::endlog;
+void if_freenameindex(struct if_nameindex *index) {
+ if(!index)
+ return;
+
+ for(struct if_nameindex *it = index; it->if_index || it->if_name; ++it)
+ free(it->if_name);
+ free(index);
}
char *if_indextoname(unsigned int index, char *name) {
@@ -20,9 +25,13 @@ 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;
+ struct if_nameindex *ret = nullptr;
+ if(int e = mlibc::sysdep_or_enosys<IfNameindex>(&ret); e) {
+ errno = e;
+ return nullptr;
+ }
+
+ return ret;
}
unsigned int if_nametoindex(const char *name) {
diff --git mlibc-clean/options/posix/generic/posix_stdio.cpp mlibc-workdir/options/posix/generic/posix_stdio.cpp
index ab4f784..ba663bb 100644
--- mlibc-clean/options/posix/generic/posix_stdio.cpp
+++ mlibc-workdir/options/posix/generic/posix_stdio.cpp
@@ -233,7 +233,10 @@ int renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_p
return 0;
}
-int renameat2(int, const char *, int, const char *, unsigned int) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
+int renameat2(int olddirfd, const char *old_path, int newdirfd, const char *new_path, unsigned int flags) {
+ if(int e = mlibc::sysdep_or_enosys<Renameat2>(olddirfd, old_path, newdirfd, new_path, flags); e) {
+ errno = e;
+ return -1;
+ }
+ return 0;
}
diff --git mlibc-clean/options/posix/include/bits/posix/posix_stdio.h mlibc-workdir/options/posix/include/bits/posix/posix_stdio.h
index f0d6edd..ab57b6b 100644
--- mlibc-clean/options/posix/include/bits/posix/posix_stdio.h
+++ mlibc-workdir/options/posix/include/bits/posix/posix_stdio.h
@@ -63,6 +63,7 @@ char *fgetln(FILE *__stream, size_t *__size);
#endif /* !__MLIBC_ABI_ONLY */
#if defined(_GNU_SOURCE)
+#define RENAME_NOREPLACE (1 << 0)
#define RENAME_EXCHANGE (1 << 1)
/* GNU extensions */
@@ -97,4 +98,3 @@ FILE *fopencookie(void *__restrict __cookie, const char *__restrict __mode, cook
#endif /* _MLIBC_POSIX_STDIO_H */
-
diff --git mlibc-clean/options/rtld/x86_64/runtime.S mlibc-workdir/options/rtld/x86_64/runtime.S
index ba9a520..b958ef3 100644
--- mlibc-clean/options/rtld/x86_64/runtime.S
+++ mlibc-workdir/options/rtld/x86_64/runtime.S
@@ -60,4 +60,3 @@ pltRelocateStub:
jmp *%r11
.section .note.GNU-stack,"",%progbits
-
diff --git mlibc-clean/sysdeps/astral/generic/astral.cpp mlibc-workdir/sysdeps/astral/generic/astral.cpp
index a86353f..3e1a18c 100644
--- mlibc-clean/sysdeps/astral/generic/astral.cpp
+++ mlibc-workdir/sysdeps/astral/generic/astral.cpp
@@ -1,13 +1,25 @@
#include <astral/syscall.h>
#include <astral/archctl.h>
+#include <astral/sysctl.h>
#include <errno.h>
#ifndef MLIBC_BUILDING_RTLD
+int sysctl(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len) {
+ long ret;
+ long error = syscall(SYSCALL_SYSCTL, &ret, (uint64_t)name, name_len, (uint64_t)oldp, (uint64_t)old_lenp, (uint64_t)newp, new_len);
+ if (error) {
+ errno = error;
+ return -1;
+ }
+
+ return 0;
+}
+
int arch_ctl(int func, void *arg) {
long ret;
long error = syscall(SYSCALL_ARCHCTL, &ret, func, (uint64_t)arg);
- if(error)
+ if (error)
errno = error;
return error ? -1 : ret;
}
diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
index 3b04372..5324a35 100644
--- mlibc-clean/sysdeps/astral/generic/generic.cpp
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
@@ -1,7 +1,9 @@
#include <bits/ensure.h>
+#include <net/if.h>
#include <mlibc/debug.hpp>
#include <mlibc/all-sysdeps.hpp>
#include <errno.h>
+#include <ifaddrs.h>
#include <astral/syscall.h>
#include <astral/archctl.h>
#include <string.h>
@@ -11,8 +13,31 @@
#include <sys/select.h>
#include <stdio.h>
#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include <sys/sysinfo.h>
+#include <sys/times.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;
+
+typedef struct {
+ struct ifaddrs ifa;
+ unsigned int if_index;
+ char if_name[IFNAMSIZ];
+ struct sockaddr addr;
+ struct sockaddr broadaddr;
+ struct sockaddr netmask;
+} astral_ifaddrs_t;
namespace mlibc {
int Sysdeps<SetGroups>::operator()(size_t size, const gid_t *list) {
@@ -31,15 +56,324 @@ namespace mlibc {
return 0;
}
- int Sysdeps<GetSockopt>::operator()(int fd, int layer, int number,
- void *__restrict buffer, socklen_t *__restrict size) {
+ int Sysdeps<GetLoadavg>::operator()(double *samples) {
+ struct sysinfo si;
+ if(int e = sysdep<Sysinfo>(&si); e)
+ return e;
+
+ for(int i = 0; i < 3; i++)
+ samples[i] = (double)si.loads[i] / (1 << SI_LOAD_SHIFT);
+
+ return 0;
+ }
+
+ int Sysdeps<Times>::operator()(struct tms *tms, clock_t *out) {
+ if(tms) {
+ tms->tms_utime = 0;
+ tms->tms_stime = 0;
+ tms->tms_cutime = 0;
+ tms->tms_cstime = 0;
+ }
+
+ *out = 0;
+ return 0;
+ }
+
+ int Sysdeps<Fadvise>::operator()(int fd, off_t offset, off_t length, int advice) {
+ (void)fd;
+ (void)offset;
+ (void)length;
+ (void)advice;
+ return 0;
+ }
+
+ int Sysdeps<Setxattr>::operator()(const char *path, const char *name,
+ const void *val, size_t size, int flags) {
+ (void)path;
+ (void)name;
+ (void)val;
(void)size;
- (void)buffer;
- // TODO unstub
- mlibc::infoLogger() << "getsockopt: " << fd << " " << layer << " " << number << frg::endlog;
+ (void)flags;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Lsetxattr>::operator()(const char *path, const char *name,
+ const void *val, size_t size, int flags) {
+ (void)path;
+ (void)name;
+ (void)val;
+ (void)size;
+ (void)flags;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Fsetxattr>::operator()(int fd, const char *name, const void *val,
+ size_t size, int flags) {
+ (void)fd;
+ (void)name;
+ (void)val;
+ (void)size;
+ (void)flags;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Getxattr>::operator()(const char *path, const char *name,
+ void *val, size_t size, ssize_t *nread) {
+ (void)path;
+ (void)name;
+ (void)val;
+ (void)size;
+ (void)nread;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Lgetxattr>::operator()(const char *path, const char *name,
+ void *val, size_t size, ssize_t *nread) {
+ (void)path;
+ (void)name;
+ (void)val;
+ (void)size;
+ (void)nread;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Fgetxattr>::operator()(int fd, const char *name, void *val,
+ size_t size, ssize_t *nread) {
+ (void)fd;
+ (void)name;
+ (void)val;
+ (void)size;
+ (void)nread;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Listxattr>::operator()(const char *path, char *list, size_t size,
+ ssize_t *nread) {
+ (void)path;
+ (void)list;
+ (void)size;
+ (void)nread;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Llistxattr>::operator()(const char *path, char *list, size_t size,
+ ssize_t *nread) {
+ (void)path;
+ (void)list;
+ (void)size;
+ (void)nread;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<Flistxattr>::operator()(int fd, char *list, size_t size,
+ ssize_t *nread) {
+ (void)fd;
+ (void)list;
+ (void)size;
+ (void)nread;
+ return ENOTSUP;
+ }
+
+ int Sysdeps<GetCurrentStackInfo>::operator()(void **stack_base, size_t *stack_size) {
+ *stack_size = 1024 * 1024 * 4;
+ *stack_base = (void *)(0x0000800000000000 - *stack_size);
return 0;
}
+#ifndef MLIBC_BUILDING_RTLD
+ int Sysdeps<Getifaddrs>::operator()(struct ifaddrs **out) {
+ struct ifaddrs *list = nullptr;
+
+ int dirfd;
+ int error = sysdep<Open>("/dev/", O_DIRECTORY | O_RDONLY, 0, &dirfd);
+ if(error)
+ return error;
+
+ struct dirent dent;
+ size_t bytes_read;
+ for(;;) {
+ error = sysdep<ReadEntries>(dirfd, &dent, sizeof(dent), &bytes_read);
+ if(error)
+ goto leave;
+
+ if(bytes_read == 0)
+ break;
+
+ struct stat st;
+ if(sysdep<Stat>(fsfd_target::fd_path, dirfd, dent.d_name, AT_SYMLINK_NOFOLLOW, &st))
+ continue;
+
+ if(!S_ISCHR(st.st_mode) || major(st.st_rdev) != 10)
+ continue;
+
+ if(strlen(dent.d_name) >= IFNAMSIZ)
+ continue;
+
+ int fd;
+ error = sysdep<Openat>(dirfd, dent.d_name, 0, 0, &fd);
+ if(error)
+ continue;
+
+ astral_net_info_t net_info = {};
+ int r;
+ error = sysdep<Ioctl>(fd, 0x1337631, &net_info, &r);
+ if(error) {
+ sysdep<Close>(fd);
+ continue;
+ }
+
+ astral_ifaddrs_t *next = (astral_ifaddrs_t *)calloc(1, sizeof(*next));
+ if(!next) {
+ sysdep<Close>(fd);
+ error = ENOMEM;
+ goto leave;
+ }
+
+ next->ifa.ifa_next = list;
+ next->if_index = minor(st.st_rdev) + 1;
+
+ strcpy(next->if_name, dent.d_name);
+ next->ifa.ifa_name = next->if_name;
+
+ next->ifa.ifa_flags = net_info.flags;
+
+ if(net_info.addr.sa_family) {
+ memcpy(&next->addr, &net_info.addr, sizeof(next->addr));
+ next->ifa.ifa_addr = &next->addr;
+ }
+
+ if(net_info.netmask.sa_family) {
+ memcpy(&next->netmask, &net_info.netmask, sizeof(next->netmask));
+ next->ifa.ifa_netmask = &next->netmask;
+ }
+
+ if(net_info.broadaddr.sa_family) {
+ memcpy(&next->broadaddr, &net_info.broadaddr, sizeof(next->broadaddr));
+ next->ifa.ifa_broadaddr = &next->broadaddr;
+ }
+
+ next->ifa.ifa_data = nullptr;
+
+ list = &next->ifa;
+ sysdep<Close>(fd);
+ }
+
+ *out = list;
+
+leave:
+ sysdep<Close>(dirfd);
+ if(error)
+ freeifaddrs(list);
+ return error;
+ }
+
+ int Sysdeps<IfIndextoname>::operator()(unsigned int index, char *name) {
+ if(!index || !name)
+ return EINVAL;
+
+ struct ifaddrs *ifaddrs;
+ if(int e = sysdep<Getifaddrs>(&ifaddrs); e)
+ return e;
+
+ int error = ENXIO;
+ for(struct ifaddrs *it = ifaddrs; it; it = it->ifa_next) {
+ astral_ifaddrs_t *entry = (astral_ifaddrs_t *)it;
+ if(entry->if_index != index)
+ continue;
+
+ strcpy(name, entry->if_name);
+ error = 0;
+ break;
+ }
+
+ freeifaddrs(ifaddrs);
+ return error;
+ }
+
+ int Sysdeps<IfNametoindex>::operator()(const char *name, unsigned int *ret) {
+ if(!name)
+ return EINVAL;
+
+ struct ifaddrs *ifaddrs;
+ if(int e = sysdep<Getifaddrs>(&ifaddrs); e)
+ return e;
+
+ int error = ENXIO;
+ for(struct ifaddrs *it = ifaddrs; it; it = it->ifa_next) {
+ astral_ifaddrs_t *entry = (astral_ifaddrs_t *)it;
+ if(strcmp(entry->if_name, name))
+ continue;
+
+ *ret = entry->if_index;
+ error = 0;
+ break;
+ }
+
+ freeifaddrs(ifaddrs);
+ return error;
+ }
+
+ int Sysdeps<IfNameindex>::operator()(struct if_nameindex **out) {
+ struct ifaddrs *ifaddrs;
+ if(int e = sysdep<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) {
+ freeifaddrs(ifaddrs);
+ return ENOMEM;
+ }
+
+ int i = 0;
+ for(struct ifaddrs *it = ifaddrs; it; it = it->ifa_next) {
+ astral_ifaddrs_t *entry = (astral_ifaddrs_t *)it;
+
+ arr[i].if_index = entry->if_index;
+ arr[i].if_name = strdup(entry->if_name);
+ if(!arr[i].if_name) {
+ for(int j = 0; j < i; ++j)
+ free(arr[j].if_name);
+ free(arr);
+ freeifaddrs(ifaddrs);
+ return ENOMEM;
+ }
+
+ ++i;
+ }
+
+ arr[count].if_index = 0;
+ arr[count].if_name = nullptr;
+
+ *out = arr;
+ freeifaddrs(ifaddrs);
+
+ return 0;
+ }
+#endif
+
+ int Sysdeps<EventfdCreate>::operator()(unsigned int initval, int flags, int *fd) {
+ long ret;
+ int error = syscall(SYSCALL_EVENTFD, &ret, initval, flags);
+ if (error)
+ return error;
+
+ *fd = ret;
+ return 0;
+ }
+
+ int Sysdeps<GetSockopt>::operator()(int fd, int layer, int number,
+ void *__restrict buffer, socklen_t *__restrict size) {
+ long ret;
+ return syscall(SYSCALL_GETSOCKOPT, &ret, fd, layer, number, (uint64_t)buffer, (uint64_t)size);
+ }
+
int Sysdeps<InetConfigured>::operator()(bool *ipv4, bool *ipv6) {
// there is no ipv6 support in the kernel currently and no way of checking for configured interfaces
*ipv4 = true;
@@ -47,6 +381,71 @@ namespace mlibc {
return 0;
}
+ int Sysdeps<Unlockpt>::operator()(int fd) {
+ int r;
+ // unlockpt is a no-op kernel side, so use this to check for an invalid pty
+ return sysdep<Ioctl>(fd, 0x13376167, nullptr, &r);
+ }
+
+ int Sysdeps<Statfs>::operator()(const char *path, struct statfs *buf) {
+ struct statvfs stvfs;
+ int ret = sysdep<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 Sysdeps<Fstatfs>::operator()(int fd, struct statfs *buf) {
+ struct statvfs stvfs;
+ int ret = sysdep<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 Sysdeps<Statvfs>::operator()(const char *path, struct statvfs *out) {
+ long r;
+ return syscall(SYSCALL_FSTATVFSAT, &r, AT_FDCWD, (uint64_t)path, (uint64_t)out, 0);
+ }
+
+ int Sysdeps<Fstatvfs>::operator()(int fd, struct statvfs *out) {
+ long r;
+ return syscall(SYSCALL_FSTATVFS, &r, fd, (uint64_t)out);
+ }
+
+ void Sysdeps<Yield>::operator()() {
+ long r;
+ syscall(SYSCALL_YIELD, &r);
+ }
+
int Sysdeps<Readv>::operator()(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);
@@ -86,6 +485,11 @@ namespace mlibc {
return e;
}
+ int Sysdeps<SetPriority>::operator()(int which, id_t who, int prio) {
+ long ret;
+ return syscall(SYSCALL_SETPRIORITY, &ret, which, who, prio);
+ }
+
int Sysdeps<Shutdown>::operator()(int sockfd, int how) {
long ret;
return syscall(SYSCALL_SHUTDOWN, &ret, sockfd, how);
@@ -487,8 +891,15 @@ namespace mlibc {
return err;
}
+ int Sysdeps<ThreadSetname>::operator()(void *tcb, const char *name) {
+ (void)tcb;
+ (void)name;
+ return 0;
+ }
+
int Sysdeps<SetSockopt>::operator()(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);
}
@@ -511,6 +922,11 @@ namespace mlibc {
return err;
}
+ int Sysdeps<Renameat2>::operator()(int old_dirfd, const char *old_path, int new_dirfd, const char *new_path, unsigned int flags) {
+ long ret;
+ return syscall(SYSCALL_RENAMEAT, &ret, old_dirfd, (uint64_t)old_path, new_dirfd, (uint64_t)new_path, flags);
+ }
+
int Sysdeps<Renameat>::operator()(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);
@@ -562,6 +978,16 @@ namespace mlibc {
return sysdep<Ioctl>(fd, TCSETS, (void *)attr, &res);
}
+ int Sysdeps<Tcgetwinsize>::operator()(int fd, struct winsize *winsz) {
+ int res;
+ return sysdep<Ioctl>(fd, TIOCGWINSZ, (void *)winsz, &res);
+ }
+
+ int Sysdeps<Tcsetwinsize>::operator()(int fd, const struct winsize *winsz) {
+ int res;
+ return sysdep<Ioctl>(fd, TIOCSWINSZ, (void *)winsz, &res);
+ }
+
int Sysdeps<Poll>::operator()(struct pollfd *fds, nfds_t count, int timeout, int *num_events) {
long ret;
long error = syscall(SYSCALL_POLL, &ret, (uint64_t)fds, count, timeout);
@@ -932,4 +1358,13 @@ namespace mlibc {
*nanos = ts.tv_nsec;
return err;
}
+
+ int Sysdeps<ClockGetres>::operator()(int clock, time_t *secs, long *nanos) {
+ struct timespec ts;
+ long ret;
+ int err = syscall(SYSCALL_CLOCK_GETRES, &ret, clock, (uint64_t)&ts);
+ *secs = ts.tv_sec;
+ *nanos = ts.tv_nsec;
+ return err;
+ }
} // namespace mlibc
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..9040d45 100644
--- mlibc-clean/sysdeps/astral/include/astral/syscall.h
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
@@ -103,6 +103,14 @@
#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
+#define SYSCALL_CLOCK_GETRES 103
+#define SYSCALL_SETPRIORITY 104
+#define SYSCALL_SYSCTL 105
+#define SYSCALL_EVENTFD 106
#ifndef __MLIBC_ABI_ONLY
diff --git mlibc-workdir/sysdeps/astral/include/astral/sysctl.h mlibc-workdir/sysdeps/astral/include/astral/sysctl.h
new file mode 100644
index 0000000..3379839
--- /dev/null
+++ mlibc-workdir/sysdeps/astral/include/astral/sysctl.h
@@ -0,0 +1,57 @@
+#ifndef _ASTRAL_SYSCTL_H
+#define _ASTRAL_SYSCTL_H
+
+#include <bits/size_t.h>
+#include <abi-bits/uid_t.h>
+#include <abi-bits/gid_t.h>
+#include <abi-bits/pid_t.h>
+#include <bits/ansi/timespec.h>
+
+#define SYS_CTL_NAME_MAX 6
+
+#define SYS_CTL_KERN 1
+#define SYS_CTL_KERN_PROC 1
+#define SYS_CTL_KERN_PROC_ALL 1
+#define SYS_CTL_KERN_CONSOLE_LOCK 2
+
+#define SYS_CTL_KERN_PROC_INFO_NAME_SIZE 64
+#define SYS_CTL_KERN_PROC_INFO_TTY_NAME_SIZE 64
+
+typedef struct {
+ pid_t pid;
+ uid_t uid;
+ uid_t euid;
+ uid_t suid;
+ gid_t gid;
+ gid_t egid;
+ gid_t sgid;
+ size_t thread_count;
+ char name[SYS_CTL_KERN_PROC_INFO_NAME_SIZE];
+ pid_t ppid;
+ pid_t pgid;
+ pid_t sid;
+ struct timespec start_timestamp;
+ struct timespec total_runtime;
+ int state;
+ int cpu_time;
+ int nice;
+ size_t virtual_pages;
+ size_t physical_pages;
+ char tty_name[SYS_CTL_KERN_PROC_INFO_TTY_NAME_SIZE];
+} sysctl_proc_info_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MLIBC_ABI_ONLY
+
+int sysctl(const int *__name, size_t __name_len, void *__oldp, size_t *__old_lenp, void *__newp, size_t __new_len);
+
+#endif /* !__MLIBC_ABI_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASTRAL_SYSCTL_H */
diff --git mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp mlibc-workdir/sysdeps/astral/include/mlibc/sysdeps.hpp
index ce91084..503110a 100644
--- mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp
+++ mlibc-workdir/sysdeps/astral/include/mlibc/sysdeps.hpp
@@ -7,8 +7,30 @@ namespace mlibc {
struct AstralSysdepTags :
SetGroups,
GetGroups,
+ GetLoadavg,
+ Times,
+ Fadvise,
+ Setxattr,
+ Lsetxattr,
+ Fsetxattr,
+ Getxattr,
+ Lgetxattr,
+ Fgetxattr,
+ Listxattr,
+ Llistxattr,
+ Flistxattr,
+ Getifaddrs,
+ IfIndextoname,
+ IfNametoindex,
+ IfNameindex,
GetSockopt,
InetConfigured,
+ Unlockpt,
+ Statfs,
+ Fstatfs,
+ Statvfs,
+ Fstatvfs,
+ Yield,
Readv,
Writev,
Sysinfo,
@@ -66,6 +88,7 @@ struct AstralSysdepTags :
SetSid,
FutexTid,
GetTid,
+ ThreadSetname,
ThreadExit,
Clone,
Listen,
@@ -77,6 +100,7 @@ struct AstralSysdepTags :
Bind,
Socket,
Renameat,
+ Renameat2,
Rename,
Utimensat,
Fchownat,
@@ -85,6 +109,8 @@ struct AstralSysdepTags :
Sleep,
Tcgetattr,
Tcsetattr,
+ Tcgetwinsize,
+ Tcsetwinsize,
Poll,
Ppoll,
Pselect,
@@ -135,7 +161,11 @@ struct AstralSysdepTags :
VmUnmap,
Isatty,
ClockGet,
- PrepareStack
+ ClockGetres,
+ PrepareStack,
+ SetPriority,
+ GetCurrentStackInfo,
+ EventfdCreate
{};
template<typename Tag>
diff --git mlibc-clean/sysdeps/astral/meson.build mlibc-workdir/sysdeps/astral/meson.build
index 43dd6b0..3e01e87 100644
--- mlibc-clean/sysdeps/astral/meson.build
+++ mlibc-workdir/sysdeps/astral/meson.build
@@ -86,6 +86,7 @@ if not no_headers
install_headers(
'include/astral/syscall.h',
'include/astral/archctl.h',
+ 'include/astral/sysctl.h',
subdir: 'astral',
follow_symlinks: true,
)
diff --git mlibc-workdir/tests/glibc/memalign.c mlibc-workdir/tests/glibc/memalign.c
new file mode 100644
index 0000000..0b3a158
--- /dev/null
+++ mlibc-workdir/tests/glibc/memalign.c
@@ -0,0 +1,22 @@
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+int main(void) {
+ void *p;
+
+ errno = 0;
+ p = memalign(256, 1);
+ assert(p != NULL);
+ assert((uintptr_t)p % 256 == 0);
+ free(p);
+
+ errno = 0;
+ p = memalign(3, 1);
+ assert(p == NULL);
+ assert(errno == EINVAL);
+
+ return 0;
+}
diff --git mlibc-clean/tests/meson.build mlibc-workdir/tests/meson.build
index 9c5bcd7..8b2b95e 100644
--- mlibc-clean/tests/meson.build
+++ mlibc-workdir/tests/meson.build
@@ -170,6 +170,7 @@ all_test_cases = [
'glibc/rpmatch',
'glibc/strverscmp',
'glibc/memmem',
+ 'glibc/memalign',
'glibc/stdio_ext',
'glibc/_dl_find_object',
'glibc/shadow',