1 //===-- PlatformRemoteGDBServer.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "PlatformRemoteGDBServer.h"
11 #include "lldb/Host/Config.h"
12 
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/ModuleList.h"
22 #include "lldb/Core/ModuleSpec.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Host/ConnectionFileDescriptor.h"
26 #include "lldb/Host/FileSpec.h"
27 #include "lldb/Host/Host.h"
28 #include "lldb/Host/HostInfo.h"
29 #include "lldb/Host/StringConvert.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/Target.h"
32 
33 #include "Utility/UriParser.h"
34 
35 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 using namespace lldb_private::platform_gdb_server;
40 
41 static bool g_initialized = false;
42 
43 void
44 PlatformRemoteGDBServer::Initialize ()
45 {
46     Platform::Initialize ();
47 
48     if (g_initialized == false)
49     {
50         g_initialized = true;
51         PluginManager::RegisterPlugin (PlatformRemoteGDBServer::GetPluginNameStatic(),
52                                        PlatformRemoteGDBServer::GetDescriptionStatic(),
53                                        PlatformRemoteGDBServer::CreateInstance);
54     }
55 }
56 
57 void
58 PlatformRemoteGDBServer::Terminate ()
59 {
60     if (g_initialized)
61     {
62         g_initialized = false;
63         PluginManager::UnregisterPlugin (PlatformRemoteGDBServer::CreateInstance);
64     }
65 
66     Platform::Terminate ();
67 }
68 
69 PlatformSP
70 PlatformRemoteGDBServer::CreateInstance (bool force, const ArchSpec *arch)
71 {
72     bool create = force;
73     if (!create)
74     {
75         create = !arch->TripleVendorWasSpecified() && !arch->TripleOSWasSpecified();
76     }
77     if (create)
78         return PlatformSP(new PlatformRemoteGDBServer());
79     return PlatformSP();
80 }
81 
82 
83 ConstString
84 PlatformRemoteGDBServer::GetPluginNameStatic()
85 {
86     static ConstString g_name("remote-gdb-server");
87     return g_name;
88 }
89 
90 const char *
91 PlatformRemoteGDBServer::GetDescriptionStatic()
92 {
93     return "A platform that uses the GDB remote protocol as the communication transport.";
94 }
95 
96 const char *
97 PlatformRemoteGDBServer::GetDescription ()
98 {
99     if (m_platform_description.empty())
100     {
101         if (IsConnected())
102         {
103             // Send the get description packet
104         }
105     }
106 
107     if (!m_platform_description.empty())
108         return m_platform_description.c_str();
109     return GetDescriptionStatic();
110 }
111 
112 Error
113 PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec,
114                                             lldb::ModuleSP &exe_module_sp,
115                                             const FileSpecList *module_search_paths_ptr)
116 {
117     // copied from PlatformRemoteiOS
118 
119     Error error;
120     // Nothing special to do here, just use the actual file and architecture
121 
122     ModuleSpec resolved_module_spec(module_spec);
123 
124     // Resolve any executable within an apk on Android?
125     //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
126 
127     if (resolved_module_spec.GetFileSpec().Exists() ||
128         module_spec.GetUUID().IsValid())
129     {
130         if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
131         {
132             error = ModuleList::GetSharedModule (resolved_module_spec,
133                                                  exe_module_sp,
134                                                  module_search_paths_ptr,
135                                                  NULL,
136                                                  NULL);
137 
138             if (exe_module_sp && exe_module_sp->GetObjectFile())
139                 return error;
140             exe_module_sp.reset();
141         }
142         // No valid architecture was specified or the exact arch wasn't
143         // found so ask the platform for the architectures that we should be
144         // using (in the correct order) and see if we can find a match that way
145         StreamString arch_names;
146         for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
147         {
148             error = ModuleList::GetSharedModule (resolved_module_spec,
149                                                  exe_module_sp,
150                                                  module_search_paths_ptr,
151                                                  NULL,
152                                                  NULL);
153             // Did we find an executable using one of the
154             if (error.Success())
155             {
156                 if (exe_module_sp && exe_module_sp->GetObjectFile())
157                     break;
158                 else
159                     error.SetErrorToGenericError();
160             }
161 
162             if (idx > 0)
163                 arch_names.PutCString (", ");
164             arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
165         }
166 
167         if (error.Fail() || !exe_module_sp)
168         {
169             if (resolved_module_spec.GetFileSpec().Readable())
170             {
171                 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
172                                                 resolved_module_spec.GetFileSpec().GetPath().c_str(),
173                                                 GetPluginName().GetCString(),
174                                                 arch_names.GetString().c_str());
175             }
176             else
177             {
178                 error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
179             }
180         }
181     }
182     else
183     {
184         error.SetErrorStringWithFormat ("'%s' does not exist",
185                                         resolved_module_spec.GetFileSpec().GetPath().c_str());
186     }
187 
188     return error;
189 }
190 
191 bool
192 PlatformRemoteGDBServer::GetModuleSpec (const FileSpec& module_file_spec,
193                                         const ArchSpec& arch,
194                                         ModuleSpec &module_spec)
195 {
196     Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
197 
198     const auto module_path = module_file_spec.GetPath (false);
199 
200     if (!m_gdb_client.GetModuleInfo (module_file_spec, arch, module_spec))
201     {
202         if (log)
203             log->Printf ("PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
204                          __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str ());
205         return false;
206     }
207 
208     if (log)
209     {
210         StreamString stream;
211         module_spec.Dump (stream);
212         log->Printf ("PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
213                      __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
214     }
215 
216     return true;
217 }
218 
219 Error
220 PlatformRemoteGDBServer::GetFileWithUUID (const FileSpec &platform_file,
221                                           const UUID *uuid_ptr,
222                                           FileSpec &local_file)
223 {
224     // Default to the local case
225     local_file = platform_file;
226     return Error();
227 }
228 
229 //------------------------------------------------------------------
230 /// Default Constructor
231 //------------------------------------------------------------------
232 PlatformRemoteGDBServer::PlatformRemoteGDBServer () :
233     Platform (false), // This is a remote platform
234     m_gdb_client ()
235 {
236 }
237 
238 //------------------------------------------------------------------
239 /// Destructor.
240 ///
241 /// The destructor is virtual since this class is designed to be
242 /// inherited from by the plug-in instance.
243 //------------------------------------------------------------------
244 PlatformRemoteGDBServer::~PlatformRemoteGDBServer()
245 {
246 }
247 
248 bool
249 PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
250 {
251     ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
252 
253     if (idx == 0)
254     {
255         arch = remote_arch;
256         return arch.IsValid();
257     }
258     else if (idx == 1 && remote_arch.IsValid() && remote_arch.GetTriple().isArch64Bit())
259     {
260         arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant());
261         return arch.IsValid();
262     }
263     return false;
264 }
265 
266 size_t
267 PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
268 {
269     // This isn't needed if the z/Z packets are supported in the GDB remote
270     // server. But we might need a packet to detect this.
271     return 0;
272 }
273 
274 bool
275 PlatformRemoteGDBServer::GetRemoteOSVersion ()
276 {
277     uint32_t major, minor, update;
278     if (m_gdb_client.GetOSVersion (major, minor, update))
279     {
280         m_major_os_version = major;
281         m_minor_os_version = minor;
282         m_update_os_version = update;
283         return true;
284     }
285     return false;
286 }
287 
288 bool
289 PlatformRemoteGDBServer::GetRemoteOSBuildString (std::string &s)
290 {
291     return m_gdb_client.GetOSBuildString (s);
292 }
293 
294 bool
295 PlatformRemoteGDBServer::GetRemoteOSKernelDescription (std::string &s)
296 {
297     return m_gdb_client.GetOSKernelDescription (s);
298 }
299 
300 // Remote Platform subclasses need to override this function
301 ArchSpec
302 PlatformRemoteGDBServer::GetRemoteSystemArchitecture ()
303 {
304     return m_gdb_client.GetSystemArchitecture();
305 }
306 
307 FileSpec
308 PlatformRemoteGDBServer::GetRemoteWorkingDirectory()
309 {
310     if (IsConnected())
311     {
312         Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
313         FileSpec working_dir;
314         if (m_gdb_client.GetWorkingDir(working_dir) && log)
315             log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
316                     working_dir.GetCString());
317         return working_dir;
318     }
319     else
320     {
321         return Platform::GetRemoteWorkingDirectory();
322     }
323 }
324 
325 bool
326 PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const FileSpec &working_dir)
327 {
328     if (IsConnected())
329     {
330         // Clear the working directory it case it doesn't get set correctly. This will
331         // for use to re-read it
332         Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
333         if (log)
334             log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
335                     working_dir.GetCString());
336         return m_gdb_client.SetWorkingDir(working_dir) == 0;
337     }
338     else
339         return Platform::SetRemoteWorkingDirectory(working_dir);
340 }
341 
342 bool
343 PlatformRemoteGDBServer::IsConnected () const
344 {
345     return m_gdb_client.IsConnected();
346 }
347 
348 Error
349 PlatformRemoteGDBServer::ConnectRemote (Args& args)
350 {
351     Error error;
352     if (IsConnected())
353     {
354         error.SetErrorStringWithFormat ("the platform is already connected to '%s', execute 'platform disconnect' to close the current connection",
355                                         GetHostname());
356     }
357     else
358     {
359         if (args.GetArgumentCount() == 1)
360         {
361             m_gdb_client.SetConnection(new ConnectionFileDescriptor());
362             // we're going to reuse the hostname when we connect to the debugserver
363             int port;
364             std::string path;
365             const char *url = args.GetArgumentAtIndex(0);
366             if (!url)
367                 return Error("URL is null.");
368             if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path))
369                 return Error("Invalid URL: %s", url);
370 
371             const ConnectionStatus status = m_gdb_client.Connect(url, &error);
372             if (status == eConnectionStatusSuccess)
373             {
374                 if (m_gdb_client.HandshakeWithServer(&error))
375                 {
376                     m_gdb_client.GetHostInfo();
377                     // If a working directory was set prior to connecting, send it down now
378                     if (m_working_dir)
379                         m_gdb_client.SetWorkingDir(m_working_dir);
380                 }
381                 else
382                 {
383                     m_gdb_client.Disconnect();
384                     if (error.Success())
385                         error.SetErrorString("handshake failed");
386                 }
387             }
388         }
389         else
390         {
391             error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
392         }
393     }
394     return error;
395 }
396 
397 Error
398 PlatformRemoteGDBServer::DisconnectRemote ()
399 {
400     Error error;
401     m_gdb_client.Disconnect(&error);
402     m_remote_signals_sp.reset();
403     return error;
404 }
405 
406 const char *
407 PlatformRemoteGDBServer::GetHostname ()
408 {
409     m_gdb_client.GetHostname (m_name);
410     if (m_name.empty())
411         return NULL;
412     return m_name.c_str();
413 }
414 
415 const char *
416 PlatformRemoteGDBServer::GetUserName (uint32_t uid)
417 {
418     // Try and get a cache user name first
419     const char *cached_user_name = Platform::GetUserName(uid);
420     if (cached_user_name)
421         return cached_user_name;
422     std::string name;
423     if (m_gdb_client.GetUserName(uid, name))
424         return SetCachedUserName(uid, name.c_str(), name.size());
425 
426     SetUserNameNotFound(uid); // Negative cache so we don't keep sending packets
427     return NULL;
428 }
429 
430 const char *
431 PlatformRemoteGDBServer::GetGroupName (uint32_t gid)
432 {
433     const char *cached_group_name = Platform::GetGroupName(gid);
434     if (cached_group_name)
435         return cached_group_name;
436     std::string name;
437     if (m_gdb_client.GetGroupName(gid, name))
438         return SetCachedGroupName(gid, name.c_str(), name.size());
439 
440     SetGroupNameNotFound(gid); // Negative cache so we don't keep sending packets
441     return NULL;
442 }
443 
444 uint32_t
445 PlatformRemoteGDBServer::FindProcesses (const ProcessInstanceInfoMatch &match_info,
446                                         ProcessInstanceInfoList &process_infos)
447 {
448     return m_gdb_client.FindProcesses (match_info, process_infos);
449 }
450 
451 bool
452 PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
453 {
454     return m_gdb_client.GetProcessInfo (pid, process_info);
455 }
456 
457 
458 Error
459 PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
460 {
461     Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
462     Error error;
463 
464     if (log)
465         log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
466 
467     auto num_file_actions = launch_info.GetNumFileActions ();
468     for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i)
469     {
470         const auto file_action = launch_info.GetFileActionAtIndex (i);
471         if (file_action->GetAction () != FileAction::eFileActionOpen)
472             continue;
473         switch(file_action->GetFD())
474         {
475         case STDIN_FILENO:
476             m_gdb_client.SetSTDIN(file_action->GetFileSpec());
477             break;
478         case STDOUT_FILENO:
479             m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
480             break;
481         case STDERR_FILENO:
482             m_gdb_client.SetSTDERR(file_action->GetFileSpec());
483             break;
484         }
485     }
486 
487     m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
488     m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
489 
490     FileSpec working_dir = launch_info.GetWorkingDirectory();
491     if (working_dir)
492     {
493         m_gdb_client.SetWorkingDir(working_dir);
494     }
495 
496     // Send the environment and the program + arguments after we connect
497     const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
498 
499     if (envp)
500     {
501         const char *env_entry;
502         for (int i=0; (env_entry = envp[i]); ++i)
503         {
504             if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0)
505                 break;
506         }
507     }
508 
509     ArchSpec arch_spec = launch_info.GetArchitecture();
510     const char *arch_triple = arch_spec.GetTriple().str().c_str();
511 
512     m_gdb_client.SendLaunchArchPacket(arch_triple);
513     if (log)
514         log->Printf ("PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
515 
516     int arg_packet_err;
517     {
518         // Scope for the scoped timeout object
519         process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_client, 5);
520         arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info);
521     }
522 
523     if (arg_packet_err == 0)
524     {
525         std::string error_str;
526         if (m_gdb_client.GetLaunchSuccess (error_str))
527         {
528             const auto pid = m_gdb_client.GetCurrentProcessID (false);
529             if (pid != LLDB_INVALID_PROCESS_ID)
530             {
531                 launch_info.SetProcessID (pid);
532                 if (log)
533                     log->Printf ("PlatformRemoteGDBServer::%s() pid %" PRIu64 " launched successfully", __FUNCTION__, pid);
534             }
535             else
536             {
537                 if (log)
538                     log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__);
539                 error.SetErrorString ("failed to get PID");
540             }
541         }
542         else
543         {
544             error.SetErrorString (error_str.c_str());
545             if (log)
546                 log->Printf ("PlatformRemoteGDBServer::%s() launch failed: %s", __FUNCTION__, error.AsCString ());
547         }
548     }
549     else
550     {
551         error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err);
552     }
553     return error;
554 }
555 
556 Error
557 PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid)
558 {
559     if (!KillSpawnedProcess(pid))
560         return Error("failed to kill remote spawned process");
561     return Error();
562 }
563 
564 lldb::ProcessSP
565 PlatformRemoteGDBServer::DebugProcess (ProcessLaunchInfo &launch_info,
566                                        Debugger &debugger,
567                                        Target *target,       // Can be NULL, if NULL create a new target, else use existing one
568                                        Error &error)
569 {
570     lldb::ProcessSP process_sp;
571     if (IsRemote())
572     {
573         if (IsConnected())
574         {
575             lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
576             uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid);
577 
578             if (port == 0)
579             {
580                 error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
581             }
582             else
583             {
584                 if (target == NULL)
585                 {
586                     TargetSP new_target_sp;
587 
588                     error = debugger.GetTargetList().CreateTarget (debugger,
589                                                                    NULL,
590                                                                    NULL,
591                                                                    false,
592                                                                    NULL,
593                                                                    new_target_sp);
594                     target = new_target_sp.get();
595                 }
596                 else
597                     error.Clear();
598 
599                 if (target && error.Success())
600                 {
601                     debugger.GetTargetList().SetSelectedTarget(target);
602 
603                     // The darwin always currently uses the GDB remote debugger plug-in
604                     // so even when debugging locally we are debugging remotely!
605                     process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
606 
607                     if (process_sp)
608                     {
609                         std::string connect_url =
610                             MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
611                         error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
612                         // Retry the connect remote one time...
613                         if (error.Fail())
614                             error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
615                         if (error.Success())
616                             error = process_sp->Launch(launch_info);
617                         else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
618                         {
619                             printf ("error: connect remote failed (%s)\n", error.AsCString());
620                             KillSpawnedProcess(debugserver_pid);
621                         }
622                     }
623                 }
624             }
625         }
626         else
627         {
628             error.SetErrorString("not connected to remote gdb server");
629         }
630     }
631     return process_sp;
632 
633 }
634 
635 uint16_t
636 PlatformRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
637 {
638     ArchSpec remote_arch = GetRemoteSystemArchitecture ();
639     llvm::Triple &remote_triple = remote_arch.GetTriple ();
640     if (remote_triple.getVendor () == llvm::Triple::Apple && remote_triple.getOS () == llvm::Triple::IOS)
641     {
642         // When remote debugging to iOS, we use a USB mux that always talks
643         // to localhost, so we will need the remote debugserver to accept connections
644         // only from localhost, no matter what our current hostname is
645         return m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1");
646     }
647     else
648     {
649         // All other hosts should use their actual hostname
650         return m_gdb_client.LaunchGDBserverAndGetPort (pid, NULL);
651     }
652 }
653 
654 bool
655 PlatformRemoteGDBServer::KillSpawnedProcess (lldb::pid_t pid)
656 {
657     return m_gdb_client.KillSpawnedProcess (pid);
658 }
659 
660 lldb::ProcessSP
661 PlatformRemoteGDBServer::Attach (ProcessAttachInfo &attach_info,
662                                  Debugger &debugger,
663                                  Target *target,       // Can be NULL, if NULL create a new target, else use existing one
664                                  Error &error)
665 {
666     lldb::ProcessSP process_sp;
667     if (IsRemote())
668     {
669         if (IsConnected())
670         {
671             lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
672             uint16_t port = LaunchGDBserverAndGetPort(debugserver_pid);
673 
674             if (port == 0)
675             {
676                 error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
677             }
678             else
679             {
680                 if (target == NULL)
681                 {
682                     TargetSP new_target_sp;
683 
684                     error = debugger.GetTargetList().CreateTarget (debugger,
685                                                                    NULL,
686                                                                    NULL,
687                                                                    false,
688                                                                    NULL,
689                                                                    new_target_sp);
690                     target = new_target_sp.get();
691                 }
692                 else
693                     error.Clear();
694 
695                 if (target && error.Success())
696                 {
697                     debugger.GetTargetList().SetSelectedTarget(target);
698 
699                     // The darwin always currently uses the GDB remote debugger plug-in
700                     // so even when debugging locally we are debugging remotely!
701                     process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
702 
703                     if (process_sp)
704                     {
705                         std::string connect_url =
706                             MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
707                         error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
708                         if (error.Success())
709                         {
710                             auto listener = attach_info.GetHijackListener();
711                             if (listener != nullptr)
712                                 process_sp->HijackProcessEvents(listener.get());
713                             error = process_sp->Attach(attach_info);
714                         }
715 
716                         if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID)
717                         {
718                             KillSpawnedProcess(debugserver_pid);
719                         }
720                     }
721                 }
722             }
723         }
724         else
725         {
726             error.SetErrorString("not connected to remote gdb server");
727         }
728     }
729     return process_sp;
730 }
731 
732 Error
733 PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec, uint32_t mode)
734 {
735     Error error = m_gdb_client.MakeDirectory(file_spec, mode);
736     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
737     if (log)
738         log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)",
739                 file_spec.GetCString(), mode, error.GetError(), error.AsCString());
740     return error;
741 }
742 
743 
744 Error
745 PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
746                                             uint32_t &file_permissions)
747 {
748     Error error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
749     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
750     if (log)
751         log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)",
752                 file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString());
753     return error;
754 }
755 
756 Error
757 PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
758                                             uint32_t file_permissions)
759 {
760     Error error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
761     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
762     if (log)
763         log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)",
764                 file_spec.GetCString(), file_permissions, error.GetError(), error.AsCString());
765     return error;
766 }
767 
768 
769 lldb::user_id_t
770 PlatformRemoteGDBServer::OpenFile (const FileSpec& file_spec,
771                                    uint32_t flags,
772                                    uint32_t mode,
773                                    Error &error)
774 {
775     return m_gdb_client.OpenFile (file_spec, flags, mode, error);
776 }
777 
778 bool
779 PlatformRemoteGDBServer::CloseFile (lldb::user_id_t fd, Error &error)
780 {
781     return m_gdb_client.CloseFile (fd, error);
782 }
783 
784 lldb::user_id_t
785 PlatformRemoteGDBServer::GetFileSize (const FileSpec& file_spec)
786 {
787     return m_gdb_client.GetFileSize(file_spec);
788 }
789 
790 uint64_t
791 PlatformRemoteGDBServer::ReadFile (lldb::user_id_t fd,
792                                    uint64_t offset,
793                                    void *dst,
794                                    uint64_t dst_len,
795                                    Error &error)
796 {
797     return m_gdb_client.ReadFile (fd, offset, dst, dst_len, error);
798 }
799 
800 uint64_t
801 PlatformRemoteGDBServer::WriteFile (lldb::user_id_t fd,
802                                     uint64_t offset,
803                                     const void* src,
804                                     uint64_t src_len,
805                                     Error &error)
806 {
807     return m_gdb_client.WriteFile (fd, offset, src, src_len, error);
808 }
809 
810 Error
811 PlatformRemoteGDBServer::PutFile (const FileSpec& source,
812          const FileSpec& destination,
813          uint32_t uid,
814          uint32_t gid)
815 {
816     return Platform::PutFile(source,destination,uid,gid);
817 }
818 
819 Error
820 PlatformRemoteGDBServer::CreateSymlink(const FileSpec &src,    // The name of the link is in src
821                                        const FileSpec &dst)    // The symlink points to dst
822 {
823     Error error = m_gdb_client.CreateSymlink(src, dst);
824     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
825     if (log)
826         log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)",
827                 src.GetCString(), dst.GetCString(), error.GetError(), error.AsCString());
828     return error;
829 }
830 
831 Error
832 PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec)
833 {
834     Error error = m_gdb_client.Unlink(file_spec);
835     Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
836     if (log)
837         log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
838                 file_spec.GetCString(), error.GetError(), error.AsCString());
839     return error;
840 }
841 
842 bool
843 PlatformRemoteGDBServer::GetFileExists (const FileSpec& file_spec)
844 {
845     return m_gdb_client.GetFileExists (file_spec);
846 }
847 
848 Error
849 PlatformRemoteGDBServer::RunShellCommand(const char *command,           // Shouldn't be NULL
850                                          const FileSpec &working_dir,   // Pass empty FileSpec to use the current working directory
851                                          int *status_ptr,               // Pass NULL if you don't want the process exit status
852                                          int *signo_ptr,                // Pass NULL if you don't want the signal that caused the process to exit
853                                          std::string *command_output,   // Pass NULL if you don't want the command output
854                                          uint32_t timeout_sec)          // Timeout in seconds to wait for shell program to finish
855 {
856     return m_gdb_client.RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
857 }
858 
859 void
860 PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames ()
861 {
862     m_trap_handlers.push_back (ConstString ("_sigtramp"));
863 }
864 
865 const UnixSignalsSP &
866 PlatformRemoteGDBServer::GetRemoteUnixSignals()
867 {
868     if (!IsConnected())
869         return Platform::GetRemoteUnixSignals();
870 
871     if (m_remote_signals_sp)
872         return m_remote_signals_sp;
873 
874     // If packet not implemented or JSON failed to parse,
875     // we'll guess the signal set based on the remote architecture.
876     m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
877 
878     const char packet[] = "jSignalsInfo";
879     StringExtractorGDBRemote response;
880     auto result = m_gdb_client.SendPacketAndWaitForResponse(
881             packet, strlen(packet), response, false);
882 
883     if (result != decltype(result)::Success ||
884             response.GetResponseType() != response.eResponse)
885         return m_remote_signals_sp;
886 
887     auto object_sp = StructuredData::ParseJSON(response.GetStringRef());
888     if (!object_sp || !object_sp->IsValid())
889         return m_remote_signals_sp;
890 
891     auto array_sp = object_sp->GetAsArray();
892     if (!array_sp || !array_sp->IsValid())
893         return m_remote_signals_sp;
894 
895     auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>();
896 
897     bool done = array_sp->ForEach(
898         [&remote_signals_sp](StructuredData::Object *object) -> bool
899         {
900             if (!object || !object->IsValid())
901                 return false;
902 
903             auto dict = object->GetAsDictionary();
904             if (!dict || !dict->IsValid())
905                 return false;
906 
907             // Signal number and signal name are required.
908             int signo;
909             if (!dict->GetValueForKeyAsInteger("signo", signo))
910                 return false;
911 
912             std::string name;
913             if (!dict->GetValueForKeyAsString("name", name))
914                 return false;
915 
916             // We can live without short_name, description, etc.
917             std::string short_name{""};
918             auto object_sp = dict->GetValueForKey("short_name");
919             if (object_sp && object_sp->IsValid())
920                 short_name = object_sp->GetStringValue();
921 
922             bool suppress{false};
923             object_sp = dict->GetValueForKey("suppress");
924             if (object_sp && object_sp->IsValid())
925                 suppress = object_sp->GetBooleanValue();
926 
927             bool stop{false};
928             object_sp = dict->GetValueForKey("stop");
929             if (object_sp && object_sp->IsValid())
930                 stop = object_sp->GetBooleanValue();
931 
932             bool notify{false};
933             object_sp = dict->GetValueForKey("notify");
934             if (object_sp && object_sp->IsValid())
935                 notify = object_sp->GetBooleanValue();
936 
937             std::string description{""};
938             object_sp = dict->GetValueForKey("description");
939             if (object_sp && object_sp->IsValid())
940                 description = object_sp->GetStringValue();
941 
942             remote_signals_sp->AddSignal(signo,
943                                          name.c_str(),
944                                          short_name.c_str(),
945                                          suppress, stop, notify,
946                                          description.c_str());
947             return true;
948         });
949 
950     if (done)
951         m_remote_signals_sp = std::move(remote_signals_sp);
952 
953     return m_remote_signals_sp;
954 }
955 
956 std::string
957 PlatformRemoteGDBServer::MakeGdbServerUrl(const std::string &platform_scheme,
958                                           const std::string &platform_hostname,
959                                           uint16_t port)
960 {
961     const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
962     const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
963     const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
964     int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
965 
966     return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
967                    override_hostname ? override_hostname : platform_hostname.c_str(),
968                    port + port_offset,
969                    nullptr);
970 }
971 
972 std::string
973 PlatformRemoteGDBServer::MakeUrl(const char* scheme,
974                                        const char* hostname,
975                                        uint16_t port,
976                                        const char* path)
977 {
978     StreamString result;
979     result.Printf("%s://%s:%u", scheme, hostname, port);
980     if (path)
981         result.Write(path, strlen(path));
982     return result.GetString();
983 }
984