blob: af4b7a83af5059b7598b1c96ab3c09516dee1ab2 [file] [log] [blame]
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001//===-- Platform.cpp --------------------------------------------*- 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#include "lldb/Target/Platform.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Error.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000017#include "lldb/Core/Log.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000018#include "lldb/Core/PluginManager.h"
19#include "lldb/Host/FileSpec.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000020#include "lldb/Host/Host.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000021#include "lldb/Target/Process.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000022#include "lldb/Target/Target.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27// Use a singleton function for g_local_platform_sp to avoid init
28// constructors since LLDB is often part of a shared library
29static PlatformSP&
30GetDefaultPlatformSP ()
31{
32 static PlatformSP g_default_platform_sp;
33 return g_default_platform_sp;
34}
35
Greg Claytone4b9c1f2011-03-08 22:40:15 +000036static Mutex &
37GetConnectedPlatformListMutex ()
38{
39 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive);
40 return g_remote_connected_platforms_mutex;
41}
42static std::vector<PlatformSP> &
43GetConnectedPlatformList ()
44{
45 static std::vector<PlatformSP> g_remote_connected_platforms;
46 return g_remote_connected_platforms;
47}
48
Greg Clayton5e342f52011-04-13 22:47:15 +000049
50const char *
51Platform::GetHostPlatformName ()
52{
53 return "host";
54}
55
Greg Claytone4b9c1f2011-03-08 22:40:15 +000056//------------------------------------------------------------------
57/// Get the native host platform plug-in.
58///
59/// There should only be one of these for each host that LLDB runs
60/// upon that should be statically compiled in and registered using
61/// preprocessor macros or other similar build mechanisms.
62///
63/// This platform will be used as the default platform when launching
64/// or attaching to processes unless another platform is specified.
65//------------------------------------------------------------------
66PlatformSP
67Platform::GetDefaultPlatform ()
68{
69 return GetDefaultPlatformSP ();
70}
71
72void
73Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp)
74{
75 // The native platform should use its static void Platform::Initialize()
76 // function to register itself as the native platform.
77 GetDefaultPlatformSP () = platform_sp;
78}
79
Greg Claytone4b9c1f2011-03-08 22:40:15 +000080Error
Greg Claytoncb8977d2011-03-23 00:09:55 +000081Platform::GetFile (const FileSpec &platform_file,
82 const UUID *uuid_ptr,
83 FileSpec &local_file)
Greg Claytone4b9c1f2011-03-08 22:40:15 +000084{
85 // Default to the local case
86 local_file = platform_file;
87 return Error();
88}
89
Greg Clayton24bc5d92011-03-30 18:16:51 +000090Error
Greg Clayton444fe992012-02-26 05:51:37 +000091Platform::GetSharedModule (const ModuleSpec &module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +000092 ModuleSP &module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +000093 const FileSpecList *module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +000094 ModuleSP *old_module_sp_ptr,
95 bool *did_create_ptr)
96{
97 // Don't do any path remapping for the default implementation
98 // of the platform GetSharedModule function, just call through
99 // to our static ModuleList function. Platform subclasses that
100 // implement remote debugging, might have a developer kits
101 // installed that have cached versions of the files for the
102 // remote target, or might implement a download and cache
103 // locally implementation.
104 const bool always_create = false;
Greg Clayton444fe992012-02-26 05:51:37 +0000105 return ModuleList::GetSharedModule (module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000106 module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000107 module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000108 old_module_sp_ptr,
109 did_create_ptr,
110 always_create);
111}
112
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000113PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +0000114Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000115{
116 PlatformCreateInstance create_callback = NULL;
117 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +0000118 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000119 {
120 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
121 if (create_callback)
Greg Claytonb1db6582012-03-20 18:34:04 +0000122 platform_sp.reset(create_callback(true, NULL));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000123 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000124 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000125 }
126 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000127 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000128 return platform_sp;
129}
130
Greg Claytonb1db6582012-03-20 18:34:04 +0000131
132PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000133Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
Greg Claytonb1db6582012-03-20 18:34:04 +0000134{
135 lldb::PlatformSP platform_sp;
136 if (arch.IsValid())
137 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000138 uint32_t idx;
Greg Claytonb1db6582012-03-20 18:34:04 +0000139 PlatformCreateInstance create_callback;
Greg Claytonb170aee2012-05-08 01:45:38 +0000140 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
Greg Claytonb1db6582012-03-20 18:34:04 +0000141 {
142 if (create_callback)
143 platform_sp.reset(create_callback(false, &arch));
Greg Claytonb170aee2012-05-08 01:45:38 +0000144 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, platform_arch_ptr))
145 return platform_sp;
Greg Claytonb1db6582012-03-20 18:34:04 +0000146 }
147 }
148 else
149 error.SetErrorString ("invalid platform name");
Greg Claytonb170aee2012-05-08 01:45:38 +0000150 if (platform_arch_ptr)
151 platform_arch_ptr->Clear();
152 platform_sp.reset();
Greg Claytonb1db6582012-03-20 18:34:04 +0000153 return platform_sp;
154}
155
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000156uint32_t
157Platform::GetNumConnectedRemotePlatforms ()
158{
159 Mutex::Locker locker (GetConnectedPlatformListMutex ());
160 return GetConnectedPlatformList().size();
161}
162
163PlatformSP
164Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
165{
166 PlatformSP platform_sp;
167 {
168 Mutex::Locker locker (GetConnectedPlatformListMutex ());
169 if (idx < GetConnectedPlatformList().size())
170 platform_sp = GetConnectedPlatformList ()[idx];
171 }
172 return platform_sp;
173}
174
175//------------------------------------------------------------------
176/// Default Constructor
177//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000178Platform::Platform (bool is_host) :
179 m_is_host (is_host),
Greg Claytonb1888f22011-03-19 01:12:21 +0000180 m_os_version_set_while_connected (false),
181 m_system_arch_set_while_connected (false),
Greg Clayton604f0d32011-06-17 03:31:01 +0000182 m_sdk_sysroot (),
183 m_sdk_build (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000184 m_remote_url (),
Greg Clayton58e26e02011-03-24 04:28:38 +0000185 m_name (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000186 m_major_os_version (UINT32_MAX),
187 m_minor_os_version (UINT32_MAX),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000188 m_update_os_version (UINT32_MAX),
189 m_system_arch(),
190 m_uid_map_mutex (Mutex::eMutexTypeNormal),
191 m_gid_map_mutex (Mutex::eMutexTypeNormal),
192 m_uid_map(),
193 m_gid_map(),
194 m_max_uid_name_len (0),
195 m_max_gid_name_len (0)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000196{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000197 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
198 if (log)
199 log->Printf ("%p Platform::Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000200}
201
202//------------------------------------------------------------------
203/// Destructor.
204///
205/// The destructor is virtual since this class is designed to be
206/// inherited from by the plug-in instance.
207//------------------------------------------------------------------
208Platform::~Platform()
209{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000210 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
211 if (log)
212 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000213}
214
Greg Clayton58e26e02011-03-24 04:28:38 +0000215void
216Platform::GetStatus (Stream &strm)
217{
218 uint32_t major = UINT32_MAX;
219 uint32_t minor = UINT32_MAX;
220 uint32_t update = UINT32_MAX;
221 std::string s;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000222 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton58e26e02011-03-24 04:28:38 +0000223
224 ArchSpec arch (GetSystemArchitecture());
225 if (arch.IsValid())
226 {
227 if (!arch.GetTriple().str().empty())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000228 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000229 }
230
231 if (GetOSVersion(major, minor, update))
232 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000233 strm.Printf("OS Version: %u", major);
Greg Clayton58e26e02011-03-24 04:28:38 +0000234 if (minor != UINT32_MAX)
235 strm.Printf(".%u", minor);
236 if (update != UINT32_MAX)
237 strm.Printf(".%u", update);
238
239 if (GetOSBuildString (s))
240 strm.Printf(" (%s)", s.c_str());
241
242 strm.EOL();
243 }
244
245 if (GetOSKernelDescription (s))
Greg Clayton24bc5d92011-03-30 18:16:51 +0000246 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000247
248 if (IsHost())
249 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000250 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton58e26e02011-03-24 04:28:38 +0000251 }
252 else
253 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000254 const bool is_connected = IsConnected();
255 if (is_connected)
256 strm.Printf(" Hostname: %s\n", GetHostname());
257 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton58e26e02011-03-24 04:28:38 +0000258 }
259}
260
Greg Claytonb1888f22011-03-19 01:12:21 +0000261
262bool
263Platform::GetOSVersion (uint32_t &major,
264 uint32_t &minor,
265 uint32_t &update)
266{
267 bool success = m_major_os_version != UINT32_MAX;
268 if (IsHost())
269 {
270 if (!success)
271 {
272 // We have a local host platform
273 success = Host::GetOSVersion (m_major_os_version,
274 m_minor_os_version,
275 m_update_os_version);
276 m_os_version_set_while_connected = success;
277 }
278 }
279 else
280 {
281 // We have a remote platform. We can only fetch the remote
282 // OS version if we are connected, and we don't want to do it
283 // more than once.
284
285 const bool is_connected = IsConnected();
286
Greg Clayton58e26e02011-03-24 04:28:38 +0000287 bool fetch = false;
Greg Claytonb1888f22011-03-19 01:12:21 +0000288 if (success)
289 {
290 // We have valid OS version info, check to make sure it wasn't
291 // manually set prior to connecting. If it was manually set prior
292 // to connecting, then lets fetch the actual OS version info
293 // if we are now connected.
294 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton58e26e02011-03-24 04:28:38 +0000295 fetch = true;
Greg Claytonb1888f22011-03-19 01:12:21 +0000296 }
297 else
298 {
299 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton58e26e02011-03-24 04:28:38 +0000300 fetch = is_connected;
Greg Claytonb1888f22011-03-19 01:12:21 +0000301 }
302
Greg Clayton58e26e02011-03-24 04:28:38 +0000303 if (fetch)
Greg Claytonb1888f22011-03-19 01:12:21 +0000304 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000305 success = GetRemoteOSVersion ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000306 m_os_version_set_while_connected = success;
307 }
308 }
309
310 if (success)
311 {
312 major = m_major_os_version;
313 minor = m_minor_os_version;
314 update = m_update_os_version;
315 }
316 return success;
317}
Greg Clayton58e26e02011-03-24 04:28:38 +0000318
319bool
320Platform::GetOSBuildString (std::string &s)
321{
322 if (IsHost())
323 return Host::GetOSBuildString (s);
324 else
325 return GetRemoteOSBuildString (s);
326}
327
328bool
329Platform::GetOSKernelDescription (std::string &s)
330{
331 if (IsHost())
332 return Host::GetOSKernelDescription (s);
333 else
334 return GetRemoteOSKernelDescription (s);
335}
336
337const char *
Greg Claytonb72d0f02011-04-12 05:54:46 +0000338Platform::GetName ()
339{
340 const char *name = GetHostname();
341 if (name == NULL || name[0] == '\0')
342 name = GetShortPluginName();
343 return name;
344}
345
346const char *
Greg Clayton58e26e02011-03-24 04:28:38 +0000347Platform::GetHostname ()
348{
Greg Clayton5e342f52011-04-13 22:47:15 +0000349 if (IsHost())
350 return "localhost";
Greg Clayton24bc5d92011-03-30 18:16:51 +0000351
352 if (m_name.empty())
353 return NULL;
354 return m_name.c_str();
355}
356
357const char *
358Platform::GetUserName (uint32_t uid)
359{
360 const char *user_name = GetCachedUserName(uid);
361 if (user_name)
362 return user_name;
363 if (IsHost())
364 {
365 std::string name;
366 if (Host::GetUserName(uid, name))
367 return SetCachedUserName (uid, name.c_str(), name.size());
368 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000369 return NULL;
370}
371
Greg Clayton24bc5d92011-03-30 18:16:51 +0000372const char *
373Platform::GetGroupName (uint32_t gid)
374{
375 const char *group_name = GetCachedGroupName(gid);
376 if (group_name)
377 return group_name;
378 if (IsHost())
379 {
380 std::string name;
381 if (Host::GetGroupName(gid, name))
382 return SetCachedGroupName (gid, name.c_str(), name.size());
383 }
384 return NULL;
385}
Greg Clayton58e26e02011-03-24 04:28:38 +0000386
Greg Claytonb1888f22011-03-19 01:12:21 +0000387bool
388Platform::SetOSVersion (uint32_t major,
389 uint32_t minor,
390 uint32_t update)
391{
392 if (IsHost())
393 {
394 // We don't need anyone setting the OS version for the host platform,
395 // we should be able to figure it out by calling Host::GetOSVersion(...).
396 return false;
397 }
398 else
399 {
400 // We have a remote platform, allow setting the target OS version if
401 // we aren't connected, since if we are connected, we should be able to
402 // request the remote OS version from the connected platform.
403 if (IsConnected())
404 return false;
405 else
406 {
407 // We aren't connected and we might want to set the OS version
408 // ahead of time before we connect so we can peruse files and
409 // use a local SDK or PDK cache of support files to disassemble
410 // or do other things.
411 m_major_os_version = major;
412 m_minor_os_version = minor;
413 m_update_os_version = update;
414 return true;
415 }
416 }
417 return false;
418}
419
420
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000421Error
422Platform::ResolveExecutable (const FileSpec &exe_file,
423 const ArchSpec &exe_arch,
Greg Clayton9ce95382012-02-13 23:10:39 +0000424 lldb::ModuleSP &exe_module_sp,
425 const FileSpecList *module_search_paths_ptr)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000426{
427 Error error;
428 if (exe_file.Exists())
429 {
Greg Clayton444fe992012-02-26 05:51:37 +0000430 ModuleSpec module_spec (exe_file, exe_arch);
431 if (module_spec.GetArchitecture().IsValid())
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000432 {
Greg Clayton444fe992012-02-26 05:51:37 +0000433 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000434 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000435 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000436 NULL,
437 NULL);
438 }
439 else
440 {
441 // No valid architecture was specified, ask the platform for
442 // the architectures that we should be using (in the correct order)
443 // and see if we can find a match that way
Greg Clayton444fe992012-02-26 05:51:37 +0000444 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000445 {
Greg Clayton444fe992012-02-26 05:51:37 +0000446 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000447 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000448 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000449 NULL,
450 NULL);
451 // Did we find an executable using one of the
452 if (error.Success() && exe_module_sp)
453 break;
454 }
455 }
456 }
457 else
458 {
459 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
460 exe_file.GetDirectory().AsCString(""),
461 exe_file.GetDirectory() ? "/" : "",
462 exe_file.GetFilename().AsCString(""));
463 }
464 return error;
465}
466
Greg Claytonf2bf8702011-08-11 16:25:18 +0000467bool
468Platform::ResolveRemotePath (const FileSpec &platform_path,
469 FileSpec &resolved_platform_path)
470{
471 resolved_platform_path = platform_path;
472 return resolved_platform_path.ResolvePath();
473}
474
Greg Claytonb1888f22011-03-19 01:12:21 +0000475
476const ArchSpec &
477Platform::GetSystemArchitecture()
478{
479 if (IsHost())
480 {
481 if (!m_system_arch.IsValid())
482 {
483 // We have a local host platform
484 m_system_arch = Host::GetArchitecture();
485 m_system_arch_set_while_connected = m_system_arch.IsValid();
486 }
487 }
488 else
489 {
490 // We have a remote platform. We can only fetch the remote
491 // system architecture if we are connected, and we don't want to do it
492 // more than once.
493
494 const bool is_connected = IsConnected();
495
496 bool fetch = false;
497 if (m_system_arch.IsValid())
498 {
499 // We have valid OS version info, check to make sure it wasn't
500 // manually set prior to connecting. If it was manually set prior
501 // to connecting, then lets fetch the actual OS version info
502 // if we are now connected.
503 if (is_connected && !m_system_arch_set_while_connected)
504 fetch = true;
505 }
506 else
507 {
508 // We don't have valid OS version info, fetch it if we are connected
509 fetch = is_connected;
510 }
511
512 if (fetch)
513 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000514 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000515 m_system_arch_set_while_connected = m_system_arch.IsValid();
516 }
517 }
518 return m_system_arch;
519}
520
521
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000522Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000523Platform::ConnectRemote (Args& args)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000524{
525 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000526 if (IsHost())
527 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
528 else
529 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000530 return error;
531}
532
533Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000534Platform::DisconnectRemote ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000535{
536 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000537 if (IsHost())
538 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
539 else
540 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000541 return error;
542}
Greg Clayton24bc5d92011-03-30 18:16:51 +0000543
544bool
Greg Claytonb72d0f02011-04-12 05:54:46 +0000545Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000546{
547 // Take care of the host case so that each subclass can just
Greg Claytonb72d0f02011-04-12 05:54:46 +0000548 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000549 if (IsHost())
550 return Host::GetProcessInfo (pid, process_info);
551 return false;
552}
553
554uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +0000555Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
556 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000557{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000558 // Take care of the host case so that each subclass can just
559 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000560 uint32_t match_count = 0;
561 if (IsHost())
562 match_count = Host::FindProcesses (match_info, process_infos);
563 return match_count;
564}
Greg Claytonb72d0f02011-04-12 05:54:46 +0000565
566
567Error
568Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
569{
570 Error error;
571 // Take care of the host case so that each subclass can just
572 // call this function to get the host functionality.
573 if (IsHost())
Greg Claytondc0a38c2012-03-26 23:03:23 +0000574 {
575 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
576 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
577
578 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
579 {
580 const bool is_localhost = true;
Greg Clayton97471182012-04-14 01:42:46 +0000581 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
582 const bool first_arg_is_full_shell_command = false;
583 if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
584 is_localhost,
585 will_debug,
586 first_arg_is_full_shell_command))
Greg Claytondc0a38c2012-03-26 23:03:23 +0000587 return error;
588 }
589
Greg Claytonb72d0f02011-04-12 05:54:46 +0000590 error = Host::LaunchProcess (launch_info);
Greg Claytondc0a38c2012-03-26 23:03:23 +0000591 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000592 else
593 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
594 return error;
595}
596
597lldb::ProcessSP
598Platform::DebugProcess (ProcessLaunchInfo &launch_info,
599 Debugger &debugger,
600 Target *target, // Can be NULL, if NULL create a new target, else use existing one
601 Listener &listener,
602 Error &error)
603{
604 ProcessSP process_sp;
605 // Make sure we stop at the entry point
606 launch_info.GetFlags ().Set (eLaunchFlagDebug);
607 error = LaunchProcess (launch_info);
608 if (error.Success())
609 {
Greg Clayton527154d2011-11-15 03:53:30 +0000610 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000611 {
Greg Clayton527154d2011-11-15 03:53:30 +0000612 ProcessAttachInfo attach_info (launch_info);
613 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytonffa43a62011-11-17 04:46:02 +0000614 if (process_sp)
615 {
616 // Since we attached to the process, it will think it needs to detach
617 // if the process object just goes away without an explicit call to
618 // Process::Kill() or Process::Detach(), so let it know to kill the
619 // process if this happens.
620 process_sp->SetShouldDetach (false);
Greg Clayton464c6162011-11-17 22:14:31 +0000621
622 // If we didn't have any file actions, the pseudo terminal might
623 // have been used where the slave side was given as the file to
624 // open for stdin/out/err after we have already opened the master
625 // so we can read/write stdin/out/err.
626 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
627 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
628 {
629 process_sp->SetSTDIOFileDescriptor(pty_fd);
630 }
Greg Claytonffa43a62011-11-17 04:46:02 +0000631 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000632 }
633 }
634 return process_sp;
635}
Greg Claytonb1db6582012-03-20 18:34:04 +0000636
637
638lldb::PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000639Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000640{
641 lldb::PlatformSP platform_sp;
642 Error error;
643 if (arch.IsValid())
Greg Claytonb170aee2012-05-08 01:45:38 +0000644 platform_sp = Platform::Create (arch, platform_arch_ptr, error);
Greg Claytonb1db6582012-03-20 18:34:04 +0000645 return platform_sp;
646}
647
648
649//------------------------------------------------------------------
650/// Lets a platform answer if it is compatible with a given
651/// architecture and the target triple contained within.
652//------------------------------------------------------------------
653bool
Greg Claytonb170aee2012-05-08 01:45:38 +0000654Platform::IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000655{
656 // If the architecture is invalid, we must answer true...
Greg Claytonb170aee2012-05-08 01:45:38 +0000657 if (arch.IsValid())
Greg Claytonb1db6582012-03-20 18:34:04 +0000658 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000659 ArchSpec platform_arch;
660 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
661 {
662 if (arch == platform_arch)
663 {
664 if (compatible_arch_ptr)
665 *compatible_arch_ptr = platform_arch;
666 return true;
667 }
668 }
Greg Claytonb1db6582012-03-20 18:34:04 +0000669 }
Greg Claytonb170aee2012-05-08 01:45:38 +0000670 if (compatible_arch_ptr)
671 compatible_arch_ptr->Clear();
Greg Claytonb1db6582012-03-20 18:34:04 +0000672 return false;
673
674}
675
676