1 //===-- PlatformRemoteMacOSX.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 <memory>
10 #include <string>
11 #include <vector>
12
13 #include "PlatformRemoteMacOSX.h"
14
15 #include "lldb/Breakpoint/BreakpointLocation.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/ModuleList.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Host/Host.h"
21 #include "lldb/Host/HostInfo.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Utility/ArchSpec.h"
25 #include "lldb/Utility/FileSpec.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/StreamString.h"
28
29 using namespace lldb;
30 using namespace lldb_private;
31
32 /// Default Constructor
PlatformRemoteMacOSX()33 PlatformRemoteMacOSX::PlatformRemoteMacOSX() : PlatformRemoteDarwinDevice() {}
34
35 // Static Variables
36 static uint32_t g_initialize_count = 0;
37
38 // Static Functions
Initialize()39 void PlatformRemoteMacOSX::Initialize() {
40 PlatformDarwin::Initialize();
41
42 if (g_initialize_count++ == 0) {
43 PluginManager::RegisterPlugin(PlatformRemoteMacOSX::GetPluginNameStatic(),
44 PlatformRemoteMacOSX::GetDescriptionStatic(),
45 PlatformRemoteMacOSX::CreateInstance);
46 }
47 }
48
Terminate()49 void PlatformRemoteMacOSX::Terminate() {
50 if (g_initialize_count > 0) {
51 if (--g_initialize_count == 0) {
52 PluginManager::UnregisterPlugin(PlatformRemoteMacOSX::CreateInstance);
53 }
54 }
55
56 PlatformDarwin::Terminate();
57 }
58
CreateInstance(bool force,const ArchSpec * arch)59 PlatformSP PlatformRemoteMacOSX::CreateInstance(bool force,
60 const ArchSpec *arch) {
61 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
62 if (log) {
63 const char *arch_name;
64 if (arch && arch->GetArchitectureName())
65 arch_name = arch->GetArchitectureName();
66 else
67 arch_name = "<null>";
68
69 const char *triple_cstr =
70 arch ? arch->GetTriple().getTriple().c_str() : "<null>";
71
72 LLDB_LOGF(log, "PlatformMacOSX::%s(force=%s, arch={%s,%s})", __FUNCTION__,
73 force ? "true" : "false", arch_name, triple_cstr);
74 }
75
76 bool create = force;
77 if (!create && arch && arch->IsValid()) {
78 const llvm::Triple &triple = arch->GetTriple();
79 switch (triple.getVendor()) {
80 case llvm::Triple::Apple:
81 create = true;
82 break;
83
84 #if defined(__APPLE__)
85 // Only accept "unknown" for vendor if the host is Apple and it "unknown"
86 // wasn't specified (it was just returned because it was NOT specified)
87 case llvm::Triple::UnknownVendor:
88 create = !arch->TripleVendorWasSpecified();
89 break;
90 #endif
91 default:
92 break;
93 }
94
95 if (create) {
96 switch (triple.getOS()) {
97 case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
98 // historical reasons
99 case llvm::Triple::MacOSX:
100 break;
101 #if defined(__APPLE__)
102 // Only accept "vendor" for vendor if the host is Apple and it "unknown"
103 // wasn't specified (it was just returned because it was NOT specified)
104 case llvm::Triple::UnknownOS:
105 create = !arch->TripleOSWasSpecified();
106 break;
107 #endif
108 default:
109 create = false;
110 break;
111 }
112 }
113 }
114
115 if (create) {
116 LLDB_LOGF(log, "PlatformRemoteMacOSX::%s() creating platform",
117 __FUNCTION__);
118 return std::make_shared<PlatformRemoteMacOSX>();
119 }
120
121 LLDB_LOGF(log, "PlatformRemoteMacOSX::%s() aborting creation of platform",
122 __FUNCTION__);
123
124 return PlatformSP();
125 }
126
GetSupportedArchitectureAtIndex(uint32_t idx,ArchSpec & arch)127 bool PlatformRemoteMacOSX::GetSupportedArchitectureAtIndex(uint32_t idx,
128 ArchSpec &arch) {
129 // macOS for ARM64 support both native and translated x86_64 processes
130 if (!m_num_arm_arches || idx < m_num_arm_arches) {
131 bool res = ARMGetSupportedArchitectureAtIndex(idx, arch);
132 if (res)
133 return true;
134 if (!m_num_arm_arches)
135 m_num_arm_arches = idx;
136 }
137
138 // We can't use x86GetSupportedArchitectureAtIndex() because it uses
139 // the system architecture for some of its return values and also
140 // has a 32bits variant.
141 if (idx == m_num_arm_arches) {
142 arch.SetTriple("x86_64-apple-macosx");
143 return true;
144 } else if (idx == m_num_arm_arches + 1) {
145 arch.SetTriple("x86_64-apple-ios-macabi");
146 return true;
147 } else if (idx == m_num_arm_arches + 2) {
148 arch.SetTriple("arm64-apple-ios");
149 return true;
150 } else if (idx == m_num_arm_arches + 3) {
151 arch.SetTriple("arm64e-apple-ios");
152 return true;
153 }
154
155 return false;
156 }
157
GetFileWithUUID(const lldb_private::FileSpec & platform_file,const lldb_private::UUID * uuid_ptr,lldb_private::FileSpec & local_file)158 lldb_private::Status PlatformRemoteMacOSX::GetFileWithUUID(
159 const lldb_private::FileSpec &platform_file,
160 const lldb_private::UUID *uuid_ptr, lldb_private::FileSpec &local_file) {
161 if (m_remote_platform_sp) {
162 std::string local_os_build;
163 #if !defined(__linux__)
164 HostInfo::GetOSBuildString(local_os_build);
165 #endif
166 std::string remote_os_build;
167 m_remote_platform_sp->GetOSBuildString(remote_os_build);
168 if (local_os_build == remote_os_build) {
169 // same OS version: the local file is good enough
170 local_file = platform_file;
171 return Status();
172 } else {
173 // try to find the file in the cache
174 std::string cache_path(GetLocalCacheDirectory());
175 std::string module_path(platform_file.GetPath());
176 cache_path.append(module_path);
177 FileSpec module_cache_spec(cache_path);
178 if (FileSystem::Instance().Exists(module_cache_spec)) {
179 local_file = module_cache_spec;
180 return Status();
181 }
182 // bring in the remote module file
183 FileSpec module_cache_folder =
184 module_cache_spec.CopyByRemovingLastPathComponent();
185 // try to make the local directory first
186 Status err(
187 llvm::sys::fs::create_directory(module_cache_folder.GetPath()));
188 if (err.Fail())
189 return err;
190 err = GetFile(platform_file, module_cache_spec);
191 if (err.Fail())
192 return err;
193 if (FileSystem::Instance().Exists(module_cache_spec)) {
194 local_file = module_cache_spec;
195 return Status();
196 } else
197 return Status("unable to obtain valid module file");
198 }
199 }
200 local_file = platform_file;
201 return Status();
202 }
203
GetPluginNameStatic()204 lldb_private::ConstString PlatformRemoteMacOSX::GetPluginNameStatic() {
205 static ConstString g_name("remote-macosx");
206 return g_name;
207 }
208
GetDescriptionStatic()209 const char *PlatformRemoteMacOSX::GetDescriptionStatic() {
210 return "Remote Mac OS X user platform plug-in.";
211 }
212
GetDeviceSupportDirectoryName()213 llvm::StringRef PlatformRemoteMacOSX::GetDeviceSupportDirectoryName() {
214 return "macOS DeviceSupport";
215 }
216
GetPlatformName()217 llvm::StringRef PlatformRemoteMacOSX::GetPlatformName() {
218 return "MacOSX.platform";
219 }
220