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