This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC v6 04/23] linux: Use 32-bit time_t for itimerval
- From: Alistair Francis <alistair dot francis at wdc dot com>
- To: libc-alpha at sourceware dot org
- Cc: arnd at arndb dot de, adhemerval dot zanella at linaro dot org, fweimer at redhat dot com, joseph at codesourcery dot com, palmerdabbelt at google dot com, macro at wdc dot com, zongbox at gmail dot com, alistair dot francis at wdc dot com, alistair23 at gmail dot com
- Date: Sun, 12 Jan 2020 02:33:41 -0800
- Subject: [RFC v6 04/23] linux: Use 32-bit time_t for itimerval
- Ironport-sdr: hLf1mFhxer1889LMKHJo+SbiMcTMjKLtOBS2pb2AiL5zeE77GZ+6yovdVlsTXYDDiK0qpIsisE +mOySHfw1U15GwlB8G9uetno82/71BSkQmhpMbg6QJPpRHkSXgQiQWBZ1YrdbqGNvNeDvgyEK1 YV3xXuZOqqhX9uzu3cN+WQYQxYdfhm6YIWua7G7AxmXxvy7NOCEWUuEb/Yo8iaPaXrsWR9CTVW 3vNOL6A2Xu8Ktyg9DRI/XPg5vrMm5dP7gDdUI2ws9IXyq02Lx1V6/Y/riBHp9RYVB0Ot/9BLSH 1wg=
- Ironport-sdr: b9Un86IT4BzZK3R01ePj53CVAxuXGKS3gWtAcsbdZ/JX9ZrGZvbDFze+OK0iRvRaH/VHyZsu6X 75eUQjKe0/u8MNDqoLjZa3QSpyq92Hjgw7lvt3aARNR+ZaR5ldaZMsVw3ukU+8tIT9jonYey1H 7+T3Ej2VcR1vizxLSSA/1Drk/JRB7G1VAKfzQbMRJ2cgSqqXn36s7shym2vNWQmWl/Ea1ZQh+C WS8xQvDKe0kOeenuW61sEiIVgrGTxhlxc97xc6Fem2N5tHdPZzDk/oOZCX0ezLoVQKjvQIi0ld znoRx3ZzlLdoe2I5z5EqKh+o
- Ironport-sdr: RD+db/2cFaavxMEgnePl7GaXR+p153Y39FaFTM9W1rflyJjmffiI4w4QyPfehpIvfS6dX2onlT TYB9tGwZ5sYfljnKM5ZJaJ9eugd6XsjuF3MCuMzFfv0VarK4H+xauNBAoJ+ul6Sy2lU9dY42yb FUj29kjtsRHARrEAvFr+ZFBOs8WzLpdWEYmHv/juUaJoTpgMWA1nms5WcZ5IDrZrrMfvHO+jFn Sac/rHvrkFMpQchiUzwdQR5PuD9O/oZ40a83+Ow3ErURx0UjkgP8JLc29qU9+XGhzSnkYme8aP GW8=
- References: <cover.1578824547.git.alistair.francis@wdc.com>
- Wdcironportexception: Internal
The Linux kernel expects itimerval to use a 32-bit time_t, even on archs
with a 64-bit time_t (like RV32). To address this let's convert
itimerval to/from 32-bit and 64-bit to ensure the kernel always gets
a 32-bit time_t.
This means that all 32-bit architectures with a 64-bit time_t will be
able to use this generic implementation.
This code is bsaed on similar code in alpha, but adjusted to pass the
32-bit time_t to the kernel.
We can't directly call the __getitimer/__setitimer functions as they
expect a struct itimerval but we need to pass in a struct itimerval32.
---
.../linux/generic/wordsize-32/getitimer.c | 42 +++++++++++++++
.../linux/generic/wordsize-32/setitimer.c | 53 +++++++++++++++++++
.../linux/generic/wordsize-32/tv32-compat.h | 35 ++++++++++++
3 files changed, 130 insertions(+)
create mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/getitimer.c
create mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/setitimer.c
create mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/getitimer.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/getitimer.c
new file mode 100644
index 0000000000..b279acbc2e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/getitimer.c
@@ -0,0 +1,42 @@
+/* getitimer -- Get the state of an interval timer. Linux/RV32/tv32 version.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/time.h>
+#include <sysdep.h>
+#include <tv32-compat.h>
+
+int
+__getitimer (__itimer_which_t which, struct itimerval *curr_value)
+{
+#if __TIMESIZE == 64
+ struct itimerval32 curr_value_32;
+ if (INLINE_SYSCALL_CALL (getitimer, which, &curr_value_32) == -1)
+ return -1;
+
+ /* Write all fields of 'curr_value' regardless of overflow. */
+ curr_value->it_interval
+ = valid_timeval_long_to_timeval64 (curr_value_32.it_interval);
+ curr_value->it_value
+ = valid_timeval_long_to_timeval64 (curr_value_32.it_value);
+ return 0;
+#else
+ return INLINE_SYSCALL_CALL (getitimer, which, curr_value);
+#endif
+}
+
+weak_alias (__getitimer, getitimer)
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/setitimer.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/setitimer.c
new file mode 100644
index 0000000000..807683ccae
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/setitimer.c
@@ -0,0 +1,53 @@
+/* getitimer -- Get the state of an interval timer. Linux/RV32/tv32 version.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/time.h>
+#include <sysdep.h>
+#include <tv32-compat.h>
+
+int
+__setitimer (__itimer_which_t which,
+ const struct itimerval *restrict new_value,
+ struct itimerval *restrict old_value)
+{
+#if __TIMESIZE == 64
+ struct itimerval32 new_value_32;
+ new_value_32.it_interval
+ = valid_timeval64_to_timeval_long (new_value->it_interval);
+ new_value_32.it_value
+ = valid_timeval64_to_timeval_long (new_value->it_value);
+
+ if (old_value == NULL)
+ return INLINE_SYSCALL_CALL (setitimer, which, &new_value_32, NULL);
+
+ struct itimerval32 old_value_32;
+ if (INLINE_SYSCALL_CALL (setitimer, which, &new_value_32, &old_value_32) == -1)
+ return -1;
+
+ /* Write all fields of 'old_value' regardless of overflow. */
+ old_value->it_interval
+ = valid_timeval_long_to_timeval64 (old_value_32.it_interval);
+ old_value->it_value
+ = valid_timeval_long_to_timeval64 (old_value_32.it_value);
+ return 0;
+#else
+ return INLINE_SYSCALL_CALL (setitimer, which, new_value, old_value);
+#endif
+}
+
+weak_alias (__setitimer, setitimer)
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h b/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h
new file mode 100644
index 0000000000..aa960a6632
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h
@@ -0,0 +1,35 @@
+/* Compatibility definitions for `struct timeval' with 32-bit time_t.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _TV32_COMPAT_H
+#define _TV32_COMPAT_H 1
+
+#include <features.h>
+
+#include <bits/types.h>
+#include <bits/types/time_t.h>
+#include <bits/types/struct_timeval.h>
+
+/* Structures containing 'struct timeval' with 32-bit time_t. */
+struct itimerval32
+{
+ struct __timeval_long it_interval;
+ struct __timeval_long it_value;
+};
+
+#endif /* tv32-compat.h */
--
2.24.1