Platform.h revision bd5c23ddf5bacc78548bbe348c8c5d98c372aedc
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/Host/Mutex.h"
26
27namespace lldb_private {
28
29    //----------------------------------------------------------------------
30    /// @class Platform Platform.h "lldb/Target/Platform.h"
31    /// @brief A plug-in interface definition class for debug platform that
32    /// includes many platform abilities such as:
33    ///     @li getting platform information such as supported architectures,
34    ///         supported binary file formats and more
35    ///     @li launching new processes
36    ///     @li attaching to existing processes
37    ///     @li download/upload files
38    ///     @li execute shell commands
39    ///     @li listing and getting info for existing processes
40    ///     @li attaching and possibly debugging the platform's kernel
41    //----------------------------------------------------------------------
42    class Platform : public PluginInterface
43    {
44    public:
45
46        //------------------------------------------------------------------
47        /// Get the native host platform plug-in.
48        ///
49        /// There should only be one of these for each host that LLDB runs
50        /// upon that should be statically compiled in and registered using
51        /// preprocessor macros or other similar build mechanisms in a
52        /// PlatformSubclass::Initialize() function.
53        ///
54        /// This platform will be used as the default platform when launching
55        /// or attaching to processes unless another platform is specified.
56        //------------------------------------------------------------------
57        static lldb::PlatformSP
58        GetDefaultPlatform ();
59
60        static lldb::PlatformSP
61        GetPlatformForArchitecture (const ArchSpec &arch,
62                                    ArchSpec *platform_arch_ptr);
63
64        static const char *
65        GetHostPlatformName ();
66
67        static void
68        SetDefaultPlatform (const lldb::PlatformSP &platform_sp);
69
70        static lldb::PlatformSP
71        Create (const char *platform_name, Error &error);
72
73        static lldb::PlatformSP
74        Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error);
75
76        static uint32_t
77        GetNumConnectedRemotePlatforms ();
78
79        static lldb::PlatformSP
80        GetConnectedRemotePlatformAtIndex (uint32_t idx);
81
82        //------------------------------------------------------------------
83        /// Default Constructor
84        //------------------------------------------------------------------
85        Platform (bool is_host_platform);
86
87        //------------------------------------------------------------------
88        /// Destructor.
89        ///
90        /// The destructor is virtual since this class is designed to be
91        /// inherited from by the plug-in instance.
92        //------------------------------------------------------------------
93        virtual
94        ~Platform();
95
96        //------------------------------------------------------------------
97        /// Set the target's executable based off of the existing
98        /// architecture information in \a target given a path to an
99        /// executable \a exe_file.
100        ///
101        /// Each platform knows the architectures that it supports and can
102        /// select the correct architecture slice within \a exe_file by
103        /// inspecting the architecture in \a target. If the target had an
104        /// architecture specified, then in can try and obey that request
105        /// and optionally fail if the architecture doesn't match up.
106        /// If no architecture is specified, the platform should select the
107        /// default architecture from \a exe_file. Any application bundles
108        /// or executable wrappers can also be inspected for the actual
109        /// application binary within the bundle that should be used.
110        ///
111        /// @return
112        ///     Returns \b true if this Platform plug-in was able to find
113        ///     a suitable executable, \b false otherwise.
114        //------------------------------------------------------------------
115        virtual Error
116        ResolveExecutable (const FileSpec &exe_file,
117                           const ArchSpec &arch,
118                           lldb::ModuleSP &module_sp,
119                           const FileSpecList *module_search_paths_ptr);
120
121        //------------------------------------------------------------------
122        /// Resolves the FileSpec to a (possibly) remote path. Remote
123        /// platforms must override this to resolve to a path on the remote
124        /// side.
125        //------------------------------------------------------------------
126        virtual bool
127        ResolveRemotePath (const FileSpec &platform_path,
128                           FileSpec &resolved_platform_path);
129
130        bool
131        GetOSVersion (uint32_t &major,
132                      uint32_t &minor,
133                      uint32_t &update);
134
135        bool
136        SetOSVersion (uint32_t major,
137                      uint32_t minor,
138                      uint32_t update);
139
140        bool
141        GetOSBuildString (std::string &s);
142
143        bool
144        GetOSKernelDescription (std::string &s);
145
146        // Returns the the hostname if we are connected, else the short plugin
147        // name.
148        const char *
149        GetName ();
150
151        virtual const char *
152        GetHostname ();
153
154        virtual const char *
155        GetDescription () = 0;
156
157        //------------------------------------------------------------------
158        /// Report the current status for this platform.
159        ///
160        /// The returned string usually involves returning the OS version
161        /// (if available), and any SDK directory that might be being used
162        /// for local file caching, and if connected a quick blurb about
163        /// what this platform is connected to.
164        //------------------------------------------------------------------
165        virtual void
166        GetStatus (Stream &strm);
167
168        //------------------------------------------------------------------
169        // Subclasses must be able to fetch the current OS version
170        //
171        // Remote classes must be connected for this to succeed. Local
172        // subclasses don't need to override this function as it will just
173        // call the Host::GetOSVersion().
174        //------------------------------------------------------------------
175        virtual bool
176        GetRemoteOSVersion ()
177        {
178            return false;
179        }
180
181        virtual bool
182        GetRemoteOSBuildString (std::string &s)
183        {
184            s.clear();
185            return false;
186        }
187
188        virtual bool
189        GetRemoteOSKernelDescription (std::string &s)
190        {
191            s.clear();
192            return false;
193        }
194
195        // Remote Platform subclasses need to override this function
196        virtual ArchSpec
197        GetRemoteSystemArchitecture ()
198        {
199            return ArchSpec(); // Return an invalid architecture
200        }
201
202        virtual const char *
203        GetUserName (uint32_t uid);
204
205        virtual const char *
206        GetGroupName (uint32_t gid);
207
208        //------------------------------------------------------------------
209        /// Locate a file for a platform.
210        ///
211        /// The default implementation of this function will return the same
212        /// file patch in \a local_file as was in \a platform_file.
213        ///
214        /// @param[in] platform_file
215        ///     The platform file path to locate and cache locally.
216        ///
217        /// @param[in] uuid_ptr
218        ///     If we know the exact UUID of the file we are looking for, it
219        ///     can be specified. If it is not specified, we might now know
220        ///     the exact file. The UUID is usually some sort of MD5 checksum
221        ///     for the file and is sometimes known by dynamic linkers/loaders.
222        ///     If the UUID is known, it is best to supply it to platform
223        ///     file queries to ensure we are finding the correct file, not
224        ///     just a file at the correct path.
225        ///
226        /// @param[out] local_file
227        ///     A locally cached version of the platform file. For platforms
228        ///     that describe the current host computer, this will just be
229        ///     the same file. For remote platforms, this file might come from
230        ///     and SDK directory, or might need to be sync'ed over to the
231        ///     current machine for efficient debugging access.
232        ///
233        /// @return
234        ///     An error object.
235        //------------------------------------------------------------------
236        virtual Error
237        GetFile (const FileSpec &platform_file,
238                 const UUID *uuid_ptr,
239                 FileSpec &local_file);
240
241        virtual Error
242        GetSharedModule (const ModuleSpec &module_spec,
243                         lldb::ModuleSP &module_sp,
244                         const FileSpecList *module_search_paths_ptr,
245                         lldb::ModuleSP *old_module_sp_ptr,
246                         bool *did_create_ptr);
247
248        virtual Error
249        ConnectRemote (Args& args);
250
251        virtual Error
252        DisconnectRemote ();
253
254        //------------------------------------------------------------------
255        /// Get the platform's supported architectures in the order in which
256        /// they should be searched.
257        ///
258        /// @param[in] idx
259        ///     A zero based architecture index
260        ///
261        /// @param[out] arch
262        ///     A copy of the archgitecture at index if the return value is
263        ///     \b true.
264        ///
265        /// @return
266        ///     \b true if \a arch was filled in and is valid, \b false
267        ///     otherwise.
268        //------------------------------------------------------------------
269        virtual bool
270        GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) = 0;
271
272        virtual size_t
273        GetSoftwareBreakpointTrapOpcode (Target &target,
274                                         BreakpointSite *bp_site) = 0;
275
276        //------------------------------------------------------------------
277        /// Launch a new process on a platform, not necessarily for
278        /// debugging, it could be just for running the process.
279        //------------------------------------------------------------------
280        virtual Error
281        LaunchProcess (ProcessLaunchInfo &launch_info);
282
283        //------------------------------------------------------------------
284        /// Lets a platform answer if it is compatible with a given
285        /// architecture and the target triple contained within.
286        //------------------------------------------------------------------
287        virtual bool
288        IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr = NULL);
289
290        //------------------------------------------------------------------
291        /// Not all platforms will support debugging a process by spawning
292        /// somehow halted for a debugger (specified using the
293        /// "eLaunchFlagDebug" launch flag) and then attaching. If your
294        /// platform doesn't support this, override this function and return
295        /// false.
296        //------------------------------------------------------------------
297        virtual bool
298        CanDebugProcess ()
299        {
300            return true;
301        }
302
303        //------------------------------------------------------------------
304        /// Subclasses should NOT need to implement this function as it uses
305        /// the Platform::LaunchProcess() followed by Platform::Attach ()
306        //------------------------------------------------------------------
307        lldb::ProcessSP
308        DebugProcess (ProcessLaunchInfo &launch_info,
309                      Debugger &debugger,
310                      Target *target,       // Can be NULL, if NULL create a new target, else use existing one
311                      Listener &listener,
312                      Error &error);
313
314        //------------------------------------------------------------------
315        /// Attach to an existing process using a process ID.
316        ///
317        /// Each platform subclass needs to implement this function and
318        /// attempt to attach to the process with the process ID of \a pid.
319        /// The platform subclass should return an appropriate ProcessSP
320        /// subclass that is attached to the process, or an empty shared
321        /// pointer with an appriopriate error.
322        ///
323        /// @param[in] pid
324        ///     The process ID that we should attempt to attach to.
325        ///
326        /// @return
327        ///     An appropriate ProcessSP containing a valid shared pointer
328        ///     to the default Process subclass for the platform that is
329        ///     attached to the process, or an empty shared pointer with an
330        ///     appriopriate error fill into the \a error object.
331        //------------------------------------------------------------------
332        virtual lldb::ProcessSP
333        Attach (ProcessAttachInfo &attach_info,
334                Debugger &debugger,
335                Target *target,       // Can be NULL, if NULL create a new target, else use existing one
336                Listener &listener,
337                Error &error) = 0;
338
339        //------------------------------------------------------------------
340        /// Attach to an existing process by process name.
341        ///
342        /// This function is not meant to be overridden by Process
343        /// subclasses. It will first call
344        /// Process::WillAttach (const char *) and if that returns \b
345        /// true, Process::DoAttach (const char *) will be called to
346        /// actually do the attach. If DoAttach returns \b true, then
347        /// Process::DidAttach() will be called.
348        ///
349        /// @param[in] process_name
350        ///     A process name to match against the current process list.
351        ///
352        /// @return
353        ///     Returns \a pid if attaching was successful, or
354        ///     LLDB_INVALID_PROCESS_ID if attaching fails.
355        //------------------------------------------------------------------
356//        virtual lldb::ProcessSP
357//        Attach (const char *process_name,
358//                bool wait_for_launch,
359//                Error &error) = 0;
360
361        //------------------------------------------------------------------
362        // The base class Platform will take care of the host platform.
363        // Subclasses will need to fill in the remote case.
364        //------------------------------------------------------------------
365        virtual uint32_t
366        FindProcesses (const ProcessInstanceInfoMatch &match_info,
367                       ProcessInstanceInfoList &proc_infos);
368
369        virtual bool
370        GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
371
372        //------------------------------------------------------------------
373        // Set a breakpoint on all functions that can end up creating a thread
374        // for this platform. This is needed when running expressions and
375        // also for process control.
376        //------------------------------------------------------------------
377        virtual lldb::BreakpointSP
378        SetThreadCreationBreakpoint (Target &target);
379
380
381        const std::string &
382        GetRemoteURL () const
383        {
384            return m_remote_url;
385        }
386
387        bool
388        IsHost () const
389        {
390            return m_is_host;    // Is this the default host platform?
391        }
392
393        bool
394        IsRemote () const
395        {
396            return !m_is_host;
397        }
398
399        virtual bool
400        IsConnected () const
401        {
402            // Remote subclasses should override this function
403            return IsHost();
404        }
405
406        const ArchSpec &
407        GetSystemArchitecture();
408
409        void
410        SetSystemArchitecture (const ArchSpec &arch)
411        {
412            m_system_arch = arch;
413            if (IsHost())
414                m_os_version_set_while_connected = m_system_arch.IsValid();
415        }
416
417        // Used for column widths
418        uint32_t
419        GetMaxUserIDNameLength() const
420        {
421            return m_max_uid_name_len;
422        }
423        // Used for column widths
424        uint32_t
425        GetMaxGroupIDNameLength() const
426        {
427            return m_max_gid_name_len;
428        }
429
430        const ConstString &
431        GetSDKRootDirectory () const
432        {
433            return m_sdk_sysroot;
434        }
435
436        void
437        SetSDKRootDirectory (const ConstString &dir)
438        {
439            m_sdk_sysroot = dir;
440        }
441
442        const ConstString &
443        GetSDKBuild () const
444        {
445            return m_sdk_build;
446        }
447
448        void
449        SetSDKBuild (const ConstString &sdk_build)
450        {
451            m_sdk_build = sdk_build;
452        }
453
454        // There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
455        // The platform will return "true" from this call if the passed in module happens to be one of these.
456
457        virtual bool
458        ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp)
459        {
460            return false;
461        }
462
463    protected:
464        bool m_is_host;
465        // Set to true when we are able to actually set the OS version while
466        // being connected. For remote platforms, we might set the version ahead
467        // of time before we actually connect and this version might change when
468        // we actually connect to a remote platform. For the host platform this
469        // will be set to the once we call Host::GetOSVersion().
470        bool m_os_version_set_while_connected;
471        bool m_system_arch_set_while_connected;
472        ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
473        ConstString m_sdk_build;
474        std::string m_remote_url;
475        std::string m_name;
476        uint32_t m_major_os_version;
477        uint32_t m_minor_os_version;
478        uint32_t m_update_os_version;
479        ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
480        typedef std::map<uint32_t, ConstString> IDToNameMap;
481        Mutex m_uid_map_mutex;
482        Mutex m_gid_map_mutex;
483        IDToNameMap m_uid_map;
484        IDToNameMap m_gid_map;
485        uint32_t m_max_uid_name_len;
486        uint32_t m_max_gid_name_len;
487
488        const char *
489        GetCachedUserName (uint32_t uid)
490        {
491            Mutex::Locker locker (m_uid_map_mutex);
492            IDToNameMap::iterator pos = m_uid_map.find (uid);
493            if (pos != m_uid_map.end())
494            {
495                // return the empty string if our string is NULL
496                // so we can tell when things were in the negative
497                // cached (didn't find a valid user name, don't keep
498                // trying)
499                return pos->second.AsCString("");
500            }
501            return NULL;
502        }
503
504        const char *
505        SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
506        {
507            Mutex::Locker locker (m_uid_map_mutex);
508            ConstString const_name (name);
509            m_uid_map[uid] = const_name;
510            if (m_max_uid_name_len < name_len)
511                m_max_uid_name_len = name_len;
512            // Const strings lives forever in our const string pool, so we can return the const char *
513            return const_name.GetCString();
514        }
515
516        void
517        SetUserNameNotFound (uint32_t uid)
518        {
519            Mutex::Locker locker (m_uid_map_mutex);
520            m_uid_map[uid] = ConstString();
521        }
522
523
524        void
525        ClearCachedUserNames ()
526        {
527            Mutex::Locker locker (m_uid_map_mutex);
528            m_uid_map.clear();
529        }
530
531        const char *
532        GetCachedGroupName (uint32_t gid)
533        {
534            Mutex::Locker locker (m_gid_map_mutex);
535            IDToNameMap::iterator pos = m_gid_map.find (gid);
536            if (pos != m_gid_map.end())
537            {
538                // return the empty string if our string is NULL
539                // so we can tell when things were in the negative
540                // cached (didn't find a valid group name, don't keep
541                // trying)
542                return pos->second.AsCString("");
543            }
544            return NULL;
545        }
546
547        const char *
548        SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
549        {
550            Mutex::Locker locker (m_gid_map_mutex);
551            ConstString const_name (name);
552            m_gid_map[gid] = const_name;
553            if (m_max_gid_name_len < name_len)
554                m_max_gid_name_len = name_len;
555            // Const strings lives forever in our const string pool, so we can return the const char *
556            return const_name.GetCString();
557        }
558
559        void
560        SetGroupNameNotFound (uint32_t gid)
561        {
562            Mutex::Locker locker (m_gid_map_mutex);
563            m_gid_map[gid] = ConstString();
564        }
565
566        void
567        ClearCachedGroupNames ()
568        {
569            Mutex::Locker locker (m_gid_map_mutex);
570            m_gid_map.clear();
571        }
572
573    private:
574        DISALLOW_COPY_AND_ASSIGN (Platform);
575    };
576
577
578    class PlatformList
579    {
580    public:
581        PlatformList() :
582            m_mutex (Mutex::eMutexTypeRecursive),
583            m_platforms (),
584            m_selected_platform_sp()
585        {
586        }
587
588        ~PlatformList()
589        {
590        }
591
592        void
593        Append (const lldb::PlatformSP &platform_sp, bool set_selected)
594        {
595            Mutex::Locker locker (m_mutex);
596            m_platforms.push_back (platform_sp);
597            if (set_selected)
598                m_selected_platform_sp = m_platforms.back();
599        }
600
601        size_t
602        GetSize()
603        {
604            Mutex::Locker locker (m_mutex);
605            return m_platforms.size();
606        }
607
608        lldb::PlatformSP
609        GetAtIndex (uint32_t idx)
610        {
611            lldb::PlatformSP platform_sp;
612            {
613                Mutex::Locker locker (m_mutex);
614                if (idx < m_platforms.size())
615                    platform_sp = m_platforms[idx];
616            }
617            return platform_sp;
618        }
619
620        //------------------------------------------------------------------
621        /// Select the active platform.
622        ///
623        /// In order to debug remotely, other platform's can be remotely
624        /// connected to and set as the selected platform for any subsequent
625        /// debugging. This allows connection to remote targets and allows
626        /// the ability to discover process info, launch and attach to remote
627        /// processes.
628        //------------------------------------------------------------------
629        lldb::PlatformSP
630        GetSelectedPlatform ()
631        {
632            Mutex::Locker locker (m_mutex);
633            if (!m_selected_platform_sp && !m_platforms.empty())
634                m_selected_platform_sp = m_platforms.front();
635
636            return m_selected_platform_sp;
637        }
638
639        void
640        SetSelectedPlatform (const lldb::PlatformSP &platform_sp)
641        {
642            if (platform_sp)
643            {
644                Mutex::Locker locker (m_mutex);
645                const size_t num_platforms = m_platforms.size();
646                for (size_t idx=0; idx<num_platforms; ++idx)
647                {
648                    if (m_platforms[idx].get() == platform_sp.get())
649                    {
650                        m_selected_platform_sp = m_platforms[idx];
651                        return;
652                    }
653                }
654                m_platforms.push_back (platform_sp);
655                m_selected_platform_sp = m_platforms.back();
656            }
657        }
658
659    protected:
660        typedef std::vector<lldb::PlatformSP> collection;
661        mutable Mutex m_mutex;
662        collection m_platforms;
663        lldb::PlatformSP m_selected_platform_sp;
664
665    private:
666        DISALLOW_COPY_AND_ASSIGN (PlatformList);
667    };
668} // namespace lldb_private
669
670#endif  // liblldb_Platform_h_
671