forked from OSchip/llvm-project
[Darwin] Fix OS version checks inside simulators
compiler-rt checks OS versions by querying the Darwin kernel version. This is not necessarily correct inside the simulators if the simulator runtime is not aligned with the host macOS. Let's instead check the `SIMULATOR_RUNTIME_VERSION` env var. rdar://63031937 Reviewed By: delcypher Differential Revision: https://reviews.llvm.org/D83977
This commit is contained in:
parent
8b2fcc42b8
commit
3fb0de8207
|
@ -606,21 +606,65 @@ HandleSignalMode GetHandleSignalMode(int signum) {
|
|||
return result;
|
||||
}
|
||||
|
||||
// This corresponds to Triple::getMacOSXVersion() in the Clang driver.
|
||||
static MacosVersion GetMacosAlignedVersionInternal() {
|
||||
u16 kernel_major = GetDarwinKernelVersion().major;
|
||||
// Darwin 0-3 -> unsupported
|
||||
// Darwin 4-19 -> macOS 10.x
|
||||
// Darwin 20+ -> macOS 11+
|
||||
CHECK_GE(kernel_major, 4);
|
||||
u16 major, minor;
|
||||
if (kernel_major < 20) {
|
||||
major = 10;
|
||||
minor = kernel_major - 4;
|
||||
using VersStr = char[64];
|
||||
|
||||
static void GetOSVersion(VersStr vers) {
|
||||
uptr len = sizeof(VersStr);
|
||||
if (SANITIZER_IOSSIM) {
|
||||
const char *vers_env = GetEnv("SIMULATOR_RUNTIME_VERSION");
|
||||
if (!vers_env) {
|
||||
Report("ERROR: Running in simulator but SIMULATOR_RUNTIME_VERSION env "
|
||||
"var is not set.\n");
|
||||
Die();
|
||||
}
|
||||
len = internal_strlcpy(vers, vers_env, len);
|
||||
} else {
|
||||
major = 11 + kernel_major - 20;
|
||||
minor = 0;
|
||||
int res =
|
||||
internal_sysctlbyname("kern.osproductversion", vers, &len, nullptr, 0);
|
||||
CHECK_EQ(res, 0);
|
||||
}
|
||||
CHECK_LT(len, sizeof(VersStr));
|
||||
}
|
||||
|
||||
void ParseVersion(const char *vers, u16 *major, u16 *minor) {
|
||||
// Format: <major>.<minor>[.<patch>]\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);
|
||||
}
|
||||
|
||||
// Aligned versions example:
|
||||
// macOS 10.15 -- iOS 13 -- tvOS 13 -- watchOS 6
|
||||
static void MapToMacos(u16 *major, u16 *minor) {
|
||||
if (TARGET_OS_OSX)
|
||||
return;
|
||||
|
||||
if (SANITIZER_IOS || SANITIZER_TVOS)
|
||||
*major += 2;
|
||||
else if (SANITIZER_WATCHOS)
|
||||
*major += 9;
|
||||
else
|
||||
UNREACHABLE("unsupported platform");
|
||||
|
||||
if (*major >= 16) { // macOS 11+
|
||||
*major -= 5;
|
||||
} else { // macOS 10.15 and below
|
||||
*minor = *major;
|
||||
*major = 10;
|
||||
}
|
||||
}
|
||||
|
||||
static MacosVersion GetMacosAlignedVersionInternal() {
|
||||
VersStr vers;
|
||||
GetOSVersion(vers);
|
||||
|
||||
u16 major, minor;
|
||||
ParseVersion(vers, &major, &minor);
|
||||
MapToMacos(&major, &minor);
|
||||
|
||||
return MacosVersion(major, minor);
|
||||
}
|
||||
|
||||
|
@ -639,24 +683,15 @@ MacosVersion GetMacosAlignedVersion() {
|
|||
return *reinterpret_cast<MacosVersion *>(&result);
|
||||
}
|
||||
|
||||
void ParseVersion(const char *vers, u16 *major, u16 *minor) {
|
||||
// Format: <major>.<minor>.<patch>\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);
|
||||
VersStr vers;
|
||||
uptr len = sizeof(VersStr);
|
||||
int res = internal_sysctlbyname("kern.osrelease", vers, &len, nullptr, 0);
|
||||
CHECK_EQ(res, 0);
|
||||
CHECK_LT(len, sizeof(VersStr));
|
||||
|
||||
u16 major, minor;
|
||||
ParseVersion(buf, &major, &minor);
|
||||
ParseVersion(vers, &major, &minor);
|
||||
|
||||
return DarwinKernelVersion(major, minor);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,38 @@
|
|||
|
||||
namespace __sanitizer {
|
||||
|
||||
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);
|
||||
|
||||
ParseVersion("1.2", &major, &minor);
|
||||
EXPECT_EQ(major, 1);
|
||||
EXPECT_EQ(minor, 2);
|
||||
}
|
||||
|
||||
// TODO(yln): Run sanitizer unit tests for the simulators (rdar://65680742)
|
||||
#if SANITIZER_IOSSIM
|
||||
TEST(SanitizerMac, GetMacosAlignedVersion) {
|
||||
const char *vers_str;
|
||||
if (SANITIZER_IOS || SANITIZER_TVOS) {
|
||||
vers_str = "13.0";
|
||||
} else if (SANITIZER_WATCHOS) {
|
||||
vers_str = "6.5";
|
||||
} else {
|
||||
FAIL() << "unsupported simulator runtime";
|
||||
}
|
||||
setenv("SIMULATOR_RUNTIME_VERSION", vers_str, /*overwrite=*/1);
|
||||
|
||||
MacosVersion vers = GetMacosAlignedVersion();
|
||||
EXPECT_EQ(vers.major, 10);
|
||||
EXPECT_EQ(vers.minor, 15);
|
||||
}
|
||||
#else
|
||||
TEST(SanitizerMac, GetMacosAlignedVersion) {
|
||||
MacosVersion vers = GetMacosAlignedVersion();
|
||||
u16 kernel_major = GetDarwinKernelVersion().major;
|
||||
|
@ -31,15 +63,7 @@ TEST(SanitizerMac, GetMacosAlignedVersion) {
|
|||
EXPECT_EQ(vers.major, expected_major);
|
||||
EXPECT_EQ(vers.minor, expected_minor);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(SanitizerMac, GetDarwinKernelVersion) {
|
||||
DarwinKernelVersion vers = GetDarwinKernelVersion();
|
||||
|
|
Loading…
Reference in New Issue