1 //===-- NativeProcessProtocol.h ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_NativeProcessProtocol_h_
11 #define liblldb_NativeProcessProtocol_h_
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"
29 #include <unordered_map>
32 namespace lldb_private {
33 class MemoryRegionInfo;
34 class ResumeActionList;
36 //------------------------------------------------------------------
37 // NativeProcessProtocol
38 //------------------------------------------------------------------
39 class NativeProcessProtocol {
41 virtual ~NativeProcessProtocol() {}
43 virtual Status Resume(const ResumeActionList &resume_actions) = 0;
45 virtual Status Halt() = 0;
47 virtual Status Detach() = 0;
49 //------------------------------------------------------------------
50 /// Sends a process a UNIX signal \a signal.
53 /// Returns an error object.
54 //------------------------------------------------------------------
55 virtual Status Signal(int signo) = 0;
57 //------------------------------------------------------------------
58 /// Tells a process to interrupt all operations as if by a Ctrl-C.
60 /// The default implementation will send a local host's equivalent of
61 /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
65 /// Returns an error object.
66 //------------------------------------------------------------------
67 virtual Status Interrupt();
69 virtual Status Kill() = 0;
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);
77 //----------------------------------------------------------------------
78 // Memory and memory region functions
79 //----------------------------------------------------------------------
81 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
82 MemoryRegionInfo &range_info);
84 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
85 size_t &bytes_read) = 0;
87 Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
90 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
91 size_t &bytes_written) = 0;
93 virtual Status AllocateMemory(size_t size, uint32_t permissions,
94 lldb::addr_t &addr) = 0;
96 virtual Status DeallocateMemory(lldb::addr_t addr) = 0;
98 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
100 virtual bool IsAlive() const;
102 virtual size_t UpdateThreads() = 0;
104 virtual const ArchSpec &GetArchitecture() const = 0;
106 //----------------------------------------------------------------------
107 // Breakpoint functions
108 //----------------------------------------------------------------------
109 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
112 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
114 //----------------------------------------------------------------------
115 // Hardware Breakpoint functions
116 //----------------------------------------------------------------------
117 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
119 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
121 virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
123 //----------------------------------------------------------------------
124 // Watchpoint functions
125 //----------------------------------------------------------------------
126 virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
128 virtual llvm::Optional<std::pair<uint32_t, uint32_t>>
129 GetHardwareDebugSupportInfo() const;
131 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
132 uint32_t watch_flags, bool hardware);
134 virtual Status RemoveWatchpoint(lldb::addr_t addr);
136 //----------------------------------------------------------------------
138 //----------------------------------------------------------------------
139 lldb::pid_t GetID() const { return m_pid; }
141 lldb::StateType GetState() const;
143 bool IsRunning() const {
144 return m_state == lldb::eStateRunning || IsStepping();
147 bool IsStepping() const { return m_state == lldb::eStateStepping; }
149 bool CanResume() const { return m_state == lldb::eStateStopped; }
151 lldb::ByteOrder GetByteOrder() const {
152 return GetArchitecture().GetByteOrder();
155 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
156 GetAuxvData() const = 0;
158 //----------------------------------------------------------------------
160 //----------------------------------------------------------------------
161 virtual llvm::Optional<WaitStatus> GetExitStatus();
163 virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
165 //----------------------------------------------------------------------
167 //----------------------------------------------------------------------
168 NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);
170 NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);
172 void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
174 lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; }
176 NativeThreadProtocol *GetCurrentThread() {
177 return GetThreadByID(m_current_thread_id);
180 //----------------------------------------------------------------------
181 // Access to inferior stdio
182 //----------------------------------------------------------------------
183 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
185 //----------------------------------------------------------------------
187 //----------------------------------------------------------------------
189 uint32_t GetStopID() const;
191 // ---------------------------------------------------------------------
192 // Callbacks for low-level process state changes
193 // ---------------------------------------------------------------------
194 class NativeDelegate {
196 virtual ~NativeDelegate() {}
198 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
200 virtual void ProcessStateChanged(NativeProcessProtocol *process,
201 lldb::StateType state) = 0;
203 virtual void DidExec(NativeProcessProtocol *process) = 0;
206 //------------------------------------------------------------------
207 /// Register a native delegate.
209 /// Clients can register nofication callbacks by passing in a
210 /// NativeDelegate impl and passing it into this function.
212 /// Note: it is required that the lifetime of the
213 /// native_delegate outlive the NativeProcessProtocol.
215 /// @param[in] native_delegate
216 /// A NativeDelegate impl to be called when certain events
217 /// happen within the NativeProcessProtocol or related threads.
220 /// true if the delegate was registered successfully;
221 /// false if the delegate was already registered.
223 /// @see NativeProcessProtocol::NativeDelegate.
224 //------------------------------------------------------------------
225 bool RegisterNativeDelegate(NativeDelegate &native_delegate);
227 //------------------------------------------------------------------
228 /// Unregister a native delegate previously registered.
230 /// @param[in] native_delegate
231 /// A NativeDelegate impl previously registered with this process.
233 /// @return Returns \b true if the NativeDelegate was
234 /// successfully removed from the process, \b false otherwise.
236 /// @see NativeProcessProtocol::NativeDelegate
237 //------------------------------------------------------------------
238 bool UnregisterNativeDelegate(NativeDelegate &native_delegate);
240 virtual Status GetLoadedModuleFileSpec(const char *module_path,
241 FileSpec &file_spec) = 0;
243 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
244 lldb::addr_t &load_addr) = 0;
249 //------------------------------------------------------------------
250 /// Launch a process for debugging.
252 /// @param[in] launch_info
253 /// Information required to launch the process.
255 /// @param[in] native_delegate
256 /// The delegate that will receive messages regarding the
257 /// inferior. Must outlive the NativeProcessProtocol
260 /// @param[in] mainloop
261 /// The mainloop instance with which the process can register
262 /// callbacks. Must outlive the NativeProcessProtocol
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;
273 //------------------------------------------------------------------
274 /// Attach to an existing process.
277 /// pid of the process locatable
279 /// @param[in] native_delegate
280 /// The delegate that will receive messages regarding the
281 /// inferior. Must outlive the NativeProcessProtocol
284 /// @param[in] mainloop
285 /// The mainloop instance with which the process can register
286 /// callbacks. Must outlive the NativeProcessProtocol
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;
298 //------------------------------------------------------------------
299 /// StartTracing API for starting a tracing instance with the
300 /// TraceOptions on a specific thread or process.
302 /// @param[in] config
303 /// The configuration to use when starting tracing.
305 /// @param[out] error
306 /// Status indicates what went wrong.
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
314 //------------------------------------------------------------------
315 virtual lldb::user_id_t StartTrace(const TraceOptions &config,
317 error.SetErrorString("Not implemented");
318 return LLDB_INVALID_UID;
321 //------------------------------------------------------------------
322 /// StopTracing API as the name suggests stops a tracing instance.
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.
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.
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");
342 //------------------------------------------------------------------
343 /// This API provides the trace data collected in the form of raw
346 /// @param[in] traceid thread
347 /// The traceid and thread provide the context for the trace
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.
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.
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,
366 return Status("Not implemented");
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,
376 return Status("Not implemented");
379 //------------------------------------------------------------------
380 /// API to query the TraceOptions for a given user id
382 /// @param[in] traceid
383 /// The user id of the tracing instance.
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
390 /// @param[out] error
391 /// Status indicates what went wrong.
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");
401 struct SoftwareBreakpoint {
403 llvm::SmallVector<uint8_t, 4> saved_opcodes;
404 llvm::ArrayRef<uint8_t> breakpoint_opcodes;
407 std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
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;
414 lldb::StateType m_state = lldb::eStateInvalid;
415 mutable std::recursive_mutex m_state_mutex;
417 llvm::Optional<WaitStatus> m_exit_status;
419 std::recursive_mutex m_delegates_mutex;
420 std::vector<NativeDelegate *> m_delegates;
421 NativeWatchpointList m_watchpoint_list;
422 HardwareBreakpointMap m_hw_breakpoints_map;
424 uint32_t m_stop_id = 0;
426 // Set of signal numbers that LLDB directly injects back to inferior without
428 llvm::DenseSet<int> m_signals_to_ignore;
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);
437 // ----------------------------------------------------------- Internal
438 // interface for state handling
439 // -----------------------------------------------------------
440 void SetState(lldb::StateType state, bool notify_delegates = true);
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.
445 // Note this function is called with the state mutex obtained by the caller.
446 virtual void DoStopIDBumped(uint32_t newBumpId);
448 // ----------------------------------------------------------- Internal
449 // interface for software breakpoints
450 // -----------------------------------------------------------
452 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
453 Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
455 virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
456 GetSoftwareBreakpointTrapOpcode(size_t size_hint);
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();
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);
469 // -----------------------------------------------------------
470 /// Notify the delegate that an exec occurred.
472 /// Provide a mechanism for a delegate to clear out any exec-
474 // -----------------------------------------------------------
475 void NotifyDidExec();
477 NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
480 void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
481 llvm::Expected<SoftwareBreakpoint>
482 EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
484 } // namespace lldb_private
486 #endif // #ifndef liblldb_NativeProcessProtocol_h_