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