1 //===-- PlatformTest.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 //===----------------------------------------------------------------------===//
8
9 #include "gtest/gtest.h"
10
11 #include "Plugins/Platform/POSIX/PlatformPOSIX.h"
12 #include "TestingSupport/SubsystemRAII.h"
13 #include "lldb/Core/PluginManager.h"
14 #include "lldb/Host/FileSystem.h"
15 #include "lldb/Host/HostInfo.h"
16 #include "lldb/Target/Platform.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 class TestPlatform : public PlatformPOSIX {
22 public:
TestPlatform()23 TestPlatform() : PlatformPOSIX(false) {}
24 };
25
26 class PlatformArm : public TestPlatform {
27 public:
28 PlatformArm() = default;
29
30 std::vector<ArchSpec>
GetSupportedArchitectures(const ArchSpec & process_host_arch)31 GetSupportedArchitectures(const ArchSpec &process_host_arch) override {
32 return {ArchSpec("arm64-apple-ps4")};
33 }
34
GetPluginName()35 llvm::StringRef GetPluginName() override { return "arm"; }
GetDescription()36 llvm::StringRef GetDescription() override { return "arm"; }
37 };
38
39 class PlatformIntel : public TestPlatform {
40 public:
41 PlatformIntel() = default;
42
43 std::vector<ArchSpec>
GetSupportedArchitectures(const ArchSpec & process_host_arch)44 GetSupportedArchitectures(const ArchSpec &process_host_arch) override {
45 return {ArchSpec("x86_64-apple-ps4")};
46 }
47
GetPluginName()48 llvm::StringRef GetPluginName() override { return "intel"; }
GetDescription()49 llvm::StringRef GetDescription() override { return "intel"; }
50 };
51
52 class PlatformThumb : public TestPlatform {
53 public:
Initialize()54 static void Initialize() {
55 PluginManager::RegisterPlugin("thumb", "thumb",
56 PlatformThumb::CreateInstance);
57 }
Terminate()58 static void Terminate() {
59 PluginManager::UnregisterPlugin(PlatformThumb::CreateInstance);
60 }
61
CreateInstance(bool force,const ArchSpec * arch)62 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
63 return std::make_shared<PlatformThumb>();
64 }
65
66 std::vector<ArchSpec>
GetSupportedArchitectures(const ArchSpec & process_host_arch)67 GetSupportedArchitectures(const ArchSpec &process_host_arch) override {
68 return {ArchSpec("thumbv7-apple-ps4"), ArchSpec("thumbv7f-apple-ps4")};
69 }
70
GetPluginName()71 llvm::StringRef GetPluginName() override { return "thumb"; }
GetDescription()72 llvm::StringRef GetDescription() override { return "thumb"; }
73 };
74
75 class PlatformTest : public ::testing::Test {
76 SubsystemRAII<FileSystem, HostInfo> subsystems;
77
78 protected:
79 PlatformList list;
80
SetHostPlatform(const PlatformSP & platform_sp)81 void SetHostPlatform(const PlatformSP &platform_sp) {
82 Platform::SetHostPlatform(platform_sp);
83 ASSERT_EQ(Platform::GetHostPlatform(), platform_sp);
84 list.Append(platform_sp, /*set_selected=*/true);
85 }
86 };
87
TEST_F(PlatformTest,GetPlatformForArchitecturesHost)88 TEST_F(PlatformTest, GetPlatformForArchitecturesHost) {
89 SetHostPlatform(std::make_shared<PlatformArm>());
90
91 const std::vector<ArchSpec> archs = {ArchSpec("arm64-apple-ps4"),
92 ArchSpec("arm64e-apple-ps4")};
93 std::vector<PlatformSP> candidates;
94
95 // The host platform matches all architectures.
96 PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
97 ASSERT_TRUE(platform_sp);
98 EXPECT_EQ(platform_sp, Platform::GetHostPlatform());
99 }
100
TEST_F(PlatformTest,GetPlatformForArchitecturesSelected)101 TEST_F(PlatformTest, GetPlatformForArchitecturesSelected) {
102 SetHostPlatform(std::make_shared<PlatformIntel>());
103
104 const std::vector<ArchSpec> archs = {ArchSpec("arm64-apple-ps4"),
105 ArchSpec("arm64e-apple-ps4")};
106 std::vector<PlatformSP> candidates;
107
108 // The host platform matches no architectures.
109 PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
110 ASSERT_FALSE(platform_sp);
111
112 // The selected platform matches all architectures.
113 const PlatformSP selected_platform_sp = std::make_shared<PlatformArm>();
114 list.Append(selected_platform_sp, /*set_selected=*/true);
115 platform_sp = list.GetOrCreate(archs, {}, candidates);
116 ASSERT_TRUE(platform_sp);
117 EXPECT_EQ(platform_sp, selected_platform_sp);
118 }
119
TEST_F(PlatformTest,GetPlatformForArchitecturesSelectedOverHost)120 TEST_F(PlatformTest, GetPlatformForArchitecturesSelectedOverHost) {
121 SetHostPlatform(std::make_shared<PlatformIntel>());
122
123 const std::vector<ArchSpec> archs = {ArchSpec("arm64-apple-ps4"),
124 ArchSpec("x86_64-apple-ps4")};
125 std::vector<PlatformSP> candidates;
126
127 // The host platform matches one architecture.
128 PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
129 ASSERT_TRUE(platform_sp);
130 EXPECT_EQ(platform_sp, Platform::GetHostPlatform());
131
132 // The selected and host platform each match one architecture.
133 // The selected platform is preferred.
134 const PlatformSP selected_platform_sp = std::make_shared<PlatformArm>();
135 list.Append(selected_platform_sp, /*set_selected=*/true);
136 platform_sp = list.GetOrCreate(archs, {}, candidates);
137 ASSERT_TRUE(platform_sp);
138 EXPECT_EQ(platform_sp, selected_platform_sp);
139 }
140
TEST_F(PlatformTest,GetPlatformForArchitecturesCandidates)141 TEST_F(PlatformTest, GetPlatformForArchitecturesCandidates) {
142 PlatformThumb::Initialize();
143
144 SetHostPlatform(std::make_shared<PlatformIntel>());
145
146 const PlatformSP selected_platform_sp = std::make_shared<PlatformArm>();
147 list.Append(selected_platform_sp, /*set_selected=*/true);
148
149 const std::vector<ArchSpec> archs = {ArchSpec("thumbv7-apple-ps4"),
150 ArchSpec("thumbv7f-apple-ps4")};
151 std::vector<PlatformSP> candidates;
152
153 // The host platform matches one architecture.
154 PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
155 ASSERT_TRUE(platform_sp);
156 EXPECT_EQ(platform_sp->GetName(), "thumb");
157
158 PlatformThumb::Terminate();
159 }
160