1 //===-- ArchSpecTest.cpp --------------------------------------------------===//
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
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"
17 using namespace lldb_private
;
19 TEST(ArchSpecTest
, TestParseMachCPUDashSubtypeTripleSimple
) {
21 // Success conditions. Valid cpu/subtype combinations using both - and .
23 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10", AS
));
24 EXPECT_EQ(12u, AS
.GetMachOCPUType());
25 EXPECT_EQ(10u, AS
.GetMachOCPUSubType());
28 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15", AS
));
29 EXPECT_EQ(12u, AS
.GetMachOCPUType());
30 EXPECT_EQ(15u, AS
.GetMachOCPUSubType());
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.
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
47 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13", AS
));
50 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13.A", AS
));
53 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("A.13", AS
));
57 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("", AS
));
60 TEST(ArchSpecTest
, TestParseMachCPUDashSubtypeTripleExtra
) {
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());
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());
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.
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());
92 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12.10.10", AS
));
95 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12-10.10", AS
));
98 TEST(ArchSpecTest
, TestSetTriple
) {
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());
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());
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());
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.
129 EXPECT_FALSE(AS
.SetTriple("unknown-unknown-unknown"));
132 EXPECT_FALSE(AS
.SetTriple("unknown"));
135 EXPECT_FALSE(AS
.SetTriple(""));
138 TEST(ArchSpecTest
, MergeFrom
) {
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());
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());
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());
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());
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());
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());
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
{
261 this->SetTriple("unknown-mach-64");
262 this->m_core
= ArchSpec::eCore_uknownMach64
;
263 this->m_byte_order
= eByteOrderLittle
;
269 ASSERT_TRUE(A
.IsValid());
271 ASSERT_TRUE(B
.IsValid());
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");
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");
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
) {
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
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
) {
474 llvm::raw_string_ostream
os(buffer
);
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")};
485 std::vector
<ArchSpec
> deserialized
;
486 llvm::yaml::Input
yin(buffer
);
489 EXPECT_EQ(archs
, deserialized
);