1 //===-- Platform.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 "lldb/Target/Platform.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Breakpoint/BreakpointIDList.h"
17 #include "lldb/Core/Error.h"
18 #include "lldb/Core/Log.h"
19 #include "lldb/Core/ModuleSpec.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Host/FileSpec.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/Target.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 // Use a singleton function for g_local_platform_sp to avoid init
30 // constructors since LLDB is often part of a shared library
31 static PlatformSP&
32 GetDefaultPlatformSP ()
33 {
34     static PlatformSP g_default_platform_sp;
35     return g_default_platform_sp;
36 }
37 
38 static Mutex &
39 GetConnectedPlatformListMutex ()
40 {
41     static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive);
42     return g_remote_connected_platforms_mutex;
43 }
44 static std::vector<PlatformSP> &
45 GetConnectedPlatformList ()
46 {
47     static std::vector<PlatformSP> g_remote_connected_platforms;
48     return g_remote_connected_platforms;
49 }
50 
51 
52 const char *
53 Platform::GetHostPlatformName ()
54 {
55     return "host";
56 }
57 
58 //------------------------------------------------------------------
59 /// Get the native host platform plug-in.
60 ///
61 /// There should only be one of these for each host that LLDB runs
62 /// upon that should be statically compiled in and registered using
63 /// preprocessor macros or other similar build mechanisms.
64 ///
65 /// This platform will be used as the default platform when launching
66 /// or attaching to processes unless another platform is specified.
67 //------------------------------------------------------------------
68 PlatformSP
69 Platform::GetDefaultPlatform ()
70 {
71     return GetDefaultPlatformSP ();
72 }
73 
74 void
75 Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp)
76 {
77     // The native platform should use its static void Platform::Initialize()
78     // function to register itself as the native platform.
79     GetDefaultPlatformSP () = platform_sp;
80 }
81 
82 Error
83 Platform::GetFile (const FileSpec &platform_file,
84                    const UUID *uuid_ptr,
85                    FileSpec &local_file)
86 {
87     // Default to the local case
88     local_file = platform_file;
89     return Error();
90 }
91 
92 FileSpecList
93 Platform::LocateExecutableScriptingResources (Target *target, Module &module)
94 {
95     return FileSpecList();
96 }
97 
98 Platform*
99 Platform::FindPlugin (Process *process, const char *plugin_name)
100 {
101     PlatformCreateInstance create_callback = NULL;
102     if (plugin_name)
103     {
104         create_callback  = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name);
105         if (create_callback)
106         {
107             ArchSpec arch;
108             if (process)
109             {
110                 arch = process->GetTarget().GetArchitecture();
111             }
112             std::unique_ptr<Platform> instance_ap(create_callback(process, &arch));
113             if (instance_ap.get())
114                 return instance_ap.release();
115         }
116     }
117     else
118     {
119         for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx)
120         {
121             std::unique_ptr<Platform> instance_ap(create_callback(process, false));
122             if (instance_ap.get())
123                 return instance_ap.release();
124         }
125     }
126     return NULL;
127 }
128 
129 Error
130 Platform::GetSharedModule (const ModuleSpec &module_spec,
131                            ModuleSP &module_sp,
132                            const FileSpecList *module_search_paths_ptr,
133                            ModuleSP *old_module_sp_ptr,
134                            bool *did_create_ptr)
135 {
136     // Don't do any path remapping for the default implementation
137     // of the platform GetSharedModule function, just call through
138     // to our static ModuleList function. Platform subclasses that
139     // implement remote debugging, might have a developer kits
140     // installed that have cached versions of the files for the
141     // remote target, or might implement a download and cache
142     // locally implementation.
143     const bool always_create = false;
144     return ModuleList::GetSharedModule (module_spec,
145                                         module_sp,
146                                         module_search_paths_ptr,
147                                         old_module_sp_ptr,
148                                         did_create_ptr,
149                                         always_create);
150 }
151 
152 PlatformSP
153 Platform::Create (const char *platform_name, Error &error)
154 {
155     PlatformCreateInstance create_callback = NULL;
156     lldb::PlatformSP platform_sp;
157     if (platform_name && platform_name[0])
158     {
159         create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
160         if (create_callback)
161             platform_sp.reset(create_callback(true, NULL));
162         else
163             error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
164     }
165     else
166         error.SetErrorString ("invalid platform name");
167     return platform_sp;
168 }
169 
170 
171 PlatformSP
172 Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
173 {
174     lldb::PlatformSP platform_sp;
175     if (arch.IsValid())
176     {
177         uint32_t idx;
178         PlatformCreateInstance create_callback;
179         // First try exact arch matches across all platform plug-ins
180         bool exact = true;
181         for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
182         {
183             if (create_callback)
184             {
185                 platform_sp.reset(create_callback(false, &arch));
186                 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
187                     return platform_sp;
188             }
189         }
190         // Next try compatible arch matches across all platform plug-ins
191         exact = false;
192         for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
193         {
194             if (create_callback)
195             {
196                 platform_sp.reset(create_callback(false, &arch));
197                 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
198                     return platform_sp;
199             }
200         }
201     }
202     else
203         error.SetErrorString ("invalid platform name");
204     if (platform_arch_ptr)
205         platform_arch_ptr->Clear();
206     platform_sp.reset();
207     return platform_sp;
208 }
209 
210 uint32_t
211 Platform::GetNumConnectedRemotePlatforms ()
212 {
213     Mutex::Locker locker (GetConnectedPlatformListMutex ());
214     return GetConnectedPlatformList().size();
215 }
216 
217 PlatformSP
218 Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
219 {
220     PlatformSP platform_sp;
221     {
222         Mutex::Locker locker (GetConnectedPlatformListMutex ());
223         if (idx < GetConnectedPlatformList().size())
224             platform_sp = GetConnectedPlatformList ()[idx];
225     }
226     return platform_sp;
227 }
228 
229 //------------------------------------------------------------------
230 /// Default Constructor
231 //------------------------------------------------------------------
232 Platform::Platform (bool is_host) :
233     m_is_host (is_host),
234     m_os_version_set_while_connected (false),
235     m_system_arch_set_while_connected (false),
236     m_sdk_sysroot (),
237     m_sdk_build (),
238     m_remote_url (),
239     m_name (),
240     m_major_os_version (UINT32_MAX),
241     m_minor_os_version (UINT32_MAX),
242     m_update_os_version (UINT32_MAX),
243     m_system_arch(),
244     m_uid_map_mutex (Mutex::eMutexTypeNormal),
245     m_gid_map_mutex (Mutex::eMutexTypeNormal),
246     m_uid_map(),
247     m_gid_map(),
248     m_max_uid_name_len (0),
249     m_max_gid_name_len (0)
250 {
251     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
252     if (log)
253         log->Printf ("%p Platform::Platform()", this);
254 }
255 
256 //------------------------------------------------------------------
257 /// Destructor.
258 ///
259 /// The destructor is virtual since this class is designed to be
260 /// inherited from by the plug-in instance.
261 //------------------------------------------------------------------
262 Platform::~Platform()
263 {
264     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
265     if (log)
266         log->Printf ("%p Platform::~Platform()", this);
267 }
268 
269 void
270 Platform::GetStatus (Stream &strm)
271 {
272     uint32_t major = UINT32_MAX;
273     uint32_t minor = UINT32_MAX;
274     uint32_t update = UINT32_MAX;
275     std::string s;
276     strm.Printf ("  Platform: %s\n", GetShortPluginName());
277 
278     ArchSpec arch (GetSystemArchitecture());
279     if (arch.IsValid())
280     {
281         if (!arch.GetTriple().str().empty())
282         strm.Printf("    Triple: %s\n", arch.GetTriple().str().c_str());
283     }
284 
285     if (GetOSVersion(major, minor, update))
286     {
287         strm.Printf("OS Version: %u", major);
288         if (minor != UINT32_MAX)
289             strm.Printf(".%u", minor);
290         if (update != UINT32_MAX)
291             strm.Printf(".%u", update);
292 
293         if (GetOSBuildString (s))
294             strm.Printf(" (%s)", s.c_str());
295 
296         strm.EOL();
297     }
298 
299     if (GetOSKernelDescription (s))
300         strm.Printf("    Kernel: %s\n", s.c_str());
301 
302     if (IsHost())
303     {
304         strm.Printf("  Hostname: %s\n", GetHostname());
305     }
306     else
307     {
308         const bool is_connected = IsConnected();
309         if (is_connected)
310             strm.Printf("  Hostname: %s\n", GetHostname());
311         strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
312     }
313 }
314 
315 
316 bool
317 Platform::GetOSVersion (uint32_t &major,
318                         uint32_t &minor,
319                         uint32_t &update)
320 {
321     bool success = m_major_os_version != UINT32_MAX;
322     if (IsHost())
323     {
324         if (!success)
325         {
326             // We have a local host platform
327             success = Host::GetOSVersion (m_major_os_version,
328                                           m_minor_os_version,
329                                           m_update_os_version);
330             m_os_version_set_while_connected = success;
331         }
332     }
333     else
334     {
335         // We have a remote platform. We can only fetch the remote
336         // OS version if we are connected, and we don't want to do it
337         // more than once.
338 
339         const bool is_connected = IsConnected();
340 
341         bool fetch = false;
342         if (success)
343         {
344             // We have valid OS version info, check to make sure it wasn't
345             // manually set prior to connecting. If it was manually set prior
346             // to connecting, then lets fetch the actual OS version info
347             // if we are now connected.
348             if (is_connected && !m_os_version_set_while_connected)
349                 fetch = true;
350         }
351         else
352         {
353             // We don't have valid OS version info, fetch it if we are connected
354             fetch = is_connected;
355         }
356 
357         if (fetch)
358         {
359             success = GetRemoteOSVersion ();
360             m_os_version_set_while_connected = success;
361         }
362     }
363 
364     if (success)
365     {
366         major = m_major_os_version;
367         minor = m_minor_os_version;
368         update = m_update_os_version;
369     }
370     return success;
371 }
372 
373 bool
374 Platform::GetOSBuildString (std::string &s)
375 {
376     if (IsHost())
377         return Host::GetOSBuildString (s);
378     else
379         return GetRemoteOSBuildString (s);
380 }
381 
382 bool
383 Platform::GetOSKernelDescription (std::string &s)
384 {
385     if (IsHost())
386         return Host::GetOSKernelDescription (s);
387     else
388         return GetRemoteOSKernelDescription (s);
389 }
390 
391 const char *
392 Platform::GetName ()
393 {
394     const char *name = GetHostname();
395     if (name == NULL || name[0] == '\0')
396         name = GetShortPluginName();
397     return name;
398 }
399 
400 const char *
401 Platform::GetHostname ()
402 {
403     if (IsHost())
404         return "localhost";
405 
406     if (m_name.empty())
407         return NULL;
408     return m_name.c_str();
409 }
410 
411 const char *
412 Platform::GetUserName (uint32_t uid)
413 {
414     const char *user_name = GetCachedUserName(uid);
415     if (user_name)
416         return user_name;
417     if (IsHost())
418     {
419         std::string name;
420         if (Host::GetUserName(uid, name))
421             return SetCachedUserName (uid, name.c_str(), name.size());
422     }
423     return NULL;
424 }
425 
426 const char *
427 Platform::GetGroupName (uint32_t gid)
428 {
429     const char *group_name = GetCachedGroupName(gid);
430     if (group_name)
431         return group_name;
432     if (IsHost())
433     {
434         std::string name;
435         if (Host::GetGroupName(gid, name))
436             return SetCachedGroupName (gid, name.c_str(), name.size());
437     }
438     return NULL;
439 }
440 
441 bool
442 Platform::SetOSVersion (uint32_t major,
443                         uint32_t minor,
444                         uint32_t update)
445 {
446     if (IsHost())
447     {
448         // We don't need anyone setting the OS version for the host platform,
449         // we should be able to figure it out by calling Host::GetOSVersion(...).
450         return false;
451     }
452     else
453     {
454         // We have a remote platform, allow setting the target OS version if
455         // we aren't connected, since if we are connected, we should be able to
456         // request the remote OS version from the connected platform.
457         if (IsConnected())
458             return false;
459         else
460         {
461             // We aren't connected and we might want to set the OS version
462             // ahead of time before we connect so we can peruse files and
463             // use a local SDK or PDK cache of support files to disassemble
464             // or do other things.
465             m_major_os_version = major;
466             m_minor_os_version = minor;
467             m_update_os_version = update;
468             return true;
469         }
470     }
471     return false;
472 }
473 
474 
475 Error
476 Platform::ResolveExecutable (const FileSpec &exe_file,
477                              const ArchSpec &exe_arch,
478                              lldb::ModuleSP &exe_module_sp,
479                              const FileSpecList *module_search_paths_ptr)
480 {
481     Error error;
482     if (exe_file.Exists())
483     {
484         ModuleSpec module_spec (exe_file, exe_arch);
485         if (module_spec.GetArchitecture().IsValid())
486         {
487             error = ModuleList::GetSharedModule (module_spec,
488                                                  exe_module_sp,
489                                                  module_search_paths_ptr,
490                                                  NULL,
491                                                  NULL);
492         }
493         else
494         {
495             // No valid architecture was specified, ask the platform for
496             // the architectures that we should be using (in the correct order)
497             // and see if we can find a match that way
498             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
499             {
500                 error = ModuleList::GetSharedModule (module_spec,
501                                                      exe_module_sp,
502                                                      module_search_paths_ptr,
503                                                      NULL,
504                                                      NULL);
505                 // Did we find an executable using one of the
506                 if (error.Success() && exe_module_sp)
507                     break;
508             }
509         }
510     }
511     else
512     {
513         error.SetErrorStringWithFormat ("'%s' does not exist",
514                                         exe_file.GetPath().c_str());
515     }
516     return error;
517 }
518 
519 Error
520 Platform::ResolveSymbolFile (Target &target,
521                              const ModuleSpec &sym_spec,
522                              FileSpec &sym_file)
523 {
524     Error error;
525     if (sym_spec.GetSymbolFileSpec().Exists())
526         sym_file = sym_spec.GetSymbolFileSpec();
527     else
528         error.SetErrorString("unable to resolve symbol file");
529     return error;
530 
531 }
532 
533 
534 
535 bool
536 Platform::ResolveRemotePath (const FileSpec &platform_path,
537                              FileSpec &resolved_platform_path)
538 {
539     resolved_platform_path = platform_path;
540     return resolved_platform_path.ResolvePath();
541 }
542 
543 
544 const ArchSpec &
545 Platform::GetSystemArchitecture()
546 {
547     if (IsHost())
548     {
549         if (!m_system_arch.IsValid())
550         {
551             // We have a local host platform
552             m_system_arch = Host::GetArchitecture();
553             m_system_arch_set_while_connected = m_system_arch.IsValid();
554         }
555     }
556     else
557     {
558         // We have a remote platform. We can only fetch the remote
559         // system architecture if we are connected, and we don't want to do it
560         // more than once.
561 
562         const bool is_connected = IsConnected();
563 
564         bool fetch = false;
565         if (m_system_arch.IsValid())
566         {
567             // We have valid OS version info, check to make sure it wasn't
568             // manually set prior to connecting. If it was manually set prior
569             // to connecting, then lets fetch the actual OS version info
570             // if we are now connected.
571             if (is_connected && !m_system_arch_set_while_connected)
572                 fetch = true;
573         }
574         else
575         {
576             // We don't have valid OS version info, fetch it if we are connected
577             fetch = is_connected;
578         }
579 
580         if (fetch)
581         {
582             m_system_arch = GetRemoteSystemArchitecture ();
583             m_system_arch_set_while_connected = m_system_arch.IsValid();
584         }
585     }
586     return m_system_arch;
587 }
588 
589 
590 Error
591 Platform::ConnectRemote (Args& args)
592 {
593     Error error;
594     if (IsHost())
595         error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
596     else
597         error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
598     return error;
599 }
600 
601 Error
602 Platform::DisconnectRemote ()
603 {
604     Error error;
605     if (IsHost())
606         error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
607     else
608         error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
609     return error;
610 }
611 
612 bool
613 Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
614 {
615     // Take care of the host case so that each subclass can just
616     // call this function to get the host functionality.
617     if (IsHost())
618         return Host::GetProcessInfo (pid, process_info);
619     return false;
620 }
621 
622 uint32_t
623 Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
624                          ProcessInstanceInfoList &process_infos)
625 {
626     // Take care of the host case so that each subclass can just
627     // call this function to get the host functionality.
628     uint32_t match_count = 0;
629     if (IsHost())
630         match_count = Host::FindProcesses (match_info, process_infos);
631     return match_count;
632 }
633 
634 
635 Error
636 Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
637 {
638     Error error;
639     // Take care of the host case so that each subclass can just
640     // call this function to get the host functionality.
641     if (IsHost())
642     {
643         if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
644             launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
645 
646         if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
647         {
648             const bool is_localhost = true;
649             const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
650             const bool first_arg_is_full_shell_command = false;
651             if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
652                                                                   is_localhost,
653                                                                   will_debug,
654                                                                   first_arg_is_full_shell_command))
655                 return error;
656         }
657 
658         error = Host::LaunchProcess (launch_info);
659     }
660     else
661         error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
662     return error;
663 }
664 
665 lldb::ProcessSP
666 Platform::DebugProcess (ProcessLaunchInfo &launch_info,
667                         Debugger &debugger,
668                         Target *target,       // Can be NULL, if NULL create a new target, else use existing one
669                         Listener &listener,
670                         Error &error)
671 {
672     ProcessSP process_sp;
673     // Make sure we stop at the entry point
674     launch_info.GetFlags ().Set (eLaunchFlagDebug);
675     // We always launch the process we are going to debug in a separate process
676     // group, since then we can handle ^C interrupts ourselves w/o having to worry
677     // about the target getting them as well.
678     launch_info.SetLaunchInSeparateProcessGroup(true);
679 
680     error = LaunchProcess (launch_info);
681     if (error.Success())
682     {
683         if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
684         {
685             ProcessAttachInfo attach_info (launch_info);
686             process_sp = Attach (attach_info, debugger, target, listener, error);
687             if (process_sp)
688             {
689                 // Since we attached to the process, it will think it needs to detach
690                 // if the process object just goes away without an explicit call to
691                 // Process::Kill() or Process::Detach(), so let it know to kill the
692                 // process if this happens.
693                 process_sp->SetShouldDetach (false);
694 
695                 // If we didn't have any file actions, the pseudo terminal might
696                 // have been used where the slave side was given as the file to
697                 // open for stdin/out/err after we have already opened the master
698                 // so we can read/write stdin/out/err.
699                 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
700                 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
701                 {
702                     process_sp->SetSTDIOFileDescriptor(pty_fd);
703                 }
704             }
705         }
706     }
707     return process_sp;
708 }
709 
710 
711 lldb::PlatformSP
712 Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
713 {
714     lldb::PlatformSP platform_sp;
715     Error error;
716     if (arch.IsValid())
717         platform_sp = Platform::Create (arch, platform_arch_ptr, error);
718     return platform_sp;
719 }
720 
721 
722 //------------------------------------------------------------------
723 /// Lets a platform answer if it is compatible with a given
724 /// architecture and the target triple contained within.
725 //------------------------------------------------------------------
726 bool
727 Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr)
728 {
729     // If the architecture is invalid, we must answer true...
730     if (arch.IsValid())
731     {
732         ArchSpec platform_arch;
733         // Try for an exact architecture match first.
734         if (exact_arch_match)
735         {
736             for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
737             {
738                 if (arch.IsExactMatch(platform_arch))
739                 {
740                     if (compatible_arch_ptr)
741                         *compatible_arch_ptr = platform_arch;
742                     return true;
743                 }
744             }
745         }
746         else
747         {
748             for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
749             {
750                 if (arch.IsCompatibleMatch(platform_arch))
751                 {
752                     if (compatible_arch_ptr)
753                         *compatible_arch_ptr = platform_arch;
754                     return true;
755                 }
756             }
757         }
758     }
759     if (compatible_arch_ptr)
760         compatible_arch_ptr->Clear();
761     return false;
762 
763 }
764 
765 
766 lldb::BreakpointSP
767 Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
768 {
769     return lldb::BreakpointSP();
770 }
771 
772 size_t
773 Platform::GetEnvironment (StringList &environment)
774 {
775     environment.Clear();
776     return false;
777 }
778 
779