1 | //===-- Platform.h ----------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_TARGET_PLATFORM_H |
10 | #define LLDB_TARGET_PLATFORM_H |
11 | |
12 | #include <functional> |
13 | #include <map> |
14 | #include <memory> |
15 | #include <mutex> |
16 | #include <string> |
17 | #include <vector> |
18 | |
19 | #include "lldb/Core/PluginInterface.h" |
20 | #include "lldb/Core/UserSettingsController.h" |
21 | #include "lldb/Host/File.h" |
22 | #include "lldb/Interpreter/Options.h" |
23 | #include "lldb/Utility/ArchSpec.h" |
24 | #include "lldb/Utility/ConstString.h" |
25 | #include "lldb/Utility/FileSpec.h" |
26 | #include "lldb/Utility/StructuredData.h" |
27 | #include "lldb/Utility/Timeout.h" |
28 | #include "lldb/Utility/UserIDResolver.h" |
29 | #include "lldb/lldb-private-forward.h" |
30 | #include "lldb/lldb-public.h" |
31 | #include "llvm/Support/VersionTuple.h" |
32 | |
33 | namespace lldb_private { |
34 | |
35 | class ProcessInstanceInfo; |
36 | class ProcessInstanceInfoMatch; |
37 | typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; |
38 | |
39 | class ModuleCache; |
40 | enum MmapFlags { eMmapFlagsPrivate = 1, eMmapFlagsAnon = 2 }; |
41 | |
42 | class PlatformProperties : public Properties { |
43 | public: |
44 | PlatformProperties(); |
45 | |
46 | static ConstString GetSettingName(); |
47 | |
48 | bool GetUseModuleCache() const; |
49 | bool SetUseModuleCache(bool use_module_cache); |
50 | |
51 | FileSpec GetModuleCacheDirectory() const; |
52 | bool SetModuleCacheDirectory(const FileSpec &dir_spec); |
53 | |
54 | private: |
55 | void SetDefaultModuleCacheDirectory(const FileSpec &dir_spec); |
56 | }; |
57 | |
58 | typedef std::shared_ptr<PlatformProperties> PlatformPropertiesSP; |
59 | typedef llvm::SmallVector<lldb::addr_t, 6> MmapArgList; |
60 | |
61 | /// \class Platform Platform.h "lldb/Target/Platform.h" |
62 | /// A plug-in interface definition class for debug platform that |
63 | /// includes many platform abilities such as: |
64 | /// \li getting platform information such as supported architectures, |
65 | /// supported binary file formats and more |
66 | /// \li launching new processes |
67 | /// \li attaching to existing processes |
68 | /// \li download/upload files |
69 | /// \li execute shell commands |
70 | /// \li listing and getting info for existing processes |
71 | /// \li attaching and possibly debugging the platform's kernel |
72 | class Platform : public PluginInterface { |
73 | public: |
74 | /// Default Constructor |
75 | Platform(bool is_host_platform); |
76 | |
77 | /// Destructor. |
78 | /// |
79 | /// The destructor is virtual since this class is designed to be inherited |
80 | /// from by the plug-in instance. |
81 | ~Platform() override; |
82 | |
83 | static void Initialize(); |
84 | |
85 | static void Terminate(); |
86 | |
87 | static const PlatformPropertiesSP &GetGlobalPlatformProperties(); |
88 | |
89 | /// Get the native host platform plug-in. |
90 | /// |
91 | /// There should only be one of these for each host that LLDB runs upon that |
92 | /// should be statically compiled in and registered using preprocessor |
93 | /// macros or other similar build mechanisms in a |
94 | /// PlatformSubclass::Initialize() function. |
95 | /// |
96 | /// This platform will be used as the default platform when launching or |
97 | /// attaching to processes unless another platform is specified. |
98 | static lldb::PlatformSP GetHostPlatform(); |
99 | |
100 | static lldb::PlatformSP |
101 | GetPlatformForArchitecture(const ArchSpec &arch, ArchSpec *platform_arch_ptr); |
102 | |
103 | static const char *GetHostPlatformName(); |
104 | |
105 | static void SetHostPlatform(const lldb::PlatformSP &platform_sp); |
106 | |
107 | // Find an existing platform plug-in by name |
108 | static lldb::PlatformSP Find(ConstString name); |
109 | |
110 | static lldb::PlatformSP Create(ConstString name, Status &error); |
111 | |
112 | static lldb::PlatformSP Create(const ArchSpec &arch, |
113 | ArchSpec *platform_arch_ptr, Status &error); |
114 | |
115 | /// Augments the triple either with information from platform or the host |
116 | /// system (if platform is null). |
117 | static ArchSpec GetAugmentedArchSpec(Platform *platform, |
118 | llvm::StringRef triple); |
119 | |
120 | /// Find a platform plugin for a given process. |
121 | /// |
122 | /// Scans the installed Platform plug-ins and tries to find an instance that |
123 | /// can be used for \a process |
124 | /// |
125 | /// \param[in] process |
126 | /// The process for which to try and locate a platform |
127 | /// plug-in instance. |
128 | /// |
129 | /// \param[in] plugin_name |
130 | /// An optional name of a specific platform plug-in that |
131 | /// should be used. If nullptr, pick the best plug-in. |
132 | // static lldb::PlatformSP |
133 | // FindPlugin (Process *process, ConstString plugin_name); |
134 | |
135 | /// Set the target's executable based off of the existing architecture |
136 | /// information in \a target given a path to an executable \a exe_file. |
137 | /// |
138 | /// Each platform knows the architectures that it supports and can select |
139 | /// the correct architecture slice within \a exe_file by inspecting the |
140 | /// architecture in \a target. If the target had an architecture specified, |
141 | /// then in can try and obey that request and optionally fail if the |
142 | /// architecture doesn't match up. If no architecture is specified, the |
143 | /// platform should select the default architecture from \a exe_file. Any |
144 | /// application bundles or executable wrappers can also be inspected for the |
145 | /// actual application binary within the bundle that should be used. |
146 | /// |
147 | /// \return |
148 | /// Returns \b true if this Platform plug-in was able to find |
149 | /// a suitable executable, \b false otherwise. |
150 | virtual Status ResolveExecutable(const ModuleSpec &module_spec, |
151 | lldb::ModuleSP &module_sp, |
152 | const FileSpecList *module_search_paths_ptr); |
153 | |
154 | /// Find a symbol file given a symbol file module specification. |
155 | /// |
156 | /// Each platform might have tricks to find symbol files for an executable |
157 | /// given information in a symbol file ModuleSpec. Some platforms might also |
158 | /// support symbol files that are bundles and know how to extract the right |
159 | /// symbol file given a bundle. |
160 | /// |
161 | /// \param[in] target |
162 | /// The target in which we are trying to resolve the symbol file. |
163 | /// The target has a list of modules that we might be able to |
164 | /// use in order to help find the right symbol file. If the |
165 | /// "m_file" or "m_platform_file" entries in the \a sym_spec |
166 | /// are filled in, then we might be able to locate a module in |
167 | /// the target, extract its UUID and locate a symbol file. |
168 | /// If just the "m_uuid" is specified, then we might be able |
169 | /// to find the module in the target that matches that UUID |
170 | /// and pair the symbol file along with it. If just "m_symbol_file" |
171 | /// is specified, we can use a variety of tricks to locate the |
172 | /// symbols in an SDK, PDK, or other development kit location. |
173 | /// |
174 | /// \param[in] sym_spec |
175 | /// A module spec that describes some information about the |
176 | /// symbol file we are trying to resolve. The ModuleSpec might |
177 | /// contain the following: |
178 | /// m_file - A full or partial path to an executable from the |
179 | /// target (might be empty). |
180 | /// m_platform_file - Another executable hint that contains |
181 | /// the path to the file as known on the |
182 | /// local/remote platform. |
183 | /// m_symbol_file - A full or partial path to a symbol file |
184 | /// or symbol bundle that should be used when |
185 | /// trying to resolve the symbol file. |
186 | /// m_arch - The architecture we are looking for when resolving |
187 | /// the symbol file. |
188 | /// m_uuid - The UUID of the executable and symbol file. This |
189 | /// can often be used to match up an executable with |
190 | /// a symbol file, or resolve an symbol file in a |
191 | /// symbol file bundle. |
192 | /// |
193 | /// \param[out] sym_file |
194 | /// The resolved symbol file spec if the returned error |
195 | /// indicates success. |
196 | /// |
197 | /// \return |
198 | /// Returns an error that describes success or failure. |
199 | virtual Status ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, |
200 | FileSpec &sym_file); |
201 | |
202 | /// Resolves the FileSpec to a (possibly) remote path. Remote platforms must |
203 | /// override this to resolve to a path on the remote side. |
204 | virtual bool ResolveRemotePath(const FileSpec &platform_path, |
205 | FileSpec &resolved_platform_path); |
206 | |
207 | /// Get the OS version from a connected platform. |
208 | /// |
209 | /// Some platforms might not be connected to a remote platform, but can |
210 | /// figure out the OS version for a process. This is common for simulator |
211 | /// platforms that will run native programs on the current host, but the |
212 | /// simulator might be simulating a different OS. The \a process parameter |
213 | /// might be specified to help to determine the OS version. |
214 | virtual llvm::VersionTuple GetOSVersion(Process *process = nullptr); |
215 | |
216 | bool SetOSVersion(llvm::VersionTuple os_version); |
217 | |
218 | bool GetOSBuildString(std::string &s); |
219 | |
220 | bool GetOSKernelDescription(std::string &s); |
221 | |
222 | // Returns the name of the platform |
223 | ConstString GetName(); |
224 | |
225 | virtual const char *GetHostname(); |
226 | |
227 | virtual ConstString GetFullNameForDylib(ConstString basename); |
228 | |
229 | virtual const char *GetDescription() = 0; |
230 | |
231 | /// Report the current status for this platform. |
232 | /// |
233 | /// The returned string usually involves returning the OS version (if |
234 | /// available), and any SDK directory that might be being used for local |
235 | /// file caching, and if connected a quick blurb about what this platform is |
236 | /// connected to. |
237 | virtual void GetStatus(Stream &strm); |
238 | |
239 | // Subclasses must be able to fetch the current OS version |
240 | // |
241 | // Remote classes must be connected for this to succeed. Local subclasses |
242 | // don't need to override this function as it will just call the |
243 | // HostInfo::GetOSVersion(). |
244 | virtual bool GetRemoteOSVersion() { return false; } |
245 | |
246 | virtual bool GetRemoteOSBuildString(std::string &s) { |
247 | s.clear(); |
248 | return false; |
249 | } |
250 | |
251 | virtual bool GetRemoteOSKernelDescription(std::string &s) { |
252 | s.clear(); |
253 | return false; |
254 | } |
255 | |
256 | // Remote Platform subclasses need to override this function |
257 | virtual ArchSpec GetRemoteSystemArchitecture() { |
258 | return ArchSpec(); // Return an invalid architecture |
259 | } |
260 | |
261 | virtual FileSpec GetRemoteWorkingDirectory() { return m_working_dir; } |
262 | |
263 | virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir); |
264 | |
265 | virtual UserIDResolver &GetUserIDResolver() = 0; |
266 | |
267 | /// Locate a file for a platform. |
268 | /// |
269 | /// The default implementation of this function will return the same file |
270 | /// patch in \a local_file as was in \a platform_file. |
271 | /// |
272 | /// \param[in] platform_file |
273 | /// The platform file path to locate and cache locally. |
274 | /// |
275 | /// \param[in] uuid_ptr |
276 | /// If we know the exact UUID of the file we are looking for, it |
277 | /// can be specified. If it is not specified, we might now know |
278 | /// the exact file. The UUID is usually some sort of MD5 checksum |
279 | /// for the file and is sometimes known by dynamic linkers/loaders. |
280 | /// If the UUID is known, it is best to supply it to platform |
281 | /// file queries to ensure we are finding the correct file, not |
282 | /// just a file at the correct path. |
283 | /// |
284 | /// \param[out] local_file |
285 | /// A locally cached version of the platform file. For platforms |
286 | /// that describe the current host computer, this will just be |
287 | /// the same file. For remote platforms, this file might come from |
288 | /// and SDK directory, or might need to be sync'ed over to the |
289 | /// current machine for efficient debugging access. |
290 | /// |
291 | /// \return |
292 | /// An error object. |
293 | virtual Status GetFileWithUUID(const FileSpec &platform_file, |
294 | const UUID *uuid_ptr, FileSpec &local_file); |
295 | |
296 | // Locate the scripting resource given a module specification. |
297 | // |
298 | // Locating the file should happen only on the local computer or using the |
299 | // current computers global settings. |
300 | virtual FileSpecList |
301 | LocateExecutableScriptingResources(Target *target, Module &module, |
302 | Stream *feedback_stream); |
303 | |
304 | virtual Status GetSharedModule( |
305 | const ModuleSpec &module_spec, Process *process, |
306 | lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, |
307 | llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr); |
308 | |
309 | virtual bool GetModuleSpec(const FileSpec &module_file_spec, |
310 | const ArchSpec &arch, ModuleSpec &module_spec); |
311 | |
312 | virtual Status ConnectRemote(Args &args); |
313 | |
314 | virtual Status DisconnectRemote(); |
315 | |
316 | /// Get the platform's supported architectures in the order in which they |
317 | /// should be searched. |
318 | /// |
319 | /// \param[in] idx |
320 | /// A zero based architecture index |
321 | /// |
322 | /// \param[out] arch |
323 | /// A copy of the architecture at index if the return value is |
324 | /// \b true. |
325 | /// |
326 | /// \return |
327 | /// \b true if \a arch was filled in and is valid, \b false |
328 | /// otherwise. |
329 | virtual bool GetSupportedArchitectureAtIndex(uint32_t idx, |
330 | ArchSpec &arch) = 0; |
331 | |
332 | virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, |
333 | BreakpointSite *bp_site); |
334 | |
335 | /// Launch a new process on a platform, not necessarily for debugging, it |
336 | /// could be just for running the process. |
337 | virtual Status LaunchProcess(ProcessLaunchInfo &launch_info); |
338 | |
339 | /// Perform expansion of the command-line for this launch info This can |
340 | /// potentially involve wildcard expansion |
341 | /// environment variable replacement, and whatever other |
342 | /// argument magic the platform defines as part of its typical |
343 | /// user experience |
344 | virtual Status ShellExpandArguments(ProcessLaunchInfo &launch_info); |
345 | |
346 | /// Kill process on a platform. |
347 | virtual Status KillProcess(const lldb::pid_t pid); |
348 | |
349 | /// Lets a platform answer if it is compatible with a given architecture and |
350 | /// the target triple contained within. |
351 | virtual bool IsCompatibleArchitecture(const ArchSpec &arch, |
352 | bool exact_arch_match, |
353 | ArchSpec *compatible_arch_ptr); |
354 | |
355 | /// Not all platforms will support debugging a process by spawning somehow |
356 | /// halted for a debugger (specified using the "eLaunchFlagDebug" launch |
357 | /// flag) and then attaching. If your platform doesn't support this, |
358 | /// override this function and return false. |
359 | virtual bool CanDebugProcess() { return true; } |
360 | |
361 | /// Subclasses do not need to implement this function as it uses the |
362 | /// Platform::LaunchProcess() followed by Platform::Attach (). Remote |
363 | /// platforms will want to subclass this function in order to be able to |
364 | /// intercept STDIO and possibly launch a separate process that will debug |
365 | /// the debuggee. |
366 | virtual lldb::ProcessSP |
367 | DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, |
368 | Target *target, // Can be nullptr, if nullptr create a new |
369 | // target, else use existing one |
370 | Status &error); |
371 | |
372 | virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, |
373 | llvm::StringRef plugin_name, |
374 | Debugger &debugger, Target *target, |
375 | Status &error); |
376 | |
377 | virtual lldb::ProcessSP |
378 | ConnectProcessSynchronous(llvm::StringRef connect_url, |
379 | llvm::StringRef plugin_name, Debugger &debugger, |
380 | Stream &stream, Target *target, Status &error); |
381 | |
382 | /// Attach to an existing process using a process ID. |
383 | /// |
384 | /// Each platform subclass needs to implement this function and attempt to |
385 | /// attach to the process with the process ID of \a pid. The platform |
386 | /// subclass should return an appropriate ProcessSP subclass that is |
387 | /// attached to the process, or an empty shared pointer with an appropriate |
388 | /// error. |
389 | /// |
390 | /// \return |
391 | /// An appropriate ProcessSP containing a valid shared pointer |
392 | /// to the default Process subclass for the platform that is |
393 | /// attached to the process, or an empty shared pointer with an |
394 | /// appropriate error fill into the \a error object. |
395 | virtual lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, |
396 | Debugger &debugger, |
397 | Target *target, // Can be nullptr, if nullptr |
398 | // create a new target, else |
399 | // use existing one |
400 | Status &error) = 0; |
401 | |
402 | /// Attach to an existing process by process name. |
403 | /// |
404 | /// This function is not meant to be overridden by Process subclasses. It |
405 | /// will first call Process::WillAttach (const char *) and if that returns |
406 | /// \b true, Process::DoAttach (const char *) will be called to actually do |
407 | /// the attach. If DoAttach returns \b true, then Process::DidAttach() will |
408 | /// be called. |
409 | /// |
410 | /// \param[in] process_name |
411 | /// A process name to match against the current process list. |
412 | /// |
413 | /// \return |
414 | /// Returns \a pid if attaching was successful, or |
415 | /// LLDB_INVALID_PROCESS_ID if attaching fails. |
416 | // virtual lldb::ProcessSP |
417 | // Attach (const char *process_name, |
418 | // bool wait_for_launch, |
419 | // Status &error) = 0; |
420 | |
421 | // The base class Platform will take care of the host platform. Subclasses |
422 | // will need to fill in the remote case. |
423 | virtual uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, |
424 | ProcessInstanceInfoList &proc_infos); |
425 | |
426 | virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info); |
427 | |
428 | // Set a breakpoint on all functions that can end up creating a thread for |
429 | // this platform. This is needed when running expressions and also for |
430 | // process control. |
431 | virtual lldb::BreakpointSP SetThreadCreationBreakpoint(Target &target); |
432 | |
433 | // Given a target, find the local SDK directory if one exists on the current |
434 | // host. |
435 | virtual lldb_private::ConstString |
436 | GetSDKDirectory(lldb_private::Target &target) { |
437 | return lldb_private::ConstString(); |
438 | } |
439 | |
440 | const std::string &GetRemoteURL() const { return m_remote_url; } |
441 | |
442 | bool IsHost() const { |
443 | return m_is_host; // Is this the default host platform? |
444 | } |
445 | |
446 | bool IsRemote() const { return !m_is_host; } |
447 | |
448 | virtual bool IsConnected() const { |
449 | // Remote subclasses should override this function |
450 | return IsHost(); |
451 | } |
452 | |
453 | const ArchSpec &GetSystemArchitecture(); |
454 | |
455 | void SetSystemArchitecture(const ArchSpec &arch) { |
456 | m_system_arch = arch; |
457 | if (IsHost()) |
458 | m_os_version_set_while_connected = m_system_arch.IsValid(); |
459 | } |
460 | |
461 | /// If the triple contains not specify the vendor, os, and environment |
462 | /// parts, we "augment" these using information from the platform and return |
463 | /// the resulting ArchSpec object. |
464 | ArchSpec GetAugmentedArchSpec(llvm::StringRef triple); |
465 | |
466 | // Used for column widths |
467 | size_t GetMaxUserIDNameLength() const { return m_max_uid_name_len; } |
468 | |
469 | // Used for column widths |
470 | size_t GetMaxGroupIDNameLength() const { return m_max_gid_name_len; } |
471 | |
472 | ConstString GetSDKRootDirectory() const { return m_sdk_sysroot; } |
473 | |
474 | void SetSDKRootDirectory(ConstString dir) { m_sdk_sysroot = dir; } |
475 | |
476 | ConstString GetSDKBuild() const { return m_sdk_build; } |
477 | |
478 | void SetSDKBuild(ConstString sdk_build) { m_sdk_build = sdk_build; } |
479 | |
480 | // Override this to return true if your platform supports Clang modules. You |
481 | // may also need to override AddClangModuleCompilationOptions to pass the |
482 | // right Clang flags for your platform. |
483 | virtual bool SupportsModules() { return false; } |
484 | |
485 | // Appends the platform-specific options required to find the modules for the |
486 | // current platform. |
487 | virtual void |
488 | AddClangModuleCompilationOptions(Target *target, |
489 | std::vector<std::string> &options); |
490 | |
491 | FileSpec GetWorkingDirectory(); |
492 | |
493 | bool SetWorkingDirectory(const FileSpec &working_dir); |
494 | |
495 | // There may be modules that we don't want to find by default for operations |
496 | // like "setting breakpoint by name". The platform will return "true" from |
497 | // this call if the passed in module happens to be one of these. |
498 | |
499 | virtual bool |
500 | ModuleIsExcludedForUnconstrainedSearches(Target &target, |
501 | const lldb::ModuleSP &module_sp) { |
502 | return false; |
503 | } |
504 | |
505 | virtual Status MakeDirectory(const FileSpec &file_spec, uint32_t permissions); |
506 | |
507 | virtual Status GetFilePermissions(const FileSpec &file_spec, |
508 | uint32_t &file_permissions); |
509 | |
510 | virtual Status SetFilePermissions(const FileSpec &file_spec, |
511 | uint32_t file_permissions); |
512 | |
513 | virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, |
514 | File::OpenOptions flags, uint32_t mode, |
515 | Status &error) { |
516 | return UINT64_MAX; |
517 | } |
518 | |
519 | virtual bool CloseFile(lldb::user_id_t fd, Status &error) { return false; } |
520 | |
521 | virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec) { |
522 | return UINT64_MAX; |
523 | } |
524 | |
525 | virtual void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, |
526 | bool only_dir) {} |
527 | |
528 | virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, |
529 | uint64_t dst_len, Status &error) { |
530 | error.SetErrorStringWithFormat( |
531 | "Platform::ReadFile() is not supported in the %s platform" , |
532 | GetName().GetCString()); |
533 | return -1; |
534 | } |
535 | |
536 | virtual uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, |
537 | const void *src, uint64_t src_len, Status &error) { |
538 | error.SetErrorStringWithFormat( |
539 | "Platform::WriteFile() is not supported in the %s platform" , |
540 | GetName().GetCString()); |
541 | return -1; |
542 | } |
543 | |
544 | virtual Status GetFile(const FileSpec &source, const FileSpec &destination); |
545 | |
546 | virtual Status PutFile(const FileSpec &source, const FileSpec &destination, |
547 | uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX); |
548 | |
549 | virtual Status |
550 | CreateSymlink(const FileSpec &src, // The name of the link is in src |
551 | const FileSpec &dst); // The symlink points to dst |
552 | |
553 | /// Install a file or directory to the remote system. |
554 | /// |
555 | /// Install is similar to Platform::PutFile(), but it differs in that if an |
556 | /// application/framework/shared library is installed on a remote platform |
557 | /// and the remote platform requires something to be done to register the |
558 | /// application/framework/shared library, then this extra registration can |
559 | /// be done. |
560 | /// |
561 | /// \param[in] src |
562 | /// The source file/directory to install on the remote system. |
563 | /// |
564 | /// \param[in] dst |
565 | /// The destination file/directory where \a src will be installed. |
566 | /// If \a dst has no filename specified, then its filename will |
567 | /// be set from \a src. It \a dst has no directory specified, it |
568 | /// will use the platform working directory. If \a dst has a |
569 | /// directory specified, but the directory path is relative, the |
570 | /// platform working directory will be prepended to the relative |
571 | /// directory. |
572 | /// |
573 | /// \return |
574 | /// An error object that describes anything that went wrong. |
575 | virtual Status Install(const FileSpec &src, const FileSpec &dst); |
576 | |
577 | virtual Environment GetEnvironment(); |
578 | |
579 | virtual bool GetFileExists(const lldb_private::FileSpec &file_spec); |
580 | |
581 | virtual Status Unlink(const FileSpec &file_spec); |
582 | |
583 | virtual MmapArgList GetMmapArgumentList(const ArchSpec &arch, |
584 | lldb::addr_t addr, |
585 | lldb::addr_t length, |
586 | unsigned prot, unsigned flags, |
587 | lldb::addr_t fd, lldb::addr_t offset); |
588 | |
589 | virtual bool GetSupportsRSync() { return m_supports_rsync; } |
590 | |
591 | virtual void SetSupportsRSync(bool flag) { m_supports_rsync = flag; } |
592 | |
593 | virtual const char *GetRSyncOpts() { return m_rsync_opts.c_str(); } |
594 | |
595 | virtual void SetRSyncOpts(const char *opts) { m_rsync_opts.assign(opts); } |
596 | |
597 | virtual const char *GetRSyncPrefix() { return m_rsync_prefix.c_str(); } |
598 | |
599 | virtual void SetRSyncPrefix(const char *prefix) { |
600 | m_rsync_prefix.assign(prefix); |
601 | } |
602 | |
603 | virtual bool GetSupportsSSH() { return m_supports_ssh; } |
604 | |
605 | virtual void SetSupportsSSH(bool flag) { m_supports_ssh = flag; } |
606 | |
607 | virtual const char *GetSSHOpts() { return m_ssh_opts.c_str(); } |
608 | |
609 | virtual void SetSSHOpts(const char *opts) { m_ssh_opts.assign(opts); } |
610 | |
611 | virtual bool GetIgnoresRemoteHostname() { return m_ignores_remote_hostname; } |
612 | |
613 | virtual void SetIgnoresRemoteHostname(bool flag) { |
614 | m_ignores_remote_hostname = flag; |
615 | } |
616 | |
617 | virtual lldb_private::OptionGroupOptions * |
618 | GetConnectionOptions(CommandInterpreter &interpreter) { |
619 | return nullptr; |
620 | } |
621 | |
622 | virtual lldb_private::Status RunShellCommand( |
623 | llvm::StringRef command, |
624 | const FileSpec &working_dir, // Pass empty FileSpec to use the current |
625 | // working directory |
626 | int *status_ptr, // Pass nullptr if you don't want the process exit status |
627 | int *signo_ptr, // Pass nullptr if you don't want the signal that caused |
628 | // the process to exit |
629 | std::string |
630 | *command_output, // Pass nullptr if you don't want the command output |
631 | const Timeout<std::micro> &timeout); |
632 | |
633 | virtual lldb_private::Status RunShellCommand( |
634 | llvm::StringRef shell, llvm::StringRef command, |
635 | const FileSpec &working_dir, // Pass empty FileSpec to use the current |
636 | // working directory |
637 | int *status_ptr, // Pass nullptr if you don't want the process exit status |
638 | int *signo_ptr, // Pass nullptr if you don't want the signal that caused |
639 | // the process to exit |
640 | std::string |
641 | *command_output, // Pass nullptr if you don't want the command output |
642 | const Timeout<std::micro> &timeout); |
643 | |
644 | virtual void SetLocalCacheDirectory(const char *local); |
645 | |
646 | virtual const char *GetLocalCacheDirectory(); |
647 | |
648 | virtual std::string GetPlatformSpecificConnectionInformation() { return "" ; } |
649 | |
650 | virtual bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, |
651 | uint64_t &high); |
652 | |
653 | virtual uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { |
654 | return 1; |
655 | } |
656 | |
657 | virtual const lldb::UnixSignalsSP &GetRemoteUnixSignals(); |
658 | |
659 | lldb::UnixSignalsSP GetUnixSignals(); |
660 | |
661 | /// Locate a queue name given a thread's qaddr |
662 | /// |
663 | /// On a system using libdispatch ("Grand Central Dispatch") style queues, a |
664 | /// thread may be associated with a GCD queue or not, and a queue may be |
665 | /// associated with multiple threads. The process/thread must provide a way |
666 | /// to find the "dispatch_qaddr" for each thread, and from that |
667 | /// dispatch_qaddr this Platform method will locate the queue name and |
668 | /// provide that. |
669 | /// |
670 | /// \param[in] process |
671 | /// A process is required for reading memory. |
672 | /// |
673 | /// \param[in] dispatch_qaddr |
674 | /// The dispatch_qaddr for this thread. |
675 | /// |
676 | /// \return |
677 | /// The name of the queue, if there is one. An empty string |
678 | /// means that this thread is not associated with a dispatch |
679 | /// queue. |
680 | virtual std::string |
681 | GetQueueNameForThreadQAddress(Process *process, lldb::addr_t dispatch_qaddr) { |
682 | return "" ; |
683 | } |
684 | |
685 | /// Locate a queue ID given a thread's qaddr |
686 | /// |
687 | /// On a system using libdispatch ("Grand Central Dispatch") style queues, a |
688 | /// thread may be associated with a GCD queue or not, and a queue may be |
689 | /// associated with multiple threads. The process/thread must provide a way |
690 | /// to find the "dispatch_qaddr" for each thread, and from that |
691 | /// dispatch_qaddr this Platform method will locate the queue ID and provide |
692 | /// that. |
693 | /// |
694 | /// \param[in] process |
695 | /// A process is required for reading memory. |
696 | /// |
697 | /// \param[in] dispatch_qaddr |
698 | /// The dispatch_qaddr for this thread. |
699 | /// |
700 | /// \return |
701 | /// The queue_id for this thread, if this thread is associated |
702 | /// with a dispatch queue. Else LLDB_INVALID_QUEUE_ID is returned. |
703 | virtual lldb::queue_id_t |
704 | GetQueueIDForThreadQAddress(Process *process, lldb::addr_t dispatch_qaddr) { |
705 | return LLDB_INVALID_QUEUE_ID; |
706 | } |
707 | |
708 | /// Provide a list of trap handler function names for this platform |
709 | /// |
710 | /// The unwinder needs to treat trap handlers specially -- the stack frame |
711 | /// may not be aligned correctly for a trap handler (the kernel often won't |
712 | /// perturb the stack pointer, or won't re-align it properly, in the process |
713 | /// of calling the handler) and the frame above the handler needs to be |
714 | /// treated by the unwinder's "frame 0" rules instead of its "middle of the |
715 | /// stack frame" rules. |
716 | /// |
717 | /// In a user process debugging scenario, the list of trap handlers is |
718 | /// typically just "_sigtramp". |
719 | /// |
720 | /// The Platform base class provides the m_trap_handlers ivar but it does |
721 | /// not populate it. Subclasses should add the names of the asynchronous |
722 | /// signal handler routines as needed. For most Unix platforms, add |
723 | /// _sigtramp. |
724 | /// |
725 | /// \return |
726 | /// A list of symbol names. The list may be empty. |
727 | virtual const std::vector<ConstString> &GetTrapHandlerSymbolNames(); |
728 | |
729 | /// Find a support executable that may not live within in the standard |
730 | /// locations related to LLDB. |
731 | /// |
732 | /// Executable might exist within the Platform SDK directories, or in |
733 | /// standard tool directories within the current IDE that is running LLDB. |
734 | /// |
735 | /// \param[in] basename |
736 | /// The basename of the executable to locate in the current |
737 | /// platform. |
738 | /// |
739 | /// \return |
740 | /// A FileSpec pointing to the executable on disk, or an invalid |
741 | /// FileSpec if the executable cannot be found. |
742 | virtual FileSpec LocateExecutable(const char *basename) { return FileSpec(); } |
743 | |
744 | /// Allow the platform to set preferred memory cache line size. If non-zero |
745 | /// (and the user has not set cache line size explicitly), this value will |
746 | /// be used as the cache line size for memory reads. |
747 | virtual uint32_t GetDefaultMemoryCacheLineSize() { return 0; } |
748 | |
749 | /// Load a shared library into this process. |
750 | /// |
751 | /// Try and load a shared library into the current process. This call might |
752 | /// fail in the dynamic loader plug-in says it isn't safe to try and load |
753 | /// shared libraries at the moment. |
754 | /// |
755 | /// \param[in] process |
756 | /// The process to load the image. |
757 | /// |
758 | /// \param[in] local_file |
759 | /// The file spec that points to the shared library that you want |
760 | /// to load if the library is located on the host. The library will |
761 | /// be copied over to the location specified by remote_file or into |
762 | /// the current working directory with the same filename if the |
763 | /// remote_file isn't specified. |
764 | /// |
765 | /// \param[in] remote_file |
766 | /// If local_file is specified then the location where the library |
767 | /// should be copied over from the host. If local_file isn't |
768 | /// specified, then the path for the shared library on the target |
769 | /// what you want to load. |
770 | /// |
771 | /// \param[out] error |
772 | /// An error object that gets filled in with any errors that |
773 | /// might occur when trying to load the shared library. |
774 | /// |
775 | /// \return |
776 | /// A token that represents the shared library that can be |
777 | /// later used to unload the shared library. A value of |
778 | /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared |
779 | /// library can't be opened. |
780 | uint32_t LoadImage(lldb_private::Process *process, |
781 | const lldb_private::FileSpec &local_file, |
782 | const lldb_private::FileSpec &remote_file, |
783 | lldb_private::Status &error); |
784 | |
785 | /// Load a shared library specified by base name into this process, |
786 | /// looking by hand along a set of paths. |
787 | /// |
788 | /// \param[in] process |
789 | /// The process to load the image. |
790 | /// |
791 | /// \param[in] library_name |
792 | /// The name of the library to look for. If library_name is an |
793 | /// absolute path, the basename will be extracted and searched for |
794 | /// along the paths. This emulates the behavior of the loader when |
795 | /// given an install name and a set (e.g. DYLD_LIBRARY_PATH provided) of |
796 | /// alternate paths. |
797 | /// |
798 | /// \param[in] paths |
799 | /// The list of paths to use to search for the library. First |
800 | /// match wins. |
801 | /// |
802 | /// \param[out] error |
803 | /// An error object that gets filled in with any errors that |
804 | /// might occur when trying to load the shared library. |
805 | /// |
806 | /// \param[out] loaded_path |
807 | /// If non-null, the path to the dylib that was successfully loaded |
808 | /// is stored in this path. |
809 | /// |
810 | /// \return |
811 | /// A token that represents the shared library which can be |
812 | /// passed to UnloadImage. A value of |
813 | /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared |
814 | /// library can't be opened. |
815 | uint32_t LoadImageUsingPaths(lldb_private::Process *process, |
816 | const lldb_private::FileSpec &library_name, |
817 | const std::vector<std::string> &paths, |
818 | lldb_private::Status &error, |
819 | lldb_private::FileSpec *loaded_path); |
820 | |
821 | virtual uint32_t DoLoadImage(lldb_private::Process *process, |
822 | const lldb_private::FileSpec &remote_file, |
823 | const std::vector<std::string> *paths, |
824 | lldb_private::Status &error, |
825 | lldb_private::FileSpec *loaded_path = nullptr); |
826 | |
827 | virtual Status UnloadImage(lldb_private::Process *process, |
828 | uint32_t image_token); |
829 | |
830 | /// Connect to all processes waiting for a debugger to attach |
831 | /// |
832 | /// If the platform have a list of processes waiting for a debugger to |
833 | /// connect to them then connect to all of these pending processes. |
834 | /// |
835 | /// \param[in] debugger |
836 | /// The debugger used for the connect. |
837 | /// |
838 | /// \param[out] error |
839 | /// If an error occurred during the connect then this object will |
840 | /// contain the error message. |
841 | /// |
842 | /// \return |
843 | /// The number of processes we are successfully connected to. |
844 | virtual size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger, |
845 | lldb_private::Status &error); |
846 | |
847 | /// Gather all of crash informations into a structured data dictionary. |
848 | /// |
849 | /// If the platform have a crashed process with crash information entries, |
850 | /// gather all the entries into an structured data dictionary or return a |
851 | /// nullptr. This dictionary is generic and extensible, as it contains an |
852 | /// array for each different type of crash information. |
853 | /// |
854 | /// \param[in] process |
855 | /// The crashed process. |
856 | /// |
857 | /// \return |
858 | /// A structured data dictionary containing at each entry, the crash |
859 | /// information type as the entry key and the matching an array as the |
860 | /// entry value. \b nullptr if not implemented or if the process has no |
861 | /// crash information entry. \b error if an error occured. |
862 | virtual llvm::Expected<StructuredData::DictionarySP> |
863 | FetchExtendedCrashInformation(lldb_private::Process &process) { |
864 | return nullptr; |
865 | } |
866 | |
867 | protected: |
868 | /// Private implementation of connecting to a process. If the stream is set |
869 | /// we connect synchronously. |
870 | lldb::ProcessSP DoConnectProcess(llvm::StringRef connect_url, |
871 | llvm::StringRef plugin_name, |
872 | Debugger &debugger, Stream *stream, |
873 | Target *target, Status &error); |
874 | bool m_is_host; |
875 | // Set to true when we are able to actually set the OS version while being |
876 | // connected. For remote platforms, we might set the version ahead of time |
877 | // before we actually connect and this version might change when we actually |
878 | // connect to a remote platform. For the host platform this will be set to |
879 | // the once we call HostInfo::GetOSVersion(). |
880 | bool m_os_version_set_while_connected; |
881 | bool m_system_arch_set_while_connected; |
882 | ConstString |
883 | m_sdk_sysroot; // the root location of where the SDK files are all located |
884 | ConstString m_sdk_build; |
885 | FileSpec m_working_dir; // The working directory which is used when installing |
886 | // modules that have no install path set |
887 | std::string m_remote_url; |
888 | std::string m_name; |
889 | llvm::VersionTuple m_os_version; |
890 | ArchSpec |
891 | m_system_arch; // The architecture of the kernel or the remote platform |
892 | typedef std::map<uint32_t, ConstString> IDToNameMap; |
893 | // Mutex for modifying Platform data structures that should only be used for |
894 | // non-reentrant code |
895 | std::mutex m_mutex; |
896 | size_t m_max_uid_name_len; |
897 | size_t m_max_gid_name_len; |
898 | bool m_supports_rsync; |
899 | std::string m_rsync_opts; |
900 | std::string m_rsync_prefix; |
901 | bool m_supports_ssh; |
902 | std::string m_ssh_opts; |
903 | bool m_ignores_remote_hostname; |
904 | std::string m_local_cache_directory; |
905 | std::vector<ConstString> m_trap_handlers; |
906 | bool m_calculated_trap_handlers; |
907 | const std::unique_ptr<ModuleCache> m_module_cache; |
908 | |
909 | /// Ask the Platform subclass to fill in the list of trap handler names |
910 | /// |
911 | /// For most Unix user process environments, this will be a single function |
912 | /// name, _sigtramp. More specialized environments may have additional |
913 | /// handler names. The unwinder code needs to know when a trap handler is |
914 | /// on the stack because the unwind rules for the frame that caused the trap |
915 | /// are different. |
916 | /// |
917 | /// The base class Platform ivar m_trap_handlers should be updated by the |
918 | /// Platform subclass when this method is called. If there are no |
919 | /// predefined trap handlers, this method may be a no-op. |
920 | virtual void CalculateTrapHandlerSymbolNames() = 0; |
921 | |
922 | Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp, |
923 | const FileSpecList *module_search_paths_ptr, |
924 | Platform &remote_platform); |
925 | |
926 | virtual Status DownloadModuleSlice(const FileSpec &src_file_spec, |
927 | const uint64_t src_offset, |
928 | const uint64_t src_size, |
929 | const FileSpec &dst_file_spec); |
930 | |
931 | virtual Status DownloadSymbolFile(const lldb::ModuleSP &module_sp, |
932 | const FileSpec &dst_file_spec); |
933 | |
934 | virtual const char *GetCacheHostname(); |
935 | |
936 | private: |
937 | typedef std::function<Status(const ModuleSpec &)> ModuleResolver; |
938 | |
939 | Status GetRemoteSharedModule(const ModuleSpec &module_spec, Process *process, |
940 | lldb::ModuleSP &module_sp, |
941 | const ModuleResolver &module_resolver, |
942 | bool *did_create_ptr); |
943 | |
944 | bool GetCachedSharedModule(const ModuleSpec &module_spec, |
945 | lldb::ModuleSP &module_sp, bool *did_create_ptr); |
946 | |
947 | Status LoadCachedExecutable(const ModuleSpec &module_spec, |
948 | lldb::ModuleSP &module_sp, |
949 | const FileSpecList *module_search_paths_ptr, |
950 | Platform &remote_platform); |
951 | |
952 | FileSpec GetModuleCacheRoot(); |
953 | }; |
954 | |
955 | class PlatformList { |
956 | public: |
957 | PlatformList() : m_mutex(), m_platforms(), m_selected_platform_sp() {} |
958 | |
959 | ~PlatformList() = default; |
960 | |
961 | void Append(const lldb::PlatformSP &platform_sp, bool set_selected) { |
962 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
963 | m_platforms.push_back(platform_sp); |
964 | if (set_selected) |
965 | m_selected_platform_sp = m_platforms.back(); |
966 | } |
967 | |
968 | size_t GetSize() { |
969 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
970 | return m_platforms.size(); |
971 | } |
972 | |
973 | lldb::PlatformSP GetAtIndex(uint32_t idx) { |
974 | lldb::PlatformSP platform_sp; |
975 | { |
976 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
977 | if (idx < m_platforms.size()) |
978 | platform_sp = m_platforms[idx]; |
979 | } |
980 | return platform_sp; |
981 | } |
982 | |
983 | /// Select the active platform. |
984 | /// |
985 | /// In order to debug remotely, other platform's can be remotely connected |
986 | /// to and set as the selected platform for any subsequent debugging. This |
987 | /// allows connection to remote targets and allows the ability to discover |
988 | /// process info, launch and attach to remote processes. |
989 | lldb::PlatformSP GetSelectedPlatform() { |
990 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
991 | if (!m_selected_platform_sp && !m_platforms.empty()) |
992 | m_selected_platform_sp = m_platforms.front(); |
993 | |
994 | return m_selected_platform_sp; |
995 | } |
996 | |
997 | void SetSelectedPlatform(const lldb::PlatformSP &platform_sp) { |
998 | if (platform_sp) { |
999 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
1000 | const size_t num_platforms = m_platforms.size(); |
1001 | for (size_t idx = 0; idx < num_platforms; ++idx) { |
1002 | if (m_platforms[idx].get() == platform_sp.get()) { |
1003 | m_selected_platform_sp = m_platforms[idx]; |
1004 | return; |
1005 | } |
1006 | } |
1007 | m_platforms.push_back(platform_sp); |
1008 | m_selected_platform_sp = m_platforms.back(); |
1009 | } |
1010 | } |
1011 | |
1012 | protected: |
1013 | typedef std::vector<lldb::PlatformSP> collection; |
1014 | mutable std::recursive_mutex m_mutex; |
1015 | collection m_platforms; |
1016 | lldb::PlatformSP m_selected_platform_sp; |
1017 | |
1018 | private: |
1019 | PlatformList(const PlatformList &) = delete; |
1020 | const PlatformList &operator=(const PlatformList &) = delete; |
1021 | }; |
1022 | |
1023 | class OptionGroupPlatformRSync : public lldb_private::OptionGroup { |
1024 | public: |
1025 | OptionGroupPlatformRSync() = default; |
1026 | |
1027 | ~OptionGroupPlatformRSync() override = default; |
1028 | |
1029 | lldb_private::Status |
1030 | SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, |
1031 | ExecutionContext *execution_context) override; |
1032 | |
1033 | void OptionParsingStarting(ExecutionContext *execution_context) override; |
1034 | |
1035 | llvm::ArrayRef<OptionDefinition> GetDefinitions() override; |
1036 | |
1037 | // Instance variables to hold the values for command options. |
1038 | |
1039 | bool m_rsync; |
1040 | std::string m_rsync_opts; |
1041 | std::string m_rsync_prefix; |
1042 | bool m_ignores_remote_hostname; |
1043 | |
1044 | private: |
1045 | OptionGroupPlatformRSync(const OptionGroupPlatformRSync &) = delete; |
1046 | const OptionGroupPlatformRSync & |
1047 | operator=(const OptionGroupPlatformRSync &) = delete; |
1048 | }; |
1049 | |
1050 | class OptionGroupPlatformSSH : public lldb_private::OptionGroup { |
1051 | public: |
1052 | OptionGroupPlatformSSH() = default; |
1053 | |
1054 | ~OptionGroupPlatformSSH() override = default; |
1055 | |
1056 | lldb_private::Status |
1057 | SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, |
1058 | ExecutionContext *execution_context) override; |
1059 | |
1060 | void OptionParsingStarting(ExecutionContext *execution_context) override; |
1061 | |
1062 | llvm::ArrayRef<OptionDefinition> GetDefinitions() override; |
1063 | |
1064 | // Instance variables to hold the values for command options. |
1065 | |
1066 | bool m_ssh; |
1067 | std::string m_ssh_opts; |
1068 | |
1069 | private: |
1070 | OptionGroupPlatformSSH(const OptionGroupPlatformSSH &) = delete; |
1071 | const OptionGroupPlatformSSH & |
1072 | operator=(const OptionGroupPlatformSSH &) = delete; |
1073 | }; |
1074 | |
1075 | class OptionGroupPlatformCaching : public lldb_private::OptionGroup { |
1076 | public: |
1077 | OptionGroupPlatformCaching() = default; |
1078 | |
1079 | ~OptionGroupPlatformCaching() override = default; |
1080 | |
1081 | lldb_private::Status |
1082 | SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, |
1083 | ExecutionContext *execution_context) override; |
1084 | |
1085 | void OptionParsingStarting(ExecutionContext *execution_context) override; |
1086 | |
1087 | llvm::ArrayRef<OptionDefinition> GetDefinitions() override; |
1088 | |
1089 | // Instance variables to hold the values for command options. |
1090 | |
1091 | std::string m_cache_dir; |
1092 | |
1093 | private: |
1094 | OptionGroupPlatformCaching(const OptionGroupPlatformCaching &) = delete; |
1095 | const OptionGroupPlatformCaching & |
1096 | operator=(const OptionGroupPlatformCaching &) = delete; |
1097 | }; |
1098 | |
1099 | } // namespace lldb_private |
1100 | |
1101 | #endif // LLDB_TARGET_PLATFORM_H |
1102 | |