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 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 31 namespace lldb_private { 32 class MemoryRegionInfo; 33 class ResumeActionList; 34 35 struct SVR4LibraryInfo { 36 std::string name; 37 lldb::addr_t link_map; 38 lldb::addr_t base_addr; 39 lldb::addr_t ld_addr; 40 lldb::addr_t next; 41 }; 42 43 // NativeProcessProtocol 44 class NativeProcessProtocol { 45 public: 46 virtual ~NativeProcessProtocol() {} 47 48 virtual Status Resume(const ResumeActionList &resume_actions) = 0; 49 50 virtual Status Halt() = 0; 51 52 virtual Status Detach() = 0; 53 54 /// Sends a process a UNIX signal \a signal. 55 /// 56 /// \return 57 /// Returns an error object. 58 virtual Status Signal(int signo) = 0; 59 60 /// Tells a process to interrupt all operations as if by a Ctrl-C. 61 /// 62 /// The default implementation will send a local host's equivalent of 63 /// a SIGSTOP to the process via the NativeProcessProtocol::Signal() 64 /// operation. 65 /// 66 /// \return 67 /// Returns an error object. 68 virtual Status Interrupt(); 69 70 virtual Status Kill() = 0; 71 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); 75 76 // Memory and memory region functions 77 78 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr, 79 MemoryRegionInfo &range_info); 80 81 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, 82 size_t &bytes_read) = 0; 83 84 Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, 85 size_t &bytes_read); 86 87 /// Reads a null terminated string from memory. 88 /// 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. 92 /// 93 /// \param[in] addr 94 /// The address in memory to read from. 95 /// 96 /// \param[in] buffer 97 /// An allocated buffer with at least \p max_size size. 98 /// 99 /// \param[in] max_size 100 /// The maximum number of bytes to read from memory until it reads the 101 /// string. 102 /// 103 /// \param[out] total_bytes_read 104 /// The number of bytes read from memory into \p buffer. 105 /// 106 /// \return 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); 111 112 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, 113 size_t &bytes_written) = 0; 114 115 virtual Status AllocateMemory(size_t size, uint32_t permissions, 116 lldb::addr_t &addr) = 0; 117 118 virtual Status DeallocateMemory(lldb::addr_t addr) = 0; 119 120 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0; 121 122 virtual llvm::Expected<std::vector<SVR4LibraryInfo>> 123 GetLoadedSVR4Libraries() { 124 return llvm::createStringError(llvm::inconvertibleErrorCode(), 125 "Not implemented"); 126 } 127 128 virtual bool IsAlive() const; 129 130 virtual size_t UpdateThreads() = 0; 131 132 virtual const ArchSpec &GetArchitecture() const = 0; 133 134 // Breakpoint functions 135 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size, 136 bool hardware) = 0; 137 138 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false); 139 140 // Hardware Breakpoint functions 141 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const; 142 143 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size); 144 145 virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr); 146 147 // Watchpoint functions 148 virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const; 149 150 virtual llvm::Optional<std::pair<uint32_t, uint32_t>> 151 GetHardwareDebugSupportInfo() const; 152 153 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size, 154 uint32_t watch_flags, bool hardware); 155 156 virtual Status RemoveWatchpoint(lldb::addr_t addr); 157 158 // Accessors 159 lldb::pid_t GetID() const { return m_pid; } 160 161 lldb::StateType GetState() const; 162 163 bool IsRunning() const { 164 return m_state == lldb::eStateRunning || IsStepping(); 165 } 166 167 bool IsStepping() const { return m_state == lldb::eStateStepping; } 168 169 bool CanResume() const { return m_state == lldb::eStateStopped; } 170 171 lldb::ByteOrder GetByteOrder() const { 172 return GetArchitecture().GetByteOrder(); 173 } 174 175 uint32_t GetAddressByteSize() const { 176 return GetArchitecture().GetAddressByteSize(); 177 } 178 179 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 180 GetAuxvData() const = 0; 181 182 // Exit Status 183 virtual llvm::Optional<WaitStatus> GetExitStatus(); 184 185 virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange); 186 187 // Access to threads 188 NativeThreadProtocol *GetThreadAtIndex(uint32_t idx); 189 190 NativeThreadProtocol *GetThreadByID(lldb::tid_t tid); 191 192 void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; } 193 194 lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; } 195 196 NativeThreadProtocol *GetCurrentThread() { 197 return GetThreadByID(m_current_thread_id); 198 } 199 200 // Access to inferior stdio 201 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; } 202 203 // Stop id interface 204 205 uint32_t GetStopID() const; 206 207 // Callbacks for low-level process state changes 208 class NativeDelegate { 209 public: 210 virtual ~NativeDelegate() {} 211 212 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0; 213 214 virtual void ProcessStateChanged(NativeProcessProtocol *process, 215 lldb::StateType state) = 0; 216 217 virtual void DidExec(NativeProcessProtocol *process) = 0; 218 }; 219 220 /// Register a native delegate. 221 /// 222 /// Clients can register nofication callbacks by passing in a 223 /// NativeDelegate impl and passing it into this function. 224 /// 225 /// Note: it is required that the lifetime of the 226 /// native_delegate outlive the NativeProcessProtocol. 227 /// 228 /// \param[in] native_delegate 229 /// A NativeDelegate impl to be called when certain events 230 /// happen within the NativeProcessProtocol or related threads. 231 /// 232 /// \return 233 /// true if the delegate was registered successfully; 234 /// false if the delegate was already registered. 235 /// 236 /// \see NativeProcessProtocol::NativeDelegate. 237 bool RegisterNativeDelegate(NativeDelegate &native_delegate); 238 239 /// Unregister a native delegate previously registered. 240 /// 241 /// \param[in] native_delegate 242 /// A NativeDelegate impl previously registered with this process. 243 /// 244 /// \return Returns \b true if the NativeDelegate was 245 /// successfully removed from the process, \b false otherwise. 246 /// 247 /// \see NativeProcessProtocol::NativeDelegate 248 bool UnregisterNativeDelegate(NativeDelegate &native_delegate); 249 250 virtual Status GetLoadedModuleFileSpec(const char *module_path, 251 FileSpec &file_spec) = 0; 252 253 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name, 254 lldb::addr_t &load_addr) = 0; 255 256 class Factory { 257 public: 258 virtual ~Factory(); 259 /// Launch a process for debugging. 260 /// 261 /// \param[in] launch_info 262 /// Information required to launch the process. 263 /// 264 /// \param[in] native_delegate 265 /// The delegate that will receive messages regarding the 266 /// inferior. Must outlive the NativeProcessProtocol 267 /// instance. 268 /// 269 /// \param[in] mainloop 270 /// The mainloop instance with which the process can register 271 /// callbacks. Must outlive the NativeProcessProtocol 272 /// instance. 273 /// 274 /// \return 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; 280 281 /// Attach to an existing process. 282 /// 283 /// \param[in] pid 284 /// pid of the process locatable 285 /// 286 /// \param[in] native_delegate 287 /// The delegate that will receive messages regarding the 288 /// inferior. Must outlive the NativeProcessProtocol 289 /// instance. 290 /// 291 /// \param[in] mainloop 292 /// The mainloop instance with which the process can register 293 /// callbacks. Must outlive the NativeProcessProtocol 294 /// instance. 295 /// 296 /// \return 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; 302 }; 303 304 /// StartTracing API for starting a tracing instance with the 305 /// TraceOptions on a specific thread or process. 306 /// 307 /// \param[in] config 308 /// The configuration to use when starting tracing. 309 /// 310 /// \param[out] error 311 /// Status indicates what went wrong. 312 /// 313 /// \return 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 318 /// thread. 319 virtual lldb::user_id_t StartTrace(const TraceOptions &config, 320 Status &error) { 321 error.SetErrorString("Not implemented"); 322 return LLDB_INVALID_UID; 323 } 324 325 /// StopTracing API as the name suggests stops a tracing instance. 326 /// 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. 332 /// 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. 336 /// 337 /// \return 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"); 342 } 343 344 /// This API provides the trace data collected in the form of raw 345 /// data. 346 /// 347 /// \param[in] traceid thread 348 /// The traceid and thread provide the context for the trace 349 /// instance. 350 /// 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. 355 /// 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. 360 /// 361 /// \return 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, 365 size_t offset = 0) { 366 return Status("Not implemented"); 367 } 368 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, 373 size_t offset = 0) { 374 return Status("Not implemented"); 375 } 376 377 /// API to query the TraceOptions for a given user id 378 /// 379 /// \param[in] traceid 380 /// The user id of the tracing instance. 381 /// 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 385 /// config. 386 /// 387 /// \param[out] error 388 /// Status indicates what went wrong. 389 /// 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"); 394 } 395 396 protected: 397 struct SoftwareBreakpoint { 398 uint32_t ref_count; 399 llvm::SmallVector<uint8_t, 4> saved_opcodes; 400 llvm::ArrayRef<uint8_t> breakpoint_opcodes; 401 }; 402 403 std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints; 404 lldb::pid_t m_pid; 405 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; 409 410 lldb::StateType m_state = lldb::eStateInvalid; 411 mutable std::recursive_mutex m_state_mutex; 412 413 llvm::Optional<WaitStatus> m_exit_status; 414 415 std::recursive_mutex m_delegates_mutex; 416 std::vector<NativeDelegate *> m_delegates; 417 NativeWatchpointList m_watchpoint_list; 418 HardwareBreakpointMap m_hw_breakpoints_map; 419 int m_terminal_fd; 420 uint32_t m_stop_id = 0; 421 422 // Set of signal numbers that LLDB directly injects back to inferior without 423 // stopping it. 424 llvm::DenseSet<int> m_signals_to_ignore; 425 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); 432 433 void SetID(lldb::pid_t pid) { m_pid = pid; } 434 435 // interface for state handling 436 void SetState(lldb::StateType state, bool notify_delegates = true); 437 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. 440 // 441 // Note this function is called with the state mutex obtained by the caller. 442 virtual void DoStopIDBumped(uint32_t newBumpId); 443 444 // interface for software breakpoints 445 446 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint); 447 Status RemoveSoftwareBreakpoint(lldb::addr_t addr); 448 449 virtual llvm::Expected<llvm::ArrayRef<uint8_t>> 450 GetSoftwareBreakpointTrapOpcode(size_t size_hint); 451 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(); 457 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); 462 463 /// Notify the delegate that an exec occurred. 464 /// 465 /// Provide a mechanism for a delegate to clear out any exec- 466 /// sensitive data. 467 void NotifyDidExec(); 468 469 NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid); 470 471 private: 472 void SynchronouslyNotifyProcessStateChanged(lldb::StateType state); 473 llvm::Expected<SoftwareBreakpoint> 474 EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint); 475 }; 476 } // namespace lldb_private 477 478 #endif // #ifndef liblldb_NativeProcessProtocol_h_ 479