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 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   int 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   TargetIterable Targets() {
189     return TargetIterable(m_target_list, m_target_list_mutex);
190   }
191 
192 private:
193   collection m_target_list;
194   mutable std::recursive_mutex m_target_list_mutex;
195   uint32_t m_selected_target_idx;
196 
197   static Status CreateTargetInternal(
198       Debugger &debugger, llvm::StringRef user_exe_path,
199       llvm::StringRef triple_str, LoadDependentFiles load_dependent_files,
200       const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp);
201 
202   static Status CreateTargetInternal(Debugger &debugger,
203                                      llvm::StringRef user_exe_path,
204                                      const ArchSpec &arch,
205                                      LoadDependentFiles get_dependent_modules,
206                                      lldb::PlatformSP &platform_sp,
207                                      lldb::TargetSP &target_sp);
208 
209   void AddTargetInternal(lldb::TargetSP target_sp, bool do_select);
210 
211   void SetSelectedTargetInternal(uint32_t index);
212 
213   TargetList(const TargetList &) = delete;
214   const TargetList &operator=(const TargetList &) = delete;
215 };
216 
217 } // namespace lldb_private
218 
219 #endif // LLDB_TARGET_TARGETLIST_H
220