blob: 6772abf00be501ea9d18b66ca8c0732addfd89cc [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
Greg Clayton24bc5d92011-03-30 18:16:51 +000092Error
Greg Clayton444fe992012-02-26 05:51:37 +000093Platform::GetSharedModule (const ModuleSpec &module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +000094 ModuleSP &module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +000095 const FileSpecList *module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +000096 ModuleSP *old_module_sp_ptr,
97 bool *did_create_ptr)
98{
99 // Don't do any path remapping for the default implementation
100 // of the platform GetSharedModule function, just call through
101 // to our static ModuleList function. Platform subclasses that
102 // implement remote debugging, might have a developer kits
103 // installed that have cached versions of the files for the
104 // remote target, or might implement a download and cache
105 // locally implementation.
106 const bool always_create = false;
Greg Clayton444fe992012-02-26 05:51:37 +0000107 return ModuleList::GetSharedModule (module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000108 module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000109 module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000110 old_module_sp_ptr,
111 did_create_ptr,
112 always_create);
113}
114
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000115PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +0000116Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000117{
118 PlatformCreateInstance create_callback = NULL;
119 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +0000120 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000121 {
122 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
123 if (create_callback)
Greg Claytonb1db6582012-03-20 18:34:04 +0000124 platform_sp.reset(create_callback(true, NULL));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000125 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000126 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000127 }
128 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000129 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000130 return platform_sp;
131}
132
Greg Claytonb1db6582012-03-20 18:34:04 +0000133
134PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000135Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
Greg Claytonb1db6582012-03-20 18:34:04 +0000136{
137 lldb::PlatformSP platform_sp;
138 if (arch.IsValid())
139 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000140 uint32_t idx;
Greg Claytonb1db6582012-03-20 18:34:04 +0000141 PlatformCreateInstance create_callback;
Greg Claytonb170aee2012-05-08 01:45:38 +0000142 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
Greg Claytonb1db6582012-03-20 18:34:04 +0000143 {
144 if (create_callback)
145 platform_sp.reset(create_callback(false, &arch));
Greg Claytonb170aee2012-05-08 01:45:38 +0000146 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, platform_arch_ptr))
147 return platform_sp;
Greg Claytonb1db6582012-03-20 18:34:04 +0000148 }
149 }
150 else
151 error.SetErrorString ("invalid platform name");
Greg Claytonb170aee2012-05-08 01:45:38 +0000152 if (platform_arch_ptr)
153 platform_arch_ptr->Clear();
154 platform_sp.reset();
Greg Claytonb1db6582012-03-20 18:34:04 +0000155 return platform_sp;
156}
157
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000158uint32_t
159Platform::GetNumConnectedRemotePlatforms ()
160{
161 Mutex::Locker locker (GetConnectedPlatformListMutex ());
162 return GetConnectedPlatformList().size();
163}
164
165PlatformSP
166Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
167{
168 PlatformSP platform_sp;
169 {
170 Mutex::Locker locker (GetConnectedPlatformListMutex ());
171 if (idx < GetConnectedPlatformList().size())
172 platform_sp = GetConnectedPlatformList ()[idx];
173 }
174 return platform_sp;
175}
176
177//------------------------------------------------------------------
178/// Default Constructor
179//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000180Platform::Platform (bool is_host) :
181 m_is_host (is_host),
Greg Claytonb1888f22011-03-19 01:12:21 +0000182 m_os_version_set_while_connected (false),
183 m_system_arch_set_while_connected (false),
Greg Clayton604f0d32011-06-17 03:31:01 +0000184 m_sdk_sysroot (),
185 m_sdk_build (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000186 m_remote_url (),
Greg Clayton58e26e02011-03-24 04:28:38 +0000187 m_name (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000188 m_major_os_version (UINT32_MAX),
189 m_minor_os_version (UINT32_MAX),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000190 m_update_os_version (UINT32_MAX),
191 m_system_arch(),
192 m_uid_map_mutex (Mutex::eMutexTypeNormal),
193 m_gid_map_mutex (Mutex::eMutexTypeNormal),
194 m_uid_map(),
195 m_gid_map(),
196 m_max_uid_name_len (0),
197 m_max_gid_name_len (0)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000198{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000199 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
200 if (log)
201 log->Printf ("%p Platform::Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000202}
203
204//------------------------------------------------------------------
205/// Destructor.
206///
207/// The destructor is virtual since this class is designed to be
208/// inherited from by the plug-in instance.
209//------------------------------------------------------------------
210Platform::~Platform()
211{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000212 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
213 if (log)
214 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000215}
216
Greg Clayton58e26e02011-03-24 04:28:38 +0000217void
218Platform::GetStatus (Stream &strm)
219{
220 uint32_t major = UINT32_MAX;
221 uint32_t minor = UINT32_MAX;
222 uint32_t update = UINT32_MAX;
223 std::string s;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000224 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton58e26e02011-03-24 04:28:38 +0000225
226 ArchSpec arch (GetSystemArchitecture());
227 if (arch.IsValid())
228 {
229 if (!arch.GetTriple().str().empty())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000230 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000231 }
232
233 if (GetOSVersion(major, minor, update))
234 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000235 strm.Printf("OS Version: %u", major);
Greg Clayton58e26e02011-03-24 04:28:38 +0000236 if (minor != UINT32_MAX)
237 strm.Printf(".%u", minor);
238 if (update != UINT32_MAX)
239 strm.Printf(".%u", update);
240
241 if (GetOSBuildString (s))
242 strm.Printf(" (%s)", s.c_str());
243
244 strm.EOL();
245 }
246
247 if (GetOSKernelDescription (s))
Greg Clayton24bc5d92011-03-30 18:16:51 +0000248 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000249
250 if (IsHost())
251 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000252 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton58e26e02011-03-24 04:28:38 +0000253 }
254 else
255 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000256 const bool is_connected = IsConnected();
257 if (is_connected)
258 strm.Printf(" Hostname: %s\n", GetHostname());
259 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton58e26e02011-03-24 04:28:38 +0000260 }
261}
262
Greg Claytonb1888f22011-03-19 01:12:21 +0000263
264bool
265Platform::GetOSVersion (uint32_t &major,
266 uint32_t &minor,
267 uint32_t &update)
268{
269 bool success = m_major_os_version != UINT32_MAX;
270 if (IsHost())
271 {
272 if (!success)
273 {
274 // We have a local host platform
275 success = Host::GetOSVersion (m_major_os_version,
276 m_minor_os_version,
277 m_update_os_version);
278 m_os_version_set_while_connected = success;
279 }
280 }
281 else
282 {
283 // We have a remote platform. We can only fetch the remote
284 // OS version if we are connected, and we don't want to do it
285 // more than once.
286
287 const bool is_connected = IsConnected();
288
Greg Clayton58e26e02011-03-24 04:28:38 +0000289 bool fetch = false;
Greg Claytonb1888f22011-03-19 01:12:21 +0000290 if (success)
291 {
292 // We have valid OS version info, check to make sure it wasn't
293 // manually set prior to connecting. If it was manually set prior
294 // to connecting, then lets fetch the actual OS version info
295 // if we are now connected.
296 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton58e26e02011-03-24 04:28:38 +0000297 fetch = true;
Greg Claytonb1888f22011-03-19 01:12:21 +0000298 }
299 else
300 {
301 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton58e26e02011-03-24 04:28:38 +0000302 fetch = is_connected;
Greg Claytonb1888f22011-03-19 01:12:21 +0000303 }
304
Greg Clayton58e26e02011-03-24 04:28:38 +0000305 if (fetch)
Greg Claytonb1888f22011-03-19 01:12:21 +0000306 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000307 success = GetRemoteOSVersion ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000308 m_os_version_set_while_connected = success;
309 }
310 }
311
312 if (success)
313 {
314 major = m_major_os_version;
315 minor = m_minor_os_version;
316 update = m_update_os_version;
317 }
318 return success;
319}
Greg Clayton58e26e02011-03-24 04:28:38 +0000320
321bool
322Platform::GetOSBuildString (std::string &s)
323{
324 if (IsHost())
325 return Host::GetOSBuildString (s);
326 else
327 return GetRemoteOSBuildString (s);
328}
329
330bool
331Platform::GetOSKernelDescription (std::string &s)
332{
333 if (IsHost())
334 return Host::GetOSKernelDescription (s);
335 else
336 return GetRemoteOSKernelDescription (s);
337}
338
339const char *
Greg Claytonb72d0f02011-04-12 05:54:46 +0000340Platform::GetName ()
341{
342 const char *name = GetHostname();
343 if (name == NULL || name[0] == '\0')
344 name = GetShortPluginName();
345 return name;
346}
347
348const char *
Greg Clayton58e26e02011-03-24 04:28:38 +0000349Platform::GetHostname ()
350{
Greg Clayton5e342f52011-04-13 22:47:15 +0000351 if (IsHost())
352 return "localhost";
Greg Clayton24bc5d92011-03-30 18:16:51 +0000353
354 if (m_name.empty())
355 return NULL;
356 return m_name.c_str();
357}
358
359const char *
360Platform::GetUserName (uint32_t uid)
361{
362 const char *user_name = GetCachedUserName(uid);
363 if (user_name)
364 return user_name;
365 if (IsHost())
366 {
367 std::string name;
368 if (Host::GetUserName(uid, name))
369 return SetCachedUserName (uid, name.c_str(), name.size());
370 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000371 return NULL;
372}
373
Greg Clayton24bc5d92011-03-30 18:16:51 +0000374const char *
375Platform::GetGroupName (uint32_t gid)
376{
377 const char *group_name = GetCachedGroupName(gid);
378 if (group_name)
379 return group_name;
380 if (IsHost())
381 {
382 std::string name;
383 if (Host::GetGroupName(gid, name))
384 return SetCachedGroupName (gid, name.c_str(), name.size());
385 }
386 return NULL;
387}
Greg Clayton58e26e02011-03-24 04:28:38 +0000388
Greg Claytonb1888f22011-03-19 01:12:21 +0000389bool
390Platform::SetOSVersion (uint32_t major,
391 uint32_t minor,
392 uint32_t update)
393{
394 if (IsHost())
395 {
396 // We don't need anyone setting the OS version for the host platform,
397 // we should be able to figure it out by calling Host::GetOSVersion(...).
398 return false;
399 }
400 else
401 {
402 // We have a remote platform, allow setting the target OS version if
403 // we aren't connected, since if we are connected, we should be able to
404 // request the remote OS version from the connected platform.
405 if (IsConnected())
406 return false;
407 else
408 {
409 // We aren't connected and we might want to set the OS version
410 // ahead of time before we connect so we can peruse files and
411 // use a local SDK or PDK cache of support files to disassemble
412 // or do other things.
413 m_major_os_version = major;
414 m_minor_os_version = minor;
415 m_update_os_version = update;
416 return true;
417 }
418 }
419 return false;
420}
421
422
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000423Error
424Platform::ResolveExecutable (const FileSpec &exe_file,
425 const ArchSpec &exe_arch,
Greg Clayton9ce95382012-02-13 23:10:39 +0000426 lldb::ModuleSP &exe_module_sp,
427 const FileSpecList *module_search_paths_ptr)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000428{
429 Error error;
430 if (exe_file.Exists())
431 {
Greg Clayton444fe992012-02-26 05:51:37 +0000432 ModuleSpec module_spec (exe_file, exe_arch);
433 if (module_spec.GetArchitecture().IsValid())
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000434 {
Greg Clayton444fe992012-02-26 05:51:37 +0000435 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000436 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000437 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000438 NULL,
439 NULL);
440 }
441 else
442 {
443 // No valid architecture was specified, ask the platform for
444 // the architectures that we should be using (in the correct order)
445 // and see if we can find a match that way
Greg Clayton444fe992012-02-26 05:51:37 +0000446 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000447 {
Greg Clayton444fe992012-02-26 05:51:37 +0000448 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000449 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000450 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000451 NULL,
452 NULL);
453 // Did we find an executable using one of the
454 if (error.Success() && exe_module_sp)
455 break;
456 }
457 }
458 }
459 else
460 {
461 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
462 exe_file.GetDirectory().AsCString(""),
463 exe_file.GetDirectory() ? "/" : "",
464 exe_file.GetFilename().AsCString(""));
465 }
466 return error;
467}
468
Greg Clayton95b765e2012-09-12 02:03:59 +0000469Error
470Platform::ResolveSymbolFile (Target &target,
471 const ModuleSpec &sym_spec,
472 FileSpec &sym_file)
473{
474 Error error;
475 if (sym_spec.GetSymbolFileSpec().Exists())
476 sym_file = sym_spec.GetSymbolFileSpec();
477 else
478 error.SetErrorString("unable to resolve symbol file");
479 return error;
480
481}
482
483
484
Greg Claytonf2bf8702011-08-11 16:25:18 +0000485bool
486Platform::ResolveRemotePath (const FileSpec &platform_path,
487 FileSpec &resolved_platform_path)
488{
489 resolved_platform_path = platform_path;
490 return resolved_platform_path.ResolvePath();
491}
492
Greg Claytonb1888f22011-03-19 01:12:21 +0000493
494const ArchSpec &
495Platform::GetSystemArchitecture()
496{
497 if (IsHost())
498 {
499 if (!m_system_arch.IsValid())
500 {
501 // We have a local host platform
502 m_system_arch = Host::GetArchitecture();
503 m_system_arch_set_while_connected = m_system_arch.IsValid();
504 }
505 }
506 else
507 {
508 // We have a remote platform. We can only fetch the remote
509 // system architecture if we are connected, and we don't want to do it
510 // more than once.
511
512 const bool is_connected = IsConnected();
513
514 bool fetch = false;
515 if (m_system_arch.IsValid())
516 {
517 // We have valid OS version info, check to make sure it wasn't
518 // manually set prior to connecting. If it was manually set prior
519 // to connecting, then lets fetch the actual OS version info
520 // if we are now connected.
521 if (is_connected && !m_system_arch_set_while_connected)
522 fetch = true;
523 }
524 else
525 {
526 // We don't have valid OS version info, fetch it if we are connected
527 fetch = is_connected;
528 }
529
530 if (fetch)
531 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000532 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000533 m_system_arch_set_while_connected = m_system_arch.IsValid();
534 }
535 }
536 return m_system_arch;
537}
538
539
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000540Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000541Platform::ConnectRemote (Args& args)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000542{
543 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000544 if (IsHost())
545 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
546 else
547 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000548 return error;
549}
550
551Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000552Platform::DisconnectRemote ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000553{
554 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000555 if (IsHost())
556 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
557 else
558 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000559 return error;
560}
Greg Clayton24bc5d92011-03-30 18:16:51 +0000561
562bool
Greg Claytonb72d0f02011-04-12 05:54:46 +0000563Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000564{
565 // Take care of the host case so that each subclass can just
Greg Claytonb72d0f02011-04-12 05:54:46 +0000566 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000567 if (IsHost())
568 return Host::GetProcessInfo (pid, process_info);
569 return false;
570}
571
572uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +0000573Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
574 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000575{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000576 // Take care of the host case so that each subclass can just
577 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000578 uint32_t match_count = 0;
579 if (IsHost())
580 match_count = Host::FindProcesses (match_info, process_infos);
581 return match_count;
582}
Greg Claytonb72d0f02011-04-12 05:54:46 +0000583
584
585Error
586Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
587{
588 Error error;
589 // Take care of the host case so that each subclass can just
590 // call this function to get the host functionality.
591 if (IsHost())
Greg Claytondc0a38c2012-03-26 23:03:23 +0000592 {
593 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
594 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
595
596 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
597 {
598 const bool is_localhost = true;
Greg Clayton97471182012-04-14 01:42:46 +0000599 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
600 const bool first_arg_is_full_shell_command = false;
601 if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
602 is_localhost,
603 will_debug,
604 first_arg_is_full_shell_command))
Greg Claytondc0a38c2012-03-26 23:03:23 +0000605 return error;
606 }
607
Greg Claytonb72d0f02011-04-12 05:54:46 +0000608 error = Host::LaunchProcess (launch_info);
Greg Claytondc0a38c2012-03-26 23:03:23 +0000609 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000610 else
611 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
612 return error;
613}
614
615lldb::ProcessSP
616Platform::DebugProcess (ProcessLaunchInfo &launch_info,
617 Debugger &debugger,
618 Target *target, // Can be NULL, if NULL create a new target, else use existing one
619 Listener &listener,
620 Error &error)
621{
622 ProcessSP process_sp;
623 // Make sure we stop at the entry point
624 launch_info.GetFlags ().Set (eLaunchFlagDebug);
Jim Inghamb7b25322012-06-01 01:22:13 +0000625 // We always launch the process we are going to debug in a separate process
626 // group, since then we can handle ^C interrupts ourselves w/o having to worry
627 // about the target getting them as well.
628 launch_info.SetLaunchInSeparateProcessGroup(true);
629
Greg Claytonb72d0f02011-04-12 05:54:46 +0000630 error = LaunchProcess (launch_info);
631 if (error.Success())
632 {
Greg Clayton527154d2011-11-15 03:53:30 +0000633 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000634 {
Greg Clayton527154d2011-11-15 03:53:30 +0000635 ProcessAttachInfo attach_info (launch_info);
636 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytonffa43a62011-11-17 04:46:02 +0000637 if (process_sp)
638 {
639 // Since we attached to the process, it will think it needs to detach
640 // if the process object just goes away without an explicit call to
641 // Process::Kill() or Process::Detach(), so let it know to kill the
642 // process if this happens.
643 process_sp->SetShouldDetach (false);
Greg Clayton464c6162011-11-17 22:14:31 +0000644
645 // If we didn't have any file actions, the pseudo terminal might
646 // have been used where the slave side was given as the file to
647 // open for stdin/out/err after we have already opened the master
648 // so we can read/write stdin/out/err.
649 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
650 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
651 {
652 process_sp->SetSTDIOFileDescriptor(pty_fd);
653 }
Greg Claytonffa43a62011-11-17 04:46:02 +0000654 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000655 }
656 }
657 return process_sp;
658}
Greg Claytonb1db6582012-03-20 18:34:04 +0000659
660
661lldb::PlatformSP
Greg Claytonb170aee2012-05-08 01:45:38 +0000662Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000663{
664 lldb::PlatformSP platform_sp;
665 Error error;
666 if (arch.IsValid())
Greg Claytonb170aee2012-05-08 01:45:38 +0000667 platform_sp = Platform::Create (arch, platform_arch_ptr, error);
Greg Claytonb1db6582012-03-20 18:34:04 +0000668 return platform_sp;
669}
670
671
672//------------------------------------------------------------------
673/// Lets a platform answer if it is compatible with a given
674/// architecture and the target triple contained within.
675//------------------------------------------------------------------
676bool
Greg Claytonb170aee2012-05-08 01:45:38 +0000677Platform::IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr)
Greg Claytonb1db6582012-03-20 18:34:04 +0000678{
679 // If the architecture is invalid, we must answer true...
Greg Claytonb170aee2012-05-08 01:45:38 +0000680 if (arch.IsValid())
Greg Claytonb1db6582012-03-20 18:34:04 +0000681 {
Greg Claytonb170aee2012-05-08 01:45:38 +0000682 ArchSpec platform_arch;
683 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
684 {
685 if (arch == platform_arch)
686 {
687 if (compatible_arch_ptr)
688 *compatible_arch_ptr = platform_arch;
689 return true;
690 }
691 }
Greg Claytonb1db6582012-03-20 18:34:04 +0000692 }
Greg Claytonb170aee2012-05-08 01:45:38 +0000693 if (compatible_arch_ptr)
694 compatible_arch_ptr->Clear();
Greg Claytonb1db6582012-03-20 18:34:04 +0000695 return false;
696
697}
698
Greg Claytonbd5c23d2012-05-15 02:33:01 +0000699lldb::BreakpointSP
700Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
701{
702 return lldb::BreakpointSP();
703}
Greg Claytonb1db6582012-03-20 18:34:04 +0000704
Greg Clayton73844aa2012-08-22 17:17:09 +0000705size_t
706Platform::GetEnvironment (StringList &environment)
707{
708 environment.Clear();
709 return false;
710}
711