1 //===-- PlatformRemoteAppleWatch.cpp ----------------------------*- C++ -*-===//
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 <string>
10 #include <vector>
11 
12 #include "PlatformRemoteAppleWatch.h"
13 
14 #include "lldb/Breakpoint/BreakpointLocation.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleList.h"
17 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Host/Host.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/ArchSpec.h"
23 #include "lldb/Utility/FileSpec.h"
24 #include "lldb/Utility/Log.h"
25 #include "lldb/Utility/Status.h"
26 #include "lldb/Utility/StreamString.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 //------------------------------------------------------------------
32 // Static Variables
33 //------------------------------------------------------------------
34 static uint32_t g_initialize_count = 0;
35 
36 //------------------------------------------------------------------
37 // Static Functions
38 //------------------------------------------------------------------
39 void PlatformRemoteAppleWatch::Initialize() {
40   PlatformDarwin::Initialize();
41 
42   if (g_initialize_count++ == 0) {
43     PluginManager::RegisterPlugin(
44         PlatformRemoteAppleWatch::GetPluginNameStatic(),
45         PlatformRemoteAppleWatch::GetDescriptionStatic(),
46         PlatformRemoteAppleWatch::CreateInstance);
47   }
48 }
49 
50 void PlatformRemoteAppleWatch::Terminate() {
51   if (g_initialize_count > 0) {
52     if (--g_initialize_count == 0) {
53       PluginManager::UnregisterPlugin(PlatformRemoteAppleWatch::CreateInstance);
54     }
55   }
56 
57   PlatformDarwin::Terminate();
58 }
59 
60 PlatformSP PlatformRemoteAppleWatch::CreateInstance(bool force,
61                                                     const ArchSpec *arch) {
62   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
63   if (log) {
64     const char *arch_name;
65     if (arch && arch->GetArchitectureName())
66       arch_name = arch->GetArchitectureName();
67     else
68       arch_name = "<null>";
69 
70     const char *triple_cstr =
71         arch ? arch->GetTriple().getTriple().c_str() : "<null>";
72 
73     log->Printf("PlatformRemoteAppleWatch::%s(force=%s, arch={%s,%s})",
74                 __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
75   }
76 
77   bool create = force;
78   if (!create && arch && arch->IsValid()) {
79     switch (arch->GetMachine()) {
80     case llvm::Triple::arm:
81     case llvm::Triple::aarch64:
82     case llvm::Triple::thumb: {
83       const llvm::Triple &triple = arch->GetTriple();
84       llvm::Triple::VendorType vendor = triple.getVendor();
85       switch (vendor) {
86       case llvm::Triple::Apple:
87         create = true;
88         break;
89 
90 #if defined(__APPLE__)
91       // Only accept "unknown" for the vendor if the host is Apple and
92       // "unknown" wasn't specified (it was just returned because it was NOT
93       // specified)
94       case llvm::Triple::UnknownVendor:
95         create = !arch->TripleVendorWasSpecified();
96         break;
97 
98 #endif
99       default:
100         break;
101       }
102       if (create) {
103         switch (triple.getOS()) {
104         case llvm::Triple::WatchOS: // This is the right triple value for Apple
105                                     // Watch debugging
106           break;
107 
108         default:
109           create = false;
110           break;
111         }
112       }
113     } break;
114     default:
115       break;
116     }
117   }
118 
119 #if defined(__APPLE__) &&                                                      \
120     (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
121   // If lldb is running on a watch, this isn't a RemoteWatch environment; it's
122   // a local system environment.
123   if (force == false) {
124     create = false;
125   }
126 #endif
127 
128   if (create) {
129     if (log)
130       log->Printf("PlatformRemoteAppleWatch::%s() creating platform",
131                   __FUNCTION__);
132 
133     return lldb::PlatformSP(new PlatformRemoteAppleWatch());
134   }
135 
136   if (log)
137     log->Printf("PlatformRemoteAppleWatch::%s() aborting creation of platform",
138                 __FUNCTION__);
139 
140   return lldb::PlatformSP();
141 }
142 
143 lldb_private::ConstString PlatformRemoteAppleWatch::GetPluginNameStatic() {
144   static ConstString g_name("remote-watchos");
145   return g_name;
146 }
147 
148 const char *PlatformRemoteAppleWatch::GetDescriptionStatic() {
149   return "Remote Apple Watch platform plug-in.";
150 }
151 
152 //------------------------------------------------------------------
153 /// Default Constructor
154 //------------------------------------------------------------------
155 PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
156     : PlatformRemoteDarwinDevice() {}
157 
158 bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
159                                                                ArchSpec &arch) {
160   ArchSpec system_arch(GetSystemArchitecture());
161 
162   const ArchSpec::Core system_core = system_arch.GetCore();
163   switch (system_core) {
164   default:
165     switch (idx) {
166     case 0:
167       arch.SetTriple("arm64-apple-watchos");
168       return true;
169     case 1:
170       arch.SetTriple("armv7k-apple-watchos");
171       return true;
172     case 2:
173       arch.SetTriple("armv7s-apple-watchos");
174       return true;
175     case 3:
176       arch.SetTriple("armv7-apple-watchos");
177       return true;
178     case 4:
179       arch.SetTriple("thumbv7k-apple-watchos");
180       return true;
181     case 5:
182       arch.SetTriple("thumbv7-apple-watchos");
183       return true;
184     case 6:
185       arch.SetTriple("thumbv7s-apple-watchos");
186       return true;
187     default:
188       break;
189     }
190     break;
191 
192   case ArchSpec::eCore_arm_arm64:
193     switch (idx) {
194     case 0:
195       arch.SetTriple("arm64-apple-watchos");
196       return true;
197     case 1:
198       arch.SetTriple("armv7k-apple-watchos");
199       return true;
200     case 2:
201       arch.SetTriple("armv7s-apple-watchos");
202       return true;
203     case 3:
204       arch.SetTriple("armv7-apple-watchos");
205       return true;
206     case 4:
207       arch.SetTriple("thumbv7k-apple-watchos");
208       return true;
209     case 5:
210       arch.SetTriple("thumbv7-apple-watchos");
211       return true;
212     case 6:
213       arch.SetTriple("thumbv7s-apple-watchos");
214       return true;
215     default:
216       break;
217     }
218     break;
219 
220   case ArchSpec::eCore_arm_armv7k:
221     switch (idx) {
222     case 0:
223       arch.SetTriple("armv7k-apple-watchos");
224       return true;
225     case 1:
226       arch.SetTriple("armv7s-apple-watchos");
227       return true;
228     case 2:
229       arch.SetTriple("armv7-apple-watchos");
230       return true;
231     case 3:
232       arch.SetTriple("thumbv7k-apple-watchos");
233       return true;
234     case 4:
235       arch.SetTriple("thumbv7-apple-watchos");
236       return true;
237     case 5:
238       arch.SetTriple("thumbv7s-apple-watchos");
239       return true;
240     default:
241       break;
242     }
243     break;
244 
245   case ArchSpec::eCore_arm_armv7s:
246     switch (idx) {
247     case 0:
248       arch.SetTriple("armv7s-apple-watchos");
249       return true;
250     case 1:
251       arch.SetTriple("armv7k-apple-watchos");
252       return true;
253     case 2:
254       arch.SetTriple("armv7-apple-watchos");
255       return true;
256     case 3:
257       arch.SetTriple("thumbv7k-apple-watchos");
258       return true;
259     case 4:
260       arch.SetTriple("thumbv7-apple-watchos");
261       return true;
262     case 5:
263       arch.SetTriple("thumbv7s-apple-watchos");
264       return true;
265     default:
266       break;
267     }
268     break;
269 
270   case ArchSpec::eCore_arm_armv7:
271     switch (idx) {
272     case 0:
273       arch.SetTriple("armv7-apple-watchos");
274       return true;
275     case 1:
276       arch.SetTriple("armv7k-apple-watchos");
277       return true;
278     case 2:
279       arch.SetTriple("thumbv7k-apple-watchos");
280       return true;
281     case 3:
282       arch.SetTriple("thumbv7-apple-watchos");
283       return true;
284     default:
285       break;
286     }
287     break;
288   }
289   arch.Clear();
290   return false;
291 }
292 
293 void PlatformRemoteAppleWatch::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
294 {
295     dirnames.clear();
296     dirnames.push_back("watchOS DeviceSupport");
297 }
298 
299 std::string PlatformRemoteAppleWatch::GetPlatformName ()
300 {
301     return "WatchOS.platform";
302 }
303