[compiler-rt] ba6b1b4 - [Darwin] Improve runtime OS version checks

Julian Lettner via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 13:44:27 PDT 2020


Author: Julian Lettner
Date: 2020-06-03T13:44:11-07:00
New Revision: ba6b1b4353e33a7a36bcbad1d1c1157826197fd2

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

LOG: [Darwin] Improve runtime OS version checks

Use a struct to represent numerical versions instead of encoding release
names in an enumeration. This avoids the need to extend the enumeration
every time there is a new release.

Rename `GetMacosVersion() -> GetMacosAlignedVersion()` to better reflect
how this is used on non-MacOS platforms.

Reviewed By: delcypher

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

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_mac.h
    compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp
    compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index 7550545ea6fa..9a0053a59a64 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -388,7 +388,7 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
   // pthread_get_stacksize_np() returns an incorrect stack size for the main
   // thread on Mavericks. See
   // https://github.com/google/sanitizers/issues/261
-  if ((GetMacosVersion() >= MACOS_VERSION_MAVERICKS) && at_initialization &&
+  if ((GetMacosAlignedVersion() >= MacosVersion(10, 9)) && at_initialization &&
       stacksize == (1 << 19))  {
     struct rlimit rl;
     CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
@@ -607,53 +607,27 @@ HandleSignalMode GetHandleSignalMode(int signum) {
   return result;
 }
 
-MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
-
-MacosVersion GetMacosVersionInternal() {
-  int mib[2] = { CTL_KERN, KERN_OSRELEASE };
-  char version[100];
-  uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]);
-  for (uptr i = 0; i < maxlen; i++) version[i] = '\0';
-  // Get the version length.
-  CHECK_NE(internal_sysctl(mib, 2, 0, &len, 0, 0), -1);
-  CHECK_LT(len, maxlen);
-  CHECK_NE(internal_sysctl(mib, 2, version, &len, 0, 0), -1);
-
-  // Expect <major>.<minor>(.<patch>)
-  CHECK_GE(len, 3);
-  const char *p = version;
-  int major = internal_simple_strtoll(p, &p, /*base=*/10);
-  if (*p != '.') return MACOS_VERSION_UNKNOWN;
-  p += 1;
-  int minor = internal_simple_strtoll(p, &p, /*base=*/10);
-  if (*p != '.') return MACOS_VERSION_UNKNOWN;
-
-  switch (major) {
-    case 11: return MACOS_VERSION_LION;
-    case 12: return MACOS_VERSION_MOUNTAIN_LION;
-    case 13: return MACOS_VERSION_MAVERICKS;
-    case 14: return MACOS_VERSION_YOSEMITE;
-    case 15: return MACOS_VERSION_EL_CAPITAN;
-    case 16: return MACOS_VERSION_SIERRA;
-    case 17: return MACOS_VERSION_HIGH_SIERRA;
-    case 18: return MACOS_VERSION_MOJAVE;
-    case 19: return MACOS_VERSION_CATALINA;
-    default:
-      if (major < 9) return MACOS_VERSION_UNKNOWN;
-      return MACOS_VERSION_UNKNOWN_NEWER;
-  }
+static MacosVersion GetMacosAlignedVersionInternal() {
+  u16 kernel_major = GetDarwinKernelVersion().major;
+  const u16 version_offset = 4;
+  CHECK_GE(kernel_major, version_offset);
+  u16 macos_major = kernel_major - version_offset;
+  return MacosVersion(10, macos_major);
 }
 
-MacosVersion GetMacosVersion() {
-  atomic_uint32_t *cache =
-      reinterpret_cast<atomic_uint32_t*>(&cached_macos_version);
-  MacosVersion result =
-      static_cast<MacosVersion>(atomic_load(cache, memory_order_acquire));
-  if (result == MACOS_VERSION_UNINITIALIZED) {
-    result = GetMacosVersionInternal();
-    atomic_store(cache, result, memory_order_release);
+static_assert(sizeof(MacosVersion) == sizeof(atomic_uint32_t::Type),
+              "MacosVersion cache size");
+static atomic_uint32_t cached_macos_version;
+
+MacosVersion GetMacosAlignedVersion() {
+  atomic_uint32_t::Type result =
+      atomic_load(&cached_macos_version, memory_order_acquire);
+  if (!result) {
+    MacosVersion version = GetMacosAlignedVersionInternal();
+    result = *reinterpret_cast<atomic_uint32_t::Type *>(&version);
+    atomic_store(&cached_macos_version, result, memory_order_release);
   }
-  return result;
+  return *reinterpret_cast<MacosVersion *>(&result);
 }
 
 DarwinKernelVersion GetDarwinKernelVersion() {
@@ -719,7 +693,7 @@ void LogFullErrorReport(const char *buffer) {
 #if !SANITIZER_GO
   // Log with os_trace. This will make it into the crash log.
 #if SANITIZER_OS_TRACE
-  if (GetMacosVersion() >= MACOS_VERSION_YOSEMITE) {
+  if (GetMacosAlignedVersion() >= MacosVersion(10, 10)) {
     // os_trace requires the message (format parameter) to be a string literal.
     if (internal_strncmp(SanitizerToolName, "AddressSanitizer",
                          sizeof("AddressSanitizer") - 1) == 0)
@@ -866,7 +840,7 @@ bool DyldNeedsEnvVariable() {
   if (!&dyldVersionNumber) return true;
   // If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
   // DYLD_INSERT_LIBRARIES is not set. However, checking OS version via
-  // GetMacosVersion() doesn't work for the simulator. Let's instead check
+  // GetMacosAlignedVersion() doesn't work for the simulator. Let's instead check
   // `dyldVersionNumber`, which is exported by dyld, against a known version
   // number from the first OS release where this appeared.
   return dyldVersionNumber < kMinDyldVersionWithAutoInterposition;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
index 34dc2c05dcf4..806aba955288 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
@@ -30,37 +30,33 @@ struct MemoryMappingLayoutData {
   bool current_instrumented;
 };
 
-enum MacosVersion {
-  MACOS_VERSION_UNINITIALIZED = 0,
-  MACOS_VERSION_UNKNOWN,
-  MACOS_VERSION_LION,  // macOS 10.7; oldest currently supported
-  MACOS_VERSION_MOUNTAIN_LION,
-  MACOS_VERSION_MAVERICKS,
-  MACOS_VERSION_YOSEMITE,
-  MACOS_VERSION_EL_CAPITAN,
-  MACOS_VERSION_SIERRA,
-  MACOS_VERSION_HIGH_SIERRA,
-  MACOS_VERSION_MOJAVE,
-  MACOS_VERSION_CATALINA,
-  MACOS_VERSION_UNKNOWN_NEWER
-};
-
-struct DarwinKernelVersion {
+template <typename VersionType>
+struct VersionBase {
   u16 major;
   u16 minor;
 
-  DarwinKernelVersion(u16 major, u16 minor) : major(major), minor(minor) {}
+  VersionBase(u16 major, u16 minor) : major(major), minor(minor) {}
 
-  bool operator==(const DarwinKernelVersion &other) const {
+  bool operator==(const VersionType &other) const {
     return major == other.major && minor == other.minor;
   }
-  bool operator>=(const DarwinKernelVersion &other) const {
+  bool operator>=(const VersionType &other) const {
     return major >= other.major ||
            (major == other.major && minor >= other.minor);
   }
 };
 
-MacosVersion GetMacosVersion();
+struct MacosVersion : VersionBase<MacosVersion> {
+  MacosVersion(u16 ten, u16 major) : VersionBase(ten, major) {
+    CHECK_EQ(ten, 10);
+  }
+};
+
+struct DarwinKernelVersion : VersionBase<DarwinKernelVersion> {
+  DarwinKernelVersion(u16 major, u16 minor) : VersionBase(major, minor) {}
+};
+
+MacosVersion GetMacosAlignedVersion();
 DarwinKernelVersion GetDarwinKernelVersion();
 
 char **GetEnviron();

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp
index cc233408d0ce..29cbf62acd5c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp
@@ -123,7 +123,7 @@ class AtosSymbolizerProcess : public SymbolizerProcess {
     argv[i++] = path_to_binary;
     argv[i++] = "-p";
     argv[i++] = &pid_str_[0];
-    if (GetMacosVersion() == MACOS_VERSION_MAVERICKS) {
+    if (GetMacosAlignedVersion() == MacosVersion(10, 9)) {
       // On Mavericks atos prints a deprecation warning which we suppress by
       // passing -d. The warning isn't present on other OSX versions, even the
       // newer ones.

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
index f92ecc5e40f6..eea52a34e97f 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
@@ -258,7 +258,7 @@ void InitializePlatform() {
       pthread_introspection_hook_install(&my_pthread_introspection_hook);
 #endif
 
-  if (GetMacosVersion() >= MACOS_VERSION_MOJAVE) {
+  if (GetMacosAlignedVersion() >= MacosVersion(10, 14)) {
     // Libsystem currently uses a process-global key; this might change.
     const unsigned kTLSLongjmpXorKeySlot = 0x7;
     longjmp_xor_key = (uptr)pthread_getspecific(kTLSLongjmpXorKeySlot);
@@ -267,7 +267,7 @@ void InitializePlatform() {
 
 #ifdef __aarch64__
 # define LONG_JMP_SP_ENV_SLOT \
-    ((GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? 12 : 13)
+    ((GetMacosAlignedVersion() >= MacosVersion(10, 14)) ? 12 : 13)
 #else
 # define LONG_JMP_SP_ENV_SLOT 2
 #endif


        


More information about the llvm-commits mailing list