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