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,58 @@ +//===-- 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) { + DarwinKernelVersion vers = GetDarwinKernelVersion(); + std::ostringstream oss; + oss << vers.major << '.' << vers.minor; + std::string actual = oss.str(); + + char buf[100]; + size_t len = sizeof(buf); + int 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