blob: 79fdfff16bd9dbf577239a5fdab551855dca430e [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
Greg Claytonbd5c23d2012-05-15 02:33:01 +000016#include "lldb/Breakpoint/BreakpointIDList.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000017#include "lldb/Core/Error.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000018#include "lldb/Core/Log.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000019#include "lldb/Core/PluginManager.h"
20#include "lldb/Host/FileSpec.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000021#include "lldb/Host/Host.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000022#include "lldb/Target/Process.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000023#include "lldb/Target/Target.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
28// Use a singleton function for g_local_platform_sp to avoid init
29// constructors since LLDB is often part of a shared library
30static PlatformSP&
31GetDefaultPlatformSP ()
32{
33 static PlatformSP g_default_platform_sp;
34 return g_default_platform_sp;
35}
36
Greg Claytone4b9c1f2011-03-08 22:40:15 +000037static Mutex &
38GetConnectedPlatformListMutex ()
39{
40 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive);
41 return g_remote_connected_platforms_mutex;
42}
43static std::vector<PlatformSP> &
44GetConnectedPlatformList ()
45{
46 static std::vector<PlatformSP> g_remote_connected_platforms;
47 return g_remote_connected_platforms;
48}
49
Greg Clayton5e342f52011-04-13 22:47:15 +000050
51const char *
52Platform::GetHostPlatformName ()
53{
54 return "host";
55}
56
Greg Claytone4b9c1f2011-03-08 22:40:15 +000057//------------------------------------------------------------------
58/// Get the native host platform plug-in.
59///
60/// There should only be one of these for each host that LLDB runs
61/// upon that should be statically compiled in and registered using
62/// preprocessor macros or other similar build mechanisms.
63///
64/// This platform will be used as the default platform when launching
65/// or attaching to processes unless another platform is specified.
66//------------------------------------------------------------------
67PlatformSP
68Platform::GetDefaultPlatform ()
69{
70 return GetDefaultPlatformSP ();
71}
72
73void
74Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp)
75{
76 // The native platform should use its static void Platform::Initialize()
77 // function to register itself as the native platform.
78 GetDefaultPlatformSP () = platform_sp;
79}
80
Greg Claytone4b9c1f2011-03-08 22:40:15 +000081Error
Greg Claytoncb8977d2011-03-23 00:09:55 +000082Platform::GetFile (const FileSpec &platform_file,
83 const UUID *uuid_ptr,
84 FileSpec &local_file)
Greg Claytone4b9c1f2011-03-08 22:40:15 +000085{
86 // Default to the local case
87 local_file = platform_file;
88 return Error();
89}
90
Greg Clayton24bc5d92011-03-30 18:16:51 +000091Error
Greg Clayton444fe992012-02-26 05:51:37 +000092Platform::GetSharedModule (const ModuleSpec &module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +000093 ModuleSP &module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +000094 const FileSpecList *module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +000095 ModuleSP *old_module_sp_ptr,
96 bool *did_create_ptr)
97{
98 // Don't do any path remapping for the default implementation
99 // of the platform GetSharedModule function, just call through
100 // to our static ModuleList function. Platform subclasses that
101 // implement remote debugging, might have a developer kits
102 // installed that have cached versions of the files for the
103 // remote target, or might implement a download and cache
104 // locally implementation.
105 const bool always_create = false;
Greg Clayton444fe992012-02-26 05:51:37 +0000106 return ModuleList::GetSharedModule (module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000107 module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000108 module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000109 old_module_sp_ptr,
110 did_create_ptr,
111 always_create);
112}
113
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000114PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +0000115Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000116{
117 PlatformCreateInstance create_callback = NULL;
118 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +0000119 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000120 {
121 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
122 if (create_callback)
Greg Claytonb1db6582012-03-20 18:34:04 +0000123 platform_sp.reset(create_callback(true, NULL));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000124 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000125 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000126 }
127 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000128 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000129 return platform_sp;
130}
131
Greg Claytonb1db6582012-03-20 18:34:04 +0000132
133PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000134Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
Greg Claytonb1db6582012-03-20 18:34:04 +0000135{
136 lldb::PlatformSP platform_sp;
137 if (arch.IsValid())
138 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000139 uint32_t idx;
Greg Claytonb1db6582012-03-20 18:34:04 +0000140 PlatformCreateInstance create_callback;
Greg Claytonb170aee2012-05-08 01:45:38 +0000141 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
Greg Claytonb1db6582012-03-20 18:34:04 +0000142 {
143 if (create_callback)
144 platform_sp.reset(create_callback(false, &arch));
Greg Claytonb170aee2012-05-08 01:45:38 +0000145 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, platform_arch_ptr))
146 return platform_sp;
Greg Claytonb1db6582012-03-20 18:34:04 +0000147 }
148 }
149 else
150 error.SetErrorString ("invalid platform name");
Greg Claytonb170aee2012-05-08 01:45:38 +0000151 if (platform_arch_ptr)
152 platform_arch_ptr->Clear();
153 platform_sp.reset();
Greg Claytonb1db6582012-03-20 18:34:04 +0000154 return platform_sp;
155}
156
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000157uint32_t
158Platform::GetNumConnectedRemotePlatforms ()
159{
160 Mutex::Locker locker (GetConnectedPlatformListMutex ());
161 return GetConnectedPlatformList().size();
162}
163
164PlatformSP
165Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
166{
167 PlatformSP platform_sp;
168 {
169 Mutex::Locker locker (GetConnectedPlatformListMutex ());
170 if (idx < GetConnectedPlatformList().size())
171 platform_sp = GetConnectedPlatformList ()[idx];
172 }
173 return platform_sp;
174}
175
176//------------------------------------------------------------------
177/// Default Constructor
178//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000179Platform::Platform (bool is_host) :
180 m_is_host (is_host),
Greg Claytonb1888f22011-03-19 01:12:21 +0000181 m_os_version_set_while_connected (false),
182 m_system_arch_set_while_connected (false),
Greg Clayton604f0d32011-06-17 03:31:01 +0000183 m_sdk_sysroot (),
184 m_sdk_build (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000185 m_remote_url (),
Greg Clayton58e26e02011-03-24 04:28:38 +0000186 m_name (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000187 m_major_os_version (UINT32_MAX),
188 m_minor_os_version (UINT32_MAX),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000189 m_update_os_version (UINT32_MAX),
190 m_system_arch(),
191 m_uid_map_mutex (Mutex::eMutexTypeNormal),
192 m_gid_map_mutex (Mutex::eMutexTypeNormal),
193 m_uid_map(),
194 m_gid_map(),
195 m_max_uid_name_len (0),
196 m_max_gid_name_len (0)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000197{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000198 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
199 if (log)
200 log->Printf ("%p Platform::Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000201}
202
203//------------------------------------------------------------------
204/// Destructor.
205///
206/// The destructor is virtual since this class is designed to be
207/// inherited from by the plug-in instance.
208//------------------------------------------------------------------
209Platform::~Platform()
210{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000211 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
212 if (log)
213 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000214}
215
Greg Clayton58e26e02011-03-24 04:28:38 +0000216void
217Platform::GetStatus (Stream &strm)
218{
219 uint32_t major = UINT32_MAX;
220 uint32_t minor = UINT32_MAX;
221 uint32_t update = UINT32_MAX;
222 std::string s;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000223 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton58e26e02011-03-24 04:28:38 +0000224
225 ArchSpec arch (GetSystemArchitecture());
226 if (arch.IsValid())
227 {
228 if (!arch.GetTriple().str().empty())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000229 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000230 }
231
232 if (GetOSVersion(major, minor, update))
233 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000234 strm.Printf("OS Version: %u", major);
Greg Clayton58e26e02011-03-24 04:28:38 +0000235 if (minor != UINT32_MAX)
236 strm.Printf(".%u", minor);
237 if (update != UINT32_MAX)
238 strm.Printf(".%u", update);
239
240 if (GetOSBuildString (s))
241 strm.Printf(" (%s)", s.c_str());
242
243 strm.EOL();
244 }
245
246 if (GetOSKernelDescription (s))
Greg Clayton24bc5d92011-03-30 18:16:51 +0000247 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000248
249 if (IsHost())
250 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000251 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton58e26e02011-03-24 04:28:38 +0000252 }
253 else
254 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000255 const bool is_connected = IsConnected();
256 if (is_connected)
257 strm.Printf(" Hostname: %s\n", GetHostname());
258 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton58e26e02011-03-24 04:28:38 +0000259 }
260}
261
Greg Claytonb1888f22011-03-19 01:12:21 +0000262
263bool
264Platform::GetOSVersion (uint32_t &major,
265 uint32_t &minor,
266 uint32_t &update)
267{
268 bool success = m_major_os_version != UINT32_MAX;
269 if (IsHost())
270 {
271 if (!success)
272 {
273 // We have a local host platform
274 success = Host::GetOSVersion (m_major_os_version,
275 m_minor_os_version,
276 m_update_os_version);
277 m_os_version_set_while_connected = success;
278 }
279 }
280 else
281 {
282 // We have a remote platform. We can only fetch the remote
283 // OS version if we are connected, and we don't want to do it
284 // more than once.
285
286 const bool is_connected = IsConnected();
287
Greg Clayton58e26e02011-03-24 04:28:38 +0000288 bool fetch = false;
Greg Claytonb1888f22011-03-19 01:12:21 +0000289 if (success)
290 {
291 // We have valid OS version info, check to make sure it wasn't
292 // manually set prior to connecting. If it was manually set prior
293 // to connecting, then lets fetch the actual OS version info
294 // if we are now connected.
295 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton58e26e02011-03-24 04:28:38 +0000296 fetch = true;
Greg Claytonb1888f22011-03-19 01:12:21 +0000297 }
298 else
299 {
300 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton58e26e02011-03-24 04:28:38 +0000301 fetch = is_connected;
Greg Claytonb1888f22011-03-19 01:12:21 +0000302 }
303
Greg Clayton58e26e02011-03-24 04:28:38 +0000304 if (fetch)
Greg Claytonb1888f22011-03-19 01:12:21 +0000305 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000306 success = GetRemoteOSVersion ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000307 m_os_version_set_while_connected = success;
308 }
309 }
310
311 if (success)
312 {
313 major = m_major_os_version;
314 minor = m_minor_os_version;
315 update = m_update_os_version;
316 }
317 return success;
318}
Greg Clayton58e26e02011-03-24 04:28:38 +0000319
320bool
321Platform::GetOSBuildString (std::string &s)
322{
323 if (IsHost())
324 return Host::GetOSBuildString (s);
325 else
326 return GetRemoteOSBuildString (s);
327}
328
329bool
330Platform::GetOSKernelDescription (std::string &s)
331{
332 if (IsHost())
333 return Host::GetOSKernelDescription (s);
334 else
335 return GetRemoteOSKernelDescription (s);
336}
337
338const char *
Greg Claytonb72d0f02011-04-12 05:54:46 +0000339Platform::GetName ()
340{
341 const char *name = GetHostname();
342 if (name == NULL || name[0] == '\0')
343 name = GetShortPluginName();
344 return name;
345}
346
347const char *
Greg Clayton58e26e02011-03-24 04:28:38 +0000348Platform::GetHostname ()
349{
Greg Clayton5e342f52011-04-13 22:47:15 +0000350 if (IsHost())
351 return "localhost";
Greg Clayton24bc5d92011-03-30 18:16:51 +0000352
353 if (m_name.empty())
354 return NULL;
355 return m_name.c_str();
356}
357
358const char *
359Platform::GetUserName (uint32_t uid)
360{
361 const char *user_name = GetCachedUserName(uid);
362 if (user_name)
363 return user_name;
364 if (IsHost())
365 {
366 std::string name;
367 if (Host::GetUserName(uid, name))
368 return SetCachedUserName (uid, name.c_str(), name.size());
369 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000370 return NULL;
371}
372
Greg Clayton24bc5d92011-03-30 18:16:51 +0000373const char *
374Platform::GetGroupName (uint32_t gid)
375{
376 const char *group_name = GetCachedGroupName(gid);
377 if (group_name)
378 return group_name;
379 if (IsHost())
380 {
381 std::string name;
382 if (Host::GetGroupName(gid, name))
383 return SetCachedGroupName (gid, name.c_str(), name.size());
384 }
385 return NULL;
386}
Greg Clayton58e26e02011-03-24 04:28:38 +0000387
Greg Claytonb1888f22011-03-19 01:12:21 +0000388bool
389Platform::SetOSVersion (uint32_t major,
390 uint32_t minor,
391 uint32_t update)
392{
393 if (IsHost())
394 {
395 // We don't need anyone setting the OS version for the host platform,
396 // we should be able to figure it out by calling Host::GetOSVersion(...).
397 return false;
398 }
399 else
400 {
401 // We have a remote platform, allow setting the target OS version if
402 // we aren't connected, since if we are connected, we should be able to
403 // request the remote OS version from the connected platform.
404 if (IsConnected())
405 return false;
406 else
407 {
408 // We aren't connected and we might want to set the OS version
409 // ahead of time before we connect so we can peruse files and
410 // use a local SDK or PDK cache of support files to disassemble
411 // or do other things.
412 m_major_os_version = major;
413 m_minor_os_version = minor;
414 m_update_os_version = update;
415 return true;
416 }
417 }
418 return false;
419}
420
421
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000422Error
423Platform::ResolveExecutable (const FileSpec &exe_file,
424 const ArchSpec &exe_arch,
Greg Clayton9ce95382012-02-13 23:10:39 +0000425 lldb::ModuleSP &exe_module_sp,
426 const FileSpecList *module_search_paths_ptr)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000427{
428 Error error;
429 if (exe_file.Exists())
430 {
Greg Clayton444fe992012-02-26 05:51:37 +0000431 ModuleSpec module_spec (exe_file, exe_arch);
432 if (module_spec.GetArchitecture().IsValid())
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000433 {
Greg Clayton444fe992012-02-26 05:51:37 +0000434 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000435 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000436 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000437 NULL,
438 NULL);
439 }
440 else
441 {
442 // No valid architecture was specified, ask the platform for
443 // the architectures that we should be using (in the correct order)
444 // and see if we can find a match that way
Greg Clayton444fe992012-02-26 05:51:37 +0000445 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000446 {
Greg Clayton444fe992012-02-26 05:51:37 +0000447 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000448 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000449 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000450 NULL,
451 NULL);
452 // Did we find an executable using one of the
453 if (error.Success() && exe_module_sp)
454 break;
455 }
456 }
457 }
458 else
459 {
460 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
461 exe_file.GetDirectory().AsCString(""),
462 exe_file.GetDirectory() ? "/" : "",
463 exe_file.GetFilename().AsCString(""));
464 }
465 return error;
466}
467
Greg Claytonf2bf8702011-08-11 16:25:18 +0000468bool
469Platform::ResolveRemotePath (const FileSpec &platform_path,
470 FileSpec &resolved_platform_path)
471{
472 resolved_platform_path = platform_path;
473 return resolved_platform_path.ResolvePath();
474}
475
Greg Claytonb1888f22011-03-19 01:12:21 +0000476
477const ArchSpec &
478Platform::GetSystemArchitecture()
479{
480 if (IsHost())
481 {
482 if (!m_system_arch.IsValid())
483 {
484 // We have a local host platform
485 m_system_arch = Host::GetArchitecture();
486 m_system_arch_set_while_connected = m_system_arch.IsValid();
487 }
488 }
489 else
490 {
491 // We have a remote platform. We can only fetch the remote
492 // system architecture if we are connected, and we don't want to do it
493 // more than once.
494
495 const bool is_connected = IsConnected();
496
497 bool fetch = false;
498 if (m_system_arch.IsValid())
499 {
500 // We have valid OS version info, check to make sure it wasn't
501 // manually set prior to connecting. If it was manually set prior
502 // to connecting, then lets fetch the actual OS version info
503 // if we are now connected.
504 if (is_connected && !m_system_arch_set_while_connected)
505 fetch = true;
506 }
507 else
508 {
509 // We don't have valid OS version info, fetch it if we are connected
510 fetch = is_connected;
511 }
512
513 if (fetch)
514 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000515 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000516 m_system_arch_set_while_connected = m_system_arch.IsValid();
517 }
518 }
519 return m_system_arch;
520}
521
522
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000523Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000524Platform::ConnectRemote (Args& args)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000525{
526 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000527 if (IsHost())
528 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
529 else
530 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000531 return error;
532}
533
534Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000535Platform::DisconnectRemote ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000536{
537 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000538 if (IsHost())
539 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
540 else
541 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000542 return error;
543}
Greg Clayton24bc5d92011-03-30 18:16:51 +0000544
545bool
Greg Claytonb72d0f02011-04-12 05:54:46 +0000546Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000547{
548 // Take care of the host case so that each subclass can just
Greg Claytonb72d0f02011-04-12 05:54:46 +0000549 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000550 if (IsHost())
551 return Host::GetProcessInfo (pid, process_info);
552 return false;
553}
554
555uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +0000556Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
557 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000558{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000559 // Take care of the host case so that each subclass can just
560 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000561 uint32_t match_count = 0;
562 if (IsHost())
563 match_count = Host::FindProcesses (match_info, process_infos);
564 return match_count;
565}
Greg Claytonb72d0f02011-04-12 05:54:46 +0000566
567
568Error
569Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
570{
571 Error error;
572 // Take care of the host case so that each subclass can just
573 // call this function to get the host functionality.
574 if (IsHost())
Greg Claytondc0a38c2012-03-26 23:03:23 +0000575 {
576 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
577 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
578
579 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
580 {
581 const bool is_localhost = true;
Greg Clayton97471182012-04-14 01:42:46 +0000582 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
583 const bool first_arg_is_full_shell_command = false;
584 if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
585 is_localhost,
586 will_debug,
587 first_arg_is_full_shell_command))
Greg Claytondc0a38c2012-03-26 23:03:23 +0000588 return error;
589 }
590
Greg Claytonb72d0f02011-04-12 05:54:46 +0000591 error = Host::LaunchProcess (launch_info);
Greg Claytondc0a38c2012-03-26 23:03:23 +0000592 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000593 else
594 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
595 return error;
596}
597
598lldb::ProcessSP
599Platform::DebugProcess (ProcessLaunchInfo &launch_info,
600 Debugger &debugger,
601 Target *target, // Can be NULL, if NULL create a new target, else use existing one
602 Listener &listener,
603 Error &error)
604{
605 ProcessSP process_sp;
606 // Make sure we stop at the entry point
607 launch_info.GetFlags ().Set (eLaunchFlagDebug);
Jim Inghamb7b25322012-06-01 01:22:13 +0000608 // We always launch the process we are going to debug in a separate process
609 // group, since then we can handle ^C interrupts ourselves w/o having to worry
610 // about the target getting them as well.
611 launch_info.SetLaunchInSeparateProcessGroup(true);
612
Greg Claytonb72d0f02011-04-12 05:54:46 +0000613 error = LaunchProcess (launch_info);
614 if (error.Success())
615 {
Greg Clayton527154d2011-11-15 03:53:30 +0000616 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000617 {
Greg Clayton527154d2011-11-15 03:53:30 +0000618 ProcessAttachInfo attach_info (launch_info);
619 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytonffa43a62011-11-17 04:46:02 +0000620 if (process_sp)
621 {
622 // Since we attached to the process, it will think it needs to detach
623 // if the process object just goes away without an explicit call to
624 // Process::Kill() or Process::Detach(), so let it know to kill the
625 // process if this happens.
626 process_sp->SetShouldDetach (false);
Greg Clayton464c6162011-11-17 22:14:31 +0000627
628 // If we didn't have any file actions, the pseudo terminal might
629 // have been used where the slave side was given as the file to
630 // open for stdin/out/err after we have already opened the master
631 // so we can read/write stdin/out/err.
632 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
633 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
634 {
635 process_sp->SetSTDIOFileDescriptor(pty_fd);
636 }
Greg Claytonffa43a62011-11-17 04:46:02 +0000637 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000638 }
639 }
640 return process_sp;
641}
Greg Claytonb1db6582012-03-20 18:34:04 +0000642
643
644lldb::PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000645Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000646{
647 lldb::PlatformSP platform_sp;
648 Error error;
649 if (arch.IsValid())
Greg Claytonb170aee2012-05-08 01:45:38 +0000650 platform_sp = Platform::Create (arch, platform_arch_ptr, error);
Greg Claytonb1db6582012-03-20 18:34:04 +0000651 return platform_sp;
652}
653
654
655//------------------------------------------------------------------
656/// Lets a platform answer if it is compatible with a given
657/// architecture and the target triple contained within.
658//------------------------------------------------------------------
659bool
Greg Claytonb170aee2012-05-08 01:45:38 +0000660Platform::IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000661{
662 // If the architecture is invalid, we must answer true...
Greg Claytonb170aee2012-05-08 01:45:38 +0000663 if (arch.IsValid())
Greg Claytonb1db6582012-03-20 18:34:04 +0000664 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000665 ArchSpec platform_arch;
666 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
667 {
668 if (arch == platform_arch)
669 {
670 if (compatible_arch_ptr)
671 *compatible_arch_ptr = platform_arch;
672 return true;
673 }
674 }
Greg Claytonb1db6582012-03-20 18:34:04 +0000675 }
Greg Claytonb170aee2012-05-08 01:45:38 +0000676 if (compatible_arch_ptr)
677 compatible_arch_ptr->Clear();
Greg Claytonb1db6582012-03-20 18:34:04 +0000678 return false;
679
680}
681
Greg Claytonbd5c23d2012-05-15 02:33:01 +0000682lldb::BreakpointSP
683Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
684{
685 return lldb::BreakpointSP();
686}
Greg Claytonb1db6582012-03-20 18:34:04 +0000687