aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2020-11-17 16:13:02 +0000
committerJonathan Wakely <jwakely@redhat.com>2020-11-17 22:38:49 +0000
commit1e3e6c700f04fe6992b9077541e434172c1cbdae (patch)
treef5fe26e1f78055d0ccd01c0e2987d270099ffc3d
parent61ef34c503443dadc0744c5150256b90d138db0a (diff)
downloadgcc-1e3e6c700f04fe6992b9077541e434172c1cbdae.zip
gcc-1e3e6c700f04fe6992b9077541e434172c1cbdae.tar.gz
gcc-1e3e6c700f04fe6992b9077541e434172c1cbdae.tar.bz2
libstdc++: Revert changes for SYS_clock_gettime64 [PR 93421]
As discussed in the PR, it's incredibly unlikely that a system that needs to use the SYS_clock_gettime syscall (e.g. glibc 2.16 or older) is going to define the SYS_clock_gettime64 macro. Ancient systems that need to use the syscall aren't going to have time64 support. This reverts the recent changes to try and make clock_gettime syscalls be compatible with systems that have been updated for time64 (those changes were wrong anyway as they misspelled the SYS_clock_gettime64 macro). The changes for futex syscalls are retained, because we still use them on modern systems that might be using time64. To ensure that the clock_gettime syscalls are safe, configure will fail if SYS_clock_gettime is needed, and SYS_clock_gettime64 is also defined (but to a distinct value from SYS_clock_gettime), and the tv_sec member of timespec is larger than long. This means we will be unable to build on a hypothetical system where we need the time32 version of SYS_clock_gettime but where userspace is using a time64 struct timespec. In the unlikely event that this failure is triggered on any real systems, we can fix it later. But we probably won't need to. libstdc++-v3/ChangeLog: PR libstdc++/93421 * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Fail if struct timespec isn't compatible with SYS_clock_gettime. * configure: Regenerate. * src/c++11/chrono.cc: Revert changes for time64 compatibility. Add static_assert instead. * src/c++11/futex.cc (_M_futex_wait_until_steady): Assume SYS_clock_gettime can use struct timespec.
-rw-r--r--libstdc++-v3/acinclude.m429
-rwxr-xr-xlibstdc++-v3/configure45
-rw-r--r--libstdc++-v3/src/c++11/chrono.cc17
-rw-r--r--libstdc++-v3/src/c++11/futex.cc7
4 files changed, 70 insertions, 28 deletions
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 650d63a..486347b 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -1561,13 +1561,34 @@ AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
#endif
syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &tp);
syscall(SYS_clock_gettime, CLOCK_REALTIME, &tp);
- ], [ac_has_clock_monotonic_syscall=yes], [ac_has_clock_monotonic_syscall=no])
- AC_MSG_RESULT($ac_has_clock_monotonic_syscall)
- if test x"$ac_has_clock_monotonic_syscall" = x"yes"; then
+ ], [ac_has_clock_gettime_syscall=yes], [ac_has_clock_gettime_syscall=no])
+ AC_MSG_RESULT($ac_has_clock_gettime_syscall)
+ if test x"$ac_has_clock_gettime_syscall" = x"yes"; then
AC_DEFINE(_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL, 1,
- [ Defined if clock_gettime syscall has monotonic and realtime clock support. ])
+ [Defined if clock_gettime syscall has monotonic and realtime clock support. ])
ac_has_clock_monotonic=yes
ac_has_clock_realtime=yes
+ AC_MSG_CHECKING([for struct timespec that matches syscall])
+ AC_TRY_COMPILE(
+ [#include <time.h>
+ #include <sys/syscall.h>
+ ],
+ [#ifdef SYS_clock_gettime64
+ #if SYS_clock_gettime64 != SYS_clock_gettime
+ // We need to use SYS_clock_gettime and libc appears to
+ // also know about the SYS_clock_gettime64 syscall.
+ // Check that userspace doesn't use time64 version of timespec.
+ static_assert(sizeof(timespec::tv_sec) == sizeof(long),
+ "struct timespec must be compatible with SYS_clock_gettime");
+ #endif
+ #endif
+ ],
+ [ac_timespec_matches_syscall=yes],
+ [ac_timespec_matches_syscall=no])
+ AC_MSG_RESULT($ac_timespec_matches_syscall)
+ if test x"$ac_timespec_matches_syscall" = no; then
+ AC_MSG_ERROR([struct timespec is not compatible with SYS_clock_gettime, please report a bug to http://gcc.gnu.org/bugzilla])
+ fi
fi;;
esac
fi
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 1997c1f..d9ed414 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -21661,19 +21661,54 @@ main ()
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_has_clock_monotonic_syscall=yes
+ ac_has_clock_gettime_syscall=yes
else
- ac_has_clock_monotonic_syscall=no
+ ac_has_clock_gettime_syscall=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_has_clock_monotonic_syscall" >&5
-$as_echo "$ac_has_clock_monotonic_syscall" >&6; }
- if test x"$ac_has_clock_monotonic_syscall" = x"yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_has_clock_gettime_syscall" >&5
+$as_echo "$ac_has_clock_gettime_syscall" >&6; }
+ if test x"$ac_has_clock_gettime_syscall" = x"yes"; then
$as_echo "#define _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL 1" >>confdefs.h
ac_has_clock_monotonic=yes
ac_has_clock_realtime=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timespec that matches syscall" >&5
+$as_echo_n "checking for struct timespec that matches syscall... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <time.h>
+ #include <sys/syscall.h>
+
+int
+main ()
+{
+#ifdef SYS_clock_gettime64
+ #if SYS_clock_gettime64 != SYS_clock_gettime
+ // We need to use SYS_clock_gettime and libc appears to
+ // also know about the SYS_clock_gettime64 syscall.
+ // Check that userspace doesn't use time64 version of timespec.
+ static_assert(sizeof(timespec::tv_sec) == sizeof(long),
+ "struct timespec must be compatible with SYS_clock_gettime");
+ #endif
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_timespec_matches_syscall=yes
+else
+ ac_timespec_matches_syscall=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_timespec_matches_syscall" >&5
+$as_echo "$ac_timespec_matches_syscall" >&6; }
+ if test x"$ac_timespec_matches_syscall" = no; then
+ as_fn_error $? "struct timespec is not compatible with SYS_clock_gettime, please report a bug to http://gcc.gnu.org/bugzilla" "$LINENO" 5
+ fi
fi;;
esac
fi
diff --git a/libstdc++-v3/src/c++11/chrono.cc b/libstdc++-v3/src/c++11/chrono.cc
index f10be7d..723f300 100644
--- a/libstdc++-v3/src/c++11/chrono.cc
+++ b/libstdc++-v3/src/c++11/chrono.cc
@@ -35,17 +35,6 @@
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
#include <unistd.h>
#include <sys/syscall.h>
-
-# if defined(SYS_clock_gettime_time64) \
- && SYS_clock_gettime_time64 != SYS_clock_gettime
- // Userspace knows about the new time64 syscalls, so it's possible that
- // userspace has also updated timespec to use a 64-bit tv_sec.
- // The SYS_clock_gettime syscall still uses the old definition
- // of timespec where tv_sec is 32 bits, so define a type that matches that.
- struct syscall_timespec { long tv_sec; long tv_nsec; };
-# else
- using syscall_timespec = ::timespec;
-# endif
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@@ -63,12 +52,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
system_clock::now() noexcept
{
#ifdef _GLIBCXX_USE_CLOCK_REALTIME
+ timespec tp;
// -EINVAL, -EFAULT
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
- syscall_timespec tp;
syscall(SYS_clock_gettime, CLOCK_REALTIME, &tp);
#else
- timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
#endif
return time_point(duration(chrono::seconds(tp.tv_sec)
@@ -92,12 +80,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
steady_clock::now() noexcept
{
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
+ timespec tp;
// -EINVAL, -EFAULT
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
- syscall_timespec tp;
syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &tp);
#else
- timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
#endif
return time_point(duration(chrono::seconds(tp.tv_sec)
diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index 9adfb89..33e2097 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -61,8 +61,8 @@ namespace
#if defined(SYS_futex_time64) && SYS_futex_time64 != SYS_futex
// Userspace knows about the new time64 syscalls, so it's possible that
// userspace has also updated timespec to use a 64-bit tv_sec.
- // The SYS_futex and SYS_clock_gettime syscalls still use the old definition
- // of timespec where tv_sec is 32 bits, so define a type that matches that.
+ // The SYS_futex syscall still uses the old definition of timespec
+ // where tv_sec is 32 bits, so define a type that matches that.
struct syscall_timespec { long tv_sec; long tv_nsec; };
#else
using syscall_timespec = ::timespec;
@@ -234,11 +234,10 @@ namespace
// We only get to here if futex_clock_monotonic_unavailable was
// true or has just been set to true.
+ struct timespec ts;
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
- syscall_timespec ts;
syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts);
#else
- struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
#endif