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