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
18namespace lldb_private {
19
20class TargetList : public Broadcaster {
21private:
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
33public:
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] user_exe_path
59  ///     The main executable file for a debug target. This value
60  ///     can be empty and the file can be set later using:
61  ///     Target::SetExecutableModule (ModuleSP&)
62  ///
63  /// \param[in] triple_str
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
182protected:
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
190private:
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