[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / lldb / unittests / Utility / ArchSpecTest.cpp
blob1ef646acdefbdba2f8e44dc9511716643aed0249
1 //===-- ArchSpecTest.cpp --------------------------------------------------===//
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 "gtest/gtest.h"
11 #include "lldb/Utility/ArchSpec.h"
12 #include "llvm/BinaryFormat/ELF.h"
13 #include "llvm/BinaryFormat/MachO.h"
14 #include "llvm/Support/YAMLParser.h"
16 using namespace lldb;
17 using namespace lldb_private;
19 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleSimple) {
21 // Success conditions. Valid cpu/subtype combinations using both - and .
22 ArchSpec AS;
23 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10", AS));
24 EXPECT_EQ(12u, AS.GetMachOCPUType());
25 EXPECT_EQ(10u, AS.GetMachOCPUSubType());
27 AS = ArchSpec();
28 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15", AS));
29 EXPECT_EQ(12u, AS.GetMachOCPUType());
30 EXPECT_EQ(15u, AS.GetMachOCPUSubType());
32 AS = ArchSpec();
33 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12.15", AS));
34 EXPECT_EQ(12u, AS.GetMachOCPUType());
35 EXPECT_EQ(15u, AS.GetMachOCPUSubType());
37 // Failure conditions.
39 // Valid string, unknown cpu/subtype.
40 AS = ArchSpec();
41 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("13.11", AS));
42 EXPECT_EQ(0u, AS.GetMachOCPUType());
43 EXPECT_EQ(0u, AS.GetMachOCPUSubType());
45 // Missing / invalid cpu or subtype
46 AS = ArchSpec();
47 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13", AS));
49 AS = ArchSpec();
50 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13.A", AS));
52 AS = ArchSpec();
53 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("A.13", AS));
55 // Empty string.
56 AS = ArchSpec();
57 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("", AS));
60 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleExtra) {
61 ArchSpec AS;
62 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor-os", AS));
63 EXPECT_EQ(12u, AS.GetMachOCPUType());
64 EXPECT_EQ(15u, AS.GetMachOCPUSubType());
65 EXPECT_EQ("vendor", AS.GetTriple().getVendorName());
66 EXPECT_EQ("os", AS.GetTriple().getOSName());
68 AS = ArchSpec();
69 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor-os-name", AS));
70 EXPECT_EQ(12u, AS.GetMachOCPUType());
71 EXPECT_EQ(10u, AS.GetMachOCPUSubType());
72 EXPECT_EQ("vendor", AS.GetTriple().getVendorName());
73 EXPECT_EQ("os", AS.GetTriple().getOSName());
75 AS = ArchSpec();
76 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor.os-name", AS));
77 EXPECT_EQ(12u, AS.GetMachOCPUType());
78 EXPECT_EQ(15u, AS.GetMachOCPUSubType());
79 EXPECT_EQ("vendor.os", AS.GetTriple().getVendorName());
80 EXPECT_EQ("name", AS.GetTriple().getOSName());
82 // These there should parse correctly, but the vendor / OS should be defaulted
83 // since they are unrecognized.
84 AS = ArchSpec();
85 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor", AS));
86 EXPECT_EQ(12u, AS.GetMachOCPUType());
87 EXPECT_EQ(10u, AS.GetMachOCPUSubType());
88 EXPECT_EQ("apple", AS.GetTriple().getVendorName());
89 EXPECT_EQ("", AS.GetTriple().getOSName());
91 AS = ArchSpec();
92 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12.10.10", AS));
94 AS = ArchSpec();
95 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12-10.10", AS));
98 TEST(ArchSpecTest, TestSetTriple) {
99 ArchSpec AS;
101 // Various flavors of valid triples.
102 EXPECT_TRUE(AS.SetTriple("12-10-apple-darwin"));
103 EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_ARM), AS.GetMachOCPUType());
104 EXPECT_EQ(10u, AS.GetMachOCPUSubType());
105 EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
106 .consume_front("armv7f-apple-darwin"));
107 EXPECT_EQ(ArchSpec::eCore_arm_armv7f, AS.GetCore());
109 AS = ArchSpec();
110 EXPECT_TRUE(AS.SetTriple("18.100-apple-darwin"));
111 EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_POWERPC), AS.GetMachOCPUType());
112 EXPECT_EQ(100u, AS.GetMachOCPUSubType());
113 EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
114 .consume_front("powerpc-apple-darwin"));
115 EXPECT_EQ(ArchSpec::eCore_ppc_ppc970, AS.GetCore());
117 AS = ArchSpec();
118 EXPECT_TRUE(AS.SetTriple("i686-pc-windows"));
119 EXPECT_EQ(llvm::Triple::x86, AS.GetTriple().getArch());
120 EXPECT_EQ(llvm::Triple::PC, AS.GetTriple().getVendor());
121 EXPECT_EQ(llvm::Triple::Win32, AS.GetTriple().getOS());
122 EXPECT_TRUE(
123 llvm::StringRef(AS.GetTriple().str()).consume_front("i686-pc-windows"));
124 EXPECT_STREQ("i686", AS.GetArchitectureName());
125 EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore());
127 // Various flavors of invalid triples.
128 AS = ArchSpec();
129 EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown"));
131 AS = ArchSpec();
132 EXPECT_FALSE(AS.SetTriple("unknown"));
134 AS = ArchSpec();
135 EXPECT_FALSE(AS.SetTriple(""));
138 TEST(ArchSpecTest, MergeFrom) {
140 ArchSpec A;
141 ArchSpec B("x86_64-pc-linux");
143 EXPECT_FALSE(A.IsValid());
144 ASSERT_TRUE(B.IsValid());
145 EXPECT_EQ(llvm::Triple::ArchType::x86_64, B.GetTriple().getArch());
146 EXPECT_EQ(llvm::Triple::VendorType::PC, B.GetTriple().getVendor());
147 EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
148 EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, B.GetCore());
150 A.MergeFrom(B);
151 ASSERT_TRUE(A.IsValid());
152 EXPECT_EQ(llvm::Triple::ArchType::x86_64, A.GetTriple().getArch());
153 EXPECT_EQ(llvm::Triple::VendorType::PC, A.GetTriple().getVendor());
154 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
155 EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, A.GetCore());
158 ArchSpec A("aarch64");
159 ArchSpec B("aarch64--linux-android");
161 ArchSpec C("arm64_32");
162 ArchSpec D("arm64_32--watchos");
164 EXPECT_TRUE(A.IsValid());
165 EXPECT_TRUE(B.IsValid());
166 EXPECT_TRUE(C.IsValid());
167 EXPECT_TRUE(D.IsValid());
169 EXPECT_EQ(llvm::Triple::ArchType::aarch64, B.GetTriple().getArch());
170 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
171 B.GetTriple().getVendor());
172 EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
173 EXPECT_EQ(llvm::Triple::EnvironmentType::Android,
174 B.GetTriple().getEnvironment());
176 A.MergeFrom(B);
177 EXPECT_EQ(llvm::Triple::ArchType::aarch64, A.GetTriple().getArch());
178 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
179 A.GetTriple().getVendor());
180 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
181 EXPECT_EQ(llvm::Triple::EnvironmentType::Android,
182 A.GetTriple().getEnvironment());
184 EXPECT_EQ(llvm::Triple::ArchType::aarch64_32, D.GetTriple().getArch());
185 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
186 D.GetTriple().getVendor());
187 EXPECT_EQ(llvm::Triple::OSType::WatchOS, D.GetTriple().getOS());
189 C.MergeFrom(D);
190 EXPECT_EQ(llvm::Triple::ArchType::aarch64_32, C.GetTriple().getArch());
191 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
192 C.GetTriple().getVendor());
193 EXPECT_EQ(llvm::Triple::OSType::WatchOS, C.GetTriple().getOS());
196 ArchSpec A, B;
197 A.SetArchitecture(eArchTypeELF, llvm::ELF::EM_ARM,
198 LLDB_INVALID_CPUTYPE, llvm::ELF::ELFOSABI_NONE);
199 B.SetArchitecture(eArchTypeELF, llvm::ELF::EM_ARM,
200 LLDB_INVALID_CPUTYPE, llvm::ELF::ELFOSABI_LINUX);
202 EXPECT_TRUE(A.IsValid());
203 EXPECT_TRUE(B.IsValid());
205 EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch());
206 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
207 B.GetTriple().getVendor());
208 EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
209 EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment,
210 B.GetTriple().getEnvironment());
212 A.MergeFrom(B);
213 EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch());
214 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
215 A.GetTriple().getVendor());
216 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
217 EXPECT_EQ(llvm::Triple::EnvironmentType::UnknownEnvironment,
218 A.GetTriple().getEnvironment());
221 ArchSpec A("arm--linux-eabihf");
222 ArchSpec B("armv8l--linux-gnueabihf");
224 EXPECT_TRUE(A.IsValid());
225 EXPECT_TRUE(B.IsValid());
227 EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch());
228 EXPECT_EQ(llvm::Triple::ArchType::arm, B.GetTriple().getArch());
230 EXPECT_EQ(ArchSpec::eCore_arm_generic, A.GetCore());
231 EXPECT_EQ(ArchSpec::eCore_arm_armv8l, B.GetCore());
233 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
234 A.GetTriple().getVendor());
235 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
236 B.GetTriple().getVendor());
238 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
239 EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS());
241 EXPECT_EQ(llvm::Triple::EnvironmentType::EABIHF,
242 A.GetTriple().getEnvironment());
243 EXPECT_EQ(llvm::Triple::EnvironmentType::GNUEABIHF,
244 B.GetTriple().getEnvironment());
246 A.MergeFrom(B);
247 EXPECT_EQ(llvm::Triple::ArchType::arm, A.GetTriple().getArch());
248 EXPECT_EQ(ArchSpec::eCore_arm_armv8l, A.GetCore());
249 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor,
250 A.GetTriple().getVendor());
251 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS());
252 EXPECT_EQ(llvm::Triple::EnvironmentType::EABIHF,
253 A.GetTriple().getEnvironment());
257 TEST(ArchSpecTest, MergeFromMachOUnknown) {
258 class MyArchSpec : public ArchSpec {
259 public:
260 MyArchSpec() {
261 this->SetTriple("unknown-mach-64");
262 this->m_core = ArchSpec::eCore_uknownMach64;
263 this->m_byte_order = eByteOrderLittle;
264 this->m_flags = 0;
268 MyArchSpec A;
269 ASSERT_TRUE(A.IsValid());
270 MyArchSpec B;
271 ASSERT_TRUE(B.IsValid());
272 A.MergeFrom(B);
273 ASSERT_EQ(A.GetCore(), ArchSpec::eCore_uknownMach64);
276 TEST(ArchSpecTest, Compatibility) {
278 ArchSpec A("x86_64-apple-macosx10.12");
279 ArchSpec B("x86_64-apple-macosx10.12");
280 ASSERT_TRUE(A.IsExactMatch(B));
281 ASSERT_TRUE(A.IsCompatibleMatch(B));
284 // The version information is auxiliary to support availability but
285 // doesn't affect compatibility.
286 ArchSpec A("x86_64-apple-macosx10.11");
287 ArchSpec B("x86_64-apple-macosx10.12");
288 ASSERT_TRUE(A.IsExactMatch(B));
289 ASSERT_TRUE(A.IsCompatibleMatch(B));
292 ArchSpec A("x86_64-apple-macosx10.13");
293 ArchSpec B("x86_64h-apple-macosx10.13");
294 ASSERT_FALSE(A.IsExactMatch(B));
295 ASSERT_TRUE(A.IsCompatibleMatch(B));
298 ArchSpec A("x86_64-apple-macosx");
299 ArchSpec B("x86_64-apple-ios-simulator");
300 ASSERT_FALSE(A.IsExactMatch(B));
301 ASSERT_FALSE(A.IsCompatibleMatch(B));
304 ArchSpec A("x86_64-*-*");
305 ArchSpec B("x86_64-apple-ios-simulator");
306 ASSERT_FALSE(A.IsExactMatch(B));
307 ASSERT_FALSE(A.IsCompatibleMatch(B));
308 ASSERT_FALSE(B.IsExactMatch(A));
309 ASSERT_FALSE(B.IsCompatibleMatch(A));
312 ArchSpec A("x86_64-apple-ios");
313 ArchSpec B("x86_64-apple-ios-simulator");
314 ASSERT_FALSE(A.IsExactMatch(B));
315 ASSERT_FALSE(A.IsCompatibleMatch(B));
316 ASSERT_FALSE(B.IsExactMatch(A));
317 ASSERT_FALSE(B.IsCompatibleMatch(A));
320 // FIXME: This is surprisingly not equivalent to "x86_64-*-*".
321 ArchSpec A("x86_64");
322 ArchSpec B("x86_64-apple-ios-simulator");
323 ASSERT_FALSE(A.IsExactMatch(B));
324 ASSERT_TRUE(A.IsCompatibleMatch(B));
325 ASSERT_FALSE(B.IsExactMatch(A));
326 ASSERT_TRUE(B.IsCompatibleMatch(A));
329 ArchSpec A("arm64-apple-ios");
330 ArchSpec B("arm64-apple-ios-simulator");
331 ASSERT_FALSE(A.IsExactMatch(B));
332 ASSERT_FALSE(A.IsCompatibleMatch(B));
333 ASSERT_FALSE(B.IsCompatibleMatch(A));
334 ASSERT_FALSE(B.IsCompatibleMatch(A));
337 ArchSpec A("arm64-*-*");
338 ArchSpec B("arm64-apple-ios");
339 ASSERT_FALSE(A.IsExactMatch(B));
340 // FIXME: This looks unintuitive and we should investigate whether
341 // this is the desired behavior.
342 ASSERT_FALSE(A.IsCompatibleMatch(B));
345 ArchSpec A("x86_64-*-*");
346 ArchSpec B("x86_64-apple-ios-simulator");
347 ASSERT_FALSE(A.IsExactMatch(B));
348 // FIXME: See above, though the extra environment complicates things.
349 ASSERT_FALSE(A.IsCompatibleMatch(B));
352 ArchSpec A("x86_64");
353 ArchSpec B("x86_64-apple-macosx10.14");
354 // FIXME: The exact match also looks unintuitive.
355 ASSERT_TRUE(A.IsExactMatch(B));
356 ASSERT_TRUE(A.IsCompatibleMatch(B));
359 ArchSpec A("x86_64");
360 ArchSpec B("x86_64-apple-ios12.0.0-macabi");
361 // FIXME: The exact match also looks unintuitive.
362 ASSERT_TRUE(A.IsExactMatch(B));
363 ASSERT_TRUE(A.IsCompatibleMatch(B));
366 ArchSpec A("x86_64-apple-ios12.0.0");
367 ArchSpec B("x86_64-apple-ios12.0.0-macabi");
368 ASSERT_FALSE(A.IsExactMatch(B));
369 ASSERT_FALSE(A.IsCompatibleMatch(B));
372 ArchSpec A("x86_64-apple-macosx10.14.2");
373 ArchSpec B("x86_64-apple-ios12.0.0-macabi");
374 ASSERT_FALSE(A.IsExactMatch(B));
375 ASSERT_TRUE(A.IsCompatibleMatch(B));
378 ArchSpec A("x86_64-apple-macosx10.14.2");
379 ArchSpec B("x86_64-apple-ios12.0.0-macabi");
380 // ios-macabi wins.
381 A.MergeFrom(B);
382 ASSERT_TRUE(A.IsExactMatch(B));
385 ArchSpec A("x86_64-apple-macosx10.14.2");
386 ArchSpec B("x86_64-apple-ios12.0.0-macabi");
387 ArchSpec C(B);
388 // ios-macabi wins.
389 B.MergeFrom(A);
390 ASSERT_TRUE(B.IsExactMatch(C));
394 TEST(ArchSpecTest, OperatorBool) {
395 EXPECT_FALSE(ArchSpec());
396 EXPECT_TRUE(ArchSpec("x86_64-pc-linux"));
399 TEST(ArchSpecTest, TripleComponentsWereSpecified) {
401 ArchSpec A("");
402 ArchSpec B("-");
403 ArchSpec C("--");
404 ArchSpec D("---");
406 ASSERT_FALSE(A.TripleVendorWasSpecified());
407 ASSERT_FALSE(A.TripleOSWasSpecified());
408 ASSERT_FALSE(A.TripleEnvironmentWasSpecified());
410 ASSERT_FALSE(B.TripleVendorWasSpecified());
411 ASSERT_FALSE(B.TripleOSWasSpecified());
412 ASSERT_FALSE(B.TripleEnvironmentWasSpecified());
414 ASSERT_FALSE(C.TripleVendorWasSpecified());
415 ASSERT_FALSE(C.TripleOSWasSpecified());
416 ASSERT_FALSE(C.TripleEnvironmentWasSpecified());
418 ASSERT_FALSE(D.TripleVendorWasSpecified());
419 ASSERT_FALSE(D.TripleOSWasSpecified());
420 ASSERT_FALSE(D.TripleEnvironmentWasSpecified());
423 // TODO: llvm::Triple::normalize treats the missing components from these
424 // triples as specified unknown components instead of unspecified
425 // components. We need to either change the behavior in llvm or work around
426 // this in lldb.
427 ArchSpec A("armv7");
428 ArchSpec B("armv7-");
429 ArchSpec C("armv7--");
430 ArchSpec D("armv7---");
432 ASSERT_FALSE(A.TripleVendorWasSpecified());
433 ASSERT_FALSE(A.TripleOSWasSpecified());
434 ASSERT_FALSE(A.TripleEnvironmentWasSpecified());
436 ASSERT_TRUE(B.TripleVendorWasSpecified());
437 ASSERT_FALSE(B.TripleOSWasSpecified());
438 ASSERT_FALSE(B.TripleEnvironmentWasSpecified());
440 ASSERT_TRUE(C.TripleVendorWasSpecified());
441 ASSERT_TRUE(C.TripleOSWasSpecified());
442 ASSERT_FALSE(C.TripleEnvironmentWasSpecified());
444 ASSERT_TRUE(D.TripleVendorWasSpecified());
445 ASSERT_TRUE(D.TripleOSWasSpecified());
446 ASSERT_TRUE(D.TripleEnvironmentWasSpecified());
449 ArchSpec A("x86_64-unknown");
450 ArchSpec B("powerpc-unknown-linux");
451 ArchSpec C("i386-pc-windows-msvc");
452 ArchSpec D("aarch64-unknown-linux-android");
454 ASSERT_TRUE(A.TripleVendorWasSpecified());
455 ASSERT_FALSE(A.TripleOSWasSpecified());
456 ASSERT_FALSE(A.TripleEnvironmentWasSpecified());
458 ASSERT_TRUE(B.TripleVendorWasSpecified());
459 ASSERT_TRUE(B.TripleOSWasSpecified());
460 ASSERT_FALSE(B.TripleEnvironmentWasSpecified());
462 ASSERT_TRUE(C.TripleVendorWasSpecified());
463 ASSERT_TRUE(C.TripleOSWasSpecified());
464 ASSERT_TRUE(C.TripleEnvironmentWasSpecified());
466 ASSERT_TRUE(D.TripleVendorWasSpecified());
467 ASSERT_TRUE(D.TripleOSWasSpecified());
468 ASSERT_TRUE(D.TripleEnvironmentWasSpecified());
472 TEST(ArchSpecTest, YAML) {
473 std::string buffer;
474 llvm::raw_string_ostream os(buffer);
476 // Serialize.
477 llvm::yaml::Output yout(os);
478 std::vector<ArchSpec> archs = {ArchSpec("x86_64-pc-linux"),
479 ArchSpec("x86_64-apple-macosx10.12"),
480 ArchSpec("i686-pc-windows")};
481 yout << archs;
482 os.flush();
484 // Deserialize.
485 std::vector<ArchSpec> deserialized;
486 llvm::yaml::Input yin(buffer);
487 yin >> deserialized;
489 EXPECT_EQ(archs, deserialized);