blob: c1834d2bd87ae7b6cae83918354eb22ac97be7ce [file] [log] [blame]
Greg Claytone996fd32011-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 Clayton4116e932012-05-15 02:33:01 +000016#include "lldb/Breakpoint/BreakpointIDList.h"
Greg Claytone996fd32011-03-08 22:40:15 +000017#include "lldb/Core/Error.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000018#include "lldb/Core/Log.h"
Greg Clayton1f746072012-08-29 21:13:06 +000019#include "lldb/Core/ModuleSpec.h"
Greg Claytone996fd32011-03-08 22:40:15 +000020#include "lldb/Core/PluginManager.h"
21#include "lldb/Host/FileSpec.h"
Greg Claytonded470d2011-03-19 01:12:21 +000022#include "lldb/Host/Host.h"
Greg Clayton8b82f082011-04-12 05:54:46 +000023#include "lldb/Target/Process.h"
Greg Claytone996fd32011-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 Claytone996fd32011-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 Claytonab65b342011-04-13 22:47:15 +000051
52const char *
53Platform::GetHostPlatformName ()
54{
55 return "host";
56}
57
Greg Claytone996fd32011-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 Claytone996fd32011-03-08 22:40:15 +000082Error
Greg Claytond314e812011-03-23 00:09:55 +000083Platform::GetFile (const FileSpec &platform_file,
84 const UUID *uuid_ptr,
85 FileSpec &local_file)
Greg Claytone996fd32011-03-08 22:40:15 +000086{
87 // Default to the local case
88 local_file = platform_file;
89 return Error();
90}
91
Greg Clayton91c0e742013-01-11 23:44:27 +000092FileSpecList
93Platform::LocateExecutableScriptingResources (Target *target, Module &module)
Enrico Granata17598482012-11-08 02:22:02 +000094{
Greg Clayton91c0e742013-01-11 23:44:27 +000095 return FileSpecList();
Enrico Granata17598482012-11-08 02:22:02 +000096}
97
Jason Molenda1c627542013-04-05 01:03:25 +000098Platform*
99Platform::FindPlugin (Process *process, const char *plugin_name)
100{
101 PlatformCreateInstance create_callback = NULL;
102 if (plugin_name)
103 {
104 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name);
105 if (create_callback)
106 {
107 ArchSpec arch;
108 if (process)
109 {
110 arch = process->GetTarget().GetArchitecture();
111 }
Greg Clayton7b0992d2013-04-18 22:45:39 +0000112 std::unique_ptr<Platform> instance_ap(create_callback(process, &arch));
Jason Molenda1c627542013-04-05 01:03:25 +0000113 if (instance_ap.get())
114 return instance_ap.release();
115 }
116 }
117 else
118 {
119 for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != NULL; ++idx)
120 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000121 std::unique_ptr<Platform> instance_ap(create_callback(process, false));
Jason Molenda1c627542013-04-05 01:03:25 +0000122 if (instance_ap.get())
123 return instance_ap.release();
124 }
125 }
126 return NULL;
127}
128
Greg Clayton32e0a752011-03-30 18:16:51 +0000129Error
Greg Claytonb9a01b32012-02-26 05:51:37 +0000130Platform::GetSharedModule (const ModuleSpec &module_spec,
Greg Clayton32e0a752011-03-30 18:16:51 +0000131 ModuleSP &module_sp,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000132 const FileSpecList *module_search_paths_ptr,
Greg Clayton32e0a752011-03-30 18:16:51 +0000133 ModuleSP *old_module_sp_ptr,
134 bool *did_create_ptr)
135{
136 // Don't do any path remapping for the default implementation
137 // of the platform GetSharedModule function, just call through
138 // to our static ModuleList function. Platform subclasses that
139 // implement remote debugging, might have a developer kits
140 // installed that have cached versions of the files for the
141 // remote target, or might implement a download and cache
142 // locally implementation.
143 const bool always_create = false;
Greg Claytonb9a01b32012-02-26 05:51:37 +0000144 return ModuleList::GetSharedModule (module_spec,
Greg Clayton32e0a752011-03-30 18:16:51 +0000145 module_sp,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000146 module_search_paths_ptr,
Greg Clayton32e0a752011-03-30 18:16:51 +0000147 old_module_sp_ptr,
148 did_create_ptr,
149 always_create);
150}
151
Greg Claytone996fd32011-03-08 22:40:15 +0000152PlatformSP
Greg Claytonded470d2011-03-19 01:12:21 +0000153Platform::Create (const char *platform_name, Error &error)
Greg Claytone996fd32011-03-08 22:40:15 +0000154{
155 PlatformCreateInstance create_callback = NULL;
156 lldb::PlatformSP platform_sp;
Greg Claytonded470d2011-03-19 01:12:21 +0000157 if (platform_name && platform_name[0])
Greg Claytone996fd32011-03-08 22:40:15 +0000158 {
159 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
160 if (create_callback)
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000161 platform_sp.reset(create_callback(true, NULL));
Greg Claytone996fd32011-03-08 22:40:15 +0000162 else
Greg Claytonded470d2011-03-19 01:12:21 +0000163 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone996fd32011-03-08 22:40:15 +0000164 }
165 else
Greg Claytonded470d2011-03-19 01:12:21 +0000166 error.SetErrorString ("invalid platform name");
Greg Claytone996fd32011-03-08 22:40:15 +0000167 return platform_sp;
168}
169
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000170
171PlatformSP
Greg Clayton70512312012-05-08 01:45:38 +0000172Platform::Create (const ArchSpec &arch, ArchSpec *platform_arch_ptr, Error &error)
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000173{
174 lldb::PlatformSP platform_sp;
175 if (arch.IsValid())
176 {
Greg Clayton70512312012-05-08 01:45:38 +0000177 uint32_t idx;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000178 PlatformCreateInstance create_callback;
Greg Clayton1e0c8842013-01-11 20:49:54 +0000179 // First try exact arch matches across all platform plug-ins
180 bool exact = true;
Greg Clayton70512312012-05-08 01:45:38 +0000181 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000182 {
183 if (create_callback)
Greg Clayton1e0c8842013-01-11 20:49:54 +0000184 {
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000185 platform_sp.reset(create_callback(false, &arch));
Greg Clayton1e0c8842013-01-11 20:49:54 +0000186 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
187 return platform_sp;
188 }
189 }
190 // Next try compatible arch matches across all platform plug-ins
191 exact = false;
192 for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
193 {
194 if (create_callback)
195 {
196 platform_sp.reset(create_callback(false, &arch));
197 if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
198 return platform_sp;
199 }
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000200 }
201 }
202 else
203 error.SetErrorString ("invalid platform name");
Greg Clayton70512312012-05-08 01:45:38 +0000204 if (platform_arch_ptr)
205 platform_arch_ptr->Clear();
206 platform_sp.reset();
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000207 return platform_sp;
208}
209
Greg Claytone996fd32011-03-08 22:40:15 +0000210uint32_t
211Platform::GetNumConnectedRemotePlatforms ()
212{
213 Mutex::Locker locker (GetConnectedPlatformListMutex ());
214 return GetConnectedPlatformList().size();
215}
216
217PlatformSP
218Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
219{
220 PlatformSP platform_sp;
221 {
222 Mutex::Locker locker (GetConnectedPlatformListMutex ());
223 if (idx < GetConnectedPlatformList().size())
224 platform_sp = GetConnectedPlatformList ()[idx];
225 }
226 return platform_sp;
227}
228
229//------------------------------------------------------------------
230/// Default Constructor
231//------------------------------------------------------------------
Greg Claytonded470d2011-03-19 01:12:21 +0000232Platform::Platform (bool is_host) :
233 m_is_host (is_host),
Greg Claytonded470d2011-03-19 01:12:21 +0000234 m_os_version_set_while_connected (false),
235 m_system_arch_set_while_connected (false),
Greg Claytonf3dd93c2011-06-17 03:31:01 +0000236 m_sdk_sysroot (),
237 m_sdk_build (),
Greg Claytonded470d2011-03-19 01:12:21 +0000238 m_remote_url (),
Greg Clayton1cb64962011-03-24 04:28:38 +0000239 m_name (),
Greg Claytonded470d2011-03-19 01:12:21 +0000240 m_major_os_version (UINT32_MAX),
241 m_minor_os_version (UINT32_MAX),
Greg Clayton32e0a752011-03-30 18:16:51 +0000242 m_update_os_version (UINT32_MAX),
243 m_system_arch(),
244 m_uid_map_mutex (Mutex::eMutexTypeNormal),
245 m_gid_map_mutex (Mutex::eMutexTypeNormal),
246 m_uid_map(),
247 m_gid_map(),
248 m_max_uid_name_len (0),
249 m_max_gid_name_len (0)
Greg Claytone996fd32011-03-08 22:40:15 +0000250{
Greg Clayton5160ce52013-03-27 23:08:40 +0000251 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Greg Clayton8b82f082011-04-12 05:54:46 +0000252 if (log)
253 log->Printf ("%p Platform::Platform()", this);
Greg Claytone996fd32011-03-08 22:40:15 +0000254}
255
256//------------------------------------------------------------------
257/// Destructor.
258///
259/// The destructor is virtual since this class is designed to be
260/// inherited from by the plug-in instance.
261//------------------------------------------------------------------
262Platform::~Platform()
263{
Greg Clayton5160ce52013-03-27 23:08:40 +0000264 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Greg Clayton8b82f082011-04-12 05:54:46 +0000265 if (log)
266 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone996fd32011-03-08 22:40:15 +0000267}
268
Greg Clayton1cb64962011-03-24 04:28:38 +0000269void
270Platform::GetStatus (Stream &strm)
271{
272 uint32_t major = UINT32_MAX;
273 uint32_t minor = UINT32_MAX;
274 uint32_t update = UINT32_MAX;
275 std::string s;
Greg Clayton32e0a752011-03-30 18:16:51 +0000276 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton1cb64962011-03-24 04:28:38 +0000277
278 ArchSpec arch (GetSystemArchitecture());
279 if (arch.IsValid())
280 {
281 if (!arch.GetTriple().str().empty())
Greg Clayton32e0a752011-03-30 18:16:51 +0000282 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton1cb64962011-03-24 04:28:38 +0000283 }
284
285 if (GetOSVersion(major, minor, update))
286 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000287 strm.Printf("OS Version: %u", major);
Greg Clayton1cb64962011-03-24 04:28:38 +0000288 if (minor != UINT32_MAX)
289 strm.Printf(".%u", minor);
290 if (update != UINT32_MAX)
291 strm.Printf(".%u", update);
292
293 if (GetOSBuildString (s))
294 strm.Printf(" (%s)", s.c_str());
295
296 strm.EOL();
297 }
298
299 if (GetOSKernelDescription (s))
Greg Clayton32e0a752011-03-30 18:16:51 +0000300 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton1cb64962011-03-24 04:28:38 +0000301
302 if (IsHost())
303 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000304 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton1cb64962011-03-24 04:28:38 +0000305 }
306 else
307 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000308 const bool is_connected = IsConnected();
309 if (is_connected)
310 strm.Printf(" Hostname: %s\n", GetHostname());
311 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton1cb64962011-03-24 04:28:38 +0000312 }
313}
314
Greg Claytonded470d2011-03-19 01:12:21 +0000315
316bool
317Platform::GetOSVersion (uint32_t &major,
318 uint32_t &minor,
319 uint32_t &update)
320{
321 bool success = m_major_os_version != UINT32_MAX;
322 if (IsHost())
323 {
324 if (!success)
325 {
326 // We have a local host platform
327 success = Host::GetOSVersion (m_major_os_version,
328 m_minor_os_version,
329 m_update_os_version);
330 m_os_version_set_while_connected = success;
331 }
332 }
333 else
334 {
335 // We have a remote platform. We can only fetch the remote
336 // OS version if we are connected, and we don't want to do it
337 // more than once.
338
339 const bool is_connected = IsConnected();
340
Greg Clayton1cb64962011-03-24 04:28:38 +0000341 bool fetch = false;
Greg Claytonded470d2011-03-19 01:12:21 +0000342 if (success)
343 {
344 // We have valid OS version info, check to make sure it wasn't
345 // manually set prior to connecting. If it was manually set prior
346 // to connecting, then lets fetch the actual OS version info
347 // if we are now connected.
348 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton1cb64962011-03-24 04:28:38 +0000349 fetch = true;
Greg Claytonded470d2011-03-19 01:12:21 +0000350 }
351 else
352 {
353 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton1cb64962011-03-24 04:28:38 +0000354 fetch = is_connected;
Greg Claytonded470d2011-03-19 01:12:21 +0000355 }
356
Greg Clayton1cb64962011-03-24 04:28:38 +0000357 if (fetch)
Greg Claytonded470d2011-03-19 01:12:21 +0000358 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000359 success = GetRemoteOSVersion ();
Greg Claytonded470d2011-03-19 01:12:21 +0000360 m_os_version_set_while_connected = success;
361 }
362 }
363
364 if (success)
365 {
366 major = m_major_os_version;
367 minor = m_minor_os_version;
368 update = m_update_os_version;
369 }
370 return success;
371}
Greg Clayton1cb64962011-03-24 04:28:38 +0000372
373bool
374Platform::GetOSBuildString (std::string &s)
375{
376 if (IsHost())
377 return Host::GetOSBuildString (s);
378 else
379 return GetRemoteOSBuildString (s);
380}
381
382bool
383Platform::GetOSKernelDescription (std::string &s)
384{
385 if (IsHost())
386 return Host::GetOSKernelDescription (s);
387 else
388 return GetRemoteOSKernelDescription (s);
389}
390
391const char *
Greg Clayton8b82f082011-04-12 05:54:46 +0000392Platform::GetName ()
393{
394 const char *name = GetHostname();
395 if (name == NULL || name[0] == '\0')
396 name = GetShortPluginName();
397 return name;
398}
399
400const char *
Greg Clayton1cb64962011-03-24 04:28:38 +0000401Platform::GetHostname ()
402{
Greg Claytonab65b342011-04-13 22:47:15 +0000403 if (IsHost())
404 return "localhost";
Greg Clayton32e0a752011-03-30 18:16:51 +0000405
406 if (m_name.empty())
407 return NULL;
408 return m_name.c_str();
409}
410
411const char *
412Platform::GetUserName (uint32_t uid)
413{
414 const char *user_name = GetCachedUserName(uid);
415 if (user_name)
416 return user_name;
417 if (IsHost())
418 {
419 std::string name;
420 if (Host::GetUserName(uid, name))
421 return SetCachedUserName (uid, name.c_str(), name.size());
422 }
Greg Clayton1cb64962011-03-24 04:28:38 +0000423 return NULL;
424}
425
Greg Clayton32e0a752011-03-30 18:16:51 +0000426const char *
427Platform::GetGroupName (uint32_t gid)
428{
429 const char *group_name = GetCachedGroupName(gid);
430 if (group_name)
431 return group_name;
432 if (IsHost())
433 {
434 std::string name;
435 if (Host::GetGroupName(gid, name))
436 return SetCachedGroupName (gid, name.c_str(), name.size());
437 }
438 return NULL;
439}
Greg Clayton1cb64962011-03-24 04:28:38 +0000440
Greg Claytonded470d2011-03-19 01:12:21 +0000441bool
442Platform::SetOSVersion (uint32_t major,
443 uint32_t minor,
444 uint32_t update)
445{
446 if (IsHost())
447 {
448 // We don't need anyone setting the OS version for the host platform,
449 // we should be able to figure it out by calling Host::GetOSVersion(...).
450 return false;
451 }
452 else
453 {
454 // We have a remote platform, allow setting the target OS version if
455 // we aren't connected, since if we are connected, we should be able to
456 // request the remote OS version from the connected platform.
457 if (IsConnected())
458 return false;
459 else
460 {
461 // We aren't connected and we might want to set the OS version
462 // ahead of time before we connect so we can peruse files and
463 // use a local SDK or PDK cache of support files to disassemble
464 // or do other things.
465 m_major_os_version = major;
466 m_minor_os_version = minor;
467 m_update_os_version = update;
468 return true;
469 }
470 }
471 return false;
472}
473
474
Greg Claytone996fd32011-03-08 22:40:15 +0000475Error
476Platform::ResolveExecutable (const FileSpec &exe_file,
477 const ArchSpec &exe_arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000478 lldb::ModuleSP &exe_module_sp,
479 const FileSpecList *module_search_paths_ptr)
Greg Claytone996fd32011-03-08 22:40:15 +0000480{
481 Error error;
482 if (exe_file.Exists())
483 {
Greg Claytonb9a01b32012-02-26 05:51:37 +0000484 ModuleSpec module_spec (exe_file, exe_arch);
485 if (module_spec.GetArchitecture().IsValid())
Greg Claytone996fd32011-03-08 22:40:15 +0000486 {
Greg Claytonb9a01b32012-02-26 05:51:37 +0000487 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone996fd32011-03-08 22:40:15 +0000488 exe_module_sp,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000489 module_search_paths_ptr,
Greg Claytone996fd32011-03-08 22:40:15 +0000490 NULL,
491 NULL);
492 }
493 else
494 {
495 // No valid architecture was specified, ask the platform for
496 // the architectures that we should be using (in the correct order)
497 // and see if we can find a match that way
Greg Claytonb9a01b32012-02-26 05:51:37 +0000498 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
Greg Claytone996fd32011-03-08 22:40:15 +0000499 {
Greg Claytonb9a01b32012-02-26 05:51:37 +0000500 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone996fd32011-03-08 22:40:15 +0000501 exe_module_sp,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000502 module_search_paths_ptr,
Greg Claytone996fd32011-03-08 22:40:15 +0000503 NULL,
504 NULL);
505 // Did we find an executable using one of the
506 if (error.Success() && exe_module_sp)
507 break;
508 }
509 }
510 }
511 else
512 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000513 error.SetErrorStringWithFormat ("'%s' does not exist",
514 exe_file.GetPath().c_str());
Greg Claytone996fd32011-03-08 22:40:15 +0000515 }
516 return error;
517}
518
Greg Clayton103f0282012-09-12 02:03:59 +0000519Error
520Platform::ResolveSymbolFile (Target &target,
521 const ModuleSpec &sym_spec,
522 FileSpec &sym_file)
523{
524 Error error;
525 if (sym_spec.GetSymbolFileSpec().Exists())
526 sym_file = sym_spec.GetSymbolFileSpec();
527 else
528 error.SetErrorString("unable to resolve symbol file");
529 return error;
530
531}
532
533
534
Greg Claytonaa516842011-08-11 16:25:18 +0000535bool
536Platform::ResolveRemotePath (const FileSpec &platform_path,
537 FileSpec &resolved_platform_path)
538{
539 resolved_platform_path = platform_path;
540 return resolved_platform_path.ResolvePath();
541}
542
Greg Claytonded470d2011-03-19 01:12:21 +0000543
544const ArchSpec &
545Platform::GetSystemArchitecture()
546{
547 if (IsHost())
548 {
549 if (!m_system_arch.IsValid())
550 {
551 // We have a local host platform
552 m_system_arch = Host::GetArchitecture();
553 m_system_arch_set_while_connected = m_system_arch.IsValid();
554 }
555 }
556 else
557 {
558 // We have a remote platform. We can only fetch the remote
559 // system architecture if we are connected, and we don't want to do it
560 // more than once.
561
562 const bool is_connected = IsConnected();
563
564 bool fetch = false;
565 if (m_system_arch.IsValid())
566 {
567 // We have valid OS version info, check to make sure it wasn't
568 // manually set prior to connecting. If it was manually set prior
569 // to connecting, then lets fetch the actual OS version info
570 // if we are now connected.
571 if (is_connected && !m_system_arch_set_while_connected)
572 fetch = true;
573 }
574 else
575 {
576 // We don't have valid OS version info, fetch it if we are connected
577 fetch = is_connected;
578 }
579
580 if (fetch)
581 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000582 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonded470d2011-03-19 01:12:21 +0000583 m_system_arch_set_while_connected = m_system_arch.IsValid();
584 }
585 }
586 return m_system_arch;
587}
588
589
Greg Claytone996fd32011-03-08 22:40:15 +0000590Error
Greg Claytond314e812011-03-23 00:09:55 +0000591Platform::ConnectRemote (Args& args)
Greg Claytone996fd32011-03-08 22:40:15 +0000592{
593 Error error;
Greg Claytond314e812011-03-23 00:09:55 +0000594 if (IsHost())
595 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
596 else
597 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone996fd32011-03-08 22:40:15 +0000598 return error;
599}
600
601Error
Greg Claytond314e812011-03-23 00:09:55 +0000602Platform::DisconnectRemote ()
Greg Claytone996fd32011-03-08 22:40:15 +0000603{
604 Error error;
Greg Claytond314e812011-03-23 00:09:55 +0000605 if (IsHost())
606 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
607 else
608 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone996fd32011-03-08 22:40:15 +0000609 return error;
610}
Greg Clayton32e0a752011-03-30 18:16:51 +0000611
612bool
Greg Clayton8b82f082011-04-12 05:54:46 +0000613Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton32e0a752011-03-30 18:16:51 +0000614{
615 // Take care of the host case so that each subclass can just
Greg Clayton8b82f082011-04-12 05:54:46 +0000616 // call this function to get the host functionality.
Greg Clayton32e0a752011-03-30 18:16:51 +0000617 if (IsHost())
618 return Host::GetProcessInfo (pid, process_info);
619 return false;
620}
621
622uint32_t
Greg Clayton8b82f082011-04-12 05:54:46 +0000623Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
624 ProcessInstanceInfoList &process_infos)
Greg Clayton32e0a752011-03-30 18:16:51 +0000625{
Greg Clayton8b82f082011-04-12 05:54:46 +0000626 // Take care of the host case so that each subclass can just
627 // call this function to get the host functionality.
Greg Clayton32e0a752011-03-30 18:16:51 +0000628 uint32_t match_count = 0;
629 if (IsHost())
630 match_count = Host::FindProcesses (match_info, process_infos);
631 return match_count;
632}
Greg Clayton8b82f082011-04-12 05:54:46 +0000633
634
635Error
636Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
637{
638 Error error;
639 // Take care of the host case so that each subclass can just
640 // call this function to get the host functionality.
641 if (IsHost())
Greg Clayton84db9102012-03-26 23:03:23 +0000642 {
643 if (::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY"))
644 launch_info.GetFlags().Set (eLaunchFlagLaunchInTTY);
645
646 if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
647 {
648 const bool is_localhost = true;
Greg Claytond1cf11a2012-04-14 01:42:46 +0000649 const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
650 const bool first_arg_is_full_shell_command = false;
651 if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
652 is_localhost,
653 will_debug,
654 first_arg_is_full_shell_command))
Greg Clayton84db9102012-03-26 23:03:23 +0000655 return error;
656 }
657
Greg Clayton8b82f082011-04-12 05:54:46 +0000658 error = Host::LaunchProcess (launch_info);
Greg Clayton84db9102012-03-26 23:03:23 +0000659 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000660 else
661 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
662 return error;
663}
664
665lldb::ProcessSP
666Platform::DebugProcess (ProcessLaunchInfo &launch_info,
667 Debugger &debugger,
668 Target *target, // Can be NULL, if NULL create a new target, else use existing one
669 Listener &listener,
670 Error &error)
671{
672 ProcessSP process_sp;
673 // Make sure we stop at the entry point
674 launch_info.GetFlags ().Set (eLaunchFlagDebug);
Jim Inghamb4451b12012-06-01 01:22:13 +0000675 // We always launch the process we are going to debug in a separate process
676 // group, since then we can handle ^C interrupts ourselves w/o having to worry
677 // about the target getting them as well.
678 launch_info.SetLaunchInSeparateProcessGroup(true);
679
Greg Clayton8b82f082011-04-12 05:54:46 +0000680 error = LaunchProcess (launch_info);
681 if (error.Success())
682 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000683 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Clayton8b82f082011-04-12 05:54:46 +0000684 {
Greg Clayton144f3a92011-11-15 03:53:30 +0000685 ProcessAttachInfo attach_info (launch_info);
686 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytone24c4ac2011-11-17 04:46:02 +0000687 if (process_sp)
688 {
689 // Since we attached to the process, it will think it needs to detach
690 // if the process object just goes away without an explicit call to
691 // Process::Kill() or Process::Detach(), so let it know to kill the
692 // process if this happens.
693 process_sp->SetShouldDetach (false);
Greg Claytonee95ed52011-11-17 22:14:31 +0000694
695 // If we didn't have any file actions, the pseudo terminal might
696 // have been used where the slave side was given as the file to
697 // open for stdin/out/err after we have already opened the master
698 // so we can read/write stdin/out/err.
699 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
700 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
701 {
702 process_sp->SetSTDIOFileDescriptor(pty_fd);
703 }
Greg Claytone24c4ac2011-11-17 04:46:02 +0000704 }
Greg Clayton8b82f082011-04-12 05:54:46 +0000705 }
706 }
707 return process_sp;
708}
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000709
710
711lldb::PlatformSP
Greg Clayton70512312012-05-08 01:45:38 +0000712Platform::GetPlatformForArchitecture (const ArchSpec &arch, ArchSpec *platform_arch_ptr)
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000713{
714 lldb::PlatformSP platform_sp;
715 Error error;
716 if (arch.IsValid())
Greg Clayton70512312012-05-08 01:45:38 +0000717 platform_sp = Platform::Create (arch, platform_arch_ptr, error);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000718 return platform_sp;
719}
720
721
722//------------------------------------------------------------------
723/// Lets a platform answer if it is compatible with a given
724/// architecture and the target triple contained within.
725//------------------------------------------------------------------
726bool
Greg Clayton1e0c8842013-01-11 20:49:54 +0000727Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr)
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000728{
729 // If the architecture is invalid, we must answer true...
Greg Clayton70512312012-05-08 01:45:38 +0000730 if (arch.IsValid())
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000731 {
Greg Clayton70512312012-05-08 01:45:38 +0000732 ArchSpec platform_arch;
Greg Clayton1e0c8842013-01-11 20:49:54 +0000733 // Try for an exact architecture match first.
734 if (exact_arch_match)
Greg Clayton70512312012-05-08 01:45:38 +0000735 {
Greg Clayton1e0c8842013-01-11 20:49:54 +0000736 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
Greg Clayton70512312012-05-08 01:45:38 +0000737 {
Greg Clayton1e0c8842013-01-11 20:49:54 +0000738 if (arch.IsExactMatch(platform_arch))
739 {
740 if (compatible_arch_ptr)
741 *compatible_arch_ptr = platform_arch;
742 return true;
743 }
744 }
745 }
746 else
747 {
748 for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
749 {
750 if (arch.IsCompatibleMatch(platform_arch))
751 {
752 if (compatible_arch_ptr)
753 *compatible_arch_ptr = platform_arch;
754 return true;
755 }
Greg Clayton70512312012-05-08 01:45:38 +0000756 }
757 }
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000758 }
Greg Clayton70512312012-05-08 01:45:38 +0000759 if (compatible_arch_ptr)
760 compatible_arch_ptr->Clear();
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000761 return false;
762
763}
764
Greg Clayton1e0c8842013-01-11 20:49:54 +0000765
Greg Clayton4116e932012-05-15 02:33:01 +0000766lldb::BreakpointSP
767Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
768{
769 return lldb::BreakpointSP();
770}
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000771
Greg Clayton67cc0632012-08-22 17:17:09 +0000772size_t
773Platform::GetEnvironment (StringList &environment)
774{
775 environment.Clear();
776 return false;
777}
778