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