File indexing completed on 2026-05-10 08:42:48
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
0010 #define LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
0011
0012 #include "NativeBreakpointList.h"
0013 #include "NativeThreadProtocol.h"
0014 #include "NativeWatchpointList.h"
0015 #include "lldb/Host/Host.h"
0016 #include "lldb/Host/MainLoop.h"
0017 #include "lldb/Utility/ArchSpec.h"
0018 #include "lldb/Utility/Iterable.h"
0019 #include "lldb/Utility/Status.h"
0020 #include "lldb/Utility/TraceGDBRemotePackets.h"
0021 #include "lldb/Utility/UnimplementedError.h"
0022 #include "lldb/lldb-private-forward.h"
0023 #include "lldb/lldb-types.h"
0024 #include "llvm/ADT/ArrayRef.h"
0025 #include "llvm/ADT/DenseSet.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/Support/Error.h"
0028 #include "llvm/Support/MemoryBuffer.h"
0029 #include <mutex>
0030 #include <optional>
0031 #include <unordered_map>
0032 #include <vector>
0033
0034 namespace lldb_private {
0035 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
0036
0037 class MemoryRegionInfo;
0038 class ResumeActionList;
0039
0040 struct SVR4LibraryInfo {
0041 std::string name;
0042 lldb::addr_t link_map;
0043 lldb::addr_t base_addr;
0044 lldb::addr_t ld_addr;
0045 lldb::addr_t next;
0046 };
0047
0048
0049 class NativeProcessProtocol {
0050 public:
0051 virtual ~NativeProcessProtocol() = default;
0052
0053 typedef std::vector<std::unique_ptr<NativeThreadProtocol>> thread_collection;
0054 template <typename I>
0055 static NativeThreadProtocol &thread_list_adapter(I &iter) {
0056 assert(*iter);
0057 return **iter;
0058 }
0059 typedef LockingAdaptedIterable<thread_collection, NativeThreadProtocol &,
0060 thread_list_adapter, std::recursive_mutex>
0061 ThreadIterable;
0062
0063 virtual Status Resume(const ResumeActionList &resume_actions) = 0;
0064
0065 virtual Status Halt() = 0;
0066
0067 virtual Status Detach() = 0;
0068
0069
0070
0071
0072
0073 virtual Status Signal(int signo) = 0;
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 virtual Status Interrupt();
0084
0085 virtual Status Kill() = 0;
0086
0087
0088
0089 virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
0090
0091
0092
0093 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
0094 MemoryRegionInfo &range_info);
0095
0096 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
0097 size_t &bytes_read) = 0;
0098
0099 Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
0100 size_t &bytes_read);
0101
0102 virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
0103 std::vector<uint8_t> &tags);
0104
0105 virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
0106 const std::vector<uint8_t> &tags);
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 llvm::Expected<llvm::StringRef>
0130 ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size,
0131 size_t &total_bytes_read);
0132
0133 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
0134 size_t &bytes_written) = 0;
0135
0136 virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
0137 uint32_t permissions) {
0138 return llvm::make_error<UnimplementedError>();
0139 }
0140
0141 virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
0142 return llvm::make_error<UnimplementedError>();
0143 }
0144
0145 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
0146
0147 virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
0148 GetLoadedSVR4Libraries() {
0149 return llvm::createStringError(llvm::inconvertibleErrorCode(),
0150 "Not implemented");
0151 }
0152
0153 virtual bool IsAlive() const;
0154
0155 virtual size_t UpdateThreads() = 0;
0156
0157 virtual const ArchSpec &GetArchitecture() const = 0;
0158
0159
0160 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
0161 bool hardware) = 0;
0162
0163 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
0164
0165
0166 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
0167
0168 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
0169
0170 virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
0171
0172
0173 virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
0174
0175 virtual std::optional<std::pair<uint32_t, uint32_t>>
0176 GetHardwareDebugSupportInfo() const;
0177
0178 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
0179 uint32_t watch_flags, bool hardware);
0180
0181 virtual Status RemoveWatchpoint(lldb::addr_t addr);
0182
0183
0184 lldb::pid_t GetID() const { return m_pid; }
0185
0186 lldb::StateType GetState() const;
0187
0188 bool IsRunning() const {
0189 return m_state == lldb::eStateRunning || IsStepping();
0190 }
0191
0192 bool IsStepping() const { return m_state == lldb::eStateStepping; }
0193
0194 bool CanResume() const { return m_state == lldb::eStateStopped; }
0195
0196 lldb::ByteOrder GetByteOrder() const {
0197 return GetArchitecture().GetByteOrder();
0198 }
0199
0200 uint32_t GetAddressByteSize() const {
0201 return GetArchitecture().GetAddressByteSize();
0202 }
0203
0204 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
0205 GetAuxvData() const = 0;
0206
0207
0208 virtual std::optional<WaitStatus> GetExitStatus();
0209
0210 virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
0211
0212
0213 NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);
0214
0215 NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);
0216
0217 void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
0218
0219 lldb::tid_t GetCurrentThreadID() const { return m_current_thread_id; }
0220
0221 NativeThreadProtocol *GetCurrentThread() {
0222 return GetThreadByID(m_current_thread_id);
0223 }
0224
0225 ThreadIterable Threads() const {
0226 return ThreadIterable(m_threads, m_threads_mutex);
0227 }
0228
0229
0230 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
0231
0232
0233
0234 uint32_t GetStopID() const;
0235
0236
0237 class NativeDelegate {
0238 public:
0239 virtual ~NativeDelegate() = default;
0240
0241 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
0242
0243 virtual void ProcessStateChanged(NativeProcessProtocol *process,
0244 lldb::StateType state) = 0;
0245
0246 virtual void DidExec(NativeProcessProtocol *process) = 0;
0247
0248 virtual void
0249 NewSubprocess(NativeProcessProtocol *parent_process,
0250 std::unique_ptr<NativeProcessProtocol> child_process) = 0;
0251 };
0252
0253 virtual Status GetLoadedModuleFileSpec(const char *module_path,
0254 FileSpec &file_spec) = 0;
0255
0256 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
0257 lldb::addr_t &load_addr) = 0;
0258
0259
0260
0261 enum class Extension {
0262 multiprocess = (1u << 0),
0263 fork = (1u << 1),
0264 vfork = (1u << 2),
0265 pass_signals = (1u << 3),
0266 auxv = (1u << 4),
0267 libraries_svr4 = (1u << 5),
0268 memory_tagging = (1u << 6),
0269 savecore = (1u << 7),
0270 siginfo_read = (1u << 8),
0271
0272 LLVM_MARK_AS_BITMASK_ENUM(siginfo_read)
0273 };
0274
0275 class Manager {
0276 public:
0277 Manager(MainLoop &mainloop) : m_mainloop(mainloop) {}
0278 Manager(const Manager &) = delete;
0279 Manager &operator=(const Manager &) = delete;
0280
0281 virtual ~Manager();
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
0302 Launch(ProcessLaunchInfo &launch_info,
0303 NativeDelegate &native_delegate) = 0;
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
0324 Attach(lldb::pid_t pid, NativeDelegate &native_delegate) = 0;
0325
0326
0327
0328
0329
0330 virtual Extension GetSupportedExtensions() const { return {}; }
0331
0332 protected:
0333 MainLoop &m_mainloop;
0334 };
0335
0336
0337 virtual void NotifyTracersProcessWillResume() {}
0338
0339
0340 virtual void NotifyTracersProcessDidStop() {}
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 virtual llvm::Error TraceStart(llvm::StringRef json_params,
0359 llvm::StringRef type) {
0360 return llvm::createStringError(llvm::inconvertibleErrorCode(),
0361 "Unsupported tracing type '%s'",
0362 type.data());
0363 }
0364
0365
0366 virtual llvm::Error TraceStop(const TraceStopRequest &request) {
0367 return llvm::createStringError(llvm::inconvertibleErrorCode(),
0368 "Unsupported tracing type '%s'",
0369 request.type.data());
0370 }
0371
0372
0373 virtual llvm::Expected<llvm::json::Value>
0374 TraceGetState(llvm::StringRef type) {
0375 return llvm::createStringError(llvm::inconvertibleErrorCode(),
0376 "Unsupported tracing type '%s'",
0377 type.data());
0378 }
0379
0380
0381 virtual llvm::Expected<std::vector<uint8_t>>
0382 TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
0383 return llvm::createStringError(
0384 llvm::inconvertibleErrorCode(),
0385 "Unsupported data kind '%s' for the '%s' tracing technology",
0386 request.kind.c_str(), request.type.c_str());
0387 }
0388
0389
0390 virtual llvm::Expected<TraceSupportedResponse> TraceSupported() {
0391 return llvm::make_error<UnimplementedError>();
0392 }
0393
0394
0395
0396
0397
0398
0399 virtual void SetEnabledExtensions(Extension flags) {
0400 m_enabled_extensions = flags;
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 virtual llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) {
0412 return llvm::createStringError(llvm::inconvertibleErrorCode(),
0413 "Not implemented");
0414 }
0415
0416 protected:
0417 struct SoftwareBreakpoint {
0418 uint32_t ref_count;
0419 llvm::SmallVector<uint8_t, 4> saved_opcodes;
0420 llvm::ArrayRef<uint8_t> breakpoint_opcodes;
0421 };
0422
0423 std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
0424 lldb::pid_t m_pid;
0425
0426 std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
0427 lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
0428 mutable std::recursive_mutex m_threads_mutex;
0429
0430 lldb::StateType m_state = lldb::eStateInvalid;
0431 mutable std::recursive_mutex m_state_mutex;
0432
0433 std::optional<WaitStatus> m_exit_status;
0434
0435 NativeDelegate &m_delegate;
0436 NativeWatchpointList m_watchpoint_list;
0437 HardwareBreakpointMap m_hw_breakpoints_map;
0438 int m_terminal_fd;
0439 uint32_t m_stop_id = 0;
0440
0441
0442
0443 llvm::DenseSet<int> m_signals_to_ignore;
0444
0445
0446 Extension m_enabled_extensions;
0447
0448
0449
0450
0451
0452 NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
0453 NativeDelegate &delegate);
0454
0455 void SetID(lldb::pid_t pid) { m_pid = pid; }
0456
0457
0458 void SetState(lldb::StateType state, bool notify_delegates = true);
0459
0460
0461
0462
0463
0464 virtual void DoStopIDBumped(uint32_t newBumpId);
0465
0466
0467
0468 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
0469 Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
0470
0471 virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
0472 GetSoftwareBreakpointTrapOpcode(size_t size_hint);
0473
0474
0475
0476
0477
0478 virtual size_t GetSoftwareBreakpointPCOffset();
0479
0480
0481
0482
0483 void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread);
0484
0485
0486
0487
0488
0489 virtual void NotifyDidExec();
0490
0491 NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
0492
0493 private:
0494 void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
0495 llvm::Expected<SoftwareBreakpoint>
0496 EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
0497 };
0498 }
0499
0500 #endif