1 //===-- ArchSpecTest.cpp ----------------------------------------*- C++ -*-===// 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 //===----------------------------------------------------------------------===// 8 9 #include "gtest/gtest.h" 10 11 #include "lldb/Utility/ArchSpec.h" 12 #include "llvm/BinaryFormat/MachO.h" 13 14 using namespace lldb; 15 using namespace lldb_private; 16 17 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleSimple) { 18 19 // Success conditions. Valid cpu/subtype combinations using both - and . 20 ArchSpec AS; 21 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10", AS)); 22 EXPECT_EQ(12u, AS.GetMachOCPUType()); 23 EXPECT_EQ(10u, AS.GetMachOCPUSubType()); 24 25 AS = ArchSpec(); 26 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15", AS)); 27 EXPECT_EQ(12u, AS.GetMachOCPUType()); 28 EXPECT_EQ(15u, AS.GetMachOCPUSubType()); 29 30 AS = ArchSpec(); 31 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12.15", AS)); 32 EXPECT_EQ(12u, AS.GetMachOCPUType()); 33 EXPECT_EQ(15u, AS.GetMachOCPUSubType()); 34 35 // Failure conditions. 36 37 // Valid string, unknown cpu/subtype. 38 AS = ArchSpec(); 39 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("13.11", AS)); 40 EXPECT_EQ(0u, AS.GetMachOCPUType()); 41 EXPECT_EQ(0u, AS.GetMachOCPUSubType()); 42 43 // Missing / invalid cpu or subtype 44 AS = ArchSpec(); 45 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13", AS)); 46 47 AS = ArchSpec(); 48 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13.A", AS)); 49 50 AS = ArchSpec(); 51 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("A.13", AS)); 52 53 // Empty string. 54 AS = ArchSpec(); 55 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("", AS)); 56 } 57 58 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleExtra) { 59 ArchSpec AS; 60 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor-os", AS)); 61 EXPECT_EQ(12u, AS.GetMachOCPUType()); 62 EXPECT_EQ(15u, AS.GetMachOCPUSubType()); 63 EXPECT_EQ("vendor", AS.GetTriple().getVendorName()); 64 EXPECT_EQ("os", AS.GetTriple().getOSName()); 65 66 AS = ArchSpec(); 67 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor-os-name", AS)); 68 EXPECT_EQ(12u, AS.GetMachOCPUType()); 69 EXPECT_EQ(10u, AS.GetMachOCPUSubType()); 70 EXPECT_EQ("vendor", AS.GetTriple().getVendorName()); 71 EXPECT_EQ("os", AS.GetTriple().getOSName()); 72 73 AS = ArchSpec(); 74 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor.os-name", AS)); 75 EXPECT_EQ(12u, AS.GetMachOCPUType()); 76 EXPECT_EQ(15u, AS.GetMachOCPUSubType()); 77 EXPECT_EQ("vendor.os", AS.GetTriple().getVendorName()); 78 EXPECT_EQ("name", AS.GetTriple().getOSName()); 79 80 // These there should parse correctly, but the vendor / OS should be defaulted 81 // since they are unrecognized. 82 AS = ArchSpec(); 83 EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor", AS)); 84 EXPECT_EQ(12u, AS.GetMachOCPUType()); 85 EXPECT_EQ(10u, AS.GetMachOCPUSubType()); 86 EXPECT_EQ("apple", AS.GetTriple().getVendorName()); 87 EXPECT_EQ("", AS.GetTriple().getOSName()); 88 89 AS = ArchSpec(); 90 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12.10.10", AS)); 91 92 AS = ArchSpec(); 93 EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12-10.10", AS)); 94 } 95 96 TEST(ArchSpecTest, TestSetTriple) { 97 ArchSpec AS; 98 99 // Various flavors of valid triples. 100 EXPECT_TRUE(AS.SetTriple("12-10-apple-darwin")); 101 EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_ARM), AS.GetMachOCPUType()); 102 EXPECT_EQ(10u, AS.GetMachOCPUSubType()); 103 EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str()) 104 .consume_front("armv7f-apple-darwin")); 105 EXPECT_EQ(ArchSpec::eCore_arm_armv7f, AS.GetCore()); 106 107 AS = ArchSpec(); 108 EXPECT_TRUE(AS.SetTriple("18.100-apple-darwin")); 109 EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_POWERPC), AS.GetMachOCPUType()); 110 EXPECT_EQ(100u, AS.GetMachOCPUSubType()); 111 EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str()) 112 .consume_front("powerpc-apple-darwin")); 113 EXPECT_EQ(ArchSpec::eCore_ppc_ppc970, AS.GetCore()); 114 115 AS = ArchSpec(); 116 EXPECT_TRUE(AS.SetTriple("i686-pc-windows")); 117 EXPECT_EQ(llvm::Triple::x86, AS.GetTriple().getArch()); 118 EXPECT_EQ(llvm::Triple::PC, AS.GetTriple().getVendor()); 119 EXPECT_EQ(llvm::Triple::Win32, AS.GetTriple().getOS()); 120 EXPECT_TRUE( 121 llvm::StringRef(AS.GetTriple().str()).consume_front("i686-pc-windows")); 122 EXPECT_STREQ("i686", AS.GetArchitectureName()); 123 EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore()); 124 125 // Various flavors of invalid triples. 126 AS = ArchSpec(); 127 EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown")); 128 129 AS = ArchSpec(); 130 EXPECT_FALSE(AS.SetTriple("unknown")); 131 132 AS = ArchSpec(); 133 EXPECT_FALSE(AS.SetTriple("")); 134 } 135 136 TEST(ArchSpecTest, MergeFrom) { 137 { 138 ArchSpec A; 139 ArchSpec B("x86_64-pc-linux"); 140 141 EXPECT_FALSE(A.IsValid()); 142 ASSERT_TRUE(B.IsValid()); 143 EXPECT_EQ(llvm::Triple::ArchType::x86_64, B.GetTriple().getArch()); 144 EXPECT_EQ(llvm::Triple::VendorType::PC, B.GetTriple().getVendor()); 145 EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); 146 EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, B.GetCore()); 147 148 A.MergeFrom(B); 149 ASSERT_TRUE(A.IsValid()); 150 EXPECT_EQ(llvm::Triple::ArchType::x86_64, A.GetTriple().getArch()); 151 EXPECT_EQ(llvm::Triple::VendorType::PC, A.GetTriple().getVendor()); 152 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); 153 EXPECT_EQ(ArchSpec::eCore_x86_64_x86_64, A.GetCore()); 154 } 155 { 156 ArchSpec A("aarch64"); 157 ArchSpec B("aarch64--linux-android"); 158 159 EXPECT_TRUE(A.IsValid()); 160 EXPECT_TRUE(B.IsValid()); 161 162 EXPECT_EQ(llvm::Triple::ArchType::aarch64, B.GetTriple().getArch()); 163 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, 164 B.GetTriple().getVendor()); 165 EXPECT_EQ(llvm::Triple::OSType::Linux, B.GetTriple().getOS()); 166 EXPECT_EQ(llvm::Triple::EnvironmentType::Android, 167 B.GetTriple().getEnvironment()); 168 169 A.MergeFrom(B); 170 EXPECT_EQ(llvm::Triple::ArchType::aarch64, A.GetTriple().getArch()); 171 EXPECT_EQ(llvm::Triple::VendorType::UnknownVendor, 172 A.GetTriple().getVendor()); 173 EXPECT_EQ(llvm::Triple::OSType::Linux, A.GetTriple().getOS()); 174 EXPECT_EQ(llvm::Triple::EnvironmentType::Android, 175 A.GetTriple().getEnvironment()); 176 } 177 } 178 179 TEST(ArchSpecTest, MergeFromMachOUnknown) { 180 class MyArchSpec : public ArchSpec { 181 public: 182 MyArchSpec() { 183 this->SetTriple("unknown-mach-64"); 184 this->m_core = ArchSpec::eCore_uknownMach64; 185 this->m_byte_order = eByteOrderLittle; 186 this->m_flags = 0; 187 } 188 }; 189 190 MyArchSpec A; 191 ASSERT_TRUE(A.IsValid()); 192 MyArchSpec B; 193 ASSERT_TRUE(B.IsValid()); 194 A.MergeFrom(B); 195 ASSERT_EQ(A.GetCore(), ArchSpec::eCore_uknownMach64); 196 } 197 198 TEST(ArchSpecTest, Compatibility) { 199 { 200 ArchSpec A("x86_64-apple-macosx10.12"); 201 ArchSpec B("x86_64-apple-macosx10.12"); 202 ASSERT_TRUE(A.IsExactMatch(B)); 203 ASSERT_TRUE(A.IsCompatibleMatch(B)); 204 } 205 { 206 // The version information is auxiliary to support availablity but 207 // doesn't affect compatibility. 208 ArchSpec A("x86_64-apple-macosx10.11"); 209 ArchSpec B("x86_64-apple-macosx10.12"); 210 ASSERT_TRUE(A.IsExactMatch(B)); 211 ASSERT_TRUE(A.IsCompatibleMatch(B)); 212 } 213 { 214 ArchSpec A("x86_64-apple-macosx10.13"); 215 ArchSpec B("x86_64h-apple-macosx10.13"); 216 ASSERT_FALSE(A.IsExactMatch(B)); 217 ASSERT_TRUE(A.IsCompatibleMatch(B)); 218 } 219 { 220 ArchSpec A("x86_64-apple-macosx"); 221 ArchSpec B("x86_64-apple-ios-simulator"); 222 ASSERT_FALSE(A.IsExactMatch(B)); 223 ASSERT_FALSE(A.IsCompatibleMatch(B)); 224 } 225 { 226 ArchSpec A("x86_64-*-*"); 227 ArchSpec B("x86_64-apple-ios-simulator"); 228 ASSERT_FALSE(A.IsExactMatch(B)); 229 ASSERT_FALSE(A.IsCompatibleMatch(B)); 230 } 231 { 232 ArchSpec A("arm64-*-*"); 233 ArchSpec B("arm64-apple-ios"); 234 ASSERT_FALSE(A.IsExactMatch(B)); 235 // FIXME: This looks unintuitive and we should investigate whether 236 // this is the desired behavior. 237 ASSERT_FALSE(A.IsCompatibleMatch(B)); 238 } 239 { 240 ArchSpec A("x86_64-*-*"); 241 ArchSpec B("x86_64-apple-ios-simulator"); 242 ASSERT_FALSE(A.IsExactMatch(B)); 243 // FIXME: See above, though the extra environment complicates things. 244 ASSERT_FALSE(A.IsCompatibleMatch(B)); 245 } 246 { 247 ArchSpec A("x86_64"); 248 ArchSpec B("x86_64-apple-macosx10.14"); 249 // FIXME: The exact match also looks unintuitive. 250 ASSERT_TRUE(A.IsExactMatch(B)); 251 ASSERT_TRUE(A.IsCompatibleMatch(B)); 252 } 253 } 254 255 TEST(ArchSpecTest, OperatorBool) { 256 EXPECT_FALSE(ArchSpec()); 257 EXPECT_TRUE(ArchSpec("x86_64-pc-linux")); 258 } 259 260 TEST(ArchSpecTest, TripleComponentsWereSpecified) { 261 { 262 ArchSpec A(""); 263 ArchSpec B("-"); 264 ArchSpec C("--"); 265 ArchSpec D("---"); 266 267 ASSERT_FALSE(A.TripleVendorWasSpecified()); 268 ASSERT_FALSE(A.TripleOSWasSpecified()); 269 ASSERT_FALSE(A.TripleEnvironmentWasSpecified()); 270 271 ASSERT_FALSE(B.TripleVendorWasSpecified()); 272 ASSERT_FALSE(B.TripleOSWasSpecified()); 273 ASSERT_FALSE(B.TripleEnvironmentWasSpecified()); 274 275 ASSERT_FALSE(C.TripleVendorWasSpecified()); 276 ASSERT_FALSE(C.TripleOSWasSpecified()); 277 ASSERT_FALSE(C.TripleEnvironmentWasSpecified()); 278 279 ASSERT_FALSE(D.TripleVendorWasSpecified()); 280 ASSERT_FALSE(D.TripleOSWasSpecified()); 281 ASSERT_FALSE(D.TripleEnvironmentWasSpecified()); 282 } 283 { 284 // TODO: llvm::Triple::normalize treats the missing components from these 285 // triples as specified unknown components instead of unspecified 286 // components. We need to either change the behavior in llvm or work around 287 // this in lldb. 288 ArchSpec A("armv7"); 289 ArchSpec B("armv7-"); 290 ArchSpec C("armv7--"); 291 ArchSpec D("armv7---"); 292 293 ASSERT_FALSE(A.TripleVendorWasSpecified()); 294 ASSERT_FALSE(A.TripleOSWasSpecified()); 295 ASSERT_FALSE(A.TripleEnvironmentWasSpecified()); 296 297 ASSERT_TRUE(B.TripleVendorWasSpecified()); 298 ASSERT_FALSE(B.TripleOSWasSpecified()); 299 ASSERT_FALSE(B.TripleEnvironmentWasSpecified()); 300 301 ASSERT_TRUE(C.TripleVendorWasSpecified()); 302 ASSERT_TRUE(C.TripleOSWasSpecified()); 303 ASSERT_FALSE(C.TripleEnvironmentWasSpecified()); 304 305 ASSERT_TRUE(D.TripleVendorWasSpecified()); 306 ASSERT_TRUE(D.TripleOSWasSpecified()); 307 ASSERT_TRUE(D.TripleEnvironmentWasSpecified()); 308 } 309 { 310 ArchSpec A("x86_64-unknown"); 311 ArchSpec B("powerpc-unknown-linux"); 312 ArchSpec C("i386-pc-windows-msvc"); 313 ArchSpec D("aarch64-unknown-linux-android"); 314 315 ASSERT_TRUE(A.TripleVendorWasSpecified()); 316 ASSERT_FALSE(A.TripleOSWasSpecified()); 317 ASSERT_FALSE(A.TripleEnvironmentWasSpecified()); 318 319 ASSERT_TRUE(B.TripleVendorWasSpecified()); 320 ASSERT_TRUE(B.TripleOSWasSpecified()); 321 ASSERT_FALSE(B.TripleEnvironmentWasSpecified()); 322 323 ASSERT_TRUE(C.TripleVendorWasSpecified()); 324 ASSERT_TRUE(C.TripleOSWasSpecified()); 325 ASSERT_TRUE(C.TripleEnvironmentWasSpecified()); 326 327 ASSERT_TRUE(D.TripleVendorWasSpecified()); 328 ASSERT_TRUE(D.TripleOSWasSpecified()); 329 ASSERT_TRUE(D.TripleEnvironmentWasSpecified()); 330 } 331 } 332