NativeProcessProtocol.h revision 344779
1//===-- NativeProcessProtocol.h ---------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_NativeProcessProtocol_h_
11#define liblldb_NativeProcessProtocol_h_
12
13#include "NativeBreakpointList.h"
14#include "NativeThreadProtocol.h"
15#include "NativeWatchpointList.h"
16#include "lldb/Host/Host.h"
17#include "lldb/Host/MainLoop.h"
18#include "lldb/Utility/ArchSpec.h"
19#include "lldb/Utility/Status.h"
20#include "lldb/Utility/TraceOptions.h"
21#include "lldb/lldb-private-forward.h"
22#include "lldb/lldb-types.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/DenseSet.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/Support/Error.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include <mutex>
29#include <unordered_map>
30#include <vector>
31
32namespace lldb_private {
33class MemoryRegionInfo;
34class ResumeActionList;
35
36//------------------------------------------------------------------
37// NativeProcessProtocol
38//------------------------------------------------------------------
39class NativeProcessProtocol {
40public:
41  virtual ~NativeProcessProtocol() {}
42
43  virtual Status Resume(const ResumeActionList &resume_actions) = 0;
44
45  virtual Status Halt() = 0;
46
47  virtual Status Detach() = 0;
48
49  //------------------------------------------------------------------
50  /// Sends a process a UNIX signal \a signal.
51  ///
52  /// @return
53  ///     Returns an error object.
54  //------------------------------------------------------------------
55  virtual Status Signal(int signo) = 0;
56
57  //------------------------------------------------------------------
58  /// Tells a process to interrupt all operations as if by a Ctrl-C.
59  ///
60  /// The default implementation will send a local host's equivalent of
61  /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
62  /// operation.
63  ///
64  /// @return
65  ///     Returns an error object.
66  //------------------------------------------------------------------
67  virtual Status Interrupt();
68
69  virtual Status Kill() = 0;
70
71  //------------------------------------------------------------------
72  // Tells a process not to stop the inferior on given signals and just
73  // reinject them back.
74  //------------------------------------------------------------------
75  virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
76
77  //----------------------------------------------------------------------
78  // Memory and memory region functions
79  //----------------------------------------------------------------------
80
81  virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
82                                     MemoryRegionInfo &range_info);
83
84  virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
85                            size_t &bytes_read) = 0;
86
87  Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
88                               size_t &bytes_read);
89
90  virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
91                             size_t &bytes_written) = 0;
92
93  virtual Status AllocateMemory(size_t size, uint32_t permissions,
94                                lldb::addr_t &addr) = 0;
95
96  virtual Status DeallocateMemory(lldb::addr_t addr) = 0;
97
98  virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
99
100  virtual bool IsAlive() const;
101
102  virtual size_t UpdateThreads() = 0;
103
104  virtual const ArchSpec &GetArchitecture() const = 0;
105
106  //----------------------------------------------------------------------
107  // Breakpoint functions
108  //----------------------------------------------------------------------
109  virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
110                               bool hardware) = 0;
111
112  virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
113
114  //----------------------------------------------------------------------
115  // Hardware Breakpoint functions
116  //----------------------------------------------------------------------
117  virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
118
119  virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
120
121  virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
122
123  //----------------------------------------------------------------------
124  // Watchpoint functions
125  //----------------------------------------------------------------------
126  virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
127
128  virtual llvm::Optional<std::pair<uint32_t, uint32_t>>
129  GetHardwareDebugSupportInfo() const;
130
131  virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
132                               uint32_t watch_flags, bool hardware);
133
134  virtual Status RemoveWatchpoint(lldb::addr_t addr);
135
136  //----------------------------------------------------------------------
137  // Accessors
138  //----------------------------------------------------------------------
139  lldb::pid_t GetID() const { return m_pid; }
140
141  lldb::StateType GetState() const;
142
143  bool IsRunning() const {
144    return m_state == lldb::eStateRunning || IsStepping();
145  }
146
147  bool IsStepping() const { return m_state == lldb::eStateStepping; }
148
149  bool CanResume() const { return m_state == lldb::eStateStopped; }
150
151  lldb::ByteOrder GetByteOrder() const {
152    return GetArchitecture().GetByteOrder();
153  }
154
155  virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
156  GetAuxvData() const = 0;
157
158  //----------------------------------------------------------------------
159  // Exit Status
160  //----------------------------------------------------------------------
161  virtual llvm::Optional<WaitStatus> GetExitStatus();
162
163  virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
164
165  //----------------------------------------------------------------------
166  // Access to threads
167  //----------------------------------------------------------------------
168  NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);
169
170  NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);
171
172  void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
173
174  lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; }
175
176  NativeThreadProtocol *GetCurrentThread() {
177    return GetThreadByID(m_current_thread_id);
178  }
179
180  //----------------------------------------------------------------------
181  // Access to inferior stdio
182  //----------------------------------------------------------------------
183  virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
184
185  //----------------------------------------------------------------------
186  // Stop id interface
187  //----------------------------------------------------------------------
188
189  uint32_t GetStopID() const;
190
191  // ---------------------------------------------------------------------
192  // Callbacks for low-level process state changes
193  // ---------------------------------------------------------------------
194  class NativeDelegate {
195  public:
196    virtual ~NativeDelegate() {}
197
198    virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
199
200    virtual void ProcessStateChanged(NativeProcessProtocol *process,
201                                     lldb::StateType state) = 0;
202
203    virtual void DidExec(NativeProcessProtocol *process) = 0;
204  };
205
206  //------------------------------------------------------------------
207  /// Register a native delegate.
208  ///
209  /// Clients can register nofication callbacks by passing in a
210  /// NativeDelegate impl and passing it into this function.
211  ///
212  /// Note: it is required that the lifetime of the
213  /// native_delegate outlive the NativeProcessProtocol.
214  ///
215  /// @param[in] native_delegate
216  ///     A NativeDelegate impl to be called when certain events
217  ///     happen within the NativeProcessProtocol or related threads.
218  ///
219  /// @return
220  ///     true if the delegate was registered successfully;
221  ///     false if the delegate was already registered.
222  ///
223  /// @see NativeProcessProtocol::NativeDelegate.
224  //------------------------------------------------------------------
225  bool RegisterNativeDelegate(NativeDelegate &native_delegate);
226
227  //------------------------------------------------------------------
228  /// Unregister a native delegate previously registered.
229  ///
230  /// @param[in] native_delegate
231  ///     A NativeDelegate impl previously registered with this process.
232  ///
233  /// @return Returns \b true if the NativeDelegate was
234  /// successfully removed from the process, \b false otherwise.
235  ///
236  /// @see NativeProcessProtocol::NativeDelegate
237  //------------------------------------------------------------------
238  bool UnregisterNativeDelegate(NativeDelegate &native_delegate);
239
240  virtual Status GetLoadedModuleFileSpec(const char *module_path,
241                                         FileSpec &file_spec) = 0;
242
243  virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
244                                    lldb::addr_t &load_addr) = 0;
245
246  class Factory {
247  public:
248    virtual ~Factory();
249    //------------------------------------------------------------------
250    /// Launch a process for debugging.
251    ///
252    /// @param[in] launch_info
253    ///     Information required to launch the process.
254    ///
255    /// @param[in] native_delegate
256    ///     The delegate that will receive messages regarding the
257    ///     inferior.  Must outlive the NativeProcessProtocol
258    ///     instance.
259    ///
260    /// @param[in] mainloop
261    ///     The mainloop instance with which the process can register
262    ///     callbacks. Must outlive the NativeProcessProtocol
263    ///     instance.
264    ///
265    /// @return
266    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
267    ///     an error object if it failed.
268    //------------------------------------------------------------------
269    virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
270    Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
271           MainLoop &mainloop) const = 0;
272
273    //------------------------------------------------------------------
274    /// Attach to an existing process.
275    ///
276    /// @param[in] pid
277    ///     pid of the process locatable
278    ///
279    /// @param[in] native_delegate
280    ///     The delegate that will receive messages regarding the
281    ///     inferior.  Must outlive the NativeProcessProtocol
282    ///     instance.
283    ///
284    /// @param[in] mainloop
285    ///     The mainloop instance with which the process can register
286    ///     callbacks. Must outlive the NativeProcessProtocol
287    ///     instance.
288    ///
289    /// @return
290    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
291    ///     an error object if it failed.
292    //------------------------------------------------------------------
293    virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
294    Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
295           MainLoop &mainloop) const = 0;
296  };
297
298  //------------------------------------------------------------------
299  /// StartTracing API for starting a tracing instance with the
300  /// TraceOptions on a specific thread or process.
301  ///
302  /// @param[in] config
303  ///     The configuration to use when starting tracing.
304  ///
305  /// @param[out] error
306  ///     Status indicates what went wrong.
307  ///
308  /// @return
309  ///     The API returns a user_id which can be used to get trace
310  ///     data, trace configuration or stopping the trace instance.
311  ///     The user_id is a key to identify and operate with a tracing
312  ///     instance. It may refer to the complete process or a single
313  ///     thread.
314  //------------------------------------------------------------------
315  virtual lldb::user_id_t StartTrace(const TraceOptions &config,
316                                     Status &error) {
317    error.SetErrorString("Not implemented");
318    return LLDB_INVALID_UID;
319  }
320
321  //------------------------------------------------------------------
322  /// StopTracing API as the name suggests stops a tracing instance.
323  ///
324  /// @param[in] traceid
325  ///     The user id of the trace intended to be stopped. Now a
326  ///     user_id may map to multiple threads in which case this API
327  ///     could be used to stop the tracing for a specific thread by
328  ///     supplying its thread id.
329  ///
330  /// @param[in] thread
331  ///     Thread is needed when the complete process is being traced
332  ///     and the user wishes to stop tracing on a particular thread.
333  ///
334  /// @return
335  ///     Status indicating what went wrong.
336  //------------------------------------------------------------------
337  virtual Status StopTrace(lldb::user_id_t traceid,
338                           lldb::tid_t thread = LLDB_INVALID_THREAD_ID) {
339    return Status("Not implemented");
340  }
341
342  //------------------------------------------------------------------
343  /// This API provides the trace data collected in the form of raw
344  /// data.
345  ///
346  /// @param[in] traceid thread
347  ///     The traceid and thread provide the context for the trace
348  ///     instance.
349  ///
350  /// @param[in] buffer
351  ///     The buffer provides the destination buffer where the trace
352  ///     data would be read to. The buffer should be truncated to the
353  ///     filled length by this function.
354  ///
355  /// @param[in] offset
356  ///     There is possibility to read partially the trace data from
357  ///     a specified offset where in such cases the buffer provided
358  ///     may be smaller than the internal trace collection container.
359  ///
360  /// @return
361  ///     The size of the data actually read.
362  //------------------------------------------------------------------
363  virtual Status GetData(lldb::user_id_t traceid, lldb::tid_t thread,
364                         llvm::MutableArrayRef<uint8_t> &buffer,
365                         size_t offset = 0) {
366    return Status("Not implemented");
367  }
368
369  //------------------------------------------------------------------
370  /// Similar API as above except it aims to provide any extra data
371  /// useful for decoding the actual trace data.
372  //------------------------------------------------------------------
373  virtual Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread,
374                             llvm::MutableArrayRef<uint8_t> &buffer,
375                             size_t offset = 0) {
376    return Status("Not implemented");
377  }
378
379  //------------------------------------------------------------------
380  /// API to query the TraceOptions for a given user id
381  ///
382  /// @param[in] traceid
383  ///     The user id of the tracing instance.
384  ///
385  /// @param[in] config
386  ///     The thread id of the tracing instance, in case configuration
387  ///     for a specific thread is needed should be specified in the
388  ///     config.
389  ///
390  /// @param[out] error
391  ///     Status indicates what went wrong.
392  ///
393  /// @param[out] config
394  ///     The actual configuration being used for tracing.
395  //------------------------------------------------------------------
396  virtual Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) {
397    return Status("Not implemented");
398  }
399
400protected:
401  struct SoftwareBreakpoint {
402    uint32_t ref_count;
403    llvm::SmallVector<uint8_t, 4> saved_opcodes;
404    llvm::ArrayRef<uint8_t> breakpoint_opcodes;
405  };
406
407  std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
408  lldb::pid_t m_pid;
409
410  std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
411  lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
412  mutable std::recursive_mutex m_threads_mutex;
413
414  lldb::StateType m_state = lldb::eStateInvalid;
415  mutable std::recursive_mutex m_state_mutex;
416
417  llvm::Optional<WaitStatus> m_exit_status;
418
419  std::recursive_mutex m_delegates_mutex;
420  std::vector<NativeDelegate *> m_delegates;
421  NativeWatchpointList m_watchpoint_list;
422  HardwareBreakpointMap m_hw_breakpoints_map;
423  int m_terminal_fd;
424  uint32_t m_stop_id = 0;
425
426  // Set of signal numbers that LLDB directly injects back to inferior without
427  // stopping it.
428  llvm::DenseSet<int> m_signals_to_ignore;
429
430  // lldb_private::Host calls should be used to launch a process for debugging,
431  // and then the process should be attached to. When attaching to a process
432  // lldb_private::Host calls should be used to locate the process to attach
433  // to, and then this function should be called.
434  NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
435                        NativeDelegate &delegate);
436
437  // ----------------------------------------------------------- Internal
438  // interface for state handling
439  // -----------------------------------------------------------
440  void SetState(lldb::StateType state, bool notify_delegates = true);
441
442  // Derived classes need not implement this.  It can be used as a hook to
443  // clear internal caches that should be invalidated when stop ids change.
444  //
445  // Note this function is called with the state mutex obtained by the caller.
446  virtual void DoStopIDBumped(uint32_t newBumpId);
447
448  // ----------------------------------------------------------- Internal
449  // interface for software breakpoints
450  // -----------------------------------------------------------
451
452  Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
453  Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
454
455  virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
456  GetSoftwareBreakpointTrapOpcode(size_t size_hint);
457
458  /// Return the offset of the PC relative to the software breakpoint that was hit. If an
459  /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset
460  /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the
461  /// PC, this offset will be the size of the breakpoint opcode.
462  virtual size_t GetSoftwareBreakpointPCOffset();
463
464  // Adjust the thread's PC after hitting a software breakpoint. On
465  // architectures where the PC points after the breakpoint instruction, this
466  // resets it to point to the breakpoint itself.
467  void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread);
468
469  // -----------------------------------------------------------
470  /// Notify the delegate that an exec occurred.
471  ///
472  /// Provide a mechanism for a delegate to clear out any exec-
473  /// sensitive data.
474  // -----------------------------------------------------------
475  void NotifyDidExec();
476
477  NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
478
479private:
480  void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
481  llvm::Expected<SoftwareBreakpoint>
482  EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
483};
484} // namespace lldb_private
485
486#endif // #ifndef liblldb_NativeProcessProtocol_h_
487