1 //===-- ArchSpecTest.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "gtest/gtest.h"
11 
12 #include "lldb/Utility/ArchSpec.h"
13 #include "llvm/BinaryFormat/MachO.h"
14 
15 using namespace lldb;
16 using namespace lldb_private;
17 
18 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleSimple) {
19 
20   // Success conditions.  Valid cpu/subtype combinations using both - and .
21   ArchSpec AS;
22   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10", AS));
23   EXPECT_EQ(12u, AS.GetMachOCPUType());
24   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
25 
26   AS = ArchSpec();
27   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15", AS));
28   EXPECT_EQ(12u, AS.GetMachOCPUType());
29   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
30 
31   AS = ArchSpec();
32   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12.15", AS));
33   EXPECT_EQ(12u, AS.GetMachOCPUType());
34   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
35 
36   // Failure conditions.
37 
38   // Valid string, unknown cpu/subtype.
39   AS = ArchSpec();
40   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("13.11", AS));
41   EXPECT_EQ(0u, AS.GetMachOCPUType());
42   EXPECT_EQ(0u, AS.GetMachOCPUSubType());
43 
44   // Missing / invalid cpu or subtype
45   AS = ArchSpec();
46   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13", AS));
47 
48   AS = ArchSpec();
49   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("13.A", AS));
50 
51   AS = ArchSpec();
52   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("A.13", AS));
53 
54   // Empty string.
55   AS = ArchSpec();
56   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("", AS));
57 }
58 
59 TEST(ArchSpecTest, TestParseMachCPUDashSubtypeTripleExtra) {
60   ArchSpec AS;
61   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor-os", AS));
62   EXPECT_EQ(12u, AS.GetMachOCPUType());
63   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
64   EXPECT_EQ("vendor", AS.GetTriple().getVendorName());
65   EXPECT_EQ("os", AS.GetTriple().getOSName());
66 
67   AS = ArchSpec();
68   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor-os-name", AS));
69   EXPECT_EQ(12u, AS.GetMachOCPUType());
70   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
71   EXPECT_EQ("vendor", AS.GetTriple().getVendorName());
72   EXPECT_EQ("os", AS.GetTriple().getOSName());
73 
74   AS = ArchSpec();
75   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-15-vendor.os-name", AS));
76   EXPECT_EQ(12u, AS.GetMachOCPUType());
77   EXPECT_EQ(15u, AS.GetMachOCPUSubType());
78   EXPECT_EQ("vendor.os", AS.GetTriple().getVendorName());
79   EXPECT_EQ("name", AS.GetTriple().getOSName());
80 
81   // These there should parse correctly, but the vendor / OS should be defaulted
82   // since they are unrecognized.
83   AS = ArchSpec();
84   EXPECT_TRUE(ParseMachCPUDashSubtypeTriple("12-10-vendor", AS));
85   EXPECT_EQ(12u, AS.GetMachOCPUType());
86   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
87   EXPECT_EQ("apple", AS.GetTriple().getVendorName());
88   EXPECT_EQ("", AS.GetTriple().getOSName());
89 
90   AS = ArchSpec();
91   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12.10.10", AS));
92 
93   AS = ArchSpec();
94   EXPECT_FALSE(ParseMachCPUDashSubtypeTriple("12-10.10", AS));
95 }
96 
97 TEST(ArchSpecTest, TestSetTriple) {
98   ArchSpec AS;
99 
100   // Various flavors of valid triples.
101   EXPECT_TRUE(AS.SetTriple("12-10-apple-darwin"));
102   EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_ARM), AS.GetMachOCPUType());
103   EXPECT_EQ(10u, AS.GetMachOCPUSubType());
104   EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
105                   .consume_front("armv7f-apple-darwin"));
106   EXPECT_EQ(ArchSpec::eCore_arm_armv7f, AS.GetCore());
107 
108   AS = ArchSpec();
109   EXPECT_TRUE(AS.SetTriple("18.100-apple-darwin"));
110   EXPECT_EQ(uint32_t(llvm::MachO::CPU_TYPE_POWERPC), AS.GetMachOCPUType());
111   EXPECT_EQ(100u, AS.GetMachOCPUSubType());
112   EXPECT_TRUE(llvm::StringRef(AS.GetTriple().str())
113                   .consume_front("powerpc-apple-darwin"));
114   EXPECT_EQ(ArchSpec::eCore_ppc_ppc970, AS.GetCore());
115 
116   AS = ArchSpec();
117   EXPECT_TRUE(AS.SetTriple("i686-pc-windows"));
118   EXPECT_EQ(llvm::Triple::x86, AS.GetTriple().getArch());
119   EXPECT_EQ(llvm::Triple::PC, AS.GetTriple().getVendor());
120   EXPECT_EQ(llvm::Triple::Win32, AS.GetTriple().getOS());
121   EXPECT_TRUE(
122       llvm::StringRef(AS.GetTriple().str()).consume_front("i686-pc-windows"));
123   EXPECT_STREQ("i686", AS.GetArchitectureName());
124   EXPECT_EQ(ArchSpec::eCore_x86_32_i686, AS.GetCore());
125 
126   // Various flavors of invalid triples.
127   AS = ArchSpec();
128   EXPECT_FALSE(AS.SetTriple("unknown-unknown-unknown"));
129 
130   AS = ArchSpec();
131   EXPECT_FALSE(AS.SetTriple("unknown"));
132 
133   AS = ArchSpec();
134   EXPECT_FALSE(AS.SetTriple(""));
135 }
136 
137 TEST(ArchSpecTest, MergeFrom) {
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 TEST(ArchSpecTest, MergeFromMachOUnknown) {
157   class MyArchSpec : public ArchSpec {
158   public:
159     MyArchSpec() {
160       this->SetTriple("unknown-mach-64");
161       this->m_core = ArchSpec::eCore_uknownMach64;
162       this->m_byte_order = eByteOrderLittle;
163       this->m_flags = 0;
164     }
165   };
166 
167   MyArchSpec A;
168   ASSERT_TRUE(A.IsValid());
169   MyArchSpec B;
170   ASSERT_TRUE(B.IsValid());
171   A.MergeFrom(B);
172   ASSERT_EQ(A.GetCore(), ArchSpec::eCore_uknownMach64);
173 }
174