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