[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / unittests / Support / Host.cpp
blobf5434b138abc48c90661baa6a06130eceeb061a5
1 //========- unittests/Support/Host.cpp - Host.cpp tests --------------========//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/Host.h"
10 #include "llvm/Config/llvm-config.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/Triple.h"
13 #include "llvm/Support/FileSystem.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/Program.h"
16 #include "llvm/Support/Threading.h"
18 #include "gtest/gtest.h"
20 #define ASSERT_NO_ERROR(x) \
21 if (std::error_code ASSERT_NO_ERROR_ec = x) { \
22 SmallString<128> MessageStorage; \
23 raw_svector_ostream Message(MessageStorage); \
24 Message << #x ": did not return errc::success.\n" \
25 << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
26 << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
27 GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
28 } else { \
31 using namespace llvm;
33 class HostTest : public testing::Test {
34 Triple Host;
36 protected:
37 bool isSupportedArchAndOS() {
38 // Initially this is only testing detection of the number of
39 // physical cores, which is currently only supported/tested on
40 // some systems.
41 return (Host.isOSWindows() && llvm_is_multithreaded()) ||
42 Host.isOSDarwin() || (Host.isX86() && Host.isOSLinux()) ||
43 (Host.isPPC64() && Host.isOSLinux()) ||
44 (Host.isSystemZ() && (Host.isOSLinux() || Host.isOSzOS()));
47 HostTest() : Host(Triple::normalize(sys::getProcessTriple())) {}
50 TEST_F(HostTest, NumPhysicalCores) {
51 int Num = sys::getHostNumPhysicalCores();
53 if (isSupportedArchAndOS())
54 ASSERT_GT(Num, 0);
55 else
56 ASSERT_EQ(Num, -1);
59 TEST(getLinuxHostCPUName, ARM) {
60 StringRef CortexA9ProcCpuinfo = R"(
61 processor : 0
62 model name : ARMv7 Processor rev 10 (v7l)
63 BogoMIPS : 1393.66
64 Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
65 CPU implementer : 0x41
66 CPU architecture: 7
67 CPU variant : 0x2
68 CPU part : 0xc09
69 CPU revision : 10
71 processor : 1
72 model name : ARMv7 Processor rev 10 (v7l)
73 BogoMIPS : 1393.66
74 Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
75 CPU implementer : 0x41
76 CPU architecture: 7
77 CPU variant : 0x2
78 CPU part : 0xc09
79 CPU revision : 10
81 Hardware : Generic OMAP4 (Flattened Device Tree)
82 Revision : 0000
83 Serial : 0000000000000000
84 )";
86 EXPECT_EQ(sys::detail::getHostCPUNameForARM(CortexA9ProcCpuinfo),
87 "cortex-a9");
88 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
89 "CPU part : 0xc0f"),
90 "cortex-a15");
91 // Verify that both CPU implementer and CPU part are checked:
92 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
93 "CPU part : 0xc0f"),
94 "generic");
95 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
96 "CPU part : 0x06f"),
97 "krait");
100 TEST(getLinuxHostCPUName, AArch64) {
101 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
102 "CPU part : 0xd03"),
103 "cortex-a53");
105 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
106 "CPU part : 0xd40"),
107 "neoverse-v1");
108 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
109 "CPU part : 0xd0c"),
110 "neoverse-n1");
111 // Verify that both CPU implementer and CPU part are checked:
112 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
113 "CPU part : 0xd03"),
114 "generic");
115 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
116 "CPU part : 0x201"),
117 "kryo");
118 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
119 "CPU part : 0x800"),
120 "cortex-a73");
121 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
122 "CPU part : 0x801"),
123 "cortex-a73");
124 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
125 "CPU part : 0xc00"),
126 "falkor");
127 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
128 "CPU part : 0xc01"),
129 "saphira");
131 // MSM8992/4 weirdness
132 StringRef MSM8992ProcCpuInfo = R"(
133 Processor : AArch64 Processor rev 3 (aarch64)
134 processor : 0
135 processor : 1
136 processor : 2
137 processor : 3
138 processor : 4
139 processor : 5
140 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
141 CPU implementer : 0x41
142 CPU architecture: 8
143 CPU variant : 0x0
144 CPU part : 0xd03
145 CPU revision : 3
147 Hardware : Qualcomm Technologies, Inc MSM8992
150 EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo),
151 "cortex-a53");
153 // Exynos big.LITTLE weirdness
154 const std::string ExynosProcCpuInfo = R"(
155 processor : 0
156 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
157 CPU implementer : 0x41
158 CPU architecture: 8
159 CPU variant : 0x0
160 CPU part : 0xd05
162 processor : 1
163 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
164 CPU implementer : 0x53
165 CPU architecture: 8
168 // Verify default for Exynos.
169 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
170 "CPU variant : 0xc\n"
171 "CPU part : 0xafe"),
172 "exynos-m3");
173 // Verify Exynos M3.
174 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
175 "CPU variant : 0x1\n"
176 "CPU part : 0x002"),
177 "exynos-m3");
178 // Verify Exynos M4.
179 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
180 "CPU variant : 0x1\n"
181 "CPU part : 0x003"),
182 "exynos-m4");
184 const std::string ThunderX2T99ProcCpuInfo = R"(
185 processor : 0
186 BogoMIPS : 400.00
187 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
188 CPU implementer : 0x43
189 CPU architecture: 8
190 CPU variant : 0x1
191 CPU part : 0x0af
194 // Verify different versions of ThunderX2T99.
195 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
196 "CPU implementer : 0x42\n"
197 "CPU part : 0x516"),
198 "thunderx2t99");
200 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
201 "CPU implementer : 0x42\n"
202 "CPU part : 0x0516"),
203 "thunderx2t99");
205 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
206 "CPU implementer : 0x43\n"
207 "CPU part : 0x516"),
208 "thunderx2t99");
210 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
211 "CPU implementer : 0x43\n"
212 "CPU part : 0x0516"),
213 "thunderx2t99");
215 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
216 "CPU implementer : 0x42\n"
217 "CPU part : 0xaf"),
218 "thunderx2t99");
220 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
221 "CPU implementer : 0x42\n"
222 "CPU part : 0x0af"),
223 "thunderx2t99");
225 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
226 "CPU implementer : 0x43\n"
227 "CPU part : 0xaf"),
228 "thunderx2t99");
230 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
231 "CPU implementer : 0x43\n"
232 "CPU part : 0x0af"),
233 "thunderx2t99");
235 // Verify ThunderXT88.
236 const std::string ThunderXT88ProcCpuInfo = R"(
237 processor : 0
238 BogoMIPS : 200.00
239 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
240 CPU implementer : 0x43
241 CPU architecture: 8
242 CPU variant : 0x1
243 CPU part : 0x0a1
246 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
247 "CPU implementer : 0x43\n"
248 "CPU part : 0x0a1"),
249 "thunderxt88");
251 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
252 "CPU implementer : 0x43\n"
253 "CPU part : 0xa1"),
254 "thunderxt88");
256 // Verify HiSilicon processors.
257 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n"
258 "CPU part : 0xd01"),
259 "tsv110");
261 // Verify A64FX.
262 const std::string A64FXProcCpuInfo = R"(
263 processor : 0
264 BogoMIPS : 200.00
265 Features : fp asimd evtstrm sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm fcma dcpop sve
266 CPU implementer : 0x46
267 CPU architecture: 8
268 CPU variant : 0x1
269 CPU part : 0x001
272 EXPECT_EQ(sys::detail::getHostCPUNameForARM(A64FXProcCpuInfo), "a64fx");
274 // Verify Nvidia Carmel.
275 const std::string CarmelProcCpuInfo = R"(
276 processor : 0
277 model name : ARMv8 Processor rev 0 (v8l)
278 BogoMIPS : 62.50
279 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm dcpop
280 CPU implementer : 0x4e
281 CPU architecture: 8
282 CPU variant : 0x0
283 CPU part : 0x004
284 CPU revision : 0
287 EXPECT_EQ(sys::detail::getHostCPUNameForARM(CarmelProcCpuInfo), "carmel");
289 // Snapdragon mixed implementer quirk
290 const std::string Snapdragon865ProcCPUInfo = R"(
291 processor : 0
292 BogoMIPS : 38.40
293 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
294 CPU implementer : 0x51
295 CPU architecture: 8
296 CPU variant : 0xd
297 CPU part : 0x805
298 CPU revision : 14
299 processor : 1
300 processor : 2
301 processor : 3
302 processor : 4
303 processor : 5
304 processor : 6
305 BogoMIPS : 38.40
306 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
307 CPU implementer : 0x41
308 CPU architecture: 8
309 CPU variant : 0x1
310 CPU part : 0xd0d
311 CPU revision : 0
313 EXPECT_EQ(sys::detail::getHostCPUNameForARM(Snapdragon865ProcCPUInfo), "cortex-a77");
316 TEST(getLinuxHostCPUName, s390x) {
317 SmallVector<std::string> ModelIDs(
318 {"3931", "8561", "3906", "2964", "2827", "2817", "2097", "2064"});
319 SmallVector<std::string> VectorSupport({"", "vx"});
320 SmallVector<StringRef> ExpectedCPUs;
322 // Model Id: 3931
323 ExpectedCPUs.push_back("zEC12");
324 ExpectedCPUs.push_back("arch14");
326 // Model Id: 8561
327 ExpectedCPUs.push_back("zEC12");
328 ExpectedCPUs.push_back("z15");
330 // Model Id: 3906
331 ExpectedCPUs.push_back("zEC12");
332 ExpectedCPUs.push_back("z14");
334 // Model Id: 2964
335 ExpectedCPUs.push_back("zEC12");
336 ExpectedCPUs.push_back("z13");
338 // Model Id: 2827
339 ExpectedCPUs.push_back("zEC12");
340 ExpectedCPUs.push_back("zEC12");
342 // Model Id: 2817
343 ExpectedCPUs.push_back("z196");
344 ExpectedCPUs.push_back("z196");
346 // Model Id: 2097
347 ExpectedCPUs.push_back("z10");
348 ExpectedCPUs.push_back("z10");
350 // Model Id: 2064
351 ExpectedCPUs.push_back("generic");
352 ExpectedCPUs.push_back("generic");
354 const std::string DummyBaseVectorInfo =
355 "features : esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs "
356 "te ";
357 const std::string DummyBaseMachineInfo =
358 "processor 0: version = FF, identification = 059C88, machine = ";
360 int CheckIndex = 0;
361 for (size_t I = 0; I < ModelIDs.size(); I++) {
362 for (size_t J = 0; J < VectorSupport.size(); J++) {
363 const std::string DummyCPUInfo = DummyBaseVectorInfo + VectorSupport[J] +
364 "\n" + DummyBaseMachineInfo +
365 ModelIDs[I];
366 EXPECT_EQ(sys::detail::getHostCPUNameForS390x(DummyCPUInfo),
367 ExpectedCPUs[CheckIndex++]);
372 static bool runAndGetCommandOutput(
373 const char *ExePath, ArrayRef<llvm::StringRef> argv,
374 std::unique_ptr<char[]> &Buffer, off_t &Size) {
375 bool Success = false;
376 [ExePath, argv, &Buffer, &Size, &Success] {
377 using namespace llvm::sys;
378 SmallString<128> TestDirectory;
379 ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
381 SmallString<128> OutputFile(TestDirectory);
382 path::append(OutputFile, "out");
383 StringRef OutputPath = OutputFile.str();
385 const Optional<StringRef> Redirects[] = {
386 /*STDIN=*/None, /*STDOUT=*/OutputPath, /*STDERR=*/None};
387 int RetCode = ExecuteAndWait(ExePath, argv, /*env=*/llvm::None, Redirects);
388 ASSERT_EQ(0, RetCode);
390 int FD = 0;
391 ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
392 Size = ::lseek(FD, 0, SEEK_END);
393 ASSERT_NE(-1, Size);
394 ::lseek(FD, 0, SEEK_SET);
395 Buffer = std::make_unique<char[]>(Size);
396 ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
397 ::close(FD);
399 ASSERT_NO_ERROR(fs::remove(OutputPath));
400 ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
401 Success = true;
402 }();
403 return Success;
406 TEST_F(HostTest, DummyRunAndGetCommandOutputUse) {
407 // Suppress defined-but-not-used warnings when the tests using the helper are
408 // disabled.
409 (void)&runAndGetCommandOutput;
412 TEST_F(HostTest, getMacOSHostVersion) {
413 llvm::Triple HostTriple(llvm::sys::getProcessTriple());
414 if (!HostTriple.isMacOSX())
415 return;
417 const char *SwVersPath = "/usr/bin/sw_vers";
418 StringRef argv[] = {SwVersPath, "-productVersion"};
419 std::unique_ptr<char[]> Buffer;
420 off_t Size;
421 ASSERT_EQ(runAndGetCommandOutput(SwVersPath, argv, Buffer, Size), true);
422 StringRef SystemVersionStr = StringRef(Buffer.get(), Size).rtrim();
424 // Ensure that the two versions match.
425 VersionTuple SystemVersion;
426 ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersionStr))
427 .getMacOSXVersion(SystemVersion),
428 true);
429 VersionTuple HostVersion;
430 ASSERT_EQ(HostTriple.getMacOSXVersion(HostVersion), true);
432 if (SystemVersion.getMajor() > 10) {
433 // Don't compare the 'Minor' and 'Micro' versions, as they're always '0' for
434 // the 'Darwin' triples on 11.x.
435 ASSERT_EQ(SystemVersion.getMajor(), HostVersion.getMajor());
436 } else {
437 // Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
438 // triples.
439 ASSERT_EQ(SystemVersion.getMajor(), HostVersion.getMajor());
440 ASSERT_EQ(SystemVersion.getMinor(), HostVersion.getMinor());
444 TEST_F(HostTest, AIXVersionDetect) {
445 llvm::Triple HostTriple(llvm::sys::getProcessTriple());
446 if (HostTriple.getOS() != Triple::AIX)
447 return;
449 llvm::Triple ConfiguredHostTriple(LLVM_HOST_TRIPLE);
450 ASSERT_EQ(ConfiguredHostTriple.getOS(), Triple::AIX);
452 const char *ExePath = "/usr/bin/oslevel";
453 StringRef argv[] = {ExePath};
454 std::unique_ptr<char[]> Buffer;
455 off_t Size;
456 ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
457 StringRef SystemVersionStr = StringRef(Buffer.get(), Size).rtrim();
459 VersionTuple SystemVersion =
460 llvm::Triple((Twine("powerpc-ibm-aix") + SystemVersionStr))
461 .getOSVersion();
463 // Ensure that the host triple version (major) and release (minor) numbers,
464 // unless explicitly configured, match with those of the current system.
465 if (!ConfiguredHostTriple.getOSMajorVersion()) {
466 VersionTuple HostVersion = HostTriple.getOSVersion();
467 ASSERT_EQ(SystemVersion.getMajor(), HostVersion.getMajor());
468 ASSERT_EQ(SystemVersion.getMinor(), HostVersion.getMinor());
471 llvm::Triple TargetTriple(llvm::sys::getDefaultTargetTriple());
472 if (TargetTriple.getOS() != Triple::AIX)
473 return;
475 // Ensure that the target triple version (major) and release (minor) numbers
476 // match with those of the current system.
477 llvm::Triple ConfiguredTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
478 if (ConfiguredTargetTriple.getOSMajorVersion())
479 return; // The version was configured explicitly; skip.
481 VersionTuple TargetVersion = TargetTriple.getOSVersion();
482 ASSERT_EQ(SystemVersion.getMajor(), TargetVersion.getMajor());
483 ASSERT_EQ(SystemVersion.getMinor(), TargetVersion.getMinor());
486 TEST_F(HostTest, AIXHostCPUDetect) {
487 llvm::Triple HostTriple(llvm::sys::getProcessTriple());
488 if (HostTriple.getOS() != Triple::AIX)
489 return;
491 // Return a value based on the current processor implementation mode.
492 const char *ExePath = "/usr/sbin/getsystype";
493 StringRef argv[] = {ExePath, "-i"};
494 std::unique_ptr<char[]> Buffer;
495 off_t Size;
496 ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
497 StringRef CPU(Buffer.get(), Size);
498 StringRef MCPU = StringSwitch<const char *>(CPU)
499 .Case("POWER 4\n", "pwr4")
500 .Case("POWER 5\n", "pwr5")
501 .Case("POWER 6\n", "pwr6")
502 .Case("POWER 7\n", "pwr7")
503 .Case("POWER 8\n", "pwr8")
504 .Case("POWER 9\n", "pwr9")
505 .Case("POWER 10\n", "pwr10")
506 .Default("unknown");
508 StringRef HostCPU = sys::getHostCPUName();
510 // Just do the comparison on the base implementation mode.
511 if (HostCPU == "970")
512 HostCPU = StringRef("pwr4");
513 else
514 HostCPU = HostCPU.rtrim('x');
516 EXPECT_EQ(HostCPU, MCPU);