1 | //===-- TargetList.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_TARGETLIST_H |
10 | #define LLDB_TARGET_TARGETLIST_H |
11 | |
12 | #include <mutex> |
13 | #include <vector> |
14 | |
15 | #include "lldb/Target/Target.h" |
16 | #include "lldb/Utility/Broadcaster.h" |
17 | #include "lldb/Utility/Iterable.h" |
18 | |
19 | namespace lldb_private { |
20 | |
21 | class TargetList : public Broadcaster { |
22 | private: |
23 | friend class Debugger; |
24 | |
25 | /// Constructor |
26 | /// |
27 | /// The constructor for the target list is private. Clients can |
28 | /// get ahold of the one and only target list through the |
29 | /// lldb_private::Debugger::GetSharedInstance().GetTargetList(). |
30 | /// |
31 | /// \see static TargetList& lldb_private::Debugger::GetTargetList(). |
32 | TargetList(Debugger &debugger); |
33 | |
34 | public: |
35 | /// Broadcaster event bits definitions. |
36 | enum { eBroadcastBitInterrupt = (1 << 0) }; |
37 | |
38 | // These two functions fill out the Broadcaster interface: |
39 | |
40 | static ConstString &GetStaticBroadcasterClass(); |
41 | |
42 | ConstString &GetBroadcasterClass() const override { |
43 | return GetStaticBroadcasterClass(); |
44 | } |
45 | |
46 | typedef std::vector<lldb::TargetSP> collection; |
47 | typedef LockingAdaptedIterable<collection, lldb::TargetSP, vector_adapter, |
48 | std::recursive_mutex> |
49 | TargetIterable; |
50 | |
51 | /// Create a new Target. |
52 | /// |
53 | /// Clients must use this function to create a Target. This allows |
54 | /// a global list of targets to be maintained in a central location |
55 | /// so signal handlers and other global functions can use it to |
56 | /// locate an appropriate target to deliver asynchronous information |
57 | /// to. |
58 | /// |
59 | /// \param[in] debugger |
60 | /// The debugger to associate this target with |
61 | /// |
62 | /// \param[in] user_exe_path |
63 | /// The main executable file for a debug target. This value |
64 | /// can be empty and the file can be set later using: |
65 | /// Target::SetExecutableModule (ModuleSP&) |
66 | /// |
67 | /// \param[in] triple_str |
68 | /// A target triple string to be used for the target. This can |
69 | /// be nullptr if the triple is not known or when attaching to a |
70 | /// process. |
71 | /// |
72 | /// \param[in] get_dependent_modules |
73 | /// Track down the dependent modules for an executable and |
74 | /// load those into the module list. |
75 | /// |
76 | /// \param[in] platform_options |
77 | /// A pointer to the platform options to use when creating this |
78 | /// target. If this value is nullptr, then the currently selected |
79 | /// platform will be used. |
80 | /// |
81 | /// \param[out] target_sp |
82 | /// A shared pointer to a target that will be filled in if |
83 | /// this call is successful. |
84 | /// |
85 | /// \return |
86 | /// An error object that indicates success or failure |
87 | Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, |
88 | llvm::StringRef triple_str, |
89 | LoadDependentFiles get_dependent_modules, |
90 | const OptionGroupPlatform *platform_options, |
91 | lldb::TargetSP &target_sp); |
92 | |
93 | /// Create a new Target. |
94 | /// |
95 | /// Same as the function above, but used when you already know the |
96 | /// platform you will be using |
97 | Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, |
98 | const ArchSpec &arch, |
99 | LoadDependentFiles get_dependent_modules, |
100 | lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp); |
101 | |
102 | /// Delete a Target object from the list. |
103 | /// |
104 | /// When clients are done with the Target objects, this function |
105 | /// should be called to release the memory associated with a target |
106 | /// object. |
107 | /// |
108 | /// \param[in] target_sp |
109 | /// The shared pointer to a target. |
110 | /// |
111 | /// \return |
112 | /// Returns \b true if the target was successfully removed from |
113 | /// from this target list, \b false otherwise. The client will |
114 | /// be left with the last remaining shared pointer to the target |
115 | /// in \a target_sp which can then be properly released. |
116 | bool DeleteTarget(lldb::TargetSP &target_sp); |
117 | |
118 | size_t GetNumTargets() const; |
119 | |
120 | lldb::TargetSP GetTargetAtIndex(uint32_t index) const; |
121 | |
122 | uint32_t GetIndexOfTarget(lldb::TargetSP target_sp) const; |
123 | |
124 | /// Find the target that contains has an executable whose path |
125 | /// matches \a exe_file_spec, and whose architecture matches |
126 | /// \a arch_ptr if arch_ptr is not nullptr. |
127 | /// |
128 | /// \param[in] exe_file_spec |
129 | /// A file spec containing a basename, or a full path (directory |
130 | /// and basename). If \a exe_file_spec contains only a filename |
131 | /// (empty GetDirectory() value) then matching will be done |
132 | /// solely based on the filenames and directories won't be |
133 | /// compared. If \a exe_file_spec contains a filename and a |
134 | /// directory, then both must match. |
135 | /// |
136 | /// \param[in] exe_arch_ptr |
137 | /// If not nullptr then the architecture also needs to match, else |
138 | /// the architectures will be compared. |
139 | /// |
140 | /// \return |
141 | /// A shared pointer to a target object. The returned shared |
142 | /// pointer will contain nullptr if no target objects have a |
143 | /// executable whose full or partial path matches |
144 | /// with a matching process ID. |
145 | lldb::TargetSP FindTargetWithExecutableAndArchitecture( |
146 | const FileSpec &exe_file_spec, |
147 | const ArchSpec *exe_arch_ptr = nullptr) const; |
148 | |
149 | /// Find the target that contains a process with process ID \a |
150 | /// pid. |
151 | /// |
152 | /// \param[in] pid |
153 | /// The process ID to search our target list for. |
154 | /// |
155 | /// \return |
156 | /// A shared pointer to a target object. The returned shared |
157 | /// pointer will contain nullptr if no target objects own a process |
158 | /// with a matching process ID. |
159 | lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid) const; |
160 | |
161 | lldb::TargetSP FindTargetWithProcess(lldb_private::Process *process) const; |
162 | |
163 | lldb::TargetSP GetTargetSP(Target *target) const; |
164 | |
165 | /// Send an async interrupt to one or all processes. |
166 | /// |
167 | /// Find the target that contains the process with process ID \a |
168 | /// pid and send a LLDB_EVENT_ASYNC_INTERRUPT event to the process's |
169 | /// event queue. |
170 | /// |
171 | /// \param[in] pid |
172 | /// The process ID to search our target list for, if \a pid is |
173 | /// LLDB_INVALID_PROCESS_ID, then the interrupt will be sent to |
174 | /// all processes. |
175 | /// |
176 | /// \return |
177 | /// The number of async interrupts sent. |
178 | uint32_t SendAsyncInterrupt(lldb::pid_t pid = LLDB_INVALID_PROCESS_ID); |
179 | |
180 | uint32_t SignalIfRunning(lldb::pid_t pid, int signo); |
181 | |
182 | void SetSelectedTarget(uint32_t index); |
183 | |
184 | void SetSelectedTarget(const lldb::TargetSP &target); |
185 | |
186 | lldb::TargetSP GetSelectedTarget(); |
187 | |
188 | /// Returns whether any module, including ones in the process of being |
189 | /// added, contains this module. I don't want to give direct access to |
190 | /// these not yet added target, but for interruption purposes, we might |
191 | /// need to ask whether this target contains this module. |
192 | bool AnyTargetContainsModule(Module &module); |
193 | |
194 | TargetIterable Targets() { |
195 | return TargetIterable(m_target_list, m_target_list_mutex); |
196 | } |
197 | |
198 | private: |
199 | collection m_target_list; |
200 | std::unordered_set<lldb::TargetSP> m_in_process_target_list; |
201 | mutable std::recursive_mutex m_target_list_mutex; |
202 | uint32_t m_selected_target_idx; |
203 | |
204 | static Status CreateTargetInternal( |
205 | Debugger &debugger, llvm::StringRef user_exe_path, |
206 | llvm::StringRef triple_str, LoadDependentFiles load_dependent_files, |
207 | const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp); |
208 | |
209 | static Status CreateTargetInternal(Debugger &debugger, |
210 | llvm::StringRef user_exe_path, |
211 | const ArchSpec &arch, |
212 | LoadDependentFiles get_dependent_modules, |
213 | lldb::PlatformSP &platform_sp, |
214 | lldb::TargetSP &target_sp); |
215 | |
216 | void RegisterInProcessTarget(lldb::TargetSP target_sp); |
217 | |
218 | void UnregisterInProcessTarget(lldb::TargetSP target_sp); |
219 | |
220 | bool IsTargetInProcess(lldb::TargetSP target_sp); |
221 | |
222 | void AddTargetInternal(lldb::TargetSP target_sp, bool do_select); |
223 | |
224 | void SetSelectedTargetInternal(uint32_t index); |
225 | |
226 | TargetList(const TargetList &) = delete; |
227 | const TargetList &operator=(const TargetList &) = delete; |
228 | }; |
229 | |
230 | } // namespace lldb_private |
231 | |
232 | #endif // LLDB_TARGET_TARGETLIST_H |
233 | |