blob: f05b8d01a1c9ff8d600620f1bf4707f828a25fef [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===-- 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
31namespace lldb_private {
32class MemoryRegionInfo;
33class ResumeActionList;
34
35// NativeProcessProtocol
36class NativeProcessProtocol {
37public:
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
357protected:
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
430private:
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_