1 //===-- NativeProcessProtocol.h ---------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_NativeProcessProtocol_h_
10 #define liblldb_NativeProcessProtocol_h_
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"
28 #include <unordered_map>
31 namespace lldb_private {
32 class MemoryRegionInfo;
33 class ResumeActionList;
35 struct SVR4LibraryInfo {
37 lldb::addr_t link_map;
38 lldb::addr_t base_addr;
43 // NativeProcessProtocol
44 class NativeProcessProtocol {
46 virtual ~NativeProcessProtocol() {}
48 virtual Status Resume(const ResumeActionList &resume_actions) = 0;
50 virtual Status Halt() = 0;
52 virtual Status Detach() = 0;
54 /// Sends a process a UNIX signal \a signal.
57 /// Returns an error object.
58 virtual Status Signal(int signo) = 0;
60 /// Tells a process to interrupt all operations as if by a Ctrl-C.
62 /// The default implementation will send a local host's equivalent of
63 /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
67 /// Returns an error object.
68 virtual Status Interrupt();
70 virtual Status Kill() = 0;
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);
76 // Memory and memory region functions
78 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
79 MemoryRegionInfo &range_info);
81 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
82 size_t &bytes_read) = 0;
84 Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
87 /// Reads a null terminated string from memory.
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.
94 /// The address in memory to read from.
97 /// An allocated buffer with at least \p max_size size.
99 /// \param[in] max_size
100 /// The maximum number of bytes to read from memory until it reads the
103 /// \param[out] total_bytes_read
104 /// The number of bytes read from memory into \p buffer.
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);
112 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
113 size_t &bytes_written) = 0;
115 virtual Status AllocateMemory(size_t size, uint32_t permissions,
116 lldb::addr_t &addr) = 0;
118 virtual Status DeallocateMemory(lldb::addr_t addr) = 0;
120 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
122 virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
123 GetLoadedSVR4Libraries() {
124 return llvm::createStringError(llvm::inconvertibleErrorCode(),
128 virtual bool IsAlive() const;
130 virtual size_t UpdateThreads() = 0;
132 virtual const ArchSpec &GetArchitecture() const = 0;
134 // Breakpoint functions
135 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
138 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
140 // Hardware Breakpoint functions
141 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
143 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
145 virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
147 // Watchpoint functions
148 virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
150 virtual llvm::Optional<std::pair<uint32_t, uint32_t>>
151 GetHardwareDebugSupportInfo() const;
153 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
154 uint32_t watch_flags, bool hardware);
156 virtual Status RemoveWatchpoint(lldb::addr_t addr);
159 lldb::pid_t GetID() const { return m_pid; }
161 lldb::StateType GetState() const;
163 bool IsRunning() const {
164 return m_state == lldb::eStateRunning || IsStepping();
167 bool IsStepping() const { return m_state == lldb::eStateStepping; }
169 bool CanResume() const { return m_state == lldb::eStateStopped; }
171 lldb::ByteOrder GetByteOrder() const {
172 return GetArchitecture().GetByteOrder();
175 uint32_t GetAddressByteSize() const {
176 return GetArchitecture().GetAddressByteSize();
179 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
180 GetAuxvData() const = 0;
183 virtual llvm::Optional<WaitStatus> GetExitStatus();
185 virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
188 NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);
190 NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);
192 void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
194 lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; }
196 NativeThreadProtocol *GetCurrentThread() {
197 return GetThreadByID(m_current_thread_id);
200 // Access to inferior stdio
201 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
205 uint32_t GetStopID() const;
207 // Callbacks for low-level process state changes
208 class NativeDelegate {
210 virtual ~NativeDelegate() {}
212 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
214 virtual void ProcessStateChanged(NativeProcessProtocol *process,
215 lldb::StateType state) = 0;
217 virtual void DidExec(NativeProcessProtocol *process) = 0;
220 /// Register a native delegate.
222 /// Clients can register nofication callbacks by passing in a
223 /// NativeDelegate impl and passing it into this function.
225 /// Note: it is required that the lifetime of the
226 /// native_delegate outlive the NativeProcessProtocol.
228 /// \param[in] native_delegate
229 /// A NativeDelegate impl to be called when certain events
230 /// happen within the NativeProcessProtocol or related threads.
233 /// true if the delegate was registered successfully;
234 /// false if the delegate was already registered.
236 /// \see NativeProcessProtocol::NativeDelegate.
237 bool RegisterNativeDelegate(NativeDelegate &native_delegate);
239 /// Unregister a native delegate previously registered.
241 /// \param[in] native_delegate
242 /// A NativeDelegate impl previously registered with this process.
244 /// \return Returns \b true if the NativeDelegate was
245 /// successfully removed from the process, \b false otherwise.
247 /// \see NativeProcessProtocol::NativeDelegate
248 bool UnregisterNativeDelegate(NativeDelegate &native_delegate);
250 virtual Status GetLoadedModuleFileSpec(const char *module_path,
251 FileSpec &file_spec) = 0;
253 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
254 lldb::addr_t &load_addr) = 0;
259 /// Launch a process for debugging.
261 /// \param[in] launch_info
262 /// Information required to launch the process.
264 /// \param[in] native_delegate
265 /// The delegate that will receive messages regarding the
266 /// inferior. Must outlive the NativeProcessProtocol
269 /// \param[in] mainloop
270 /// The mainloop instance with which the process can register
271 /// callbacks. Must outlive the NativeProcessProtocol
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;
281 /// Attach to an existing process.
284 /// pid of the process locatable
286 /// \param[in] native_delegate
287 /// The delegate that will receive messages regarding the
288 /// inferior. Must outlive the NativeProcessProtocol
291 /// \param[in] mainloop
292 /// The mainloop instance with which the process can register
293 /// callbacks. Must outlive the NativeProcessProtocol
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;
304 /// StartTracing API for starting a tracing instance with the
305 /// TraceOptions on a specific thread or process.
307 /// \param[in] config
308 /// The configuration to use when starting tracing.
310 /// \param[out] error
311 /// Status indicates what went wrong.
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
319 virtual lldb::user_id_t StartTrace(const TraceOptions &config,
321 error.SetErrorString("Not implemented");
322 return LLDB_INVALID_UID;
325 /// StopTracing API as the name suggests stops a tracing instance.
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.
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.
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");
344 /// This API provides the trace data collected in the form of raw
347 /// \param[in] traceid thread
348 /// The traceid and thread provide the context for the trace
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.
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.
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,
366 return Status("Not implemented");
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,
374 return Status("Not implemented");
377 /// API to query the TraceOptions for a given user id
379 /// \param[in] traceid
380 /// The user id of the tracing instance.
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
387 /// \param[out] error
388 /// Status indicates what went wrong.
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");
397 struct SoftwareBreakpoint {
399 llvm::SmallVector<uint8_t, 4> saved_opcodes;
400 llvm::ArrayRef<uint8_t> breakpoint_opcodes;
403 std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
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;
410 lldb::StateType m_state = lldb::eStateInvalid;
411 mutable std::recursive_mutex m_state_mutex;
413 llvm::Optional<WaitStatus> m_exit_status;
415 std::recursive_mutex m_delegates_mutex;
416 std::vector<NativeDelegate *> m_delegates;
417 NativeWatchpointList m_watchpoint_list;
418 HardwareBreakpointMap m_hw_breakpoints_map;
420 uint32_t m_stop_id = 0;
422 // Set of signal numbers that LLDB directly injects back to inferior without
424 llvm::DenseSet<int> m_signals_to_ignore;
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);
433 void SetID(lldb::pid_t pid) { m_pid = pid; }
435 // interface for state handling
436 void SetState(lldb::StateType state, bool notify_delegates = true);
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.
441 // Note this function is called with the state mutex obtained by the caller.
442 virtual void DoStopIDBumped(uint32_t newBumpId);
444 // interface for software breakpoints
446 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
447 Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
449 virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
450 GetSoftwareBreakpointTrapOpcode(size_t size_hint);
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();
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);
463 /// Notify the delegate that an exec occurred.
465 /// Provide a mechanism for a delegate to clear out any exec-
467 void NotifyDidExec();
469 NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
472 void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
473 llvm::Expected<SoftwareBreakpoint>
474 EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
476 } // namespace lldb_private
478 #endif // #ifndef liblldb_NativeProcessProtocol_h_