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 // NativeProcessProtocol 36 class NativeProcessProtocol { 37 public: 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 357 protected: 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 430 private: 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_ 438