Platform.h revision 263363
1//===-- Platform.h ----------------------------------------------*- 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#ifndef liblldb_Platform_h_
11#define liblldb_Platform_h_
12
13// C Includes
14// C++ Includes
15#include <map>
16#include <string>
17#include <vector>
18
19// Other libraries and framework includes
20// Project includes
21#include "lldb/lldb-public.h"
22#include "lldb/Core/ArchSpec.h"
23#include "lldb/Core/ConstString.h"
24#include "lldb/Core/PluginInterface.h"
25#include "lldb/Interpreter/Options.h"
26#include "lldb/Host/Mutex.h"
27
28namespace lldb_private {
29
30    //----------------------------------------------------------------------
31    /// @class Platform Platform.h "lldb/Target/Platform.h"
32    /// @brief A plug-in interface definition class for debug platform that
33    /// includes many platform abilities such as:
34    ///     @li getting platform information such as supported architectures,
35    ///         supported binary file formats and more
36    ///     @li launching new processes
37    ///     @li attaching to existing processes
38    ///     @li download/upload files
39    ///     @li execute shell commands
40    ///     @li listing and getting info for existing processes
41    ///     @li attaching and possibly debugging the platform's kernel
42    //----------------------------------------------------------------------
43    class Platform : public PluginInterface
44    {
45    public:
46
47        //------------------------------------------------------------------
48        /// Get the native host platform plug-in.
49        ///
50        /// There should only be one of these for each host that LLDB runs
51        /// upon that should be statically compiled in and registered using
52        /// preprocessor macros or other similar build mechanisms in a
53        /// PlatformSubclass::Initialize() function.
54        ///
55        /// This platform will be used as the default platform when launching
56        /// or attaching to processes unless another platform is specified.
57        //------------------------------------------------------------------
58        static lldb::PlatformSP
59        GetDefaultPlatform ();
60
61        static lldb::PlatformSP
62        GetPlatformForArchitecture (const ArchSpec &arch,
63                                    ArchSpec *platform_arch_ptr);
64
65        static const char *
66        GetHostPlatformName ();
67
68        static void
69        SetDefaultPlatform (const lldb::PlatformSP &platform_sp);
70
71        static lldb::PlatformSP
72        Create (const char *platform_name, Error &error);
73
74        static lldb::PlatformSP
75        Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error);
76
77        static uint32_t
78        GetNumConnectedRemotePlatforms ();
79
80        static lldb::PlatformSP
81        GetConnectedRemotePlatformAtIndex (uint32_t idx);
82
83        //------------------------------------------------------------------
84        /// Default Constructor
85        //------------------------------------------------------------------
86        Platform (bool is_host_platform);
87
88        //------------------------------------------------------------------
89        /// Destructor.
90        ///
91        /// The destructor is virtual since this class is designed to be
92        /// inherited from by the plug-in instance.
93        //------------------------------------------------------------------
94        virtual
95        ~Platform();
96
97        //------------------------------------------------------------------
98        /// Find a platform plugin for a given process.
99        ///
100        /// Scans the installed Platform plug-ins and tries to find
101        /// an instance that can be used for \a process
102        ///
103        /// @param[in] process
104        ///     The process for which to try and locate a platform
105        ///     plug-in instance.
106        ///
107        /// @param[in] plugin_name
108        ///     An optional name of a specific platform plug-in that
109        ///     should be used. If NULL, pick the best plug-in.
110        //------------------------------------------------------------------
111        static Platform*
112        FindPlugin (Process *process, const ConstString &plugin_name);
113
114        //------------------------------------------------------------------
115        /// Set the target's executable based off of the existing
116        /// architecture information in \a target given a path to an
117        /// executable \a exe_file.
118        ///
119        /// Each platform knows the architectures that it supports and can
120        /// select the correct architecture slice within \a exe_file by
121        /// inspecting the architecture in \a target. If the target had an
122        /// architecture specified, then in can try and obey that request
123        /// and optionally fail if the architecture doesn't match up.
124        /// If no architecture is specified, the platform should select the
125        /// default architecture from \a exe_file. Any application bundles
126        /// or executable wrappers can also be inspected for the actual
127        /// application binary within the bundle that should be used.
128        ///
129        /// @return
130        ///     Returns \b true if this Platform plug-in was able to find
131        ///     a suitable executable, \b false otherwise.
132        //------------------------------------------------------------------
133        virtual Error
134        ResolveExecutable (const FileSpec &exe_file,
135                           const ArchSpec &arch,
136                           lldb::ModuleSP &module_sp,
137                           const FileSpecList *module_search_paths_ptr);
138
139
140        //------------------------------------------------------------------
141        /// Find a symbol file given a symbol file module specification.
142        ///
143        /// Each platform might have tricks to find symbol files for an
144        /// executable given information in a symbol file ModuleSpec. Some
145        /// platforms might also support symbol files that are bundles and
146        /// know how to extract the right symbol file given a bundle.
147        ///
148        /// @param[in] target
149        ///     The target in which we are trying to resolve the symbol file.
150        ///     The target has a list of modules that we might be able to
151        ///     use in order to help find the right symbol file. If the
152        ///     "m_file" or "m_platform_file" entries in the \a sym_spec
153        ///     are filled in, then we might be able to locate a module in
154        ///     the target, extract its UUID and locate a symbol file.
155        ///     If just the "m_uuid" is specified, then we might be able
156        ///     to find the module in the target that matches that UUID
157        ///     and pair the symbol file along with it. If just "m_symbol_file"
158        ///     is specified, we can use a variety of tricks to locate the
159        ///     symbols in an SDK, PDK, or other development kit location.
160        ///
161        /// @param[in] sym_spec
162        ///     A module spec that describes some information about the
163        ///     symbol file we are trying to resolve. The ModuleSpec might
164        ///     contain the following:
165        ///     m_file - A full or partial path to an executable from the
166        ///              target (might be empty).
167        ///     m_platform_file - Another executable hint that contains
168        ///                       the path to the file as known on the
169        ///                       local/remote platform.
170        ///     m_symbol_file - A full or partial path to a symbol file
171        ///                     or symbol bundle that should be used when
172        ///                     trying to resolve the symbol file.
173        ///     m_arch - The architecture we are looking for when resolving
174        ///              the symbol file.
175        ///     m_uuid - The UUID of the executable and symbol file. This
176        ///              can often be used to match up an exectuable with
177        ///              a symbol file, or resolve an symbol file in a
178        ///              symbol file bundle.
179        ///
180        /// @param[out] sym_file
181        ///     The resolved symbol file spec if the returned error
182        ///     indicates succes.
183        ///
184        /// @return
185        ///     Returns an error that describes success or failure.
186        //------------------------------------------------------------------
187        virtual Error
188        ResolveSymbolFile (Target &target,
189                           const ModuleSpec &sym_spec,
190                           FileSpec &sym_file);
191
192        //------------------------------------------------------------------
193        /// Resolves the FileSpec to a (possibly) remote path. Remote
194        /// platforms must override this to resolve to a path on the remote
195        /// side.
196        //------------------------------------------------------------------
197        virtual bool
198        ResolveRemotePath (const FileSpec &platform_path,
199                           FileSpec &resolved_platform_path);
200
201        bool
202        GetOSVersion (uint32_t &major,
203                      uint32_t &minor,
204                      uint32_t &update);
205
206        bool
207        SetOSVersion (uint32_t major,
208                      uint32_t minor,
209                      uint32_t update);
210
211        bool
212        GetOSBuildString (std::string &s);
213
214        bool
215        GetOSKernelDescription (std::string &s);
216
217        // Returns the the hostname if we are connected, else the short plugin
218        // name.
219        ConstString
220        GetName ();
221
222        virtual const char *
223        GetHostname ();
224
225        virtual const char *
226        GetDescription () = 0;
227
228        //------------------------------------------------------------------
229        /// Report the current status for this platform.
230        ///
231        /// The returned string usually involves returning the OS version
232        /// (if available), and any SDK directory that might be being used
233        /// for local file caching, and if connected a quick blurb about
234        /// what this platform is connected to.
235        //------------------------------------------------------------------
236        virtual void
237        GetStatus (Stream &strm);
238
239        //------------------------------------------------------------------
240        // Subclasses must be able to fetch the current OS version
241        //
242        // Remote classes must be connected for this to succeed. Local
243        // subclasses don't need to override this function as it will just
244        // call the Host::GetOSVersion().
245        //------------------------------------------------------------------
246        virtual bool
247        GetRemoteOSVersion ()
248        {
249            return false;
250        }
251
252        virtual bool
253        GetRemoteOSBuildString (std::string &s)
254        {
255            s.clear();
256            return false;
257        }
258
259        virtual bool
260        GetRemoteOSKernelDescription (std::string &s)
261        {
262            s.clear();
263            return false;
264        }
265
266        // Remote Platform subclasses need to override this function
267        virtual ArchSpec
268        GetRemoteSystemArchitecture ()
269        {
270            return ArchSpec(); // Return an invalid architecture
271        }
272
273        virtual const char *
274        GetUserName (uint32_t uid);
275
276        virtual const char *
277        GetGroupName (uint32_t gid);
278
279        //------------------------------------------------------------------
280        /// Locate a file for a platform.
281        ///
282        /// The default implementation of this function will return the same
283        /// file patch in \a local_file as was in \a platform_file.
284        ///
285        /// @param[in] platform_file
286        ///     The platform file path to locate and cache locally.
287        ///
288        /// @param[in] uuid_ptr
289        ///     If we know the exact UUID of the file we are looking for, it
290        ///     can be specified. If it is not specified, we might now know
291        ///     the exact file. The UUID is usually some sort of MD5 checksum
292        ///     for the file and is sometimes known by dynamic linkers/loaders.
293        ///     If the UUID is known, it is best to supply it to platform
294        ///     file queries to ensure we are finding the correct file, not
295        ///     just a file at the correct path.
296        ///
297        /// @param[out] local_file
298        ///     A locally cached version of the platform file. For platforms
299        ///     that describe the current host computer, this will just be
300        ///     the same file. For remote platforms, this file might come from
301        ///     and SDK directory, or might need to be sync'ed over to the
302        ///     current machine for efficient debugging access.
303        ///
304        /// @return
305        ///     An error object.
306        //------------------------------------------------------------------
307        virtual Error
308        GetFile (const FileSpec &platform_file,
309                 const UUID *uuid_ptr,
310                 FileSpec &local_file);
311
312        //----------------------------------------------------------------------
313        // Locate the scripting resource given a module specification.
314        //
315        // Locating the file should happen only on the local computer or using
316        // the current computers global settings.
317        //----------------------------------------------------------------------
318        virtual FileSpecList
319        LocateExecutableScriptingResources (Target *target,
320                                            Module &module);
321
322        virtual Error
323        GetSharedModule (const ModuleSpec &module_spec,
324                         lldb::ModuleSP &module_sp,
325                         const FileSpecList *module_search_paths_ptr,
326                         lldb::ModuleSP *old_module_sp_ptr,
327                         bool *did_create_ptr);
328
329        virtual Error
330        ConnectRemote (Args& args);
331
332        virtual Error
333        DisconnectRemote ();
334
335        //------------------------------------------------------------------
336        /// Get the platform's supported architectures in the order in which
337        /// they should be searched.
338        ///
339        /// @param[in] idx
340        ///     A zero based architecture index
341        ///
342        /// @param[out] arch
343        ///     A copy of the archgitecture at index if the return value is
344        ///     \b true.
345        ///
346        /// @return
347        ///     \b true if \a arch was filled in and is valid, \b false
348        ///     otherwise.
349        //------------------------------------------------------------------
350        virtual bool
351        GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) = 0;
352
353        virtual size_t
354        GetSoftwareBreakpointTrapOpcode (Target &target,
355                                         BreakpointSite *bp_site) = 0;
356
357        //------------------------------------------------------------------
358        /// Launch a new process on a platform, not necessarily for
359        /// debugging, it could be just for running the process.
360        //------------------------------------------------------------------
361        virtual Error
362        LaunchProcess (ProcessLaunchInfo &launch_info);
363
364        //------------------------------------------------------------------
365        /// Lets a platform answer if it is compatible with a given
366        /// architecture and the target triple contained within.
367        //------------------------------------------------------------------
368        virtual bool
369        IsCompatibleArchitecture (const ArchSpec &arch,
370                                  bool exact_arch_match,
371                                  ArchSpec *compatible_arch_ptr);
372
373        //------------------------------------------------------------------
374        /// Not all platforms will support debugging a process by spawning
375        /// somehow halted for a debugger (specified using the
376        /// "eLaunchFlagDebug" launch flag) and then attaching. If your
377        /// platform doesn't support this, override this function and return
378        /// false.
379        //------------------------------------------------------------------
380        virtual bool
381        CanDebugProcess ()
382        {
383            return true;
384        }
385
386        //------------------------------------------------------------------
387        /// Subclasses should NOT need to implement this function as it uses
388        /// the Platform::LaunchProcess() followed by Platform::Attach ()
389        //------------------------------------------------------------------
390        lldb::ProcessSP
391        DebugProcess (ProcessLaunchInfo &launch_info,
392                      Debugger &debugger,
393                      Target *target,       // Can be NULL, if NULL create a new target, else use existing one
394                      Listener &listener,
395                      Error &error);
396
397        //------------------------------------------------------------------
398        /// Attach to an existing process using a process ID.
399        ///
400        /// Each platform subclass needs to implement this function and
401        /// attempt to attach to the process with the process ID of \a pid.
402        /// The platform subclass should return an appropriate ProcessSP
403        /// subclass that is attached to the process, or an empty shared
404        /// pointer with an appriopriate error.
405        ///
406        /// @param[in] pid
407        ///     The process ID that we should attempt to attach to.
408        ///
409        /// @return
410        ///     An appropriate ProcessSP containing a valid shared pointer
411        ///     to the default Process subclass for the platform that is
412        ///     attached to the process, or an empty shared pointer with an
413        ///     appriopriate error fill into the \a error object.
414        //------------------------------------------------------------------
415        virtual lldb::ProcessSP
416        Attach (ProcessAttachInfo &attach_info,
417                Debugger &debugger,
418                Target *target,       // Can be NULL, if NULL create a new target, else use existing one
419                Listener &listener,
420                Error &error) = 0;
421
422        //------------------------------------------------------------------
423        /// Attach to an existing process by process name.
424        ///
425        /// This function is not meant to be overridden by Process
426        /// subclasses. It will first call
427        /// Process::WillAttach (const char *) and if that returns \b
428        /// true, Process::DoAttach (const char *) will be called to
429        /// actually do the attach. If DoAttach returns \b true, then
430        /// Process::DidAttach() will be called.
431        ///
432        /// @param[in] process_name
433        ///     A process name to match against the current process list.
434        ///
435        /// @return
436        ///     Returns \a pid if attaching was successful, or
437        ///     LLDB_INVALID_PROCESS_ID if attaching fails.
438        //------------------------------------------------------------------
439//        virtual lldb::ProcessSP
440//        Attach (const char *process_name,
441//                bool wait_for_launch,
442//                Error &error) = 0;
443
444        //------------------------------------------------------------------
445        // The base class Platform will take care of the host platform.
446        // Subclasses will need to fill in the remote case.
447        //------------------------------------------------------------------
448        virtual uint32_t
449        FindProcesses (const ProcessInstanceInfoMatch &match_info,
450                       ProcessInstanceInfoList &proc_infos);
451
452        virtual bool
453        GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
454
455        //------------------------------------------------------------------
456        // Set a breakpoint on all functions that can end up creating a thread
457        // for this platform. This is needed when running expressions and
458        // also for process control.
459        //------------------------------------------------------------------
460        virtual lldb::BreakpointSP
461        SetThreadCreationBreakpoint (Target &target);
462
463        //------------------------------------------------------------------
464        // Given a target, find the local SDK directory if one exists on the
465        // current host.
466        //------------------------------------------------------------------
467        virtual lldb_private::ConstString
468        GetSDKDirectory (lldb_private::Target &target)
469        {
470            return lldb_private::ConstString();
471        }
472
473        const std::string &
474        GetRemoteURL () const
475        {
476            return m_remote_url;
477        }
478
479        bool
480        IsHost () const
481        {
482            return m_is_host;    // Is this the default host platform?
483        }
484
485        bool
486        IsRemote () const
487        {
488            return !m_is_host;
489        }
490
491        virtual bool
492        IsConnected () const
493        {
494            // Remote subclasses should override this function
495            return IsHost();
496        }
497
498        const ArchSpec &
499        GetSystemArchitecture();
500
501        void
502        SetSystemArchitecture (const ArchSpec &arch)
503        {
504            m_system_arch = arch;
505            if (IsHost())
506                m_os_version_set_while_connected = m_system_arch.IsValid();
507        }
508
509        // Used for column widths
510        size_t
511        GetMaxUserIDNameLength() const
512        {
513            return m_max_uid_name_len;
514        }
515        // Used for column widths
516        size_t
517        GetMaxGroupIDNameLength() const
518        {
519            return m_max_gid_name_len;
520        }
521
522        const ConstString &
523        GetSDKRootDirectory () const
524        {
525            return m_sdk_sysroot;
526        }
527
528        void
529        SetSDKRootDirectory (const ConstString &dir)
530        {
531            m_sdk_sysroot = dir;
532        }
533
534        const ConstString &
535        GetSDKBuild () const
536        {
537            return m_sdk_build;
538        }
539
540        void
541        SetSDKBuild (const ConstString &sdk_build)
542        {
543            m_sdk_build = sdk_build;
544        }
545
546        // There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
547        // The platform will return "true" from this call if the passed in module happens to be one of these.
548
549        virtual bool
550        ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp)
551        {
552            return false;
553        }
554
555        virtual uint32_t
556        MakeDirectory (const std::string &path,
557                       mode_t mode)
558        {
559            return UINT32_MAX;
560        }
561
562        // this need not be virtual: the core behavior is in
563        // MakeDirectory(std::string,mode_t)
564        uint32_t
565        MakeDirectory (const FileSpec &spec,
566                       mode_t mode);
567
568        virtual lldb::user_id_t
569        OpenFile (const FileSpec& file_spec,
570                  uint32_t flags,
571                  mode_t mode,
572                  Error &error)
573        {
574            return UINT64_MAX;
575        }
576
577        virtual bool
578        CloseFile (lldb::user_id_t fd,
579                   Error &error)
580        {
581            return false;
582        }
583
584        virtual lldb::user_id_t
585        GetFileSize (const FileSpec& file_spec)
586        {
587            return UINT64_MAX;
588        }
589
590        virtual uint64_t
591        ReadFile (lldb::user_id_t fd,
592                  uint64_t offset,
593                  void *dst,
594                  uint64_t dst_len,
595                  Error &error)
596        {
597            error.SetErrorStringWithFormat ("Platform::ReadFile() is not supported in the %s platform", GetName().GetCString());
598            return -1;
599        }
600
601        virtual uint64_t
602        WriteFile (lldb::user_id_t fd,
603                   uint64_t offset,
604                   const void* src,
605                   uint64_t src_len,
606                   Error &error)
607        {
608            error.SetErrorStringWithFormat ("Platform::ReadFile() is not supported in the %s platform", GetName().GetCString());
609            return -1;
610        }
611
612        virtual Error
613        PutFile (const FileSpec& source,
614                 const FileSpec& destination,
615                 uint32_t uid = UINT32_MAX,
616                 uint32_t gid = UINT32_MAX);
617
618        virtual size_t
619        GetEnvironment (StringList &environment);
620
621        virtual Error
622        GetFile (const FileSpec& source,
623                 const FileSpec& destination);
624
625        virtual bool
626        GetFileExists (const lldb_private::FileSpec& file_spec);
627
628        virtual uint32_t
629        GetFilePermissions (const lldb_private::FileSpec &file_spec,
630                            Error &error)
631        {
632            error.SetErrorStringWithFormat ("Platform::GetFilePermissions() is not supported in the %s platform", GetName().GetCString());
633            return 0;
634        }
635
636        virtual bool
637        GetSupportsRSync ()
638        {
639            return m_supports_rsync;
640        }
641
642        virtual void
643        SetSupportsRSync(bool flag)
644        {
645            m_supports_rsync = flag;
646        }
647
648        virtual const char*
649        GetRSyncOpts ()
650        {
651            return m_rsync_opts.c_str();
652        }
653
654        virtual void
655        SetRSyncOpts (const char* opts)
656        {
657            m_rsync_opts.assign(opts);
658        }
659
660        virtual const char*
661        GetRSyncPrefix ()
662        {
663            return m_rsync_prefix.c_str();
664        }
665
666        virtual void
667        SetRSyncPrefix (const char* prefix)
668        {
669            m_rsync_prefix.assign(prefix);
670        }
671
672        virtual bool
673        GetSupportsSSH ()
674        {
675            return m_supports_ssh;
676        }
677
678        virtual void
679        SetSupportsSSH(bool flag)
680        {
681            m_supports_ssh = flag;
682        }
683
684        virtual const char*
685        GetSSHOpts ()
686        {
687            return m_ssh_opts.c_str();
688        }
689
690        virtual void
691        SetSSHOpts (const char* opts)
692        {
693            m_ssh_opts.assign(opts);
694        }
695
696        virtual bool
697        GetIgnoresRemoteHostname ()
698        {
699            return m_ignores_remote_hostname;
700        }
701
702        virtual void
703        SetIgnoresRemoteHostname(bool flag)
704        {
705            m_ignores_remote_hostname = flag;
706        }
707
708        virtual lldb_private::OptionGroupOptions *
709        GetConnectionOptions (CommandInterpreter& interpreter)
710        {
711            return NULL;
712        }
713
714        virtual lldb_private::Error
715        RunShellCommand (const char *command,           // Shouldn't be NULL
716                         const char *working_dir,       // Pass NULL to use the current working directory
717                         int *status_ptr,               // Pass NULL if you don't want the process exit status
718                         int *signo_ptr,                // Pass NULL if you don't want the signal that caused the process to exit
719                         std::string *command_output,   // Pass NULL if you don't want the command output
720                         uint32_t timeout_sec);         // Timeout in seconds to wait for shell program to finish
721
722        virtual void
723        SetLocalCacheDirectory (const char* local);
724
725        virtual const char*
726        GetLocalCacheDirectory ();
727
728        virtual std::string
729        GetPlatformSpecificConnectionInformation()
730        {
731            return "";
732        }
733
734        virtual bool
735        CalculateMD5 (const FileSpec& file_spec,
736                      uint64_t &low,
737                      uint64_t &high);
738
739        virtual int32_t
740        GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
741        {
742            return 1;
743        }
744
745        //------------------------------------------------------------------
746        /// Locate a queue name given a thread's qaddr
747        ///
748        /// On a system using libdispatch ("Grand Central Dispatch") style
749        /// queues, a thread may be associated with a GCD queue or not,
750        /// and a queue may be associated with multiple threads.
751        /// The process/thread must provide a way to find the "dispatch_qaddr"
752        /// for each thread, and from that dispatch_qaddr this Platform method
753        /// will locate the queue name and provide that.
754        ///
755        /// @param[in] process
756        ///     A process is required for reading memory.
757        ///
758        /// @param[in] dispatch_qaddr
759        ///     The dispatch_qaddr for this thread.
760        ///
761        /// @return
762        ///     The name of the queue, if there is one.  An empty string
763        ///     means that this thread is not associated with a dispatch
764        ///     queue.
765        //------------------------------------------------------------------
766        virtual std::string
767        GetQueueNameForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr)
768        {
769            return "";
770        }
771
772        //------------------------------------------------------------------
773        /// Locate a queue ID given a thread's qaddr
774        ///
775        /// On a system using libdispatch ("Grand Central Dispatch") style
776        /// queues, a thread may be associated with a GCD queue or not,
777        /// and a queue may be associated with multiple threads.
778        /// The process/thread must provide a way to find the "dispatch_qaddr"
779        /// for each thread, and from that dispatch_qaddr this Platform method
780        /// will locate the queue ID and provide that.
781        ///
782        /// @param[in] process
783        ///     A process is required for reading memory.
784        ///
785        /// @param[in] dispatch_qaddr
786        ///     The dispatch_qaddr for this thread.
787        ///
788        /// @return
789        ///     The queue_id for this thread, if this thread is associated
790        ///     with a dispatch queue.  Else LLDB_INVALID_QUEUE_ID is returned.
791        //------------------------------------------------------------------
792        virtual lldb::queue_id_t
793        GetQueueIDForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr)
794        {
795            return LLDB_INVALID_QUEUE_ID;
796        }
797
798    protected:
799        bool m_is_host;
800        // Set to true when we are able to actually set the OS version while
801        // being connected. For remote platforms, we might set the version ahead
802        // of time before we actually connect and this version might change when
803        // we actually connect to a remote platform. For the host platform this
804        // will be set to the once we call Host::GetOSVersion().
805        bool m_os_version_set_while_connected;
806        bool m_system_arch_set_while_connected;
807        ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
808        ConstString m_sdk_build;
809        std::string m_remote_url;
810        std::string m_name;
811        uint32_t m_major_os_version;
812        uint32_t m_minor_os_version;
813        uint32_t m_update_os_version;
814        ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
815        typedef std::map<uint32_t, ConstString> IDToNameMap;
816        Mutex m_uid_map_mutex;
817        Mutex m_gid_map_mutex;
818        IDToNameMap m_uid_map;
819        IDToNameMap m_gid_map;
820        size_t m_max_uid_name_len;
821        size_t m_max_gid_name_len;
822        bool m_supports_rsync;
823        std::string m_rsync_opts;
824        std::string m_rsync_prefix;
825        bool m_supports_ssh;
826        std::string m_ssh_opts;
827        bool m_ignores_remote_hostname;
828        std::string m_local_cache_directory;
829
830        const char *
831        GetCachedUserName (uint32_t uid)
832        {
833            Mutex::Locker locker (m_uid_map_mutex);
834            IDToNameMap::iterator pos = m_uid_map.find (uid);
835            if (pos != m_uid_map.end())
836            {
837                // return the empty string if our string is NULL
838                // so we can tell when things were in the negative
839                // cached (didn't find a valid user name, don't keep
840                // trying)
841                return pos->second.AsCString("");
842            }
843            return NULL;
844        }
845
846        const char *
847        SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
848        {
849            Mutex::Locker locker (m_uid_map_mutex);
850            ConstString const_name (name);
851            m_uid_map[uid] = const_name;
852            if (m_max_uid_name_len < name_len)
853                m_max_uid_name_len = name_len;
854            // Const strings lives forever in our const string pool, so we can return the const char *
855            return const_name.GetCString();
856        }
857
858        void
859        SetUserNameNotFound (uint32_t uid)
860        {
861            Mutex::Locker locker (m_uid_map_mutex);
862            m_uid_map[uid] = ConstString();
863        }
864
865
866        void
867        ClearCachedUserNames ()
868        {
869            Mutex::Locker locker (m_uid_map_mutex);
870            m_uid_map.clear();
871        }
872
873        const char *
874        GetCachedGroupName (uint32_t gid)
875        {
876            Mutex::Locker locker (m_gid_map_mutex);
877            IDToNameMap::iterator pos = m_gid_map.find (gid);
878            if (pos != m_gid_map.end())
879            {
880                // return the empty string if our string is NULL
881                // so we can tell when things were in the negative
882                // cached (didn't find a valid group name, don't keep
883                // trying)
884                return pos->second.AsCString("");
885            }
886            return NULL;
887        }
888
889        const char *
890        SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
891        {
892            Mutex::Locker locker (m_gid_map_mutex);
893            ConstString const_name (name);
894            m_gid_map[gid] = const_name;
895            if (m_max_gid_name_len < name_len)
896                m_max_gid_name_len = name_len;
897            // Const strings lives forever in our const string pool, so we can return the const char *
898            return const_name.GetCString();
899        }
900
901        void
902        SetGroupNameNotFound (uint32_t gid)
903        {
904            Mutex::Locker locker (m_gid_map_mutex);
905            m_gid_map[gid] = ConstString();
906        }
907
908        void
909        ClearCachedGroupNames ()
910        {
911            Mutex::Locker locker (m_gid_map_mutex);
912            m_gid_map.clear();
913        }
914
915    private:
916        DISALLOW_COPY_AND_ASSIGN (Platform);
917    };
918
919
920    class PlatformList
921    {
922    public:
923        PlatformList() :
924            m_mutex (Mutex::eMutexTypeRecursive),
925            m_platforms (),
926            m_selected_platform_sp()
927        {
928        }
929
930        ~PlatformList()
931        {
932        }
933
934        void
935        Append (const lldb::PlatformSP &platform_sp, bool set_selected)
936        {
937            Mutex::Locker locker (m_mutex);
938            m_platforms.push_back (platform_sp);
939            if (set_selected)
940                m_selected_platform_sp = m_platforms.back();
941        }
942
943        size_t
944        GetSize()
945        {
946            Mutex::Locker locker (m_mutex);
947            return m_platforms.size();
948        }
949
950        lldb::PlatformSP
951        GetAtIndex (uint32_t idx)
952        {
953            lldb::PlatformSP platform_sp;
954            {
955                Mutex::Locker locker (m_mutex);
956                if (idx < m_platforms.size())
957                    platform_sp = m_platforms[idx];
958            }
959            return platform_sp;
960        }
961
962        //------------------------------------------------------------------
963        /// Select the active platform.
964        ///
965        /// In order to debug remotely, other platform's can be remotely
966        /// connected to and set as the selected platform for any subsequent
967        /// debugging. This allows connection to remote targets and allows
968        /// the ability to discover process info, launch and attach to remote
969        /// processes.
970        //------------------------------------------------------------------
971        lldb::PlatformSP
972        GetSelectedPlatform ()
973        {
974            Mutex::Locker locker (m_mutex);
975            if (!m_selected_platform_sp && !m_platforms.empty())
976                m_selected_platform_sp = m_platforms.front();
977
978            return m_selected_platform_sp;
979        }
980
981        void
982        SetSelectedPlatform (const lldb::PlatformSP &platform_sp)
983        {
984            if (platform_sp)
985            {
986                Mutex::Locker locker (m_mutex);
987                const size_t num_platforms = m_platforms.size();
988                for (size_t idx=0; idx<num_platforms; ++idx)
989                {
990                    if (m_platforms[idx].get() == platform_sp.get())
991                    {
992                        m_selected_platform_sp = m_platforms[idx];
993                        return;
994                    }
995                }
996                m_platforms.push_back (platform_sp);
997                m_selected_platform_sp = m_platforms.back();
998            }
999        }
1000
1001    protected:
1002        typedef std::vector<lldb::PlatformSP> collection;
1003        mutable Mutex m_mutex;
1004        collection m_platforms;
1005        lldb::PlatformSP m_selected_platform_sp;
1006
1007    private:
1008        DISALLOW_COPY_AND_ASSIGN (PlatformList);
1009    };
1010
1011    class OptionGroupPlatformRSync : public lldb_private::OptionGroup
1012    {
1013    public:
1014        OptionGroupPlatformRSync ();
1015
1016        virtual
1017        ~OptionGroupPlatformRSync ();
1018
1019        virtual lldb_private::Error
1020        SetOptionValue (CommandInterpreter &interpreter,
1021                        uint32_t option_idx,
1022                        const char *option_value);
1023
1024        void
1025        OptionParsingStarting (CommandInterpreter &interpreter);
1026
1027        const lldb_private::OptionDefinition*
1028        GetDefinitions ();
1029
1030        virtual uint32_t
1031        GetNumDefinitions ();
1032
1033        // Options table: Required for subclasses of Options.
1034
1035        static lldb_private::OptionDefinition g_option_table[];
1036
1037        // Instance variables to hold the values for command options.
1038
1039        bool m_rsync;
1040        std::string m_rsync_opts;
1041        std::string m_rsync_prefix;
1042        bool m_ignores_remote_hostname;
1043    private:
1044        DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformRSync);
1045    };
1046
1047    class OptionGroupPlatformSSH : public lldb_private::OptionGroup
1048    {
1049    public:
1050        OptionGroupPlatformSSH ();
1051
1052        virtual
1053        ~OptionGroupPlatformSSH ();
1054
1055        virtual lldb_private::Error
1056        SetOptionValue (CommandInterpreter &interpreter,
1057                        uint32_t option_idx,
1058                        const char *option_value);
1059
1060        void
1061        OptionParsingStarting (CommandInterpreter &interpreter);
1062
1063        virtual uint32_t
1064        GetNumDefinitions ();
1065
1066        const lldb_private::OptionDefinition*
1067        GetDefinitions ();
1068
1069        // Options table: Required for subclasses of Options.
1070
1071        static lldb_private::OptionDefinition g_option_table[];
1072
1073        // Instance variables to hold the values for command options.
1074
1075        bool m_ssh;
1076        std::string m_ssh_opts;
1077    private:
1078        DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH);
1079    };
1080
1081    class OptionGroupPlatformCaching : public lldb_private::OptionGroup
1082    {
1083    public:
1084        OptionGroupPlatformCaching ();
1085
1086        virtual
1087        ~OptionGroupPlatformCaching ();
1088
1089        virtual lldb_private::Error
1090        SetOptionValue (CommandInterpreter &interpreter,
1091                        uint32_t option_idx,
1092                        const char *option_value);
1093
1094        void
1095        OptionParsingStarting (CommandInterpreter &interpreter);
1096
1097        virtual uint32_t
1098        GetNumDefinitions ();
1099
1100        const lldb_private::OptionDefinition*
1101        GetDefinitions ();
1102
1103        // Options table: Required for subclasses of Options.
1104
1105        static lldb_private::OptionDefinition g_option_table[];
1106
1107        // Instance variables to hold the values for command options.
1108
1109        std::string m_cache_dir;
1110    private:
1111        DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformCaching);
1112    };
1113
1114} // namespace lldb_private
1115
1116#endif  // liblldb_Platform_h_
1117