1254721Semaste//===-- Platform.h ----------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef liblldb_Platform_h_
11254721Semaste#define liblldb_Platform_h_
12254721Semaste
13254721Semaste// C Includes
14254721Semaste// C++ Includes
15254721Semaste#include <map>
16254721Semaste#include <string>
17254721Semaste#include <vector>
18254721Semaste
19254721Semaste// Other libraries and framework includes
20254721Semaste// Project includes
21254721Semaste#include "lldb/lldb-public.h"
22254721Semaste#include "lldb/Core/ArchSpec.h"
23254721Semaste#include "lldb/Core/ConstString.h"
24254721Semaste#include "lldb/Core/PluginInterface.h"
25254721Semaste#include "lldb/Host/Mutex.h"
26254721Semaste
27254721Semastenamespace lldb_private {
28254721Semaste
29254721Semaste    //----------------------------------------------------------------------
30254721Semaste    /// @class Platform Platform.h "lldb/Target/Platform.h"
31254721Semaste    /// @brief A plug-in interface definition class for debug platform that
32254721Semaste    /// includes many platform abilities such as:
33254721Semaste    ///     @li getting platform information such as supported architectures,
34254721Semaste    ///         supported binary file formats and more
35254721Semaste    ///     @li launching new processes
36254721Semaste    ///     @li attaching to existing processes
37254721Semaste    ///     @li download/upload files
38254721Semaste    ///     @li execute shell commands
39254721Semaste    ///     @li listing and getting info for existing processes
40254721Semaste    ///     @li attaching and possibly debugging the platform's kernel
41254721Semaste    //----------------------------------------------------------------------
42254721Semaste    class Platform : public PluginInterface
43254721Semaste    {
44254721Semaste    public:
45254721Semaste
46254721Semaste        //------------------------------------------------------------------
47254721Semaste        /// Get the native host platform plug-in.
48254721Semaste        ///
49254721Semaste        /// There should only be one of these for each host that LLDB runs
50254721Semaste        /// upon that should be statically compiled in and registered using
51254721Semaste        /// preprocessor macros or other similar build mechanisms in a
52254721Semaste        /// PlatformSubclass::Initialize() function.
53254721Semaste        ///
54254721Semaste        /// This platform will be used as the default platform when launching
55254721Semaste        /// or attaching to processes unless another platform is specified.
56254721Semaste        //------------------------------------------------------------------
57254721Semaste        static lldb::PlatformSP
58254721Semaste        GetDefaultPlatform ();
59254721Semaste
60254721Semaste        static lldb::PlatformSP
61254721Semaste        GetPlatformForArchitecture (const ArchSpec &arch,
62254721Semaste                                    ArchSpec *platform_arch_ptr);
63254721Semaste
64254721Semaste        static const char *
65254721Semaste        GetHostPlatformName ();
66254721Semaste
67254721Semaste        static void
68254721Semaste        SetDefaultPlatform (const lldb::PlatformSP &platform_sp);
69254721Semaste
70254721Semaste        static lldb::PlatformSP
71254721Semaste        Create (const char *platform_name, Error &error);
72254721Semaste
73254721Semaste        static lldb::PlatformSP
74254721Semaste        Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error);
75254721Semaste
76254721Semaste        static uint32_t
77254721Semaste        GetNumConnectedRemotePlatforms ();
78254721Semaste
79254721Semaste        static lldb::PlatformSP
80254721Semaste        GetConnectedRemotePlatformAtIndex (uint32_t idx);
81254721Semaste
82254721Semaste        //------------------------------------------------------------------
83254721Semaste        /// Default Constructor
84254721Semaste        //------------------------------------------------------------------
85254721Semaste        Platform (bool is_host_platform);
86254721Semaste
87254721Semaste        //------------------------------------------------------------------
88254721Semaste        /// Destructor.
89254721Semaste        ///
90254721Semaste        /// The destructor is virtual since this class is designed to be
91254721Semaste        /// inherited from by the plug-in instance.
92254721Semaste        //------------------------------------------------------------------
93254721Semaste        virtual
94254721Semaste        ~Platform();
95254721Semaste
96254721Semaste        //------------------------------------------------------------------
97254721Semaste        /// Find a platform plugin for a given process.
98254721Semaste        ///
99254721Semaste        /// Scans the installed Platform plug-ins and tries to find
100254721Semaste        /// an instance that can be used for \a process
101254721Semaste        ///
102254721Semaste        /// @param[in] process
103254721Semaste        ///     The process for which to try and locate a platform
104254721Semaste        ///     plug-in instance.
105254721Semaste        ///
106254721Semaste        /// @param[in] plugin_name
107254721Semaste        ///     An optional name of a specific platform plug-in that
108254721Semaste        ///     should be used. If NULL, pick the best plug-in.
109254721Semaste        //------------------------------------------------------------------
110254721Semaste        static Platform*
111254721Semaste        FindPlugin (Process *process, const ConstString &plugin_name);
112254721Semaste
113254721Semaste        //------------------------------------------------------------------
114254721Semaste        /// Set the target's executable based off of the existing
115254721Semaste        /// architecture information in \a target given a path to an
116254721Semaste        /// executable \a exe_file.
117254721Semaste        ///
118254721Semaste        /// Each platform knows the architectures that it supports and can
119254721Semaste        /// select the correct architecture slice within \a exe_file by
120254721Semaste        /// inspecting the architecture in \a target. If the target had an
121254721Semaste        /// architecture specified, then in can try and obey that request
122254721Semaste        /// and optionally fail if the architecture doesn't match up.
123254721Semaste        /// If no architecture is specified, the platform should select the
124254721Semaste        /// default architecture from \a exe_file. Any application bundles
125254721Semaste        /// or executable wrappers can also be inspected for the actual
126254721Semaste        /// application binary within the bundle that should be used.
127254721Semaste        ///
128254721Semaste        /// @return
129254721Semaste        ///     Returns \b true if this Platform plug-in was able to find
130254721Semaste        ///     a suitable executable, \b false otherwise.
131254721Semaste        //------------------------------------------------------------------
132254721Semaste        virtual Error
133254721Semaste        ResolveExecutable (const FileSpec &exe_file,
134254721Semaste                           const ArchSpec &arch,
135254721Semaste                           lldb::ModuleSP &module_sp,
136254721Semaste                           const FileSpecList *module_search_paths_ptr);
137254721Semaste
138254721Semaste
139254721Semaste        //------------------------------------------------------------------
140254721Semaste        /// Find a symbol file given a symbol file module specification.
141254721Semaste        ///
142254721Semaste        /// Each platform might have tricks to find symbol files for an
143254721Semaste        /// executable given information in a symbol file ModuleSpec. Some
144254721Semaste        /// platforms might also support symbol files that are bundles and
145254721Semaste        /// know how to extract the right symbol file given a bundle.
146254721Semaste        ///
147254721Semaste        /// @param[in] target
148254721Semaste        ///     The target in which we are trying to resolve the symbol file.
149254721Semaste        ///     The target has a list of modules that we might be able to
150254721Semaste        ///     use in order to help find the right symbol file. If the
151254721Semaste        ///     "m_file" or "m_platform_file" entries in the \a sym_spec
152254721Semaste        ///     are filled in, then we might be able to locate a module in
153254721Semaste        ///     the target, extract its UUID and locate a symbol file.
154254721Semaste        ///     If just the "m_uuid" is specified, then we might be able
155254721Semaste        ///     to find the module in the target that matches that UUID
156254721Semaste        ///     and pair the symbol file along with it. If just "m_symbol_file"
157254721Semaste        ///     is specified, we can use a variety of tricks to locate the
158254721Semaste        ///     symbols in an SDK, PDK, or other development kit location.
159254721Semaste        ///
160254721Semaste        /// @param[in] sym_spec
161254721Semaste        ///     A module spec that describes some information about the
162254721Semaste        ///     symbol file we are trying to resolve. The ModuleSpec might
163254721Semaste        ///     contain the following:
164254721Semaste        ///     m_file - A full or partial path to an executable from the
165254721Semaste        ///              target (might be empty).
166254721Semaste        ///     m_platform_file - Another executable hint that contains
167254721Semaste        ///                       the path to the file as known on the
168254721Semaste        ///                       local/remote platform.
169254721Semaste        ///     m_symbol_file - A full or partial path to a symbol file
170254721Semaste        ///                     or symbol bundle that should be used when
171254721Semaste        ///                     trying to resolve the symbol file.
172254721Semaste        ///     m_arch - The architecture we are looking for when resolving
173254721Semaste        ///              the symbol file.
174254721Semaste        ///     m_uuid - The UUID of the executable and symbol file. This
175254721Semaste        ///              can often be used to match up an exectuable with
176254721Semaste        ///              a symbol file, or resolve an symbol file in a
177254721Semaste        ///              symbol file bundle.
178254721Semaste        ///
179254721Semaste        /// @param[out] sym_file
180254721Semaste        ///     The resolved symbol file spec if the returned error
181254721Semaste        ///     indicates succes.
182254721Semaste        ///
183254721Semaste        /// @return
184254721Semaste        ///     Returns an error that describes success or failure.
185254721Semaste        //------------------------------------------------------------------
186254721Semaste        virtual Error
187254721Semaste        ResolveSymbolFile (Target &target,
188254721Semaste                           const ModuleSpec &sym_spec,
189254721Semaste                           FileSpec &sym_file);
190254721Semaste
191254721Semaste        //------------------------------------------------------------------
192254721Semaste        /// Resolves the FileSpec to a (possibly) remote path. Remote
193254721Semaste        /// platforms must override this to resolve to a path on the remote
194254721Semaste        /// side.
195254721Semaste        //------------------------------------------------------------------
196254721Semaste        virtual bool
197254721Semaste        ResolveRemotePath (const FileSpec &platform_path,
198254721Semaste                           FileSpec &resolved_platform_path);
199254721Semaste
200254721Semaste        bool
201254721Semaste        GetOSVersion (uint32_t &major,
202254721Semaste                      uint32_t &minor,
203254721Semaste                      uint32_t &update);
204254721Semaste
205254721Semaste        bool
206254721Semaste        SetOSVersion (uint32_t major,
207254721Semaste                      uint32_t minor,
208254721Semaste                      uint32_t update);
209254721Semaste
210254721Semaste        bool
211254721Semaste        GetOSBuildString (std::string &s);
212254721Semaste
213254721Semaste        bool
214254721Semaste        GetOSKernelDescription (std::string &s);
215254721Semaste
216254721Semaste        // Returns the the hostname if we are connected, else the short plugin
217254721Semaste        // name.
218254721Semaste        ConstString
219254721Semaste        GetName ();
220254721Semaste
221254721Semaste        virtual const char *
222254721Semaste        GetHostname ();
223254721Semaste
224254721Semaste        virtual const char *
225254721Semaste        GetDescription () = 0;
226254721Semaste
227254721Semaste        //------------------------------------------------------------------
228254721Semaste        /// Report the current status for this platform.
229254721Semaste        ///
230254721Semaste        /// The returned string usually involves returning the OS version
231254721Semaste        /// (if available), and any SDK directory that might be being used
232254721Semaste        /// for local file caching, and if connected a quick blurb about
233254721Semaste        /// what this platform is connected to.
234254721Semaste        //------------------------------------------------------------------
235254721Semaste        virtual void
236254721Semaste        GetStatus (Stream &strm);
237254721Semaste
238254721Semaste        //------------------------------------------------------------------
239254721Semaste        // Subclasses must be able to fetch the current OS version
240254721Semaste        //
241254721Semaste        // Remote classes must be connected for this to succeed. Local
242254721Semaste        // subclasses don't need to override this function as it will just
243254721Semaste        // call the Host::GetOSVersion().
244254721Semaste        //------------------------------------------------------------------
245254721Semaste        virtual bool
246254721Semaste        GetRemoteOSVersion ()
247254721Semaste        {
248254721Semaste            return false;
249254721Semaste        }
250254721Semaste
251254721Semaste        virtual bool
252254721Semaste        GetRemoteOSBuildString (std::string &s)
253254721Semaste        {
254254721Semaste            s.clear();
255254721Semaste            return false;
256254721Semaste        }
257254721Semaste
258254721Semaste        virtual bool
259254721Semaste        GetRemoteOSKernelDescription (std::string &s)
260254721Semaste        {
261254721Semaste            s.clear();
262254721Semaste            return false;
263254721Semaste        }
264254721Semaste
265254721Semaste        // Remote Platform subclasses need to override this function
266254721Semaste        virtual ArchSpec
267254721Semaste        GetRemoteSystemArchitecture ()
268254721Semaste        {
269254721Semaste            return ArchSpec(); // Return an invalid architecture
270254721Semaste        }
271254721Semaste
272254721Semaste        virtual const char *
273254721Semaste        GetUserName (uint32_t uid);
274254721Semaste
275254721Semaste        virtual const char *
276254721Semaste        GetGroupName (uint32_t gid);
277254721Semaste
278254721Semaste        //------------------------------------------------------------------
279254721Semaste        /// Locate a file for a platform.
280254721Semaste        ///
281254721Semaste        /// The default implementation of this function will return the same
282254721Semaste        /// file patch in \a local_file as was in \a platform_file.
283254721Semaste        ///
284254721Semaste        /// @param[in] platform_file
285254721Semaste        ///     The platform file path to locate and cache locally.
286254721Semaste        ///
287254721Semaste        /// @param[in] uuid_ptr
288254721Semaste        ///     If we know the exact UUID of the file we are looking for, it
289254721Semaste        ///     can be specified. If it is not specified, we might now know
290254721Semaste        ///     the exact file. The UUID is usually some sort of MD5 checksum
291254721Semaste        ///     for the file and is sometimes known by dynamic linkers/loaders.
292254721Semaste        ///     If the UUID is known, it is best to supply it to platform
293254721Semaste        ///     file queries to ensure we are finding the correct file, not
294254721Semaste        ///     just a file at the correct path.
295254721Semaste        ///
296254721Semaste        /// @param[out] local_file
297254721Semaste        ///     A locally cached version of the platform file. For platforms
298254721Semaste        ///     that describe the current host computer, this will just be
299254721Semaste        ///     the same file. For remote platforms, this file might come from
300254721Semaste        ///     and SDK directory, or might need to be sync'ed over to the
301254721Semaste        ///     current machine for efficient debugging access.
302254721Semaste        ///
303254721Semaste        /// @return
304254721Semaste        ///     An error object.
305254721Semaste        //------------------------------------------------------------------
306254721Semaste        virtual Error
307254721Semaste        GetFile (const FileSpec &platform_file,
308254721Semaste                 const UUID *uuid_ptr,
309254721Semaste                 FileSpec &local_file);
310254721Semaste
311254721Semaste        //----------------------------------------------------------------------
312254721Semaste        // Locate the scripting resource given a module specification.
313254721Semaste        //
314254721Semaste        // Locating the file should happen only on the local computer or using
315254721Semaste        // the current computers global settings.
316254721Semaste        //----------------------------------------------------------------------
317254721Semaste        virtual FileSpecList
318254721Semaste        LocateExecutableScriptingResources (Target *target,
319254721Semaste                                            Module &module);
320254721Semaste
321254721Semaste        virtual Error
322254721Semaste        GetSharedModule (const ModuleSpec &module_spec,
323254721Semaste                         lldb::ModuleSP &module_sp,
324254721Semaste                         const FileSpecList *module_search_paths_ptr,
325254721Semaste                         lldb::ModuleSP *old_module_sp_ptr,
326254721Semaste                         bool *did_create_ptr);
327254721Semaste
328254721Semaste        virtual Error
329254721Semaste        ConnectRemote (Args& args);
330254721Semaste
331254721Semaste        virtual Error
332254721Semaste        DisconnectRemote ();
333254721Semaste
334254721Semaste        //------------------------------------------------------------------
335254721Semaste        /// Get the platform's supported architectures in the order in which
336254721Semaste        /// they should be searched.
337254721Semaste        ///
338254721Semaste        /// @param[in] idx
339254721Semaste        ///     A zero based architecture index
340254721Semaste        ///
341254721Semaste        /// @param[out] arch
342254721Semaste        ///     A copy of the archgitecture at index if the return value is
343254721Semaste        ///     \b true.
344254721Semaste        ///
345254721Semaste        /// @return
346254721Semaste        ///     \b true if \a arch was filled in and is valid, \b false
347254721Semaste        ///     otherwise.
348254721Semaste        //------------------------------------------------------------------
349254721Semaste        virtual bool
350254721Semaste        GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) = 0;
351254721Semaste
352254721Semaste        virtual size_t
353254721Semaste        GetSoftwareBreakpointTrapOpcode (Target &target,
354254721Semaste                                         BreakpointSite *bp_site) = 0;
355254721Semaste
356254721Semaste        //------------------------------------------------------------------
357254721Semaste        /// Launch a new process on a platform, not necessarily for
358254721Semaste        /// debugging, it could be just for running the process.
359254721Semaste        //------------------------------------------------------------------
360254721Semaste        virtual Error
361254721Semaste        LaunchProcess (ProcessLaunchInfo &launch_info);
362254721Semaste
363254721Semaste        //------------------------------------------------------------------
364254721Semaste        /// Lets a platform answer if it is compatible with a given
365254721Semaste        /// architecture and the target triple contained within.
366254721Semaste        //------------------------------------------------------------------
367254721Semaste        virtual bool
368254721Semaste        IsCompatibleArchitecture (const ArchSpec &arch,
369254721Semaste                                  bool exact_arch_match,
370254721Semaste                                  ArchSpec *compatible_arch_ptr);
371254721Semaste
372254721Semaste        //------------------------------------------------------------------
373254721Semaste        /// Not all platforms will support debugging a process by spawning
374254721Semaste        /// somehow halted for a debugger (specified using the
375254721Semaste        /// "eLaunchFlagDebug" launch flag) and then attaching. If your
376254721Semaste        /// platform doesn't support this, override this function and return
377254721Semaste        /// false.
378254721Semaste        //------------------------------------------------------------------
379254721Semaste        virtual bool
380254721Semaste        CanDebugProcess ()
381254721Semaste        {
382254721Semaste            return true;
383254721Semaste        }
384254721Semaste
385254721Semaste        //------------------------------------------------------------------
386254721Semaste        /// Subclasses should NOT need to implement this function as it uses
387254721Semaste        /// the Platform::LaunchProcess() followed by Platform::Attach ()
388254721Semaste        //------------------------------------------------------------------
389254721Semaste        lldb::ProcessSP
390254721Semaste        DebugProcess (ProcessLaunchInfo &launch_info,
391254721Semaste                      Debugger &debugger,
392254721Semaste                      Target *target,       // Can be NULL, if NULL create a new target, else use existing one
393254721Semaste                      Listener &listener,
394254721Semaste                      Error &error);
395254721Semaste
396254721Semaste        //------------------------------------------------------------------
397254721Semaste        /// Attach to an existing process using a process ID.
398254721Semaste        ///
399254721Semaste        /// Each platform subclass needs to implement this function and
400254721Semaste        /// attempt to attach to the process with the process ID of \a pid.
401254721Semaste        /// The platform subclass should return an appropriate ProcessSP
402254721Semaste        /// subclass that is attached to the process, or an empty shared
403254721Semaste        /// pointer with an appriopriate error.
404254721Semaste        ///
405254721Semaste        /// @param[in] pid
406254721Semaste        ///     The process ID that we should attempt to attach to.
407254721Semaste        ///
408254721Semaste        /// @return
409254721Semaste        ///     An appropriate ProcessSP containing a valid shared pointer
410254721Semaste        ///     to the default Process subclass for the platform that is
411254721Semaste        ///     attached to the process, or an empty shared pointer with an
412254721Semaste        ///     appriopriate error fill into the \a error object.
413254721Semaste        //------------------------------------------------------------------
414254721Semaste        virtual lldb::ProcessSP
415254721Semaste        Attach (ProcessAttachInfo &attach_info,
416254721Semaste                Debugger &debugger,
417254721Semaste                Target *target,       // Can be NULL, if NULL create a new target, else use existing one
418254721Semaste                Listener &listener,
419254721Semaste                Error &error) = 0;
420254721Semaste
421254721Semaste        //------------------------------------------------------------------
422254721Semaste        /// Attach to an existing process by process name.
423254721Semaste        ///
424254721Semaste        /// This function is not meant to be overridden by Process
425254721Semaste        /// subclasses. It will first call
426254721Semaste        /// Process::WillAttach (const char *) and if that returns \b
427254721Semaste        /// true, Process::DoAttach (const char *) will be called to
428254721Semaste        /// actually do the attach. If DoAttach returns \b true, then
429254721Semaste        /// Process::DidAttach() will be called.
430254721Semaste        ///
431254721Semaste        /// @param[in] process_name
432254721Semaste        ///     A process name to match against the current process list.
433254721Semaste        ///
434254721Semaste        /// @return
435254721Semaste        ///     Returns \a pid if attaching was successful, or
436254721Semaste        ///     LLDB_INVALID_PROCESS_ID if attaching fails.
437254721Semaste        //------------------------------------------------------------------
438254721Semaste//        virtual lldb::ProcessSP
439254721Semaste//        Attach (const char *process_name,
440254721Semaste//                bool wait_for_launch,
441254721Semaste//                Error &error) = 0;
442254721Semaste
443254721Semaste        //------------------------------------------------------------------
444254721Semaste        // The base class Platform will take care of the host platform.
445254721Semaste        // Subclasses will need to fill in the remote case.
446254721Semaste        //------------------------------------------------------------------
447254721Semaste        virtual uint32_t
448254721Semaste        FindProcesses (const ProcessInstanceInfoMatch &match_info,
449254721Semaste                       ProcessInstanceInfoList &proc_infos);
450254721Semaste
451254721Semaste        virtual bool
452254721Semaste        GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info);
453254721Semaste
454254721Semaste        //------------------------------------------------------------------
455254721Semaste        // Set a breakpoint on all functions that can end up creating a thread
456254721Semaste        // for this platform. This is needed when running expressions and
457254721Semaste        // also for process control.
458254721Semaste        //------------------------------------------------------------------
459254721Semaste        virtual lldb::BreakpointSP
460254721Semaste        SetThreadCreationBreakpoint (Target &target);
461254721Semaste
462254721Semaste
463254721Semaste        const std::string &
464254721Semaste        GetRemoteURL () const
465254721Semaste        {
466254721Semaste            return m_remote_url;
467254721Semaste        }
468254721Semaste
469254721Semaste        bool
470254721Semaste        IsHost () const
471254721Semaste        {
472254721Semaste            return m_is_host;    // Is this the default host platform?
473254721Semaste        }
474254721Semaste
475254721Semaste        bool
476254721Semaste        IsRemote () const
477254721Semaste        {
478254721Semaste            return !m_is_host;
479254721Semaste        }
480254721Semaste
481254721Semaste        virtual bool
482254721Semaste        IsConnected () const
483254721Semaste        {
484254721Semaste            // Remote subclasses should override this function
485254721Semaste            return IsHost();
486254721Semaste        }
487254721Semaste
488254721Semaste        const ArchSpec &
489254721Semaste        GetSystemArchitecture();
490254721Semaste
491254721Semaste        void
492254721Semaste        SetSystemArchitecture (const ArchSpec &arch)
493254721Semaste        {
494254721Semaste            m_system_arch = arch;
495254721Semaste            if (IsHost())
496254721Semaste                m_os_version_set_while_connected = m_system_arch.IsValid();
497254721Semaste        }
498254721Semaste
499254721Semaste        // Used for column widths
500254721Semaste        size_t
501254721Semaste        GetMaxUserIDNameLength() const
502254721Semaste        {
503254721Semaste            return m_max_uid_name_len;
504254721Semaste        }
505254721Semaste        // Used for column widths
506254721Semaste        size_t
507254721Semaste        GetMaxGroupIDNameLength() const
508254721Semaste        {
509254721Semaste            return m_max_gid_name_len;
510254721Semaste        }
511254721Semaste
512254721Semaste        const ConstString &
513254721Semaste        GetSDKRootDirectory () const
514254721Semaste        {
515254721Semaste            return m_sdk_sysroot;
516254721Semaste        }
517254721Semaste
518254721Semaste        void
519254721Semaste        SetSDKRootDirectory (const ConstString &dir)
520254721Semaste        {
521254721Semaste            m_sdk_sysroot = dir;
522254721Semaste        }
523254721Semaste
524254721Semaste        const ConstString &
525254721Semaste        GetSDKBuild () const
526254721Semaste        {
527254721Semaste            return m_sdk_build;
528254721Semaste        }
529254721Semaste
530254721Semaste        void
531254721Semaste        SetSDKBuild (const ConstString &sdk_build)
532254721Semaste        {
533254721Semaste            m_sdk_build = sdk_build;
534254721Semaste        }
535254721Semaste
536254721Semaste        // There may be modules that we don't want to find by default for operations like "setting breakpoint by name".
537254721Semaste        // The platform will return "true" from this call if the passed in module happens to be one of these.
538254721Semaste
539254721Semaste        virtual bool
540254721Semaste        ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp)
541254721Semaste        {
542254721Semaste            return false;
543254721Semaste        }
544254721Semaste
545254721Semaste        virtual size_t
546254721Semaste        GetEnvironment (StringList &environment);
547254721Semaste
548254721Semaste    protected:
549254721Semaste        bool m_is_host;
550254721Semaste        // Set to true when we are able to actually set the OS version while
551254721Semaste        // being connected. For remote platforms, we might set the version ahead
552254721Semaste        // of time before we actually connect and this version might change when
553254721Semaste        // we actually connect to a remote platform. For the host platform this
554254721Semaste        // will be set to the once we call Host::GetOSVersion().
555254721Semaste        bool m_os_version_set_while_connected;
556254721Semaste        bool m_system_arch_set_while_connected;
557254721Semaste        ConstString m_sdk_sysroot; // the root location of where the SDK files are all located
558254721Semaste        ConstString m_sdk_build;
559254721Semaste        std::string m_remote_url;
560254721Semaste        std::string m_name;
561254721Semaste        uint32_t m_major_os_version;
562254721Semaste        uint32_t m_minor_os_version;
563254721Semaste        uint32_t m_update_os_version;
564254721Semaste        ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
565254721Semaste        typedef std::map<uint32_t, ConstString> IDToNameMap;
566254721Semaste        Mutex m_uid_map_mutex;
567254721Semaste        Mutex m_gid_map_mutex;
568254721Semaste        IDToNameMap m_uid_map;
569254721Semaste        IDToNameMap m_gid_map;
570254721Semaste        size_t m_max_uid_name_len;
571254721Semaste        size_t m_max_gid_name_len;
572254721Semaste
573254721Semaste        const char *
574254721Semaste        GetCachedUserName (uint32_t uid)
575254721Semaste        {
576254721Semaste            Mutex::Locker locker (m_uid_map_mutex);
577254721Semaste            IDToNameMap::iterator pos = m_uid_map.find (uid);
578254721Semaste            if (pos != m_uid_map.end())
579254721Semaste            {
580254721Semaste                // return the empty string if our string is NULL
581254721Semaste                // so we can tell when things were in the negative
582254721Semaste                // cached (didn't find a valid user name, don't keep
583254721Semaste                // trying)
584254721Semaste                return pos->second.AsCString("");
585254721Semaste            }
586254721Semaste            return NULL;
587254721Semaste        }
588254721Semaste
589254721Semaste        const char *
590254721Semaste        SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
591254721Semaste        {
592254721Semaste            Mutex::Locker locker (m_uid_map_mutex);
593254721Semaste            ConstString const_name (name);
594254721Semaste            m_uid_map[uid] = const_name;
595254721Semaste            if (m_max_uid_name_len < name_len)
596254721Semaste                m_max_uid_name_len = name_len;
597254721Semaste            // Const strings lives forever in our const string pool, so we can return the const char *
598254721Semaste            return const_name.GetCString();
599254721Semaste        }
600254721Semaste
601254721Semaste        void
602254721Semaste        SetUserNameNotFound (uint32_t uid)
603254721Semaste        {
604254721Semaste            Mutex::Locker locker (m_uid_map_mutex);
605254721Semaste            m_uid_map[uid] = ConstString();
606254721Semaste        }
607254721Semaste
608254721Semaste
609254721Semaste        void
610254721Semaste        ClearCachedUserNames ()
611254721Semaste        {
612254721Semaste            Mutex::Locker locker (m_uid_map_mutex);
613254721Semaste            m_uid_map.clear();
614254721Semaste        }
615254721Semaste
616254721Semaste        const char *
617254721Semaste        GetCachedGroupName (uint32_t gid)
618254721Semaste        {
619254721Semaste            Mutex::Locker locker (m_gid_map_mutex);
620254721Semaste            IDToNameMap::iterator pos = m_gid_map.find (gid);
621254721Semaste            if (pos != m_gid_map.end())
622254721Semaste            {
623254721Semaste                // return the empty string if our string is NULL
624254721Semaste                // so we can tell when things were in the negative
625254721Semaste                // cached (didn't find a valid group name, don't keep
626254721Semaste                // trying)
627254721Semaste                return pos->second.AsCString("");
628254721Semaste            }
629254721Semaste            return NULL;
630254721Semaste        }
631254721Semaste
632254721Semaste        const char *
633254721Semaste        SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
634254721Semaste        {
635254721Semaste            Mutex::Locker locker (m_gid_map_mutex);
636254721Semaste            ConstString const_name (name);
637254721Semaste            m_gid_map[gid] = const_name;
638254721Semaste            if (m_max_gid_name_len < name_len)
639254721Semaste                m_max_gid_name_len = name_len;
640254721Semaste            // Const strings lives forever in our const string pool, so we can return the const char *
641254721Semaste            return const_name.GetCString();
642254721Semaste        }
643254721Semaste
644254721Semaste        void
645254721Semaste        SetGroupNameNotFound (uint32_t gid)
646254721Semaste        {
647254721Semaste            Mutex::Locker locker (m_gid_map_mutex);
648254721Semaste            m_gid_map[gid] = ConstString();
649254721Semaste        }
650254721Semaste
651254721Semaste        void
652254721Semaste        ClearCachedGroupNames ()
653254721Semaste        {
654254721Semaste            Mutex::Locker locker (m_gid_map_mutex);
655254721Semaste            m_gid_map.clear();
656254721Semaste        }
657254721Semaste
658254721Semaste    private:
659254721Semaste        DISALLOW_COPY_AND_ASSIGN (Platform);
660254721Semaste    };
661254721Semaste
662254721Semaste
663254721Semaste    class PlatformList
664254721Semaste    {
665254721Semaste    public:
666254721Semaste        PlatformList() :
667254721Semaste            m_mutex (Mutex::eMutexTypeRecursive),
668254721Semaste            m_platforms (),
669254721Semaste            m_selected_platform_sp()
670254721Semaste        {
671254721Semaste        }
672254721Semaste
673254721Semaste        ~PlatformList()
674254721Semaste        {
675254721Semaste        }
676254721Semaste
677254721Semaste        void
678254721Semaste        Append (const lldb::PlatformSP &platform_sp, bool set_selected)
679254721Semaste        {
680254721Semaste            Mutex::Locker locker (m_mutex);
681254721Semaste            m_platforms.push_back (platform_sp);
682254721Semaste            if (set_selected)
683254721Semaste                m_selected_platform_sp = m_platforms.back();
684254721Semaste        }
685254721Semaste
686254721Semaste        size_t
687254721Semaste        GetSize()
688254721Semaste        {
689254721Semaste            Mutex::Locker locker (m_mutex);
690254721Semaste            return m_platforms.size();
691254721Semaste        }
692254721Semaste
693254721Semaste        lldb::PlatformSP
694254721Semaste        GetAtIndex (uint32_t idx)
695254721Semaste        {
696254721Semaste            lldb::PlatformSP platform_sp;
697254721Semaste            {
698254721Semaste                Mutex::Locker locker (m_mutex);
699254721Semaste                if (idx < m_platforms.size())
700254721Semaste                    platform_sp = m_platforms[idx];
701254721Semaste            }
702254721Semaste            return platform_sp;
703254721Semaste        }
704254721Semaste
705254721Semaste        //------------------------------------------------------------------
706254721Semaste        /// Select the active platform.
707254721Semaste        ///
708254721Semaste        /// In order to debug remotely, other platform's can be remotely
709254721Semaste        /// connected to and set as the selected platform for any subsequent
710254721Semaste        /// debugging. This allows connection to remote targets and allows
711254721Semaste        /// the ability to discover process info, launch and attach to remote
712254721Semaste        /// processes.
713254721Semaste        //------------------------------------------------------------------
714254721Semaste        lldb::PlatformSP
715254721Semaste        GetSelectedPlatform ()
716254721Semaste        {
717254721Semaste            Mutex::Locker locker (m_mutex);
718254721Semaste            if (!m_selected_platform_sp && !m_platforms.empty())
719254721Semaste                m_selected_platform_sp = m_platforms.front();
720254721Semaste
721254721Semaste            return m_selected_platform_sp;
722254721Semaste        }
723254721Semaste
724254721Semaste        void
725254721Semaste        SetSelectedPlatform (const lldb::PlatformSP &platform_sp)
726254721Semaste        {
727254721Semaste            if (platform_sp)
728254721Semaste            {
729254721Semaste                Mutex::Locker locker (m_mutex);
730254721Semaste                const size_t num_platforms = m_platforms.size();
731254721Semaste                for (size_t idx=0; idx<num_platforms; ++idx)
732254721Semaste                {
733254721Semaste                    if (m_platforms[idx].get() == platform_sp.get())
734254721Semaste                    {
735254721Semaste                        m_selected_platform_sp = m_platforms[idx];
736254721Semaste                        return;
737254721Semaste                    }
738254721Semaste                }
739254721Semaste                m_platforms.push_back (platform_sp);
740254721Semaste                m_selected_platform_sp = m_platforms.back();
741254721Semaste            }
742254721Semaste        }
743254721Semaste
744254721Semaste    protected:
745254721Semaste        typedef std::vector<lldb::PlatformSP> collection;
746254721Semaste        mutable Mutex m_mutex;
747254721Semaste        collection m_platforms;
748254721Semaste        lldb::PlatformSP m_selected_platform_sp;
749254721Semaste
750254721Semaste    private:
751254721Semaste        DISALLOW_COPY_AND_ASSIGN (PlatformList);
752254721Semaste    };
753254721Semaste} // namespace lldb_private
754254721Semaste
755254721Semaste#endif  // liblldb_Platform_h_
756