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