blob: 32ac194b66cba63e07740795a12b4307bba70111 [file] [log] [blame]
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001//===-- Platform.cpp --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Target/Platform.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Error.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Host/FileSpec.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000019#include "lldb/Host/Host.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000020#include "lldb/Target/Target.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
25// Use a singleton function for g_local_platform_sp to avoid init
26// constructors since LLDB is often part of a shared library
27static PlatformSP&
28GetDefaultPlatformSP ()
29{
30 static PlatformSP g_default_platform_sp;
31 return g_default_platform_sp;
32}
33
Greg Claytone4b9c1f2011-03-08 22:40:15 +000034static Mutex &
35GetConnectedPlatformListMutex ()
36{
37 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive);
38 return g_remote_connected_platforms_mutex;
39}
40static std::vector<PlatformSP> &
41GetConnectedPlatformList ()
42{
43 static std::vector<PlatformSP> g_remote_connected_platforms;
44 return g_remote_connected_platforms;
45}
46
47//------------------------------------------------------------------
48/// Get the native host platform plug-in.
49///
50/// There should only be one of these for each host that LLDB runs
51/// upon that should be statically compiled in and registered using
52/// preprocessor macros or other similar build mechanisms.
53///
54/// This platform will be used as the default platform when launching
55/// or attaching to processes unless another platform is specified.
56//------------------------------------------------------------------
57PlatformSP
58Platform::GetDefaultPlatform ()
59{
60 return GetDefaultPlatformSP ();
61}
62
63void
64Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp)
65{
66 // The native platform should use its static void Platform::Initialize()
67 // function to register itself as the native platform.
68 GetDefaultPlatformSP () = platform_sp;
69}
70
Greg Claytone4b9c1f2011-03-08 22:40:15 +000071Error
72Platform::GetFile (const FileSpec &platform_file, FileSpec &local_file)
73{
74 // Default to the local case
75 local_file = platform_file;
76 return Error();
77}
78
79
80PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +000081Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +000082{
83 PlatformCreateInstance create_callback = NULL;
84 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +000085 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +000086 {
87 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
88 if (create_callback)
Greg Claytone4b9c1f2011-03-08 22:40:15 +000089 platform_sp.reset(create_callback());
Greg Claytone4b9c1f2011-03-08 22:40:15 +000090 else
Greg Claytonb1888f22011-03-19 01:12:21 +000091 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +000092 }
93 else
Greg Claytonb1888f22011-03-19 01:12:21 +000094 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +000095 return platform_sp;
96}
97
98uint32_t
99Platform::GetNumConnectedRemotePlatforms ()
100{
101 Mutex::Locker locker (GetConnectedPlatformListMutex ());
102 return GetConnectedPlatformList().size();
103}
104
105PlatformSP
106Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
107{
108 PlatformSP platform_sp;
109 {
110 Mutex::Locker locker (GetConnectedPlatformListMutex ());
111 if (idx < GetConnectedPlatformList().size())
112 platform_sp = GetConnectedPlatformList ()[idx];
113 }
114 return platform_sp;
115}
116
117//------------------------------------------------------------------
118/// Default Constructor
119//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000120Platform::Platform (bool is_host) :
121 m_is_host (is_host),
122 m_is_connected (is_host), // If this is the default host platform, then we are always connected
123 m_os_version_set_while_connected (false),
124 m_system_arch_set_while_connected (false),
125 m_remote_url (),
126 m_major_os_version (UINT32_MAX),
127 m_minor_os_version (UINT32_MAX),
128 m_update_os_version (UINT32_MAX)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000129{
130}
131
132//------------------------------------------------------------------
133/// Destructor.
134///
135/// The destructor is virtual since this class is designed to be
136/// inherited from by the plug-in instance.
137//------------------------------------------------------------------
138Platform::~Platform()
139{
140}
141
Greg Claytonb1888f22011-03-19 01:12:21 +0000142
143bool
144Platform::GetOSVersion (uint32_t &major,
145 uint32_t &minor,
146 uint32_t &update)
147{
148 bool success = m_major_os_version != UINT32_MAX;
149 if (IsHost())
150 {
151 if (!success)
152 {
153 // We have a local host platform
154 success = Host::GetOSVersion (m_major_os_version,
155 m_minor_os_version,
156 m_update_os_version);
157 m_os_version_set_while_connected = success;
158 }
159 }
160 else
161 {
162 // We have a remote platform. We can only fetch the remote
163 // OS version if we are connected, and we don't want to do it
164 // more than once.
165
166 const bool is_connected = IsConnected();
167
168 bool fetch_os_version = false;
169 if (success)
170 {
171 // We have valid OS version info, check to make sure it wasn't
172 // manually set prior to connecting. If it was manually set prior
173 // to connecting, then lets fetch the actual OS version info
174 // if we are now connected.
175 if (is_connected && !m_os_version_set_while_connected)
176 fetch_os_version = true;
177 }
178 else
179 {
180 // We don't have valid OS version info, fetch it if we are connected
181 fetch_os_version = is_connected;
182 }
183
184 if (fetch_os_version)
185 {
186 success = FetchRemoteOSVersion ();
187 m_os_version_set_while_connected = success;
188 }
189 }
190
191 if (success)
192 {
193 major = m_major_os_version;
194 minor = m_minor_os_version;
195 update = m_update_os_version;
196 }
197 return success;
198}
199
200bool
201Platform::SetOSVersion (uint32_t major,
202 uint32_t minor,
203 uint32_t update)
204{
205 if (IsHost())
206 {
207 // We don't need anyone setting the OS version for the host platform,
208 // we should be able to figure it out by calling Host::GetOSVersion(...).
209 return false;
210 }
211 else
212 {
213 // We have a remote platform, allow setting the target OS version if
214 // we aren't connected, since if we are connected, we should be able to
215 // request the remote OS version from the connected platform.
216 if (IsConnected())
217 return false;
218 else
219 {
220 // We aren't connected and we might want to set the OS version
221 // ahead of time before we connect so we can peruse files and
222 // use a local SDK or PDK cache of support files to disassemble
223 // or do other things.
224 m_major_os_version = major;
225 m_minor_os_version = minor;
226 m_update_os_version = update;
227 return true;
228 }
229 }
230 return false;
231}
232
233
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000234Error
235Platform::ResolveExecutable (const FileSpec &exe_file,
236 const ArchSpec &exe_arch,
237 lldb::ModuleSP &exe_module_sp)
238{
239 Error error;
240 if (exe_file.Exists())
241 {
242 if (exe_arch.IsValid())
243 {
244 error = ModuleList::GetSharedModule (exe_file,
245 exe_arch,
246 NULL,
247 NULL,
248 0,
249 exe_module_sp,
250 NULL,
251 NULL);
252 }
253 else
254 {
255 // No valid architecture was specified, ask the platform for
256 // the architectures that we should be using (in the correct order)
257 // and see if we can find a match that way
258 ArchSpec platform_arch;
259 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
260 {
261 error = ModuleList::GetSharedModule (exe_file,
262 platform_arch,
263 NULL,
264 NULL,
265 0,
266 exe_module_sp,
267 NULL,
268 NULL);
269 // Did we find an executable using one of the
270 if (error.Success() && exe_module_sp)
271 break;
272 }
273 }
274 }
275 else
276 {
277 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
278 exe_file.GetDirectory().AsCString(""),
279 exe_file.GetDirectory() ? "/" : "",
280 exe_file.GetFilename().AsCString(""));
281 }
282 return error;
283}
284
Greg Claytonb1888f22011-03-19 01:12:21 +0000285
286const ArchSpec &
287Platform::GetSystemArchitecture()
288{
289 if (IsHost())
290 {
291 if (!m_system_arch.IsValid())
292 {
293 // We have a local host platform
294 m_system_arch = Host::GetArchitecture();
295 m_system_arch_set_while_connected = m_system_arch.IsValid();
296 }
297 }
298 else
299 {
300 // We have a remote platform. We can only fetch the remote
301 // system architecture if we are connected, and we don't want to do it
302 // more than once.
303
304 const bool is_connected = IsConnected();
305
306 bool fetch = false;
307 if (m_system_arch.IsValid())
308 {
309 // We have valid OS version info, check to make sure it wasn't
310 // manually set prior to connecting. If it was manually set prior
311 // to connecting, then lets fetch the actual OS version info
312 // if we are now connected.
313 if (is_connected && !m_system_arch_set_while_connected)
314 fetch = true;
315 }
316 else
317 {
318 // We don't have valid OS version info, fetch it if we are connected
319 fetch = is_connected;
320 }
321
322 if (fetch)
323 {
324 m_system_arch = FetchRemoteSystemArchitecture ();
325 m_system_arch_set_while_connected = m_system_arch.IsValid();
326 }
327 }
328 return m_system_arch;
329}
330
331
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000332Error
333Platform::ConnectRemote (const char *remote_url)
334{
335 Error error;
336 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
337 return error;
338}
339
340Error
341Platform::DisconnectRemote (const lldb::PlatformSP &platform_sp)
342{
343 Error error;
344 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
345 return error;
346}