blob: 86ef2a022eaf8a19bab28420e93692d5281e63e9 [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 Clayton49ce8962012-08-29 21:13:06 +000019#include "lldb/Core/ModuleSpec.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000020#include "lldb/Core/PluginManager.h"
21#include "lldb/Host/FileSpec.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000022#include "lldb/Host/Host.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000023#include "lldb/Target/Process.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000024#include "lldb/Target/Target.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29// Use a singleton function for g_local_platform_sp to avoid init
30// constructors since LLDB is often part of a shared library
31static PlatformSP&
32GetDefaultPlatformSP ()
33{
34 static PlatformSP g_default_platform_sp;
35 return g_default_platform_sp;
36}
37
Greg Claytone4b9c1f2011-03-08 22:40:15 +000038static Mutex &
39GetConnectedPlatformListMutex ()
40{
41 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive);
42 return g_remote_connected_platforms_mutex;
43}
44static std::vector<PlatformSP> &
45GetConnectedPlatformList ()
46{
47 static std::vector<PlatformSP> g_remote_connected_platforms;
48 return g_remote_connected_platforms;
49}
50
Greg Clayton5e342f52011-04-13 22:47:15 +000051
52const char *
53Platform::GetHostPlatformName ()
54{
55 return "host";
56}
57
Greg Claytone4b9c1f2011-03-08 22:40:15 +000058//------------------------------------------------------------------
59/// Get the native host platform plug-in.
60///
61/// There should only be one of these for each host that LLDB runs
62/// upon that should be statically compiled in and registered using
63/// preprocessor macros or other similar build mechanisms.
64///
65/// This platform will be used as the default platform when launching
66/// or attaching to processes unless another platform is specified.
67//------------------------------------------------------------------
68PlatformSP
69Platform::GetDefaultPlatform ()
70{
71 return GetDefaultPlatformSP ();
72}
73
74void
75Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp)
76{
77 // The native platform should use its static void Platform::Initialize()
78 // function to register itself as the native platform.
79 GetDefaultPlatformSP () = platform_sp;
80}
81
Greg Claytone4b9c1f2011-03-08 22:40:15 +000082Error
Greg Claytoncb8977d2011-03-23 00:09:55 +000083Platform::GetFile (const FileSpec &platform_file,
84 const UUID *uuid_ptr,
85 FileSpec &local_file)
Greg Claytone4b9c1f2011-03-08 22:40:15 +000086{
87 // Default to the local case
88 local_file = platform_file;
89 return Error();
90}
91
Enrico Granata146d9522012-11-08 02:22:02 +000092FileSpec
93Platform::LocateExecutableScriptingResource (const ModuleSpec &module_spec)
94{
95 return FileSpec();
96}
97
Greg Clayton24bc5d92011-03-30 18:16:51 +000098Error
Greg Clayton444fe992012-02-26 05:51:37 +000099Platform::GetSharedModule (const ModuleSpec &module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000100 ModuleSP &module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000101 const FileSpecList *module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000102 ModuleSP *old_module_sp_ptr,
103 bool *did_create_ptr)
104{
105 // Don't do any path remapping for the default implementation
106 // of the platform GetSharedModule function, just call through
107 // to our static ModuleList function. Platform subclasses that
108 // implement remote debugging, might have a developer kits
109 // installed that have cached versions of the files for the
110 // remote target, or might implement a download and cache
111 // locally implementation.
112 const bool always_create = false;
Greg Clayton444fe992012-02-26 05:51:37 +0000113 return ModuleList::GetSharedModule (module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000114 module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000115 module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000116 old_module_sp_ptr,
117 did_create_ptr,
118 always_create);
119}
120
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000121PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +0000122Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000123{
124 PlatformCreateInstance create_callback = NULL;
125 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +0000126 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000127 {
128 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
129 if (create_callback)
Greg Claytonb1db6582012-03-20 18:34:04 +0000130 platform_sp.reset(create_callback(true, NULL));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000131 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000132 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000133 }
134 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000135 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000136 return platform_sp;
137}
138
Greg Claytonb1db6582012-03-20 18:34:04 +0000139
140PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000141Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
Greg Claytonb1db6582012-03-20 18:34:04 +0000142{
143 lldb::PlatformSP platform_sp;
144 if (arch.IsValid())
145 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000146 uint32_t idx;
Greg Claytonb1db6582012-03-20 18:34:04 +0000147 PlatformCreateInstance create_callback;
Greg Claytonb170aee2012-05-08 01:45:38 +0000148 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
Greg Claytonb1db6582012-03-20 18:34:04 +0000149 {
150 if (create_callback)
151 platform_sp.reset(create_callback(false, &arch));
Greg Claytonb170aee2012-05-08 01:45:38 +0000152 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, platform_arch_ptr))
153 return platform_sp;
Greg Claytonb1db6582012-03-20 18:34:04 +0000154 }
155 }
156 else
157 error.SetErrorString ("invalid platform name");
Greg Claytonb170aee2012-05-08 01:45:38 +0000158 if (platform_arch_ptr)
159 platform_arch_ptr->Clear();
160 platform_sp.reset();
Greg Claytonb1db6582012-03-20 18:34:04 +0000161 return platform_sp;
162}
163
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000164uint32_t
165Platform::GetNumConnectedRemotePlatforms ()
166{
167 Mutex::Locker locker (GetConnectedPlatformListMutex ());
168 return GetConnectedPlatformList().size();
169}
170
171PlatformSP
172Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
173{
174 PlatformSP platform_sp;
175 {
176 Mutex::Locker locker (GetConnectedPlatformListMutex ());
177 if (idx < GetConnectedPlatformList().size())
178 platform_sp = GetConnectedPlatformList ()[idx];
179 }
180 return platform_sp;
181}
182
183//------------------------------------------------------------------
184/// Default Constructor
185//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000186Platform::Platform (bool is_host) :
187 m_is_host (is_host),
Greg Claytonb1888f22011-03-19 01:12:21 +0000188 m_os_version_set_while_connected (false),
189 m_system_arch_set_while_connected (false),
Greg Clayton604f0d32011-06-17 03:31:01 +0000190 m_sdk_sysroot (),
191 m_sdk_build (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000192 m_remote_url (),
Greg Clayton58e26e02011-03-24 04:28:38 +0000193 m_name (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000194 m_major_os_version (UINT32_MAX),
195 m_minor_os_version (UINT32_MAX),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000196 m_update_os_version (UINT32_MAX),
197 m_system_arch(),
198 m_uid_map_mutex (Mutex::eMutexTypeNormal),
199 m_gid_map_mutex (Mutex::eMutexTypeNormal),
200 m_uid_map(),
201 m_gid_map(),
202 m_max_uid_name_len (0),
203 m_max_gid_name_len (0)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000204{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000205 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
206 if (log)
207 log->Printf ("%p Platform::Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000208}
209
210//------------------------------------------------------------------
211/// Destructor.
212///
213/// The destructor is virtual since this class is designed to be
214/// inherited from by the plug-in instance.
215//------------------------------------------------------------------
216Platform::~Platform()
217{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000218 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
219 if (log)
220 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000221}
222
Greg Clayton58e26e02011-03-24 04:28:38 +0000223void
224Platform::GetStatus (Stream &strm)
225{
226 uint32_t major = UINT32_MAX;
227 uint32_t minor = UINT32_MAX;
228 uint32_t update = UINT32_MAX;
229 std::string s;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000230 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton58e26e02011-03-24 04:28:38 +0000231
232 ArchSpec arch (GetSystemArchitecture());
233 if (arch.IsValid())
234 {
235 if (!arch.GetTriple().str().empty())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000236 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000237 }
238
239 if (GetOSVersion(major, minor, update))
240 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000241 strm.Printf("OS Version: %u", major);
Greg Clayton58e26e02011-03-24 04:28:38 +0000242 if (minor != UINT32_MAX)
243 strm.Printf(".%u", minor);
244 if (update != UINT32_MAX)
245 strm.Printf(".%u", update);
246
247 if (GetOSBuildString (s))
248 strm.Printf(" (%s)", s.c_str());
249
250 strm.EOL();
251 }
252
253 if (GetOSKernelDescription (s))
Greg Clayton24bc5d92011-03-30 18:16:51 +0000254 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000255
256 if (IsHost())
257 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000258 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton58e26e02011-03-24 04:28:38 +0000259 }
260 else
261 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000262 const bool is_connected = IsConnected();
263 if (is_connected)
264 strm.Printf(" Hostname: %s\n", GetHostname());
265 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton58e26e02011-03-24 04:28:38 +0000266 }
267}
268
Greg Claytonb1888f22011-03-19 01:12:21 +0000269
270bool
271Platform::GetOSVersion (uint32_t &major,
272 uint32_t &minor,
273 uint32_t &update)
274{
275 bool success = m_major_os_version != UINT32_MAX;
276 if (IsHost())
277 {
278 if (!success)
279 {
280 // We have a local host platform
281 success = Host::GetOSVersion (m_major_os_version,
282 m_minor_os_version,
283 m_update_os_version);
284 m_os_version_set_while_connected = success;
285 }
286 }
287 else
288 {
289 // We have a remote platform. We can only fetch the remote
290 // OS version if we are connected, and we don't want to do it
291 // more than once.
292
293 const bool is_connected = IsConnected();
294
Greg Clayton58e26e02011-03-24 04:28:38 +0000295 bool fetch = false;
Greg Claytonb1888f22011-03-19 01:12:21 +0000296 if (success)
297 {
298 // We have valid OS version info, check to make sure it wasn't
299 // manually set prior to connecting. If it was manually set prior
300 // to connecting, then lets fetch the actual OS version info
301 // if we are now connected.
302 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton58e26e02011-03-24 04:28:38 +0000303 fetch = true;
Greg Claytonb1888f22011-03-19 01:12:21 +0000304 }
305 else
306 {
307 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton58e26e02011-03-24 04:28:38 +0000308 fetch = is_connected;
Greg Claytonb1888f22011-03-19 01:12:21 +0000309 }
310
Greg Clayton58e26e02011-03-24 04:28:38 +0000311 if (fetch)
Greg Claytonb1888f22011-03-19 01:12:21 +0000312 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000313 success = GetRemoteOSVersion ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000314 m_os_version_set_while_connected = success;
315 }
316 }
317
318 if (success)
319 {
320 major = m_major_os_version;
321 minor = m_minor_os_version;
322 update = m_update_os_version;
323 }
324 return success;
325}
Greg Clayton58e26e02011-03-24 04:28:38 +0000326
327bool
328Platform::GetOSBuildString (std::string &s)
329{
330 if (IsHost())
331 return Host::GetOSBuildString (s);
332 else
333 return GetRemoteOSBuildString (s);
334}
335
336bool
337Platform::GetOSKernelDescription (std::string &s)
338{
339 if (IsHost())
340 return Host::GetOSKernelDescription (s);
341 else
342 return GetRemoteOSKernelDescription (s);
343}
344
345const char *
Greg Claytonb72d0f02011-04-12 05:54:46 +0000346Platform::GetName ()
347{
348 const char *name = GetHostname();
349 if (name == NULL || name[0] == '\0')
350 name = GetShortPluginName();
351 return name;
352}
353
354const char *
Greg Clayton58e26e02011-03-24 04:28:38 +0000355Platform::GetHostname ()
356{
Greg Clayton5e342f52011-04-13 22:47:15 +0000357 if (IsHost())
358 return "localhost";
Greg Clayton24bc5d92011-03-30 18:16:51 +0000359
360 if (m_name.empty())
361 return NULL;
362 return m_name.c_str();
363}
364
365const char *
366Platform::GetUserName (uint32_t uid)
367{
368 const char *user_name = GetCachedUserName(uid);
369 if (user_name)
370 return user_name;
371 if (IsHost())
372 {
373 std::string name;
374 if (Host::GetUserName(uid, name))
375 return SetCachedUserName (uid, name.c_str(), name.size());
376 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000377 return NULL;
378}
379
Greg Clayton24bc5d92011-03-30 18:16:51 +0000380const char *
381Platform::GetGroupName (uint32_t gid)
382{
383 const char *group_name = GetCachedGroupName(gid);
384 if (group_name)
385 return group_name;
386 if (IsHost())
387 {
388 std::string name;
389 if (Host::GetGroupName(gid, name))
390 return SetCachedGroupName (gid, name.c_str(), name.size());
391 }
392 return NULL;
393}
Greg Clayton58e26e02011-03-24 04:28:38 +0000394
Greg Claytonb1888f22011-03-19 01:12:21 +0000395bool
396Platform::SetOSVersion (uint32_t major,
397 uint32_t minor,
398 uint32_t update)
399{
400 if (IsHost())
401 {
402 // We don't need anyone setting the OS version for the host platform,
403 // we should be able to figure it out by calling Host::GetOSVersion(...).
404 return false;
405 }
406 else
407 {
408 // We have a remote platform, allow setting the target OS version if
409 // we aren't connected, since if we are connected, we should be able to
410 // request the remote OS version from the connected platform.
411 if (IsConnected())
412 return false;
413 else
414 {
415 // We aren't connected and we might want to set the OS version
416 // ahead of time before we connect so we can peruse files and
417 // use a local SDK or PDK cache of support files to disassemble
418 // or do other things.
419 m_major_os_version = major;
420 m_minor_os_version = minor;
421 m_update_os_version = update;
422 return true;
423 }
424 }
425 return false;
426}
427
428
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000429Error
430Platform::ResolveExecutable (const FileSpec &exe_file,
431 const ArchSpec &exe_arch,
Greg Clayton9ce95382012-02-13 23:10:39 +0000432 lldb::ModuleSP &exe_module_sp,
433 const FileSpecList *module_search_paths_ptr)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000434{
435 Error error;
436 if (exe_file.Exists())
437 {
Greg Clayton444fe992012-02-26 05:51:37 +0000438 ModuleSpec module_spec (exe_file, exe_arch);
439 if (module_spec.GetArchitecture().IsValid())
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000440 {
Greg Clayton444fe992012-02-26 05:51:37 +0000441 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000442 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000443 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000444 NULL,
445 NULL);
446 }
447 else
448 {
449 // No valid architecture was specified, ask the platform for
450 // the architectures that we should be using (in the correct order)
451 // and see if we can find a match that way
Greg Clayton444fe992012-02-26 05:51:37 +0000452 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000453 {
Greg Clayton444fe992012-02-26 05:51:37 +0000454 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000455 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000456 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000457 NULL,
458 NULL);
459 // Did we find an executable using one of the
460 if (error.Success() && exe_module_sp)
461 break;
462 }
463 }
464 }
465 else
466 {
467 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
468 exe_file.GetDirectory().AsCString(""),
469 exe_file.GetDirectory() ? "/" : "",
470 exe_file.GetFilename().AsCString(""));
471 }
472 return error;
473}
474
Greg Clayton95b765e2012-09-12 02:03:59 +0000475Error
476Platform::ResolveSymbolFile (Target &target,
477 const ModuleSpec &sym_spec,
478 FileSpec &sym_file)
479{
480 Error error;
481 if (sym_spec.GetSymbolFileSpec().Exists())
482 sym_file = sym_spec.GetSymbolFileSpec();
483 else
484 error.SetErrorString("unable to resolve symbol file");
485 return error;
486
487}
488
489
490
Greg Claytonf2bf8702011-08-11 16:25:18 +0000491bool
492Platform::ResolveRemotePath (const FileSpec &platform_path,
493 FileSpec &resolved_platform_path)
494{
495 resolved_platform_path = platform_path;
496 return resolved_platform_path.ResolvePath();
497}
498
Greg Claytonb1888f22011-03-19 01:12:21 +0000499
500const ArchSpec &
501Platform::GetSystemArchitecture()
502{
503 if (IsHost())
504 {
505 if (!m_system_arch.IsValid())
506 {
507 // We have a local host platform
508 m_system_arch = Host::GetArchitecture();
509 m_system_arch_set_while_connected = m_system_arch.IsValid();
510 }
511 }
512 else
513 {
514 // We have a remote platform. We can only fetch the remote
515 // system architecture if we are connected, and we don't want to do it
516 // more than once.
517
518 const bool is_connected = IsConnected();
519
520 bool fetch = false;
521 if (m_system_arch.IsValid())
522 {
523 // We have valid OS version info, check to make sure it wasn't
524 // manually set prior to connecting. If it was manually set prior
525 // to connecting, then lets fetch the actual OS version info
526 // if we are now connected.
527 if (is_connected && !m_system_arch_set_while_connected)
528 fetch = true;
529 }
530 else
531 {
532 // We don't have valid OS version info, fetch it if we are connected
533 fetch = is_connected;
534 }
535
536 if (fetch)
537 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000538 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000539 m_system_arch_set_while_connected = m_system_arch.IsValid();
540 }
541 }
542 return m_system_arch;
543}
544
545
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000546Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000547Platform::ConnectRemote (Args& args)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000548{
549 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000550 if (IsHost())
551 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
552 else
553 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000554 return error;
555}
556
557Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000558Platform::DisconnectRemote ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000559{
560 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000561 if (IsHost())
562 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
563 else
564 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000565 return error;
566}
Greg Clayton24bc5d92011-03-30 18:16:51 +0000567
568bool
Greg Claytonb72d0f02011-04-12 05:54:46 +0000569Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000570{
571 // Take care of the host case so that each subclass can just
Greg Claytonb72d0f02011-04-12 05:54:46 +0000572 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000573 if (IsHost())
574 return Host::GetProcessInfo (pid, process_info);
575 return false;
576}
577
578uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +0000579Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
580 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000581{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000582 // Take care of the host case so that each subclass can just
583 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000584 uint32_t match_count = 0;
585 if (IsHost())
586 match_count = Host::FindProcesses (match_info, process_infos);
587 return match_count;
588}
Greg Claytonb72d0f02011-04-12 05:54:46 +0000589
590
591Error
592Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
593{
594 Error error;
595 // Take care of the host case so that each subclass can just
596 // call this function to get the host functionality.
597 if (IsHost())
Greg Claytondc0a38c2012-03-26 23:03:23 +0000598 {
599 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
600 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
601
602 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
603 {
604 const bool is_localhost = true;
Greg Clayton97471182012-04-14 01:42:46 +0000605 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
606 const bool first_arg_is_full_shell_command = false;
607 if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
608 is_localhost,
609 will_debug,
610 first_arg_is_full_shell_command))
Greg Claytondc0a38c2012-03-26 23:03:23 +0000611 return error;
612 }
613
Greg Claytonb72d0f02011-04-12 05:54:46 +0000614 error = Host::LaunchProcess (launch_info);
Greg Claytondc0a38c2012-03-26 23:03:23 +0000615 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000616 else
617 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
618 return error;
619}
620
621lldb::ProcessSP
622Platform::DebugProcess (ProcessLaunchInfo &launch_info,
623 Debugger &debugger,
624 Target *target, // Can be NULL, if NULL create a new target, else use existing one
625 Listener &listener,
626 Error &error)
627{
628 ProcessSP process_sp;
629 // Make sure we stop at the entry point
630 launch_info.GetFlags ().Set (eLaunchFlagDebug);
Jim Inghamb7b25322012-06-01 01:22:13 +0000631 // We always launch the process we are going to debug in a separate process
632 // group, since then we can handle ^C interrupts ourselves w/o having to worry
633 // about the target getting them as well.
634 launch_info.SetLaunchInSeparateProcessGroup(true);
635
Greg Claytonb72d0f02011-04-12 05:54:46 +0000636 error = LaunchProcess (launch_info);
637 if (error.Success())
638 {
Greg Clayton527154d2011-11-15 03:53:30 +0000639 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000640 {
Greg Clayton527154d2011-11-15 03:53:30 +0000641 ProcessAttachInfo attach_info (launch_info);
642 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytonffa43a62011-11-17 04:46:02 +0000643 if (process_sp)
644 {
645 // Since we attached to the process, it will think it needs to detach
646 // if the process object just goes away without an explicit call to
647 // Process::Kill() or Process::Detach(), so let it know to kill the
648 // process if this happens.
649 process_sp->SetShouldDetach (false);
Greg Clayton464c6162011-11-17 22:14:31 +0000650
651 // If we didn't have any file actions, the pseudo terminal might
652 // have been used where the slave side was given as the file to
653 // open for stdin/out/err after we have already opened the master
654 // so we can read/write stdin/out/err.
655 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
656 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
657 {
658 process_sp->SetSTDIOFileDescriptor(pty_fd);
659 }
Greg Claytonffa43a62011-11-17 04:46:02 +0000660 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000661 }
662 }
663 return process_sp;
664}
Greg Claytonb1db6582012-03-20 18:34:04 +0000665
666
667lldb::PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000668Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000669{
670 lldb::PlatformSP platform_sp;
671 Error error;
672 if (arch.IsValid())
Greg Claytonb170aee2012-05-08 01:45:38 +0000673 platform_sp = Platform::Create (arch, platform_arch_ptr, error);
Greg Claytonb1db6582012-03-20 18:34:04 +0000674 return platform_sp;
675}
676
677
678//------------------------------------------------------------------
679/// Lets a platform answer if it is compatible with a given
680/// architecture and the target triple contained within.
681//------------------------------------------------------------------
682bool
Greg Claytonb170aee2012-05-08 01:45:38 +0000683Platform::IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000684{
685 // If the architecture is invalid, we must answer true...
Greg Claytonb170aee2012-05-08 01:45:38 +0000686 if (arch.IsValid())
Greg Claytonb1db6582012-03-20 18:34:04 +0000687 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000688 ArchSpec platform_arch;
689 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
690 {
691 if (arch == platform_arch)
692 {
693 if (compatible_arch_ptr)
694 *compatible_arch_ptr = platform_arch;
695 return true;
696 }
697 }
Greg Claytonb1db6582012-03-20 18:34:04 +0000698 }
Greg Claytonb170aee2012-05-08 01:45:38 +0000699 if (compatible_arch_ptr)
700 compatible_arch_ptr->Clear();
Greg Claytonb1db6582012-03-20 18:34:04 +0000701 return false;
702
703}
704
Greg Claytonbd5c23d2012-05-15 02:33:01 +0000705lldb::BreakpointSP
706Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
707{
708 return lldb::BreakpointSP();
709}
Greg Claytonb1db6582012-03-20 18:34:04 +0000710
Greg Clayton73844aa2012-08-22 17:17:09 +0000711size_t
712Platform::GetEnvironment (StringList &environment)
713{
714 environment.Clear();
715 return false;
716}
717