[Darwin] Add and adopt a way to query the Darwin kernel version
authorJulian Lettner <julian.lettner@apple.com>
Thu, 14 May 2020 20:43:33 +0000 (13:43 -0700)
committerJulian Lettner <julian.lettner@apple.com>
Mon, 1 Jun 2020 17:37:03 +0000 (10:37 -0700)
This applies the learnings from [1].  What I intended as a simple
cleanup made me realize that the compiler-rt version checks have two
separate issues:

1) In some places (e.g., mmap flag setting) what matters is the kernel
   version, not the OS version.
2) OS version checks are implemented by querying the kernel version.
   This is not necessarily correct inside the simulators if the
   simulator runtime isn't aligned with the host macOS.

This commit tackles 1) by adopting a separate query function for the
Darwin kernel version.  2) (and cleanups) will be dealt with in
follow-ups.

[1] https://reviews.llvm.org/D78942

rdar://63031937

Reviewed By: delcypher

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

compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
compiler-rt/lib/sanitizer_common/sanitizer_mac.h

index 85fc21a..7550545 100644 (file)
@@ -635,11 +635,7 @@ MacosVersion GetMacosVersionInternal() {
     case 14: return MACOS_VERSION_YOSEMITE;
     case 15: return MACOS_VERSION_EL_CAPITAN;
     case 16: return MACOS_VERSION_SIERRA;
-    case 17:
-      // Not a typo, 17.5 Darwin Kernel Version maps to High Sierra 10.13.4.
-      if (minor >= 5)
-        return MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4;
-      return MACOS_VERSION_HIGH_SIERRA;
+    case 17: return MACOS_VERSION_HIGH_SIERRA;
     case 18: return MACOS_VERSION_MOJAVE;
     case 19: return MACOS_VERSION_CATALINA;
     default:
@@ -660,6 +656,23 @@ MacosVersion GetMacosVersion() {
   return result;
 }
 
+DarwinKernelVersion GetDarwinKernelVersion() {
+  char buf[100];
+  size_t len = sizeof(buf);
+  int res = internal_sysctlbyname("kern.osrelease", buf, &len, nullptr, 0);
+  CHECK_EQ(res, 0);
+
+  // Format: <major>.<minor>.<patch>\0
+  CHECK_GE(len, 6);
+  const char *p = buf;
+  u16 major = internal_simple_strtoll(p, &p, /*base=*/10);
+  CHECK_EQ(*p, '.');
+  p += 1;
+  u16 minor = internal_simple_strtoll(p, &p, /*base=*/10);
+
+  return DarwinKernelVersion(major, minor);
+}
+
 uptr GetRSS() {
   struct task_basic_info info;
   unsigned count = TASK_BASIC_INFO_COUNT;
@@ -796,10 +809,10 @@ void SignalContext::InitPcSpBp() {
 }
 
 void InitializePlatformEarly() {
-  // Only use xnu_fast_mmap when on x86_64 and the OS supports it.
+  // Only use xnu_fast_mmap when on x86_64 and the kernel supports it.
   use_xnu_fast_mmap =
 #if defined(__x86_64__)
-      GetMacosVersion() >= MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4;
+      GetDarwinKernelVersion() >= DarwinKernelVersion(17, 5);
 #else
       false;
 #endif
index 2226fcb..34dc2c0 100644 (file)
@@ -40,13 +40,28 @@ enum MacosVersion {
   MACOS_VERSION_EL_CAPITAN,
   MACOS_VERSION_SIERRA,
   MACOS_VERSION_HIGH_SIERRA,
-  MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4,
   MACOS_VERSION_MOJAVE,
   MACOS_VERSION_CATALINA,
   MACOS_VERSION_UNKNOWN_NEWER
 };
 
+struct DarwinKernelVersion {
+  u16 major;
+  u16 minor;
+
+  DarwinKernelVersion(u16 major, u16 minor) : major(major), minor(minor) {}
+
+  bool operator==(const DarwinKernelVersion &other) const {
+    return major == other.major && minor == other.minor;
+  }
+  bool operator>=(const DarwinKernelVersion &other) const {
+    return major >= other.major ||
+           (major == other.major && minor >= other.minor);
+  }
+};
+
 MacosVersion GetMacosVersion();
+DarwinKernelVersion GetDarwinKernelVersion();
 
 char **GetEnviron();