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: |
23 | TestPlatform() : PlatformPOSIX(false) {} |
24 | }; |
25 | |
26 | class PlatformArm : public TestPlatform { |
27 | public: |
28 | PlatformArm() = default; |
29 | |
30 | std::vector<ArchSpec> |
31 | GetSupportedArchitectures(const ArchSpec &process_host_arch) override { |
32 | return {ArchSpec("arm64-apple-ps4" )}; |
33 | } |
34 | |
35 | llvm::StringRef GetPluginName() override { return "arm" ; } |
36 | llvm::StringRef GetDescription() override { return "arm" ; } |
37 | }; |
38 | |
39 | class PlatformIntel : public TestPlatform { |
40 | public: |
41 | PlatformIntel() = default; |
42 | |
43 | std::vector<ArchSpec> |
44 | GetSupportedArchitectures(const ArchSpec &process_host_arch) override { |
45 | return {ArchSpec("x86_64-apple-ps4" )}; |
46 | } |
47 | |
48 | llvm::StringRef GetPluginName() override { return "intel" ; } |
49 | llvm::StringRef GetDescription() override { return "intel" ; } |
50 | }; |
51 | |
52 | class PlatformThumb : public TestPlatform { |
53 | public: |
54 | static void Initialize() { |
55 | PluginManager::RegisterPlugin(name: "thumb" , description: "thumb" , |
56 | create_callback: PlatformThumb::CreateInstance); |
57 | } |
58 | static void Terminate() { |
59 | PluginManager::UnregisterPlugin(create_callback: PlatformThumb::CreateInstance); |
60 | } |
61 | |
62 | static PlatformSP CreateInstance(bool force, const ArchSpec *arch) { |
63 | return std::make_shared<PlatformThumb>(); |
64 | } |
65 | |
66 | std::vector<ArchSpec> |
67 | GetSupportedArchitectures(const ArchSpec &process_host_arch) override { |
68 | return {ArchSpec("thumbv7-apple-ps4" ), ArchSpec("thumbv7f-apple-ps4" )}; |
69 | } |
70 | |
71 | llvm::StringRef GetPluginName() override { return "thumb" ; } |
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 | |
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 | |
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, process_host_arch: {}, candidates); |
97 | ASSERT_TRUE(platform_sp); |
98 | EXPECT_EQ(platform_sp, Platform::GetHostPlatform()); |
99 | } |
100 | |
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, process_host_arch: {}, 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(platform_sp: selected_platform_sp, /*set_selected=*/true); |
115 | platform_sp = list.GetOrCreate(archs, process_host_arch: {}, candidates); |
116 | ASSERT_TRUE(platform_sp); |
117 | EXPECT_EQ(platform_sp, selected_platform_sp); |
118 | } |
119 | |
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, process_host_arch: {}, 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(platform_sp: selected_platform_sp, /*set_selected=*/true); |
136 | platform_sp = list.GetOrCreate(archs, process_host_arch: {}, candidates); |
137 | ASSERT_TRUE(platform_sp); |
138 | EXPECT_EQ(platform_sp, selected_platform_sp); |
139 | } |
140 | |
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(platform_sp: 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, process_host_arch: {}, candidates); |
155 | ASSERT_TRUE(platform_sp); |
156 | EXPECT_EQ(platform_sp->GetName(), "thumb" ); |
157 | |
158 | PlatformThumb::Terminate(); |
159 | } |
160 | |