Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h
Line
Count
Source (jump to first uncovered line)
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/Iterable.h"
19
#include "lldb/Utility/Status.h"
20
#include "lldb/Utility/TraceGDBRemotePackets.h"
21
#include "lldb/Utility/UnimplementedError.h"
22
#include "lldb/lldb-private-forward.h"
23
#include "lldb/lldb-types.h"
24
#include "llvm/ADT/ArrayRef.h"
25
#include "llvm/ADT/DenseSet.h"
26
#include "llvm/ADT/StringRef.h"
27
#include "llvm/Support/Error.h"
28
#include "llvm/Support/MemoryBuffer.h"
29
#include <mutex>
30
#include <optional>
31
#include <unordered_map>
32
#include <vector>
33
34
namespace lldb_private {
35
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
36
37
class MemoryRegionInfo;
38
class ResumeActionList;
39
40
struct SVR4LibraryInfo {
41
  std::string name;
42
  lldb::addr_t link_map;
43
  lldb::addr_t base_addr;
44
  lldb::addr_t ld_addr;
45
  lldb::addr_t next;
46
};
47
48
// NativeProcessProtocol
49
class NativeProcessProtocol {
50
public:
51
  virtual ~NativeProcessProtocol() = default;
52
53
  typedef std::vector<std::unique_ptr<NativeThreadProtocol>> thread_collection;
54
  template <typename I>
55
0
  static NativeThreadProtocol &thread_list_adapter(I &iter) {
56
0
    assert(*iter);
57
0
    return **iter;
58
0
  }
59
  typedef LockingAdaptedIterable<thread_collection, NativeThreadProtocol &,
60
                                 thread_list_adapter, std::recursive_mutex>
61
      ThreadIterable;
62
63
  virtual Status Resume(const ResumeActionList &resume_actions) = 0;
64
65
  virtual Status Halt() = 0;
66
67
  virtual Status Detach() = 0;
68
69
  /// Sends a process a UNIX signal \a signal.
70
  ///
71
  /// \return
72
  ///     Returns an error object.
73
  virtual Status Signal(int signo) = 0;
74
75
  /// Tells a process to interrupt all operations as if by a Ctrl-C.
76
  ///
77
  /// The default implementation will send a local host's equivalent of
78
  /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
79
  /// operation.
80
  ///
81
  /// \return
82
  ///     Returns an error object.
83
  virtual Status Interrupt();
84
85
  virtual Status Kill() = 0;
86
87
  // Tells a process not to stop the inferior on given signals and just
88
  // reinject them back.
89
  virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
90
91
  // Memory and memory region functions
92
93
  virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
94
                                     MemoryRegionInfo &range_info);
95
96
  virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
97
                            size_t &bytes_read) = 0;
98
99
  Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
100
                               size_t &bytes_read);
101
102
  virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
103
                                std::vector<uint8_t> &tags);
104
105
  virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
106
                                 const std::vector<uint8_t> &tags);
107
108
  /// Reads a null terminated string from memory.
109
  ///
110
  /// Reads up to \p max_size bytes of memory until it finds a '\0'.
111
  /// If a '\0' is not found then it reads max_size-1 bytes as a string and a
112
  /// '\0' is added as the last character of the \p buffer.
113
  ///
114
  /// \param[in] addr
115
  ///     The address in memory to read from.
116
  ///
117
  /// \param[in] buffer
118
  ///     An allocated buffer with at least \p max_size size.
119
  ///
120
  /// \param[in] max_size
121
  ///     The maximum number of bytes to read from memory until it reads the
122
  ///     string.
123
  ///
124
  /// \param[out] total_bytes_read
125
  ///     The number of bytes read from memory into \p buffer.
126
  ///
127
  /// \return
128
  ///     Returns a StringRef backed up by the \p buffer passed in.
129
  llvm::Expected<llvm::StringRef>
130
  ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size,
131
                        size_t &total_bytes_read);
132
133
  virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
134
                             size_t &bytes_written) = 0;
135
136
  virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
137
0
                                                      uint32_t permissions) {
138
0
    return llvm::make_error<UnimplementedError>();
139
0
  }
140
141
0
  virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
142
0
    return llvm::make_error<UnimplementedError>();
143
0
  }
144
145
  virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
146
147
  virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
148
0
  GetLoadedSVR4Libraries() {
149
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
150
0
                                   "Not implemented");
151
0
  }
152
153
  virtual bool IsAlive() const;
154
155
  virtual size_t UpdateThreads() = 0;
156
157
  virtual const ArchSpec &GetArchitecture() const = 0;
158
159
  // Breakpoint functions
160
  virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
161
                               bool hardware) = 0;
162
163
  virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
164
165
  // Hardware Breakpoint functions
166
  virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
167
168
  virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
169
170
  virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
171
172
  // Watchpoint functions
173
  virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
174
175
  virtual std::optional<std::pair<uint32_t, uint32_t>>
176
  GetHardwareDebugSupportInfo() const;
177
178
  virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
179
                               uint32_t watch_flags, bool hardware);
180
181
  virtual Status RemoveWatchpoint(lldb::addr_t addr);
182
183
  // Accessors
184
0
  lldb::pid_t GetID() const { return m_pid; }
185
186
  lldb::StateType GetState() const;
187
188
0
  bool IsRunning() const {
189
0
    return m_state == lldb::eStateRunning || IsStepping();
190
0
  }
191
192
0
  bool IsStepping() const { return m_state == lldb::eStateStepping; }
193
194
0
  bool CanResume() const { return m_state == lldb::eStateStopped; }
195
196
0
  lldb::ByteOrder GetByteOrder() const {
197
0
    return GetArchitecture().GetByteOrder();
198
0
  }
199
200
0
  uint32_t GetAddressByteSize() const {
201
0
    return GetArchitecture().GetAddressByteSize();
202
0
  }
203
204
  virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
205
  GetAuxvData() const = 0;
206
207
  // Exit Status
208
  virtual std::optional<WaitStatus> GetExitStatus();
209
210
  virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
211
212
  // Access to threads
213
  NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);
214
215
  NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);
216
217
0
  void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
218
219
0
  lldb::tid_t GetCurrentThreadID() const { return m_current_thread_id; }
220
221
0
  NativeThreadProtocol *GetCurrentThread() {
222
0
    return GetThreadByID(m_current_thread_id);
223
0
  }
224
225
0
  ThreadIterable Threads() const {
226
0
    return ThreadIterable(m_threads, m_threads_mutex);
227
0
  }
228
229
  // Access to inferior stdio
230
0
  virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
231
232
  // Stop id interface
233
234
  uint32_t GetStopID() const;
235
236
  // Callbacks for low-level process state changes
237
  class NativeDelegate {
238
  public:
239
8
    virtual ~NativeDelegate() = default;
240
241
    virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
242
243
    virtual void ProcessStateChanged(NativeProcessProtocol *process,
244
                                     lldb::StateType state) = 0;
245
246
    virtual void DidExec(NativeProcessProtocol *process) = 0;
247
248
    virtual void
249
    NewSubprocess(NativeProcessProtocol *parent_process,
250
                  std::unique_ptr<NativeProcessProtocol> child_process) = 0;
251
  };
252
253
  virtual Status GetLoadedModuleFileSpec(const char *module_path,
254
                                         FileSpec &file_spec) = 0;
255
256
  virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
257
                                    lldb::addr_t &load_addr) = 0;
258
259
  /// Extension flag constants, returned by Manager::GetSupportedExtensions()
260
  /// and passed to SetEnabledExtension()
261
  enum class Extension {
262
    multiprocess = (1u << 0),
263
    fork = (1u << 1),
264
    vfork = (1u << 2),
265
    pass_signals = (1u << 3),
266
    auxv = (1u << 4),
267
    libraries_svr4 = (1u << 5),
268
    memory_tagging = (1u << 6),
269
    savecore = (1u << 7),
270
    siginfo_read = (1u << 8),
271
272
    LLVM_MARK_AS_BITMASK_ENUM(siginfo_read)
273
  };
274
275
  class Manager {
276
  public:
277
0
    Manager(MainLoop &mainloop) : m_mainloop(mainloop) {}
278
    Manager(const Manager &) = delete;
279
    Manager &operator=(const Manager &) = delete;
280
281
    virtual ~Manager();
282
283
    /// Launch a process for debugging.
284
    ///
285
    /// \param[in] launch_info
286
    ///     Information required to launch the process.
287
    ///
288
    /// \param[in] native_delegate
289
    ///     The delegate that will receive messages regarding the
290
    ///     inferior.  Must outlive the NativeProcessProtocol
291
    ///     instance.
292
    ///
293
    /// \param[in] mainloop
294
    ///     The mainloop instance with which the process can register
295
    ///     callbacks. Must outlive the NativeProcessProtocol
296
    ///     instance.
297
    ///
298
    /// \return
299
    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
300
    ///     an error object if it failed.
301
    virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
302
    Launch(ProcessLaunchInfo &launch_info,
303
           NativeDelegate &native_delegate) = 0;
304
305
    /// Attach to an existing process.
306
    ///
307
    /// \param[in] pid
308
    ///     pid of the process locatable
309
    ///
310
    /// \param[in] native_delegate
311
    ///     The delegate that will receive messages regarding the
312
    ///     inferior.  Must outlive the NativeProcessProtocol
313
    ///     instance.
314
    ///
315
    /// \param[in] mainloop
316
    ///     The mainloop instance with which the process can register
317
    ///     callbacks. Must outlive the NativeProcessProtocol
318
    ///     instance.
319
    ///
320
    /// \return
321
    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
322
    ///     an error object if it failed.
323
    virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
324
    Attach(lldb::pid_t pid, NativeDelegate &native_delegate) = 0;
325
326
    /// Get the bitmask of extensions supported by this process plugin.
327
    ///
328
    /// \return
329
    ///     A NativeProcessProtocol::Extension bitmask.
330
0
    virtual Extension GetSupportedExtensions() const { return {}; }
331
332
  protected:
333
    MainLoop &m_mainloop;
334
  };
335
336
  /// Notify tracers that the target process will resume
337
0
  virtual void NotifyTracersProcessWillResume() {}
338
339
  /// Notify tracers that the target process just stopped
340
0
  virtual void NotifyTracersProcessDidStop() {}
341
342
  /// Start tracing a process or its threads.
343
  ///
344
  /// \param[in] json_params
345
  ///     JSON object with the information of what and how to trace.
346
  ///     In the case of gdb-remote, this object should conform to the
347
  ///     jLLDBTraceStart packet.
348
  ///
349
  ///     This object should have a string entry called "type", which is the
350
  ///     tracing technology name.
351
  ///
352
  /// \param[in] type
353
  ///     Tracing technology type, as described in the \a json_params.
354
  ///
355
  /// \return
356
  ///     \a llvm::Error::success if the operation was successful, or an
357
  ///     \a llvm::Error otherwise.
358
  virtual llvm::Error TraceStart(llvm::StringRef json_params,
359
0
                                 llvm::StringRef type) {
360
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
361
0
                                   "Unsupported tracing type '%s'",
362
0
                                   type.data());
363
0
  }
364
365
  /// \copydoc Process::TraceStop(const TraceStopRequest &)
366
0
  virtual llvm::Error TraceStop(const TraceStopRequest &request) {
367
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
368
0
                                   "Unsupported tracing type '%s'",
369
0
                                   request.type.data());
370
0
  }
371
372
  /// \copydoc Process::TraceGetState(llvm::StringRef type)
373
  virtual llvm::Expected<llvm::json::Value>
374
0
  TraceGetState(llvm::StringRef type) {
375
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
376
0
                                   "Unsupported tracing type '%s'",
377
0
                                   type.data());
378
0
  }
379
380
  /// \copydoc Process::TraceGetBinaryData(const TraceGetBinaryDataRequest &)
381
  virtual llvm::Expected<std::vector<uint8_t>>
382
0
  TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
383
0
    return llvm::createStringError(
384
0
        llvm::inconvertibleErrorCode(),
385
0
        "Unsupported data kind '%s' for the '%s' tracing technology",
386
0
        request.kind.c_str(), request.type.c_str());
387
0
  }
388
389
  /// \copydoc Process::TraceSupported()
390
0
  virtual llvm::Expected<TraceSupportedResponse> TraceSupported() {
391
0
    return llvm::make_error<UnimplementedError>();
392
0
  }
393
394
  /// Method called in order to propagate the bitmap of protocol
395
  /// extensions supported by the client.
396
  ///
397
  /// \param[in] flags
398
  ///     The bitmap of enabled extensions.
399
0
  virtual void SetEnabledExtensions(Extension flags) {
400
0
    m_enabled_extensions = flags;
401
0
  }
402
403
  /// Write a core dump (without crashing the program).
404
  ///
405
  /// \param[in] path_hint
406
  ///     Suggested core dump path (optional, can be empty).
407
  ///
408
  /// \return
409
  ///     Path to the core dump if successfully written, an error
410
  ///     otherwise.
411
0
  virtual llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) {
412
0
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
413
0
                                   "Not implemented");
414
0
  }
415
416
protected:
417
  struct SoftwareBreakpoint {
418
    uint32_t ref_count;
419
    llvm::SmallVector<uint8_t, 4> saved_opcodes;
420
    llvm::ArrayRef<uint8_t> breakpoint_opcodes;
421
  };
422
423
  std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
424
  lldb::pid_t m_pid;
425
426
  std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
427
  lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
428
  mutable std::recursive_mutex m_threads_mutex;
429
430
  lldb::StateType m_state = lldb::eStateInvalid;
431
  mutable std::recursive_mutex m_state_mutex;
432
433
  std::optional<WaitStatus> m_exit_status;
434
435
  NativeDelegate &m_delegate;
436
  NativeWatchpointList m_watchpoint_list;
437
  HardwareBreakpointMap m_hw_breakpoints_map;
438
  int m_terminal_fd;
439
  uint32_t m_stop_id = 0;
440
441
  // Set of signal numbers that LLDB directly injects back to inferior without
442
  // stopping it.
443
  llvm::DenseSet<int> m_signals_to_ignore;
444
445
  // Extensions enabled per the last SetEnabledExtensions() call.
446
  Extension m_enabled_extensions;
447
448
  // lldb_private::Host calls should be used to launch a process for debugging,
449
  // and then the process should be attached to. When attaching to a process
450
  // lldb_private::Host calls should be used to locate the process to attach
451
  // to, and then this function should be called.
452
  NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
453
                        NativeDelegate &delegate);
454
455
0
  void SetID(lldb::pid_t pid) { m_pid = pid; }
456
457
  // interface for state handling
458
  void SetState(lldb::StateType state, bool notify_delegates = true);
459
460
  // Derived classes need not implement this.  It can be used as a hook to
461
  // clear internal caches that should be invalidated when stop ids change.
462
  //
463
  // Note this function is called with the state mutex obtained by the caller.
464
  virtual void DoStopIDBumped(uint32_t newBumpId);
465
466
  // interface for software breakpoints
467
468
  Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
469
  Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
470
471
  virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
472
  GetSoftwareBreakpointTrapOpcode(size_t size_hint);
473
474
  /// Return the offset of the PC relative to the software breakpoint that was hit. If an
475
  /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset
476
  /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the
477
  /// PC, this offset will be the size of the breakpoint opcode.
478
  virtual size_t GetSoftwareBreakpointPCOffset();
479
480
  // Adjust the thread's PC after hitting a software breakpoint. On
481
  // architectures where the PC points after the breakpoint instruction, this
482
  // resets it to point to the breakpoint itself.
483
  void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread);
484
485
  /// Notify the delegate that an exec occurred.
486
  ///
487
  /// Provide a mechanism for a delegate to clear out any exec-
488
  /// sensitive data.
489
  virtual void NotifyDidExec();
490
491
  NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
492
493
private:
494
  void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
495
  llvm::Expected<SoftwareBreakpoint>
496
  EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
497
};
498
} // namespace lldb_private
499
500
#endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H