diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -606,12 +606,37 @@ return result; } +void ParseVersion(const char *vers, u16 *major, u16 *minor) { + // Format: .[.]\0 + CHECK_GE(internal_strlen(vers), 3); + const char *p = vers; + *major = internal_simple_strtoll(p, &p, /*base=*/10); + CHECK_EQ(*p, '.'); + p += 1; + *minor = internal_simple_strtoll(p, &p, /*base=*/10); +} + +constexpr u16 GetMacosVersionOffset() { + if (SANITIZER_IOS || SANITIZER_TVOS) return 2; + if (SANITIZER_WATCHOS) return 9; + return 0; +} + static MacosVersion GetMacosAlignedVersionInternal() { + if (SANITIZER_IOSSIM) { + if (auto vers = GetEnv("SIMULATOR_RUNTIME_VERSION")) { + u16 major, minor; + ParseVersion(vers, &major, &minor); + return MacosVersion(10, major + GetMacosVersionOffset()); + } + Report("WARNING: Running in simulator but SIMULATOR_RUNTIME_VERSION env " + "var is not set.\n"); + } + u16 kernel_major = GetDarwinKernelVersion().major; - const u16 version_offset = 4; + u16 version_offset = 4; CHECK_GE(kernel_major, version_offset); - u16 macos_major = kernel_major - version_offset; - return MacosVersion(10, macos_major); + return MacosVersion(10, kernel_major - version_offset); } static_assert(sizeof(MacosVersion) == sizeof(atomic_uint32_t::Type), @@ -629,24 +654,14 @@ return *reinterpret_cast(&result); } -void ParseVersion(const char *vers, u16 *major, u16 *minor) { - // Format: ..\0 - CHECK_GE(internal_strlen(vers), 5); - const char *p = vers; - *major = internal_simple_strtoll(p, &p, /*base=*/10); - CHECK_EQ(*p, '.'); - p += 1; - *minor = internal_simple_strtoll(p, &p, /*base=*/10); -} - DarwinKernelVersion GetDarwinKernelVersion() { - char buf[100]; - size_t len = sizeof(buf); - int res = internal_sysctlbyname("kern.osrelease", buf, &len, nullptr, 0); + char vers[100]; + size_t len = sizeof(vers); + int res = internal_sysctlbyname("kern.osrelease", vers, &len, nullptr, 0); CHECK_EQ(res, 0); u16 major, minor; - ParseVersion(buf, &major, &minor); + ParseVersion(vers, &major, &minor); return DarwinKernelVersion(major, minor); } diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp @@ -22,20 +22,43 @@ namespace __sanitizer { -TEST(SanitizerMac, GetMacosAlignedVersion) { - MacosVersion vers = GetMacosAlignedVersion(); - EXPECT_EQ(vers.major, 10); - EXPECT_EQ(vers.minor, GetDarwinKernelVersion().major - 4); -} - void ParseVersion(const char *vers, u16 *major, u16 *minor); TEST(SanitizerMac, ParseVersion) { u16 major, minor; + ParseVersion("11.22.33", &major, &minor); - EXPECT_EQ(major, 11); - EXPECT_EQ(minor, 22); + EXPECT_EQ(major, 11); EXPECT_EQ(minor, 22); + + ParseVersion("1.2", &major, &minor); + EXPECT_EQ(major, 1); EXPECT_EQ(minor, 2); +} + +#if SANITIZER_IOSSIM +TEST(SanitizerMac, GetMacosAlignedVersion) { + if (SANITIZER_IOSSIM) { + const char *vers; + if (SANITIZER_IOS || SANITIZER_TVOS) { + vers = "13.0"; + } else if (SANITIZER_WATCHOS) { + vers = "6.5" + } else { + FAIL() << "unsupported simulator runtime"; + } + setenv("SIMULATOR_RUNTIME_VERSION", vers, /*overwrite=*/1); + } + + MacosVersion vers = GetMacosAlignedVersion(); + EXPECT_EQ(vers.major, 10); + EXPECT_EQ(vers.minor, 15); +} +#else +TEST(SanitizerMac, GetMacosAlignedVersion) { + MacosVersion vers = GetMacosAlignedVersion(); + EXPECT_EQ(vers.major, 10); + EXPECT_EQ(vers.minor, GetDarwinKernelVersion().major - 4); } +#endif TEST(SanitizerMac, GetDarwinKernelVersion) { DarwinKernelVersion vers = GetDarwinKernelVersion();