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