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