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