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("thumb", "thumb", 56 PlatformThumb::CreateInstance); 57 } 58 static void Terminate() { 59 PluginManager::UnregisterPlugin(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, {}, 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, {}, 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 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 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