From d26183b908af41cce760d3715ccc67a2a1b90a7a Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Sat, 17 Feb 2024 03:15:53 +0300 Subject: [PATCH 1/6] options/ansi: use __mlibc_int64 for time_t --- options/ansi/include/bits/ansi/time_t.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/options/ansi/include/bits/ansi/time_t.h b/options/ansi/include/bits/ansi/time_t.h index 1c29fa0f67..bd0c4a7e5b 100644 --- a/options/ansi/include/bits/ansi/time_t.h +++ b/options/ansi/include/bits/ansi/time_t.h @@ -2,7 +2,8 @@ #ifndef MLIBC_TIME_T #define MLIBC_TIME_T -typedef long time_t; +#include +typedef __mlibc_int64 time_t; #endif From 51287efcea6564e204102770804008c5ea31b2cd Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Sat, 17 Feb 2024 03:38:32 +0300 Subject: [PATCH 2/6] tests/ansi: use PRId64 in timegm --- tests/ansi/timegm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/ansi/timegm.c b/tests/ansi/timegm.c index f5af03ea43..6a7e0c07fb 100644 --- a/tests/ansi/timegm.c +++ b/tests/ansi/timegm.c @@ -1,6 +1,7 @@ #include #include #include +#include int main() { struct tm soon = {}; @@ -14,7 +15,7 @@ int main() { time_t expected_result = 0; // This should be epoch. result = timegm(&soon); - printf("epoch: %ld\n", result); + printf("epoch: %" PRId64 "\n", result); assert(result == expected_result); soon.tm_sec = 12; @@ -26,7 +27,7 @@ int main() { expected_result = 1652803692; result = timegm(&soon); // On my host, this returned 1652803692, verify this. - printf("epoch: %ld\n", result); + printf("epoch: %" PRId64 "\n", result); assert(result == expected_result); soon.tm_sec = 45; @@ -38,7 +39,7 @@ int main() { expected_result = -9181035; result = timegm(&soon); // On my host, this returned -9181035, verify this. - printf("epoch: %ld\n", result); + printf("epoch: %" PRId64 "\n", result); assert(result == expected_result); return 0; From d47a2ae8feda6e55347a81ab34005147670a03f0 Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Mon, 4 Mar 2024 21:15:50 +0300 Subject: [PATCH 3/6] sysdeps/linux: use 64-bit compat syscalls --- sysdeps/linux/generic/sysdeps.cpp | 74 ++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/sysdeps/linux/generic/sysdeps.cpp b/sysdeps/linux/generic/sysdeps.cpp index 447ec75b7e..355166aebf 100644 --- a/sysdeps/linux/generic/sysdeps.cpp +++ b/sysdeps/linux/generic/sysdeps.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -235,7 +236,11 @@ int sys_vm_unmap(void *pointer, size_t size) { int sys_clock_get(int clock, time_t *secs, long *nanos) { struct timespec tp = {}; +#if UINTPTR_MAX == UINT64_MAX auto ret = do_syscall(SYS_clock_gettime, clock, &tp); +#else + auto ret = do_syscall(SYS_clock_gettime64, clock, &tp); +#endif if (int e = sc_error(ret); e) return e; *secs = tp.tv_sec; @@ -245,7 +250,11 @@ int sys_clock_get(int clock, time_t *secs, long *nanos) { int sys_clock_getres(int clock, time_t *secs, long *nanos) { struct timespec tp = {}; +#if UINTPTR_MAX == UINT64_MAX auto ret = do_syscall(SYS_clock_getres, clock, &tp); +#else + auto ret = do_syscall(SYS_clock_getres_time64, clock, &tp); +#endif if (int e = sc_error(ret); e) return e; *secs = tp.tv_sec; @@ -272,14 +281,22 @@ int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, struct stat } int sys_statfs(const char *path, struct statfs *buf) { +#if UINTPTR_MAX == UINT64_MAX auto ret = do_cp_syscall(SYS_statfs, path, buf); +#else + auto ret = do_cp_syscall(SYS_statfs64, path, buf); +#endif if (int e = sc_error(ret); e) return e; return 0; } int sys_fstatfs(int fd, struct statfs *buf) { +#if UINTPTR_MAX == UINT64_MAX auto ret = do_cp_syscall(SYS_fstatfs, fd, buf); +#else + auto ret = do_cp_syscall(SYS_fstatfs64, fd, buf); +#endif if (int e = sc_error(ret); e) return e; return 0; @@ -307,11 +324,11 @@ int sys_sigaction(int signum, const struct sigaction *act, static_assert(sizeof(sigset_t) == 8); - auto ret = do_syscall(SYS_rt_sigaction, signum, act ? - &kernel_act : NULL, oldact ? - &kernel_oldact : NULL, sizeof(sigset_t)); - if (int e = sc_error(ret); e) - return e; + auto ret = do_syscall(SYS_rt_sigaction, signum, act ? + &kernel_act : NULL, oldact ? + &kernel_oldact : NULL, sizeof(sigset_t)); + if (int e = sc_error(ret); e) + return e; if (oldact) { oldact->sa_handler = kernel_oldact.handler; @@ -763,9 +780,42 @@ int sys_setpriority(int which, id_t who, int prio) { } int sys_setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) { +#if UINTPTR_MAX == UINT64_MAX auto ret = do_syscall(SYS_setitimer, which, new_value, old_value); + if (int e = sc_error(ret); e) return e; + +#else + if (new_value->it_interval.tv_sec > INT32_MAX) + return -ENOTSUP; + if (new_value->it_value.tv_sec > INT32_MAX) + return -ENOTSUP; + + long new_isec = (long)new_value->it_interval.tv_sec; + long new_vsec = (long)new_value->it_value.tv_sec; + + long new_raw[4] = { + new_isec, new_value->it_interval.tv_usec, + new_vsec, new_value->it_value.tv_usec, + }; + long old_raw[4]; + + auto ret = do_syscall(SYS_setitimer, which, new_raw, old_raw); + + if (int e = sc_error(ret); e) { + return e; + } + + + if (old_value) { + old_value->it_interval.tv_sec = old_raw[0]; + old_value->it_interval.tv_usec = old_raw[1]; + old_value->it_value.tv_sec = old_raw[2]; + old_value->it_value.tv_usec = old_raw[3]; + } + +#endif return 0; } @@ -811,7 +861,11 @@ int sys_timer_create(clockid_t clk, struct sigevent *__restrict evp, timer_t *__ } int sys_timer_settime(timer_t t, int flags, const struct itimerspec *__restrict val, struct itimerspec *__restrict old) { +#if UINTPTR_MAX == UINT64_MAX auto ret = do_syscall(SYS_timer_settime, t, flags, val, old); +#else + auto ret = do_syscall(SYS_timer_settime64, t, flags, val, old); +#endif if (int e = sc_error(ret); e) { return e; } @@ -1019,7 +1073,11 @@ int sys_timerfd_create(int clockid, int flags, int *fd) { } int sys_timerfd_settime(int fd, int flags, const struct itimerspec *value, struct itimerspec *oldvalue) { +#if UINTPTR_MAX == UINT64_MAX auto ret = do_syscall(SYS_timerfd_settime, fd, flags, value, oldvalue); +#else + auto ret = do_syscall(SYS_timerfd_settime64, fd, flags, value, oldvalue); +#endif if (int e = sc_error(ret); e) return e; return 0; @@ -1579,9 +1637,15 @@ int sys_futex_tid() { } int sys_futex_wait(int *pointer, int expected, const struct timespec *time) { +#if UINTPTR_MAX == UINT64_MAX auto ret = do_cp_syscall(SYS_futex, pointer, FUTEX_WAIT, expected, time); +#else + auto ret = do_cp_syscall(SYS_futex_time64, pointer, FUTEX_WAIT, expected, time); +#endif + if (int e = sc_error(ret); e) return e; + return 0; } From 6936e88981127ac3092f565f5bd5925fc3f88af8 Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Mon, 4 Mar 2024 21:59:36 +0300 Subject: [PATCH 4/6] options/ansi: pad tv_nsec in timespec --- options/ansi/include/bits/ansi/timespec.h | 3 ++- options/internal/include/bits/field-padding.h | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 options/internal/include/bits/field-padding.h diff --git a/options/ansi/include/bits/ansi/timespec.h b/options/ansi/include/bits/ansi/timespec.h index d34aa649e3..70d06eebe1 100644 --- a/options/ansi/include/bits/ansi/timespec.h +++ b/options/ansi/include/bits/ansi/timespec.h @@ -3,10 +3,11 @@ #define MLIBC_TIMESPEC_H #include +#include struct timespec { time_t tv_sec; - long tv_nsec; + __MLIBC_FIELD_PADDED(long, tv_nsec, long long); }; #endif // MLIBC_TIMESPEC_H diff --git a/options/internal/include/bits/field-padding.h b/options/internal/include/bits/field-padding.h new file mode 100644 index 0000000000..7fe9a95fb2 --- /dev/null +++ b/options/internal/include/bits/field-padding.h @@ -0,0 +1,15 @@ +#ifndef MLIBC_FIELD_PADDING_H +#define MLIBC_FIELD_PADDING_H + +#ifdef __GNUC__ + +#define __MLIBC_FIELD_PADDED(T, F, PT) \ + PT : (sizeof(PT)-sizeof(T))*8*(BYTE_ORDER == BIG_ENDIAN); \ + T F; \ + PT : (sizeof(PT)-sizeof(T))*8*(BYTE_ORDER == LITTLE_ENDIAN) + +#else +#error "Unsupported compiler" +#endif + +#endif From 6774dcf6738396867a290f1538bee082c77bc8d9 Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Mon, 4 Mar 2024 23:55:11 +0300 Subject: [PATCH 5/6] options/ansi: add a comment about layout of timespec --- options/ansi/include/bits/ansi/timespec.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/options/ansi/include/bits/ansi/timespec.h b/options/ansi/include/bits/ansi/timespec.h index 70d06eebe1..926d8e7f3c 100644 --- a/options/ansi/include/bits/ansi/timespec.h +++ b/options/ansi/include/bits/ansi/timespec.h @@ -5,8 +5,13 @@ #include #include +// Equivalent of timespec64 in glibc. +// Should be used only with 64-bit syscalls +// or with appropriate compat syscalls. struct timespec { time_t tv_sec; + // tv_nspec is required to be long by the C standard. + // However linux kernel expects long long. So we add padding. __MLIBC_FIELD_PADDED(long, tv_nsec, long long); }; From f0098ed65db2b27a6bd4c74f7e6707e588826e82 Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Mon, 4 Mar 2024 23:56:21 +0300 Subject: [PATCH 6/6] options/internal: remove __GNUC__ requirement for __MLIBC_FIELD_PADDED --- options/ansi/include/bits/ansi/timespec.h | 2 +- options/internal/include/bits/field-padding.h | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/options/ansi/include/bits/ansi/timespec.h b/options/ansi/include/bits/ansi/timespec.h index 926d8e7f3c..13a6e546e6 100644 --- a/options/ansi/include/bits/ansi/timespec.h +++ b/options/ansi/include/bits/ansi/timespec.h @@ -12,7 +12,7 @@ struct timespec { time_t tv_sec; // tv_nspec is required to be long by the C standard. // However linux kernel expects long long. So we add padding. - __MLIBC_FIELD_PADDED(long, tv_nsec, long long); + __MLIBC_FIELD_PADDED(long, long long, tv_nsec); }; #endif // MLIBC_TIMESPEC_H diff --git a/options/internal/include/bits/field-padding.h b/options/internal/include/bits/field-padding.h index 7fe9a95fb2..935953613d 100644 --- a/options/internal/include/bits/field-padding.h +++ b/options/internal/include/bits/field-padding.h @@ -1,15 +1,9 @@ #ifndef MLIBC_FIELD_PADDING_H #define MLIBC_FIELD_PADDING_H -#ifdef __GNUC__ - -#define __MLIBC_FIELD_PADDED(T, F, PT) \ - PT : (sizeof(PT)-sizeof(T))*8*(BYTE_ORDER == BIG_ENDIAN); \ +#define __MLIBC_FIELD_PADDED(T, AT, F) \ + AT : (sizeof(AT)-sizeof(T))*8*(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__); \ T F; \ - PT : (sizeof(PT)-sizeof(T))*8*(BYTE_ORDER == LITTLE_ENDIAN) - -#else -#error "Unsupported compiler" -#endif + AT : (sizeof(AT)-sizeof(T))*8*(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) #endif