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 @@ -27,7 +27,6 @@ #include "sanitizer_flags.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" -#include "sanitizer_placement_new.h" #include "sanitizer_platform_limits_posix.h" #include "sanitizer_procmaps.h" #include "sanitizer_ptrauth.h" @@ -630,19 +629,24 @@ 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); CHECK_EQ(res, 0); - // Format: ..\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); + u16 major, minor; + ParseVersion(buf, major, minor); return DarwinKernelVersion(major, minor); } diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -21,6 +21,7 @@ sanitizer_libc_test.cpp sanitizer_linux_test.cpp sanitizer_list_test.cpp + sanitizer_mac_test.cpp sanitizer_mutex_test.cpp sanitizer_nolibc_test.cpp sanitizer_posix_test.cpp diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp @@ -0,0 +1,60 @@ +//===-- sanitizer_mac_test.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Tests for sanitizer_mac.{h,cpp} +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_platform.h" +#if SANITIZER_MAC + +#include "sanitizer_common/sanitizer_mac.h" + +#include "gtest/gtest.h" + +#include // sysctlbyname +#include // KERN_SUCCESS + +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); +} + +TEST(SanitizerMac, GetDarwinKernelVersion) { + char buf[100]; + int res; + + DarwinKernelVersion vers = GetDarwinKernelVersion(); + res = snprintf(buf, sizeof(buf), "%d.%d", vers.major, vers.minor); + ASSERT_GT(res, 0); + std::string actual(buf); + + size_t len = sizeof(buf); + res = sysctlbyname("kern.osrelease", buf, &len, nullptr, 0); + ASSERT_EQ(res, KERN_SUCCESS); + std::string expected(buf); + + // Prefix match + ASSERT_TRUE(expected.compare(0, actual.size(), actual) == 0); +} + +} // namespace __sanitizer + +#endif // SANITIZER_MAC