blob: 5be9cb657382a4c2e40f88e68022ab13f6dda5b7 [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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02009#ifndef LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
10#define LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
Andrew Walbran3d2c1972020-04-07 12:24:26 +010011
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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020020#include "lldb/Utility/UnimplementedError.h"
Andrew Walbran3d2c1972020-04-07 12:24:26 +010021#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
32namespace lldb_private {
33class MemoryRegionInfo;
34class ResumeActionList;
35
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020036struct 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
Andrew Walbran3d2c1972020-04-07 12:24:26 +010044// NativeProcessProtocol
45class NativeProcessProtocol {
46public:
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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020088 /// 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
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100113 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
114 size_t &bytes_written) = 0;
115
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200116 virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
117 uint32_t permissions) {
118 return llvm::make_error<UnimplementedError>();
119 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100120
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200121 virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
122 return llvm::make_error<UnimplementedError>();
123 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100124
125 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
126
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200127 virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
128 GetLoadedSVR4Libraries() {
129 return llvm::createStringError(llvm::inconvertibleErrorCode(),
130 "Not implemented");
131 }
132
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100133 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 ///
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100387 /// \param[out] config
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200388 /// The configuration being used for tracing.
389 ///
390 /// \return A status indicating what went wrong.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100391 virtual Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) {
392 return Status("Not implemented");
393 }
394
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200395 /// \copydoc Process::GetSupportedTraceType()
396 virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() {
397 return llvm::make_error<UnimplementedError>();
398 }
399
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100400protected:
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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200437 void SetID(lldb::pid_t pid) { m_pid = pid; }
438
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100439 // 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
475private:
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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200482#endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H