[compiler-rt] ca747e4 - [sanitizer] Restrict clock_gettime workaround to glibc

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 6 10:32:33 PST 2021


Author: Fangrui Song
Date: 2021-03-06T10:32:27-08:00
New Revision: ca747e48afa091afd8568df8973dfcbd43b8e334

URL: https://github.com/llvm/llvm-project/commit/ca747e48afa091afd8568df8973dfcbd43b8e334
DIFF: https://github.com/llvm/llvm-project/commit/ca747e48afa091afd8568df8973dfcbd43b8e334.diff

LOG: [sanitizer] Restrict clock_gettime workaround to glibc

The hackery is due to glibc clock_gettime crashing from preinit_array (D40679).
32-bit musl architectures do not define `__NR_clock_gettime` so the code causes a compile error.

Tested on Alpine Linux x86-64 (musl) and FreeBSD x86-64.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D96925

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_linux.h
    compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index d4b9ea5f7f06..f1cf51f5b2bf 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2178,6 +2178,7 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
   }
   return res;
 }
+#if SANITIZER_GLIBC
 namespace __sanitizer {
 extern "C" {
 int real_clock_gettime(u32 clk_id, void *tp) {
@@ -2187,6 +2188,7 @@ int real_clock_gettime(u32 clk_id, void *tp) {
 }
 }  // extern "C"
 }  // namespace __sanitizer
+#endif
 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 253767709702..9d4fd06ed37e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -500,11 +500,13 @@ u64 NanoTime() {
   internal_syscall(SYSCALL(gettimeofday), &tv, 0);
   return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
 }
+#endif  // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
 
+#if SANITIZER_GLIBC
 uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
   return internal_syscall(SYSCALL(clock_gettime), clk_id, tp);
 }
-#endif  // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+#endif  // SANITIZER_GLIBC
 
 // Like getenv, but reads env directly from /proc (on Linux) or parses the
 // 'environ' array (on some others) and does not use libc. This function

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 24902d1b6bce..41ae072d6cac 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -49,7 +49,9 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
 uptr internal_sigaltstack(const void* ss, void* oss);
 uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
     __sanitizer_sigset_t *oldset);
+#if SANITIZER_GLIBC
 uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp);
+#endif
 
 // Linux-only syscalls.
 #if SANITIZER_LINUX

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index f20b9001c2c2..2fff501651a9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -803,20 +803,13 @@ void LogMessageOnPrintf(const char *str) {
 
 #endif  // SANITIZER_LINUX
 
-#if SANITIZER_LINUX && !SANITIZER_GO
+#if SANITIZER_GLIBC && !SANITIZER_GO
 // glibc crashes when using clock_gettime from a preinit_array function as the
 // vDSO function pointers haven't been initialized yet. __progname is
 // initialized after the vDSO function pointers, so if it exists, is not null
 // and is not empty, we can use clock_gettime.
 extern "C" SANITIZER_WEAK_ATTRIBUTE char *__progname;
-inline bool CanUseVDSO() {
-  // Bionic is safe, it checks for the vDSO function pointers to be initialized.
-  if (SANITIZER_ANDROID)
-    return true;
-  if (&__progname && __progname && *__progname)
-    return true;
-  return false;
-}
+inline bool CanUseVDSO() { return &__progname && __progname && *__progname; }
 
 // MonotonicNanoTime is a timing function that can leverage the vDSO by calling
 // clock_gettime. real_clock_gettime only exists if clock_gettime is
@@ -836,10 +829,10 @@ u64 MonotonicNanoTime() {
   return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
 }
 #else
-// Non-Linux & Go always use the syscall.
+// Non-Linux & Go always use the regular function.
 u64 MonotonicNanoTime() {
   timespec ts;
-  internal_clock_gettime(CLOCK_MONOTONIC, &ts);
+  clock_gettime(CLOCK_MONOTONIC, &ts);
   return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
 }
 #endif  // SANITIZER_LINUX && !SANITIZER_GO


        


More information about the llvm-commits mailing list